Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8b13126d0 | ||
|
|
96cfe0b70d | ||
|
|
6dbb938368 | ||
|
|
46fe7a8aed | ||
|
|
3151ac6bf0 | ||
|
|
dc5210f691 | ||
|
|
1f02265003 | ||
|
|
e4af9032e2 | ||
|
|
e8650b2420 | ||
|
|
9c6b718be2 | ||
|
|
8f12114a56 | ||
|
|
dc6ebffab1 | ||
|
|
13e894e9a3 | ||
|
|
4c95773131 | ||
|
|
38776a01e4 | ||
|
|
b2563e534d | ||
|
|
37f25c1f97 | ||
|
|
642085ca32 | ||
|
|
5dee29a21c | ||
|
|
b01d13976b | ||
|
|
ae1c83a011 | ||
|
|
e5f962dc3f | ||
|
|
54dd79d2dd | ||
|
|
935fb6ffe3 | ||
|
|
48d1c1a080 | ||
|
|
2d02ce2a1b | ||
|
|
29fda59a72 | ||
|
|
05f0dfd4f5 | ||
|
|
0bdc5a83f1 | ||
|
|
8688bf1210 | ||
|
|
bf0858d57e | ||
|
|
8d4d391310 | ||
|
|
8fb15336c4 | ||
|
|
883385c42b | ||
|
|
6d1139796e | ||
|
|
e58eb5f56a | ||
|
|
2b0ce49646 | ||
|
|
73364127d2 | ||
|
|
84a986bc88 | ||
|
|
f13051aa31 | ||
|
|
6bb559303b | ||
|
|
b7324f9a44 | ||
|
|
c0b2bbe552 | ||
|
|
8c36cf40fd | ||
|
|
717296269f | ||
|
|
4be29abede | ||
|
|
528af9684e | ||
|
|
ff7a4ef190 | ||
|
|
99a2dbb956 | ||
|
|
280341791a | ||
|
|
1759565920 | ||
|
|
f57fa678f6 | ||
|
|
f8b5b16109 | ||
|
|
005a678089 | ||
|
|
315dd53dcb | ||
|
|
bb24495b3f | ||
|
|
b9f2764990 | ||
|
|
a9a00629b1 | ||
|
|
1223a9013f | ||
|
|
ab019eef0f | ||
|
|
20f82ff739 | ||
|
|
4d55a6a7e9 | ||
|
|
d7ec41d56e | ||
|
|
a6a1929a43 | ||
|
|
722850ceb6 | ||
|
|
5a976764c3 | ||
|
|
f90becb2f6 | ||
|
|
5296b2eb39 | ||
|
|
987a30e15f | ||
|
|
0880c3639c | ||
|
|
2972d40d92 | ||
|
|
c4430ef18d | ||
|
|
6b97af13bf | ||
|
|
cd18ca64bb | ||
|
|
d3c6302681 | ||
|
|
58bd3cc706 | ||
|
|
8d3401f962 | ||
|
|
dfc86015bd | ||
|
|
772ee3a680 | ||
|
|
f217ca9bbe | ||
|
|
fab8d604d2 | ||
|
|
7767ae497b | ||
|
|
58e41dfcf1 | ||
|
|
796ab2bf90 | ||
|
|
dfa07bf94b | ||
|
|
f43c74d59b | ||
|
|
fd9ee45dac |
@@ -31,43 +31,44 @@ do
|
||||
exit 1
|
||||
fi
|
||||
echo "Compiling source for $ARCH in directory $OPUS_DIR"
|
||||
|
||||
echo "cd $OPUS_DIR"
|
||||
cd $OPUS_DIR
|
||||
|
||||
DIST_DIR=$DIST_DIR_BASE-$ARCH
|
||||
echo "mkdir -p $DIST_DIR"
|
||||
mkdir -p $DIST_DIR
|
||||
CFLAGS_ARCH=$ARCH
|
||||
case $ARCH in
|
||||
armv7)
|
||||
EXTRA_FLAGS="--with-pic --enable-fixed-point"
|
||||
EXTRA_CFLAGS="-mcpu=cortex-a8 -mfpu=neon"
|
||||
EXTRA_CFLAGS="-mcpu=cortex-a8 -mfpu=neon -miphoneos-version-min=7.1"
|
||||
PLATFORM="${PLATFORMBASE}/iPhoneOS.platform"
|
||||
IOSSDK=iPhoneOS${IOSSDK_VER}
|
||||
IOSSDK=iPhoneOS
|
||||
;;
|
||||
armv7s)
|
||||
EXTRA_FLAGS="--with-pic --enable-fixed-point"
|
||||
EXTRA_CFLAGS="-mcpu=cortex-a9 -mfpu=neon -miphoneos-version-min=6.0"
|
||||
EXTRA_CFLAGS="-mcpu=cortex-a9 -mfpu=neon -miphoneos-version-min=7.1"
|
||||
PLATFORM="${PLATFORMBASE}/iPhoneOS.platform"
|
||||
IOSSDK=iPhoneOS${IOSSDK_VER}
|
||||
IOSSDK=iPhoneOS
|
||||
;;
|
||||
aarch64)
|
||||
CFLAGS_ARCH="arm64"
|
||||
EXTRA_FLAGS="--with-pic --enable-fixed-point"
|
||||
EXTRA_CFLAGS="-miphoneos-version-min=7.1"
|
||||
PLATFORM="${PLATFORMBASE}/iPhoneOS.platform"
|
||||
IOSSDK=iPhoneOS${IOSSDK_VER}
|
||||
IOSSDK=iPhoneOS
|
||||
;;
|
||||
x86_64)
|
||||
EXTRA_FLAGS="--with-pic"
|
||||
EXTRA_CFLAGS="-miphoneos-version-min=7.1"
|
||||
PLATFORM="${PLATFORMBASE}/iPhoneSimulator.platform"
|
||||
IOSSDK=iPhoneSimulator${IOSSDK_VER}
|
||||
IOSSDK=iPhoneSimulator
|
||||
;;
|
||||
i386)
|
||||
EXTRA_FLAGS="--with-pic"
|
||||
EXTRA_CFLAGS="-miphoneos-version-min=7.1"
|
||||
PLATFORM="${PLATFORMBASE}/iPhoneSimulator.platform"
|
||||
IOSSDK=iPhoneSimulator${IOSSDK_VER}
|
||||
IOSSDK=iPhoneSimulator
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported architecture ${ARCH}"
|
||||
@@ -76,7 +77,7 @@ do
|
||||
esac
|
||||
|
||||
echo "Configuring opus for $ARCH..."
|
||||
|
||||
echo "./autogen.sh"
|
||||
./autogen.sh
|
||||
|
||||
CFLAGS="-g -O2 -pipe -arch ${CFLAGS_ARCH} \
|
||||
@@ -86,7 +87,10 @@ do
|
||||
LDFLAGS="-arch ${CFLAGS_ARCH} \
|
||||
-isysroot ${PLATFORM}/Developer/SDKs/${IOSSDK}.sdk \
|
||||
-L${PLATFORM}/Developer/SDKs/${IOSSDK}.sdk/usr/lib"
|
||||
|
||||
|
||||
echo "CFLAGS=$CFLAGS"
|
||||
echo "LDFLAGS=$LDFLAGS"
|
||||
|
||||
export CFLAGS
|
||||
export LDFLAGS
|
||||
|
||||
@@ -100,7 +104,15 @@ do
|
||||
export NM="/usr/bin/nm"
|
||||
export RANLIB="/usr/bin/ranlib"
|
||||
export STRIP="/usr/bin/strip"
|
||||
|
||||
echo "./configure \
|
||||
--prefix=$DIST_DIR \
|
||||
--host=${ARCH}-apple-darwin \
|
||||
--with-sysroot=${PLATFORM}/Developer/SDKs/${IOSSDK}.sdk \
|
||||
--enable-static=yes \
|
||||
--enable-shared=no \
|
||||
--disable-doc \
|
||||
${EXTRA_FLAGS}"
|
||||
|
||||
./configure \
|
||||
--prefix=$DIST_DIR \
|
||||
--host=${ARCH}-apple-darwin \
|
||||
@@ -111,10 +123,14 @@ do
|
||||
${EXTRA_FLAGS}
|
||||
|
||||
echo "Installing opus for $ARCH..."
|
||||
echo "make clean"
|
||||
make clean
|
||||
echo "make -j$NJOB V=1"
|
||||
make -j$NJOB V=1
|
||||
echo "make install"
|
||||
make install
|
||||
|
||||
echo "cd $SCRIPT_DIR"
|
||||
cd $SCRIPT_DIR
|
||||
|
||||
if [ -d $DIST_DIR/bin ]
|
||||
|
||||
@@ -7,7 +7,6 @@ source config.sh
|
||||
SCRIPT_DIR=$( (cd -P $(dirname $0) && pwd) )
|
||||
DIST_DIR_BASE=${DIST_DIR_BASE:="$SCRIPT_DIR/dist"}
|
||||
|
||||
git submodule update --init opus
|
||||
cd opus
|
||||
git checkout master
|
||||
git pull origin master
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6254" systemVersion="14C81f" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="8121.17" systemVersion="15A204h" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6247"/>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8101.14"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
@@ -10,24 +11,21 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright (c) 2014 Limelight Stream. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
|
||||
<rect key="frame" x="22" y="439" width="437" height="21"/>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright (c) 2015 Moonlight Stream. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
|
||||
<rect key="frame" x="18" y="439.5" width="444" height="20.5"/>
|
||||
<animations/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" red="0.070588235294117646" green="0.45490196078431372" blue="0.074509803921568626" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="textColor" red="0.72941176470000002" green="0.69411764710000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<variation key="widthClass=compact">
|
||||
<fontDescription key="fontDescription" type="system" pointSize="11"/>
|
||||
</variation>
|
||||
</label>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Limelight Flat Design Banner" translatesAutoresizingMaskIntoConstraints="NO" id="lr8-1h-ydW">
|
||||
<rect key="frame" x="-8" y="115" width="496" height="251"/>
|
||||
</imageView>
|
||||
</subviews>
|
||||
<animations/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="centerY" secondItem="lr8-1h-ydW" secondAttribute="centerY" id="C8A-9E-cM6"/>
|
||||
<constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Gnz-uJ-CDw"/>
|
||||
<constraint firstAttribute="centerX" secondItem="lr8-1h-ydW" secondAttribute="centerX" id="WCv-Cd-TyR"/>
|
||||
<constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
|
||||
</constraints>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
@@ -35,7 +33,4 @@
|
||||
<point key="canvasLocation" x="404" y="445"/>
|
||||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="Limelight Flat Design Banner" width="496" height="251"/>
|
||||
</resources>
|
||||
</document>
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
//
|
||||
// App.h
|
||||
// Limelight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/22/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface App : NSObject
|
||||
|
||||
@property NSString* appId;
|
||||
@property NSString* appName;
|
||||
@property UIImage* appImage;
|
||||
@property BOOL isRunning;
|
||||
|
||||
@end
|
||||
@@ -1,15 +0,0 @@
|
||||
//
|
||||
// App.m
|
||||
// Limelight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/22/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "App.h"
|
||||
#import "HttpManager.h"
|
||||
|
||||
@implementation App
|
||||
@synthesize appId, appName, appImage, isRunning;
|
||||
|
||||
@end
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// AppDelegate.h
|
||||
// Limelight-iOS
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 1/17/14.
|
||||
// Copyright (c) 2014 Diego Waxemberg. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// AppDelegate.m
|
||||
// Limelight-iOS
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 1/17/14.
|
||||
// Copyright (c) 2014 Diego Waxemberg. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "AppDelegate.h"
|
||||
@@ -103,7 +103,7 @@ static NSOperationQueue* mainQueue;
|
||||
|
||||
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
|
||||
if (coordinator != nil) {
|
||||
_managedObjectContext = [[NSManagedObjectContext alloc] init];
|
||||
_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
|
||||
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
|
||||
}
|
||||
return _managedObjectContext;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// CryptoManager.h
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/14/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
@@ -16,6 +16,7 @@
|
||||
+ (NSData*) readKeyFromFile;
|
||||
+ (NSData*) readP12FromFile;
|
||||
+ (NSData*) getSignatureFromCert:(NSData*)cert;
|
||||
+ (NSData*) nullTerminateString:(NSData*)data;
|
||||
|
||||
- (NSData*) createAESKeyFromSalt:(NSData*)saltedPIN;
|
||||
- (NSData*) SHA1HashData:(NSData*)data;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// CryptoManager.m
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/14/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CryptoManager.h"
|
||||
@@ -76,8 +76,14 @@ static NSData* p12 = nil;
|
||||
return (((int)[data length] + 15) / 16) * 16;
|
||||
}
|
||||
|
||||
+ (NSData*) nullTerminateString:(NSData*)data {
|
||||
NSMutableData* mutData = [NSMutableData dataWithData:data];
|
||||
[mutData appendBytes:"" length:1];
|
||||
return mutData;
|
||||
}
|
||||
|
||||
- (bool) verifySignature:(NSData *)data withSignature:(NSData*)signature andCert:(NSData*)cert {
|
||||
const char* buffer = [cert bytes];
|
||||
const char* buffer = [[CryptoManager nullTerminateString:cert] bytes];
|
||||
X509* x509;
|
||||
BIO* bio = BIO_new(BIO_s_mem());
|
||||
BIO_puts(bio, buffer);
|
||||
@@ -105,7 +111,7 @@ static NSData* p12 = nil;
|
||||
}
|
||||
|
||||
- (NSData *)signData:(NSData *)data withKey:(NSData *)key {
|
||||
const char* buffer = [key bytes];
|
||||
const char* buffer = [[CryptoManager nullTerminateString:key] bytes];
|
||||
BIO* bio = BIO_new(BIO_s_mem());
|
||||
BIO_puts(bio, buffer);
|
||||
|
||||
@@ -188,7 +194,7 @@ static NSData* p12 = nil;
|
||||
}
|
||||
|
||||
+ (NSData *)getSignatureFromCert:(NSData *)cert {
|
||||
const char* buffer = [cert bytes];
|
||||
const char* buffer = [[CryptoManager nullTerminateString:cert] bytes];
|
||||
X509* x509;
|
||||
BIO* bio = BIO_new(BIO_s_mem());
|
||||
BIO_puts(bio, buffer);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// mkcert.h
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/16/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef Limelight_mkcert_h
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// App+CoreDataProperties.h
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 7/10/15.
|
||||
// Copyright © 2015 Limelight Stream. All rights reserved.
|
||||
//
|
||||
// Delete this file and regenerate it using "Create NSManagedObject Subclass…"
|
||||
// to keep your implementation up to date with your model.
|
||||
//
|
||||
|
||||
#import "App.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface App (CoreDataProperties)
|
||||
|
||||
@property (nullable, nonatomic, retain) NSString *id;
|
||||
@property (nullable, nonatomic, retain) NSData *image;
|
||||
@property (nullable, nonatomic, retain) NSString *name;
|
||||
@property (nullable, nonatomic, retain) Host *host;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// App.h
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 7/10/15.
|
||||
// Copyright © 2015 Limelight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <CoreData/CoreData.h>
|
||||
|
||||
@class Host;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface App : NSManagedObject
|
||||
|
||||
@property BOOL isRunning;
|
||||
|
||||
- (NSComparisonResult)compareName:(App *)other;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#import "App+CoreDataProperties.h"
|
||||
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// App.m
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 7/10/15.
|
||||
// Copyright © 2015 Limelight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "App.h"
|
||||
#import "Host.h"
|
||||
|
||||
@implementation App
|
||||
|
||||
@synthesize isRunning;
|
||||
|
||||
- (NSComparisonResult)compareName:(App *)other {
|
||||
return [self.name caseInsensitiveCompare:other.name];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,15 +1,16 @@
|
||||
//
|
||||
// DataManager.h
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/28/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "Settings.h"
|
||||
#import "AppDelegate.h"
|
||||
#import "Host.h"
|
||||
#import "App.h"
|
||||
|
||||
@interface DataManager : NSObject
|
||||
|
||||
@@ -18,8 +19,10 @@
|
||||
- (void) saveSettingsWithBitrate:(NSInteger)bitrate framerate:(NSInteger)framerate height:(NSInteger)height width:(NSInteger)width onscreenControls:(NSInteger)onscreenControls;
|
||||
- (Settings*) retrieveSettings;
|
||||
- (NSArray*) retrieveHosts;
|
||||
- (void) saveHosts;
|
||||
- (void) saveData;
|
||||
- (Host*) createHost;
|
||||
- (void) removeHost:(Host*)host;
|
||||
- (App*) createApp;
|
||||
- (void) removeApp:(App*)app;
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// DataManager.m
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/28/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "DataManager.h"
|
||||
@@ -48,15 +48,15 @@
|
||||
|
||||
- (Host*) createHost {
|
||||
NSEntityDescription* entity = [NSEntityDescription entityForName:@"Host" inManagedObjectContext:[self.appDelegate managedObjectContext]];
|
||||
Host* host = [[Host alloc] initWithEntity:entity insertIntoManagedObjectContext:[self.appDelegate managedObjectContext]];
|
||||
return host;
|
||||
return [[Host alloc] initWithEntity:entity insertIntoManagedObjectContext:[self.appDelegate managedObjectContext]];
|
||||
}
|
||||
|
||||
- (void) removeHost:(Host*)host {
|
||||
[[self.appDelegate managedObjectContext] deleteObject:host];
|
||||
[self saveData];
|
||||
}
|
||||
|
||||
- (void) saveHosts {
|
||||
- (void) saveData {
|
||||
NSError* error;
|
||||
if (![[self.appDelegate managedObjectContext] save:&error]) {
|
||||
Log(LOG_E, @"Unable to save hosts to database: %@", error);
|
||||
@@ -68,6 +68,15 @@
|
||||
return [self fetchRecords:@"Host"];
|
||||
}
|
||||
|
||||
- (App*) createApp {
|
||||
NSEntityDescription* entity = [NSEntityDescription entityForName:@"App" inManagedObjectContext:[self.appDelegate managedObjectContext]];
|
||||
return [[App alloc] initWithEntity:entity insertIntoManagedObjectContext:[self.appDelegate managedObjectContext]];
|
||||
}
|
||||
|
||||
- (void) removeApp:(App*)app {
|
||||
[[self.appDelegate managedObjectContext] deleteObject:app];
|
||||
}
|
||||
|
||||
- (NSArray*) fetchRecords:(NSString*)entityName {
|
||||
NSFetchRequest* fetchRequest = [[NSFetchRequest alloc] init];
|
||||
NSEntityDescription* entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:[self.appDelegate managedObjectContext]];
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// Host+CoreDataProperties.h
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 7/10/15.
|
||||
// Copyright © 2015 Limelight Stream. All rights reserved.
|
||||
//
|
||||
// Delete this file and regenerate it using "Create NSManagedObject Subclass…"
|
||||
// to keep your implementation up to date with your model.
|
||||
//
|
||||
|
||||
#import "Host.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface Host (CoreDataProperties)
|
||||
|
||||
@property (nullable, nonatomic, retain) NSString *address;
|
||||
@property (nullable, nonatomic, retain) NSString *externalAddress;
|
||||
@property (nullable, nonatomic, retain) NSString *localAddress;
|
||||
@property (nullable, nonatomic, retain) NSString *mac;
|
||||
@property (nullable, nonatomic, retain) NSString *name;
|
||||
@property (nullable, nonatomic, retain) NSNumber *pairState;
|
||||
@property (nullable, nonatomic, retain) NSString *uuid;
|
||||
@property (nullable, nonatomic, retain) NSSet *appList;
|
||||
|
||||
@end
|
||||
|
||||
@interface Host (CoreDataGeneratedAccessors)
|
||||
|
||||
- (void)addAppListObject:(NSManagedObject *)value;
|
||||
- (void)removeAppListObject:(NSManagedObject *)value;
|
||||
- (void)addAppList:(NSSet *)values;
|
||||
- (void)removeAppList:(NSSet *)values;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -1,24 +1,25 @@
|
||||
//
|
||||
// Host.h
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/28/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Created by Diego Waxemberg on 7/10/15.
|
||||
// Copyright © 2015 Limelight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <CoreData/CoreData.h>
|
||||
#import "Utils.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface Host : NSManagedObject
|
||||
|
||||
@property (nonatomic, retain) NSString * name;
|
||||
@property (nonatomic, retain) NSString * address;
|
||||
@property (nonatomic, retain) NSString * localAddress;
|
||||
@property (nonatomic, retain) NSString * externalAddress;
|
||||
@property (nonatomic, retain) NSString * uuid;
|
||||
@property (nonatomic, retain) NSString * mac;
|
||||
@property (nonatomic) BOOL online;
|
||||
@property (nonatomic) PairState pairState;
|
||||
@property (nonatomic) NSString * activeAddress;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#import "Host+CoreDataProperties.h"
|
||||
|
||||
@@ -1,23 +1,17 @@
|
||||
//
|
||||
// Host.m
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/28/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Created by Diego Waxemberg on 7/10/15.
|
||||
// Copyright © 2015 Limelight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Host.h"
|
||||
|
||||
|
||||
@implementation Host
|
||||
|
||||
@dynamic name;
|
||||
@dynamic address;
|
||||
@dynamic localAddress;
|
||||
@dynamic externalAddress;
|
||||
@dynamic uuid;
|
||||
@dynamic mac;
|
||||
@dynamic pairState;
|
||||
@synthesize online;
|
||||
@synthesize activeAddress;
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// Settings.h
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/28/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// Settings.m
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/28/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Settings.h"
|
||||
|
||||
@@ -3,17 +3,17 @@
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x",
|
||||
"filename" : "a_button.png"
|
||||
"filename" : "a_button_40x40@1x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "a_button-1.png"
|
||||
"filename" : "a_button_80x80@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"filename" : "a_button-2.png"
|
||||
"filename" : "a_button_120x120@3x.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
||||
|
Before Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 6.5 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
@@ -1,80 +1,80 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "2x",
|
||||
"filename" : "Icon-Small@2x.png"
|
||||
"idiom" : "iphone",
|
||||
"filename" : "app_icon_settings_58x58_@2x-1.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "3x",
|
||||
"filename" : "Icon-Small@3x.png"
|
||||
"idiom" : "iphone",
|
||||
"filename" : "app_icon_settings_87x87_@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "2x",
|
||||
"filename" : "Icon-40@2x.png"
|
||||
"idiom" : "iphone",
|
||||
"filename" : "app_icon_spotlight_80x80_@2x-1.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "3x",
|
||||
"filename" : "Icon-40@3x.png"
|
||||
"idiom" : "iphone",
|
||||
"filename" : "app_icon_spotlight_120x120_@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "2x",
|
||||
"filename" : "[email protected]"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"filename" : "[email protected]",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"scale" : "3x",
|
||||
"filename" : "Icon-60@3x.png"
|
||||
"idiom" : "iphone",
|
||||
"filename" : "app_icon_180x180_@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "29x29",
|
||||
"scale" : "1x",
|
||||
"filename" : "Icon-Small.png"
|
||||
"idiom" : "ipad",
|
||||
"filename" : "app_icon_settings_29x29_@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "29x29",
|
||||
"scale" : "2x",
|
||||
"filename" : "Icon-Small@2x.png"
|
||||
"idiom" : "ipad",
|
||||
"filename" : "app_icon_settings_58x58_@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "40x40",
|
||||
"scale" : "1x",
|
||||
"filename" : "Icon-40.png"
|
||||
"idiom" : "ipad",
|
||||
"filename" : "app_icon_spotlight_40x40_@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "40x40",
|
||||
"scale" : "2x",
|
||||
"filename" : "Icon-40@2x.png"
|
||||
"idiom" : "ipad",
|
||||
"filename" : "app_icon_spotlight_80x80_@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "76x76",
|
||||
"scale" : "1x",
|
||||
"filename" : "Icon-76.png"
|
||||
"idiom" : "ipad",
|
||||
"filename" : "app_icon_76x76_@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "76x76",
|
||||
"scale" : "2x",
|
||||
"filename" : "Icon-76@2x.png"
|
||||
"idiom" : "ipad",
|
||||
"filename" : "app_icon_152x152_@2x.png",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "makeappicon"
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 9.3 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 8.7 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 57 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 41 KiB |
@@ -3,17 +3,17 @@
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x",
|
||||
"filename" : "b_button.png"
|
||||
"filename" : "b_button_40x40@1x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "b_button-1.png"
|
||||
"filename" : "b_button_80x80@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"filename" : "b_button-2.png"
|
||||
"filename" : "b_button_120x120@3x.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
||||
|
Before Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 6.3 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
@@ -3,17 +3,17 @@
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x",
|
||||
"filename" : "down.png"
|
||||
"filename" : "down_31x38@1x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "down-1.png"
|
||||
"filename" : "down_61x75@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"filename" : "down-2.png"
|
||||
"filename" : "down_93x114@3x.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
||||
|
Before Width: | Height: | Size: 455 B |
|
Before Width: | Height: | Size: 455 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 455 B After Width: | Height: | Size: 455 B |
|
After Width: | Height: | Size: 3.6 KiB |
@@ -3,17 +3,17 @@
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x",
|
||||
"filename" : "L1-1.png"
|
||||
"filename" : "L1_40x40@1x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "L1.png"
|
||||
"filename" : "L1_80x80@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"filename" : "L1-2.png"
|
||||
"filename" : "L1_120x120@3x.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
||||
|
Before Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 6.3 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
@@ -3,17 +3,17 @@
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x",
|
||||
"filename" : "L2.png"
|
||||
"filename" : "L2_60x60@1x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "L2-1.png"
|
||||
"filename" : "L2_120x120@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"filename" : "L2-2.png"
|
||||
"filename" : "L2_180x180@3x.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
||||
|
Before Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 8.1 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
@@ -3,17 +3,17 @@
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x",
|
||||
"filename" : "L3.png"
|
||||
"filename" : "L3_80x80@1x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "L3-1.png"
|
||||
"filename" : "L3_160x160@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"filename" : "L3-2.png"
|
||||
"filename" : "L3_240x240@3x.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
||||
|
Before Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 77 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 5.5 KiB |
@@ -1,51 +0,0 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"orientation" : "portrait",
|
||||
"idiom" : "iphone",
|
||||
"extent" : "full-screen",
|
||||
"minimum-system-version" : "7.0",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"orientation" : "portrait",
|
||||
"idiom" : "iphone",
|
||||
"extent" : "full-screen",
|
||||
"minimum-system-version" : "7.0",
|
||||
"subtype" : "retina4",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"orientation" : "portrait",
|
||||
"idiom" : "ipad",
|
||||
"extent" : "full-screen",
|
||||
"minimum-system-version" : "7.0",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"orientation" : "landscape",
|
||||
"idiom" : "ipad",
|
||||
"extent" : "full-screen",
|
||||
"minimum-system-version" : "7.0",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"orientation" : "portrait",
|
||||
"idiom" : "ipad",
|
||||
"extent" : "full-screen",
|
||||
"minimum-system-version" : "7.0",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"orientation" : "landscape",
|
||||
"idiom" : "ipad",
|
||||
"extent" : "full-screen",
|
||||
"minimum-system-version" : "7.0",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@@ -3,17 +3,17 @@
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x",
|
||||
"filename" : "left.png"
|
||||
"filename" : "left_38x31@1x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "left-1.png"
|
||||
"filename" : "left_76x61@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"filename" : "left-2.png"
|
||||
"filename" : "left_114x92@3x.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
||||
|
Before Width: | Height: | Size: 525 B |
|
Before Width: | Height: | Size: 525 B |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 525 B After Width: | Height: | Size: 525 B |
|
Before Width: | Height: | Size: 138 KiB |
@@ -2,7 +2,16 @@
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "Limelight-logo.pdf"
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "logo_universal.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
||||
|
After Width: | Height: | Size: 36 KiB |
@@ -7,7 +7,7 @@
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "Limelight Flat Design Banner.png"
|
||||
"filename" : "play.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
|
After Width: | Height: | Size: 17 KiB |
@@ -3,17 +3,17 @@
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x",
|
||||
"filename" : "R1.png"
|
||||
"filename" : "R1_40x40@1x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "R1-1.png"
|
||||
"filename" : "R1_80x80@1x-1.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"filename" : "R1-2.png"
|
||||
"filename" : "R1_120x120@3x.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
||||
|
Before Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 7.5 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
@@ -3,17 +3,17 @@
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x",
|
||||
"filename" : "R2-1.png"
|
||||
"filename" : "R2_60x60@1x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "R2.png"
|
||||
"filename" : "R2_120x120@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"filename" : "R2-2.png"
|
||||
"filename" : "R2_120x120@3x.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
||||
|
Before Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 9.3 KiB |
|
After Width: | Height: | Size: 8.7 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
@@ -3,17 +3,17 @@
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x",
|
||||
"filename" : "R3.png"
|
||||
"filename" : "R3_80x80@1x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "R3-1.png"
|
||||
"filename" : "R3_160x160@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"filename" : "R3-2.png"
|
||||
"filename" : "R3_240x240@3x.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
||||
|
Before Width: | Height: | Size: 91 KiB |
|
Before Width: | Height: | Size: 91 KiB |
|
Before Width: | Height: | Size: 91 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
@@ -3,17 +3,17 @@
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x",
|
||||
"filename" : "right.png"
|
||||
"filename" : "right_38x31@1x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "right-1.png"
|
||||
"filename" : "right_75x61@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"filename" : "right-2.png"
|
||||
"filename" : "right_114x93@3x.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
||||
|
Before Width: | Height: | Size: 549 B |
|
Before Width: | Height: | Size: 549 B |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 549 B After Width: | Height: | Size: 549 B |
@@ -3,17 +3,17 @@
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x",
|
||||
"filename" : "select_button-1.png"
|
||||
"filename" : "select_button_54x24@1x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "select_button.png"
|
||||
"filename" : "select_button_108x48@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"filename" : "select_button-2.png"
|
||||
"filename" : "select_button_162x72@3x.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
||||
|
Before Width: | Height: | Size: 735 B |
|
Before Width: | Height: | Size: 735 B |
|
Before Width: | Height: | Size: 735 B After Width: | Height: | Size: 735 B |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
@@ -1,23 +0,0 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x",
|
||||
"filename" : "settings_1x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "settings_2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"filename" : "settings_3x.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
@@ -3,17 +3,17 @@
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x",
|
||||
"filename" : "start_button-1.png"
|
||||
"filename" : "start_button_54x24@1x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "start_button.png"
|
||||
"filename" : "start_button_108x48@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"filename" : "start_button-2.png"
|
||||
"filename" : "start_button_162x72@3x.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
||||
|
Before Width: | Height: | Size: 774 B |
|
Before Width: | Height: | Size: 774 B |
|
Before Width: | Height: | Size: 774 B After Width: | Height: | Size: 774 B |
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
@@ -3,17 +3,17 @@
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x",
|
||||
"filename" : "stick_inner-1.png"
|
||||
"filename" : "stick_inner_48x49@1x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "stick_inner.png"
|
||||
"filename" : "stick_inner_96x97@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"filename" : "stick_inner-2.png"
|
||||
"filename" : "stick_inner_144x146@3x.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
@@ -3,17 +3,17 @@
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x",
|
||||
"filename" : "stick_outer-1.png"
|
||||
"filename" : "stick_outer_80x80@1x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "stick_outer.png"
|
||||
"filename" : "stick_outer_160x160@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"filename" : "stick_outer-2.png"
|
||||
"filename" : "stick_outer_240x240@3x.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
||||
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
@@ -3,17 +3,17 @@
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x",
|
||||
"filename" : "up-1.png"
|
||||
"filename" : "up_31x39@1x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "up.png"
|
||||
"filename" : "up_61x76@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"filename" : "up-2.png"
|
||||
"filename" : "up_93x116@3x.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
||||
|
Before Width: | Height: | Size: 452 B |
|
Before Width: | Height: | Size: 452 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 452 B After Width: | Height: | Size: 452 B |
|
After Width: | Height: | Size: 3.4 KiB |
@@ -3,17 +3,17 @@
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x",
|
||||
"filename" : "x_button-1.png"
|
||||
"filename" : "x_button_40x40@1x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "x_button.png"
|
||||
"filename" : "x_button_80x80@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"filename" : "x_button-2.png"
|
||||
"filename" : "x_button_120x120@3x.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 6.9 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
@@ -3,17 +3,17 @@
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x",
|
||||
"filename" : "y_button.png"
|
||||
"filename" : "y_button_40x40@1x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "y_button-1.png"
|
||||
"filename" : "y_button_80x80@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"filename" : "y_button-2.png"
|
||||
"filename" : "y_button_120x120@3x.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
||||
|
Before Width: | Height: | Size: 969 B |
|
Before Width: | Height: | Size: 969 B |
|
After Width: | Height: | Size: 6.2 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 969 B After Width: | Height: | Size: 969 B |
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// Controller.h
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 2/1/15.
|
||||
// Copyright (c) 2015 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2015 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// Controller.m
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 2/1/15.
|
||||
// Copyright (c) 2015 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2015 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Controller.h"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// ControllerSupport.h
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Cameron Gutman on 10/20/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// ControllerSupport.m
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Cameron Gutman on 10/20/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "ControllerSupport.h"
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
//
|
||||
// OnScreenControls.h
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 12/28/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "StreamView.h"
|
||||
|
||||
@class ControllerSupport;
|
||||
|
||||
@@ -23,7 +24,7 @@ typedef NS_ENUM(NSInteger, OnScreenControlsLevel) {
|
||||
OnScreenControlsLevelAutoGCExtendedGamepad,
|
||||
};
|
||||
|
||||
- (id) initWithView:(UIView*)view controllerSup:(ControllerSupport*)controllerSupport;
|
||||
- (id) initWithView:(UIView*)view controllerSup:(ControllerSupport*)controllerSupport swipeDelegate:(id<EdgeDetectionDelegate>)edgeDelegate;
|
||||
- (BOOL) handleTouchDownEvent:(NSSet*)touches;
|
||||
- (BOOL) handleTouchUpEvent:(NSSet*)touches;
|
||||
- (BOOL) handleTouchMovedEvent:(NSSet*)touches;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// OnScreenControls.m
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 12/28/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OnScreenControls.h"
|
||||
@@ -35,6 +35,7 @@
|
||||
CALayer* _l1Button;
|
||||
CALayer* _l2Button;
|
||||
CALayer* _l3Button;
|
||||
CALayer* _edge;
|
||||
|
||||
UITouch* _aTouch;
|
||||
UITouch* _bTouch;
|
||||
@@ -54,6 +55,7 @@
|
||||
UITouch* _l1Touch;
|
||||
UITouch* _l2Touch;
|
||||
UITouch* _l3Touch;
|
||||
UITouch* _edgeTouch;
|
||||
|
||||
NSDate* l3TouchStart;
|
||||
NSDate* r3TouchStart;
|
||||
@@ -66,42 +68,35 @@
|
||||
|
||||
ControllerSupport *_controllerSupport;
|
||||
Controller *_controller;
|
||||
id<EdgeDetectionDelegate> _edgeDelegate;
|
||||
}
|
||||
|
||||
static const float BUTTON_SIZE = 50;
|
||||
static const float EDGE_WIDTH = .1;
|
||||
|
||||
//static const float BUTTON_SIZE = 50;
|
||||
static const float BUTTON_DIST = 20;
|
||||
static float BUTTON_CENTER_X;
|
||||
static float BUTTON_CENTER_Y;
|
||||
|
||||
static const float D_PAD_SHORT = 50;
|
||||
static const float D_PAD_LONG = 65;
|
||||
static const float D_PAD_DIST = 15;
|
||||
static float D_PAD_CENTER_X;
|
||||
static float D_PAD_CENTER_Y;
|
||||
|
||||
static const double STICK_CLICK_RATE = 100;
|
||||
static const float STICK_INNER_SIZE = 80;
|
||||
static const float STICK_OUTER_SIZE = 120;
|
||||
static const float STICK_DEAD_ZONE = .1;
|
||||
static float STICK_INNER_SIZE;
|
||||
static float STICK_OUTER_SIZE;
|
||||
static float LS_CENTER_X;
|
||||
static float LS_CENTER_Y;
|
||||
static float RS_CENTER_X;
|
||||
static float RS_CENTER_Y;
|
||||
|
||||
static const float START_WIDTH = 50;
|
||||
static const float START_HEIGHT = 30;
|
||||
static float START_X;
|
||||
static float START_Y;
|
||||
|
||||
static const float SELECT_WIDTH = 50;
|
||||
static const float SELECT_HEIGHT = 30;
|
||||
static float SELECT_X;
|
||||
static float SELECT_Y;
|
||||
|
||||
static const float BUMPER_SIZE = 45;
|
||||
static const float TRIGGER_SIZE = 60;
|
||||
static const float L3R3_SIZE = 80;
|
||||
|
||||
static float R1_X;
|
||||
static float R1_Y;
|
||||
static float R2_X;
|
||||
@@ -115,12 +110,13 @@ static float L2_Y;
|
||||
static float L3_X;
|
||||
static float L3_Y;
|
||||
|
||||
- (id) initWithView:(UIView*)view controllerSup:(ControllerSupport*)controllerSupport {
|
||||
- (id) initWithView:(UIView*)view controllerSup:(ControllerSupport*)controllerSupport swipeDelegate:(id<EdgeDetectionDelegate>)swipeDelegate {
|
||||
self = [self init];
|
||||
_view = view;
|
||||
_controllerSupport = controllerSupport;
|
||||
_controller = [[Controller alloc] init];
|
||||
_controller.playerIndex = 0;
|
||||
_edgeDelegate = swipeDelegate;
|
||||
|
||||
_aButton = [CALayer layer];
|
||||
_bButton = [CALayer layer];
|
||||
@@ -142,7 +138,10 @@ static float L3_Y;
|
||||
_rightStickBackground = [CALayer layer];
|
||||
_leftStick = [CALayer layer];
|
||||
_rightStick = [CALayer layer];
|
||||
_edge = [CALayer layer];
|
||||
|
||||
[self setupEdgeDetection];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -210,6 +209,11 @@ static float L3_Y;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) setupEdgeDetection {
|
||||
_edge.frame = CGRectMake(0, 0, _view.frame.size.width * EDGE_WIDTH, _view.frame.size.height);
|
||||
[_view.layer addSublayer:_edge];
|
||||
}
|
||||
|
||||
// For GCExtendedGamepad controls we move start, select, L3, and R3 to the button
|
||||
- (void) setupExtendedGamepadControls {
|
||||
// Start with the default complex layout
|
||||
@@ -236,10 +240,12 @@ static float L3_Y;
|
||||
START_Y = _view.frame.size.height * .9;
|
||||
SELECT_Y = _view.frame.size.height * .9;
|
||||
|
||||
L1_Y = _view.frame.size.height * .75;
|
||||
L1_Y = _view.frame.size.height * .7;
|
||||
L2_Y = _view.frame.size.height * .9;
|
||||
R1_Y = _view.frame.size.height * .75;
|
||||
L2_X = _view.frame.size.width * .1;
|
||||
R1_Y = _view.frame.size.height * .7;
|
||||
R2_Y = _view.frame.size.height * .9;
|
||||
R2_X = _view.frame.size.width * .9;
|
||||
}
|
||||
|
||||
- (void) setupComplexControls
|
||||
@@ -254,133 +260,156 @@ static float L3_Y;
|
||||
RS_CENTER_X = _view.frame.size.width * .65;
|
||||
RS_CENTER_Y = _view.frame.size.height * .75;
|
||||
|
||||
START_X = _view.frame.size.width * .55;
|
||||
START_X = _view.frame.size.width * .6;
|
||||
START_Y = _view.frame.size.height * .1;
|
||||
SELECT_X = _view.frame.size.width * .45;
|
||||
SELECT_X = _view.frame.size.width * .4;
|
||||
SELECT_Y = _view.frame.size.height * .1;
|
||||
|
||||
L1_X = _view.frame.size.width * .15;
|
||||
L1_Y = _view.frame.size.height * .25;
|
||||
L1_Y = _view.frame.size.height * .27;
|
||||
L2_X = _view.frame.size.width * .15;
|
||||
L2_Y = _view.frame.size.height * .1;
|
||||
R1_X = _view.frame.size.width * .85;
|
||||
R1_Y = _view.frame.size.height * .25;
|
||||
R1_Y = _view.frame.size.height * .27;
|
||||
R2_X = _view.frame.size.width * .85;
|
||||
R2_Y = _view.frame.size.height * .1;
|
||||
L3_X = _view.frame.size.width * .25;
|
||||
L3_Y = _view.frame.size.height * .85;
|
||||
L3_Y = _view.frame.size.height * .75;
|
||||
R3_X = _view.frame.size.width * .75;
|
||||
R3_Y = _view.frame.size.height * .85;
|
||||
R3_Y = _view.frame.size.height * .75;
|
||||
}
|
||||
|
||||
- (void) drawButtons {
|
||||
// create A button
|
||||
_aButton.contents = (id) [UIImage imageNamed:@"AButton"].CGImage;
|
||||
_aButton.frame = CGRectMake(BUTTON_CENTER_X - BUTTON_SIZE / 2, BUTTON_CENTER_Y + BUTTON_DIST, BUTTON_SIZE, BUTTON_SIZE);
|
||||
UIImage* aButtonImage = [UIImage imageNamed:@"AButton"];
|
||||
_aButton.contents = (id) aButtonImage.CGImage;
|
||||
_aButton.frame = CGRectMake(BUTTON_CENTER_X - aButtonImage.size.width / 2, BUTTON_CENTER_Y + BUTTON_DIST, aButtonImage.size.width, aButtonImage.size.height);
|
||||
[_view.layer addSublayer:_aButton];
|
||||
|
||||
// create B button
|
||||
_bButton.frame = CGRectMake(BUTTON_CENTER_X + BUTTON_DIST, BUTTON_CENTER_Y - BUTTON_SIZE / 2, BUTTON_SIZE, BUTTON_SIZE);
|
||||
_bButton.contents = (id) [UIImage imageNamed:@"BButton"].CGImage;
|
||||
UIImage* bButtonImage = [UIImage imageNamed:@"BButton"];
|
||||
_bButton.frame = CGRectMake(BUTTON_CENTER_X + BUTTON_DIST, BUTTON_CENTER_Y - bButtonImage.size.height / 2, bButtonImage.size.width, bButtonImage.size.height);
|
||||
_bButton.contents = (id) bButtonImage.CGImage;
|
||||
[_view.layer addSublayer:_bButton];
|
||||
|
||||
// create X Button
|
||||
_xButton.frame = CGRectMake(BUTTON_CENTER_X - BUTTON_DIST - BUTTON_SIZE, BUTTON_CENTER_Y - BUTTON_SIZE / 2, BUTTON_SIZE, BUTTON_SIZE);
|
||||
_xButton.contents = (id) [UIImage imageNamed:@"XButton"].CGImage;
|
||||
UIImage* xButtonImage = [UIImage imageNamed:@"XButton"];
|
||||
_xButton.frame = CGRectMake(BUTTON_CENTER_X - BUTTON_DIST - xButtonImage.size.width, BUTTON_CENTER_Y - xButtonImage.size.height/ 2, xButtonImage.size.width, xButtonImage.size.height);
|
||||
_xButton.contents = (id) xButtonImage.CGImage;
|
||||
[_view.layer addSublayer:_xButton];
|
||||
|
||||
// create Y Button
|
||||
_yButton.frame = CGRectMake(BUTTON_CENTER_X - BUTTON_SIZE / 2, BUTTON_CENTER_Y - BUTTON_DIST - BUTTON_SIZE, BUTTON_SIZE, BUTTON_SIZE);
|
||||
_yButton.contents = (id) [UIImage imageNamed:@"YButton"].CGImage;
|
||||
UIImage* yButtonImage = [UIImage imageNamed:@"YButton"];
|
||||
_yButton.frame = CGRectMake(BUTTON_CENTER_X - yButtonImage.size.width / 2, BUTTON_CENTER_Y - BUTTON_DIST - yButtonImage.size.height, yButtonImage.size.width, yButtonImage.size.height);
|
||||
_yButton.contents = (id) yButtonImage.CGImage;
|
||||
[_view.layer addSublayer:_yButton];
|
||||
|
||||
// create Down button
|
||||
_downButton.frame = CGRectMake(D_PAD_CENTER_X - D_PAD_SHORT / 2, D_PAD_CENTER_Y + D_PAD_DIST, D_PAD_SHORT, D_PAD_LONG);
|
||||
_downButton.contents = (id) [UIImage imageNamed:@"DownButton"].CGImage;
|
||||
UIImage* downButtonImage = [UIImage imageNamed:@"DownButton"];
|
||||
_downButton.frame = CGRectMake(D_PAD_CENTER_X - downButtonImage.size.width / 2, D_PAD_CENTER_Y + D_PAD_DIST, downButtonImage.size.width, downButtonImage.size.height);
|
||||
_downButton.contents = (id) downButtonImage.CGImage;
|
||||
[_view.layer addSublayer:_downButton];
|
||||
|
||||
// create Right button
|
||||
_rightButton.frame = CGRectMake(D_PAD_CENTER_X + D_PAD_DIST, D_PAD_CENTER_Y - D_PAD_SHORT / 2, D_PAD_LONG, D_PAD_SHORT);
|
||||
_rightButton.contents = (id) [UIImage imageNamed:@"RightButton"].CGImage;
|
||||
UIImage* rightButtonImage = [UIImage imageNamed:@"RightButton"];
|
||||
_rightButton.frame = CGRectMake(D_PAD_CENTER_X + D_PAD_DIST, D_PAD_CENTER_Y - rightButtonImage.size.height / 2, rightButtonImage.size.width, rightButtonImage.size.height);
|
||||
_rightButton.contents = (id) rightButtonImage.CGImage;
|
||||
[_view.layer addSublayer:_rightButton];
|
||||
|
||||
// create Up button
|
||||
_upButton.frame = CGRectMake(D_PAD_CENTER_X - D_PAD_SHORT / 2, D_PAD_CENTER_Y - D_PAD_DIST - D_PAD_LONG, D_PAD_SHORT, D_PAD_LONG);
|
||||
_upButton.contents = (id) [UIImage imageNamed:@"UpButton"].CGImage;
|
||||
UIImage* upButtonImage = [UIImage imageNamed:@"UpButton"];
|
||||
_upButton.frame = CGRectMake(D_PAD_CENTER_X - upButtonImage.size.width / 2, D_PAD_CENTER_Y - D_PAD_DIST - upButtonImage.size.height, upButtonImage.size.width, upButtonImage.size.height);
|
||||
_upButton.contents = (id) upButtonImage.CGImage;
|
||||
[_view.layer addSublayer:_upButton];
|
||||
|
||||
// create Left button
|
||||
_leftButton.frame = CGRectMake(D_PAD_CENTER_X - D_PAD_DIST - D_PAD_LONG, D_PAD_CENTER_Y - D_PAD_SHORT / 2, D_PAD_LONG, D_PAD_SHORT);
|
||||
_leftButton.contents = (id) [UIImage imageNamed:@"LeftButton"].CGImage;
|
||||
UIImage* leftButtonImage = [UIImage imageNamed:@"LeftButton"];
|
||||
_leftButton.frame = CGRectMake(D_PAD_CENTER_X - D_PAD_DIST - leftButtonImage.size.width, D_PAD_CENTER_Y - leftButtonImage.size.height / 2, leftButtonImage.size.width, leftButtonImage.size.height);
|
||||
_leftButton.contents = (id) leftButtonImage.CGImage;
|
||||
[_view.layer addSublayer:_leftButton];
|
||||
}
|
||||
|
||||
- (void) drawStartSelect {
|
||||
// create Start button
|
||||
_startButton.frame = CGRectMake(START_X - START_WIDTH / 2, START_Y - START_HEIGHT / 2, START_WIDTH, START_HEIGHT);
|
||||
_startButton.contents = (id) [UIImage imageNamed:@"StartButton"].CGImage;
|
||||
UIImage* startButtonImage = [UIImage imageNamed:@"StartButton"];
|
||||
_startButton.frame = CGRectMake(START_X - startButtonImage.size.width / 2, START_Y - startButtonImage.size.height / 2, startButtonImage.size.width, startButtonImage.size.height);
|
||||
_startButton.contents = (id) startButtonImage.CGImage;
|
||||
[_view.layer addSublayer:_startButton];
|
||||
|
||||
// create Select button
|
||||
_selectButton.frame = CGRectMake(SELECT_X - SELECT_WIDTH / 2, SELECT_Y - SELECT_HEIGHT / 2, SELECT_WIDTH, SELECT_HEIGHT);
|
||||
_selectButton.contents = (id) [UIImage imageNamed:@"SelectButton"].CGImage;
|
||||
UIImage* selectButtonImage = [UIImage imageNamed:@"SelectButton"];
|
||||
_selectButton.frame = CGRectMake(SELECT_X - selectButtonImage.size.width / 2, SELECT_Y - selectButtonImage.size.height / 2, selectButtonImage.size.width, selectButtonImage.size.height);
|
||||
_selectButton.contents = (id) selectButtonImage.CGImage;
|
||||
[_view.layer addSublayer:_selectButton];
|
||||
}
|
||||
|
||||
- (void) drawBumpers {
|
||||
// create L1 button
|
||||
_l1Button.frame = CGRectMake(L1_X - BUMPER_SIZE / 2, L1_Y - BUMPER_SIZE / 2, BUMPER_SIZE, BUMPER_SIZE);
|
||||
_l1Button.contents = (id) [UIImage imageNamed:@"L1"].CGImage;
|
||||
UIImage* l1ButtonImage = [UIImage imageNamed:@"L1"];
|
||||
_l1Button.frame = CGRectMake(L1_X - l1ButtonImage.size.width / 2, L1_Y - l1ButtonImage.size.height / 2, l1ButtonImage.size.width, l1ButtonImage.size.height);
|
||||
_l1Button.contents = (id) l1ButtonImage.CGImage;
|
||||
[_view.layer addSublayer:_l1Button];
|
||||
|
||||
// create R1 button
|
||||
_r1Button.frame = CGRectMake(R1_X - BUMPER_SIZE / 2, R1_Y - BUMPER_SIZE / 2, BUMPER_SIZE, BUMPER_SIZE);
|
||||
_r1Button.contents = (id) [UIImage imageNamed:@"R1"].CGImage;
|
||||
UIImage* r1ButtonImage = [UIImage imageNamed:@"R1"];
|
||||
_r1Button.frame = CGRectMake(R1_X - r1ButtonImage.size.width / 2, R1_Y - r1ButtonImage.size.height / 2, r1ButtonImage.size.width, r1ButtonImage.size.height);
|
||||
_r1Button.contents = (id) r1ButtonImage.CGImage;
|
||||
[_view.layer addSublayer:_r1Button];
|
||||
}
|
||||
|
||||
- (void) drawTriggers {
|
||||
// create L2 button
|
||||
_l2Button.frame = CGRectMake(L2_X - TRIGGER_SIZE / 2, L2_Y - TRIGGER_SIZE / 2, TRIGGER_SIZE, TRIGGER_SIZE);
|
||||
_l2Button.contents = (id) [UIImage imageNamed:@"L2"].CGImage;
|
||||
UIImage* l2ButtonImage = [UIImage imageNamed:@"L2"];
|
||||
_l2Button.frame = CGRectMake(L2_X - l2ButtonImage.size.width / 2, L2_Y - l2ButtonImage.size.height / 2, l2ButtonImage.size.width, l2ButtonImage.size.height);
|
||||
_l2Button.contents = (id) l2ButtonImage.CGImage;
|
||||
[_view.layer addSublayer:_l2Button];
|
||||
|
||||
// create R2 button
|
||||
_r2Button.frame = CGRectMake(R2_X - TRIGGER_SIZE / 2, R2_Y - TRIGGER_SIZE / 2, TRIGGER_SIZE, TRIGGER_SIZE);
|
||||
_r2Button.contents = (id) [UIImage imageNamed:@"R2"].CGImage;
|
||||
UIImage* r2ButtonImage = [UIImage imageNamed:@"R2"];
|
||||
_r2Button.frame = CGRectMake(R2_X - r2ButtonImage.size.width / 2, R2_Y - r2ButtonImage.size.height / 2, r2ButtonImage.size.width, r2ButtonImage.size.height);
|
||||
_r2Button.contents = (id) r2ButtonImage.CGImage;
|
||||
[_view.layer addSublayer:_r2Button];
|
||||
}
|
||||
|
||||
- (void) drawSticks {
|
||||
// create left analog stick
|
||||
_leftStickBackground.frame = CGRectMake(LS_CENTER_X - STICK_OUTER_SIZE / 2, LS_CENTER_Y - STICK_OUTER_SIZE / 2, STICK_OUTER_SIZE, STICK_OUTER_SIZE);
|
||||
_leftStickBackground.contents = (id) [UIImage imageNamed:@"StickOuter"].CGImage;
|
||||
UIImage* leftStickBgImage = [UIImage imageNamed:@"StickOuter"];
|
||||
_leftStickBackground.frame = CGRectMake(LS_CENTER_X - leftStickBgImage.size.width / 2, LS_CENTER_Y - leftStickBgImage.size.height / 2, leftStickBgImage.size.width, leftStickBgImage.size.height);
|
||||
_leftStickBackground.contents = (id) leftStickBgImage.CGImage;
|
||||
[_view.layer addSublayer:_leftStickBackground];
|
||||
|
||||
_leftStick.frame = CGRectMake(LS_CENTER_X - STICK_INNER_SIZE / 2, LS_CENTER_Y - STICK_INNER_SIZE / 2, STICK_INNER_SIZE, STICK_INNER_SIZE);
|
||||
_leftStick.contents = (id) [UIImage imageNamed:@"StickInner"].CGImage;
|
||||
UIImage* leftStickImage = [UIImage imageNamed:@"StickInner"];
|
||||
_leftStick.frame = CGRectMake(LS_CENTER_X - leftStickImage.size.width / 2, LS_CENTER_Y - leftStickImage.size.height / 2, leftStickImage.size.width, leftStickImage.size.height);
|
||||
_leftStick.contents = (id) leftStickImage.CGImage;
|
||||
[_view.layer addSublayer:_leftStick];
|
||||
|
||||
// create right analog stick
|
||||
_rightStickBackground.frame = CGRectMake(RS_CENTER_X - STICK_OUTER_SIZE / 2, RS_CENTER_Y - STICK_OUTER_SIZE / 2, STICK_OUTER_SIZE, STICK_OUTER_SIZE);
|
||||
_rightStickBackground.contents = (id) [UIImage imageNamed:@"StickOuter"].CGImage;
|
||||
UIImage* rightStickBgImage = [UIImage imageNamed:@"StickOuter"];
|
||||
_rightStickBackground.frame = CGRectMake(RS_CENTER_X - rightStickBgImage.size.width / 2, RS_CENTER_Y - rightStickBgImage.size.height / 2, rightStickBgImage.size.width, rightStickBgImage.size.height);
|
||||
_rightStickBackground.contents = (id) rightStickBgImage.CGImage;
|
||||
[_view.layer addSublayer:_rightStickBackground];
|
||||
|
||||
_rightStick.frame = CGRectMake(RS_CENTER_X - STICK_INNER_SIZE / 2, RS_CENTER_Y - STICK_INNER_SIZE / 2, STICK_INNER_SIZE, STICK_INNER_SIZE);
|
||||
_rightStick.contents = (id) [UIImage imageNamed:@"StickInner"].CGImage;
|
||||
UIImage* rightStickImage = [UIImage imageNamed:@"StickInner"];
|
||||
_rightStick.frame = CGRectMake(RS_CENTER_X - rightStickImage.size.width / 2, RS_CENTER_Y - rightStickImage.size.height / 2, rightStickImage.size.width, rightStickImage.size.height);
|
||||
_rightStick.contents = (id) rightStickImage.CGImage;
|
||||
[_view.layer addSublayer:_rightStick];
|
||||
|
||||
STICK_INNER_SIZE = rightStickImage.size.width;
|
||||
STICK_OUTER_SIZE = rightStickBgImage.size.width;
|
||||
}
|
||||
|
||||
- (void) drawL3R3 {
|
||||
_l3Button.frame = CGRectMake(L3_X - L3R3_SIZE / 2, L3_Y - L3R3_SIZE / 2, L3R3_SIZE, L3R3_SIZE);
|
||||
_l3Button.contents = (id) [UIImage imageNamed:@"L3"].CGImage;
|
||||
_l3Button.cornerRadius = L3R3_SIZE / 2;
|
||||
UIImage* l3ButtonImage = [UIImage imageNamed:@"L3"];
|
||||
_l3Button.frame = CGRectMake(L3_X - l3ButtonImage.size.width / 2, L3_Y - l3ButtonImage.size.height / 2, l3ButtonImage.size.width, l3ButtonImage.size.height);
|
||||
_l3Button.contents = (id) l3ButtonImage.CGImage;
|
||||
_l3Button.cornerRadius = l3ButtonImage.size.width / 2;
|
||||
_l3Button.borderColor = [UIColor colorWithRed:15.f/255 green:160.f/255 blue:40.f/255 alpha:1.f].CGColor;
|
||||
[_view.layer addSublayer:_l3Button];
|
||||
|
||||
_r3Button.frame = CGRectMake(R3_X - L3R3_SIZE / 2, R3_Y - L3R3_SIZE / 2, L3R3_SIZE, L3R3_SIZE);
|
||||
_r3Button.contents = (id) [UIImage imageNamed:@"R3"].CGImage;
|
||||
_r3Button.cornerRadius = L3R3_SIZE / 2;
|
||||
UIImage* r3ButtonImage = [UIImage imageNamed:@"R3"];
|
||||
_r3Button.frame = CGRectMake(R3_X - r3ButtonImage.size.width / 2, R3_Y - r3ButtonImage.size.height / 2, r3ButtonImage.size.width, r3ButtonImage.size.height);
|
||||
_r3Button.contents = (id) r3ButtonImage.CGImage;
|
||||
_r3Button.cornerRadius = r3ButtonImage.size.width / 2;
|
||||
_r3Button.borderColor = [UIColor colorWithRed:15.f/255 green:160.f/255 blue:40.f/255 alpha:1.f].CGColor;
|
||||
[_view.layer addSublayer:_r3Button];
|
||||
}
|
||||
@@ -518,7 +547,7 @@ static float L3_Y;
|
||||
BOOL stickTouch = false;
|
||||
for (UITouch* touch in touches) {
|
||||
CGPoint touchLocation = [touch locationInView:_view];
|
||||
|
||||
|
||||
if ([_aButton.presentationLayer hitTest:touchLocation]) {
|
||||
[_controllerSupport setButtonFlag:_controller flags:A_FLAG];
|
||||
_aTouch = touch;
|
||||
@@ -621,6 +650,8 @@ static float L3_Y;
|
||||
}
|
||||
_rsTouch = touch;
|
||||
stickTouch = true;
|
||||
} else if ([_edge.presentationLayer hitTest:touchLocation]) {
|
||||
_edgeTouch = touch;
|
||||
}
|
||||
}
|
||||
if (updated) {
|
||||
@@ -711,6 +742,11 @@ static float L3_Y;
|
||||
else if (touch == _r3Touch) {
|
||||
_r3Touch = nil;
|
||||
touched = true;
|
||||
} else if (touch == _edgeTouch) {
|
||||
_edgeTouch = nil;
|
||||
if (![_edge.presentationLayer hitTest:[touch locationInView:_view]]) {
|
||||
[_edgeDelegate edgeSwiped];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (updated) {
|
||||
|
||||
@@ -1,17 +1,23 @@
|
||||
//
|
||||
// StreamView.h
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Cameron Gutman on 10/19/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "ControllerSupport.h"
|
||||
|
||||
@protocol EdgeDetectionDelegate <NSObject>
|
||||
|
||||
- (void) edgeSwiped;
|
||||
|
||||
@end
|
||||
|
||||
@interface StreamView : UIView
|
||||
|
||||
- (void) setupOnScreenControls:(ControllerSupport*)controllerSupport;
|
||||
- (void) setupOnScreenControls:(ControllerSupport*)controllerSupport swipeDelegate:(id<EdgeDetectionDelegate>)swipeDelegate;
|
||||
- (void) setMouseDeltaFactors:(float)x y:(float)y;
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// StreamView.m
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Cameron Gutman on 10/19/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "StreamView.h"
|
||||
@@ -29,8 +29,8 @@
|
||||
screenFactor = [[UIScreen mainScreen] scale];
|
||||
}
|
||||
|
||||
- (void) setupOnScreenControls:(ControllerSupport*)controllerSupport {
|
||||
onScreenControls = [[OnScreenControls alloc] initWithView:self controllerSup:controllerSupport];
|
||||
- (void) setupOnScreenControls:(ControllerSupport*)controllerSupport swipeDelegate:(id<EdgeDetectionDelegate>)swipeDelegate {
|
||||
onScreenControls = [[OnScreenControls alloc] initWithView:self controllerSup:controllerSupport swipeDelegate:swipeDelegate];
|
||||
DataManager* dataMan = [[DataManager alloc] init];
|
||||
OnScreenControlsLevel level = (OnScreenControlsLevel)[[dataMan retrieveSettings].onscreenControls integerValue];
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.limelight-stream.$(PRODUCT_NAME:rfc1034identifier)</string>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
@@ -17,15 +17,20 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.4.1</string>
|
||||
<string>0.9.2</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<string>2</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.games</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>UIAppFonts</key>
|
||||
<array>
|
||||
<string>Roboto-Black.ttf</string>
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>_XCCurrentVersionName</key>
|
||||
<string>Limelight 0.3.1.xcdatamodel</string>
|
||||
<string>Moonlight v1.0.xcdatamodel</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<model userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="8118.17" systemVersion="15A204h" minimumToolsVersion="Automatic">
|
||||
<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"/>
|
||||
<attribute name="name" optional="YES" attributeType="String" syncable="YES"/>
|
||||
<relationship name="host" maxCount="1" deletionRule="Nullify" destinationEntity="Host" inverseName="appList" inverseEntity="Host" syncable="YES"/>
|
||||
</entity>
|
||||
<entity name="Host" representedClassName="Host" syncable="YES">
|
||||
<attribute name="address" attributeType="String" syncable="YES"/>
|
||||
<attribute name="externalAddress" optional="YES" attributeType="String" syncable="YES"/>
|
||||
<attribute name="localAddress" optional="YES" attributeType="String" syncable="YES"/>
|
||||
<attribute name="mac" optional="YES" attributeType="String" syncable="YES"/>
|
||||
<attribute name="name" attributeType="String" syncable="YES"/>
|
||||
<attribute name="pairState" optional="YES" attributeType="Integer 32" defaultValueString="0" 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="width" attributeType="Integer 32" defaultValueString="1280" 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="120"/>
|
||||
</elements>
|
||||
</model>
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// AppManager.h
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/25/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
@@ -20,7 +20,7 @@
|
||||
@interface AppAssetManager : NSObject
|
||||
|
||||
- (id) initWithCallback:(id<AppAssetCallback>)callback;
|
||||
- (void) retrieveAssets:(NSArray*)appList fromHost:(Host*)host;
|
||||
- (void) retrieveAssetsFromHost:(Host*)host;
|
||||
- (void) stopRetrieving;
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// AppManager.m
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/25/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "AppAssetManager.h"
|
||||
@@ -15,35 +15,29 @@
|
||||
@implementation AppAssetManager {
|
||||
NSOperationQueue* _opQueue;
|
||||
id<AppAssetCallback> _callback;
|
||||
Host* _host;
|
||||
NSMutableDictionary* _imageCache;
|
||||
}
|
||||
|
||||
static const int MAX_REQUEST_COUNT = 4;
|
||||
|
||||
- (id) initWithCallback:(id<AppAssetCallback>)callback {
|
||||
self = [super init];
|
||||
_callback = callback;
|
||||
_opQueue = [[NSOperationQueue alloc] init];
|
||||
_imageCache = [[NSMutableDictionary alloc] init];
|
||||
|
||||
[_opQueue setMaxConcurrentOperationCount:MAX_REQUEST_COUNT];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) retrieveAssets:(NSArray*)appList fromHost:(Host*)host {
|
||||
Host* oldHost = _host;
|
||||
_host = host;
|
||||
BOOL useCache = [oldHost.uuid isEqualToString:_host.uuid];
|
||||
Log(LOG_I, @"Using cached app images: %d", useCache);
|
||||
if (!useCache) {
|
||||
[_imageCache removeAllObjects];
|
||||
}
|
||||
for (App* app in appList) {
|
||||
AppAssetRetriever* retriever = [[AppAssetRetriever alloc] init];
|
||||
retriever.app = app;
|
||||
retriever.host = _host;
|
||||
retriever.callback = _callback;
|
||||
retriever.cache = _imageCache;
|
||||
retriever.useCache = useCache;
|
||||
[_opQueue addOperation:retriever];
|
||||
- (void) retrieveAssetsFromHost:(Host*)host {
|
||||
for (App* app in host.appList) {
|
||||
if (app.image == nil) {
|
||||
AppAssetRetriever* retriever = [[AppAssetRetriever alloc] init];
|
||||
retriever.app = app;
|
||||
retriever.host = host;
|
||||
retriever.callback = _callback;
|
||||
|
||||
[_opQueue addOperation:retriever];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// AppAssetResponse.h
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 2/1/15.
|
||||
// Copyright (c) 2015 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2015 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// AppAssetResponse.m
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 2/1/15.
|
||||
// Copyright (c) 2015 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2015 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "AppAssetResponse.h"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// AppAssetRetriever.h
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 1/31/15.
|
||||
// Copyright (c) 2015 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2015 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
@@ -15,8 +15,6 @@
|
||||
|
||||
@property (nonatomic) Host* host;
|
||||
@property (nonatomic) App* app;
|
||||
@property (nonatomic) NSMutableDictionary* cache;
|
||||
@property (nonatomic) id<AppAssetCallback> callback;
|
||||
@property (nonatomic) BOOL useCache;
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// AppAssetRetriever.m
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 1/31/15.
|
||||
// Copyright (c) 2015 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2015 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "AppAssetRetriever.h"
|
||||
@@ -16,35 +16,21 @@
|
||||
static const double RETRY_DELAY = 2; // seconds
|
||||
static const int MAX_ATTEMPTS = 5;
|
||||
|
||||
|
||||
- (void) main {
|
||||
UIImage* appImage = nil;
|
||||
int attempts = 0;
|
||||
while (![self isCancelled] && appImage == nil && attempts++ < MAX_ATTEMPTS) {
|
||||
if (self.useCache) {
|
||||
@synchronized(self.cache) {
|
||||
UIImage* cachedImage = [self.cache objectForKey:self.app.appId];
|
||||
if (cachedImage != nil) {
|
||||
appImage = cachedImage;
|
||||
self.app.appImage = appImage;
|
||||
}
|
||||
}
|
||||
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:_host.activeAddress uniqueId:[CryptoManager getUniqueID] deviceName:deviceName cert:[CryptoManager readCertFromFile]];
|
||||
AppAssetResponse* appAssetResp = [[AppAssetResponse alloc] init];
|
||||
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:appAssetResp withUrlRequest:[hMan newAppAssetRequestWithAppId:self.app.id]]];
|
||||
|
||||
appImage = [UIImage imageWithData:appAssetResp.data];
|
||||
self.app.image = UIImagePNGRepresentation(appImage);
|
||||
|
||||
if (![self isCancelled] && appImage == nil) {
|
||||
[NSThread sleepForTimeInterval:RETRY_DELAY];
|
||||
}
|
||||
if (appImage == nil) {
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:_host.address uniqueId:[CryptoManager getUniqueID] deviceName:deviceName cert:[CryptoManager readCertFromFile]];
|
||||
AppAssetResponse* appAssetResp = [[AppAssetResponse alloc] init];
|
||||
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:appAssetResp withUrlRequest:[hMan newAppAssetRequestWithAppId:self.app.appId]]];
|
||||
|
||||
appImage = [UIImage imageWithData:appAssetResp.data];
|
||||
self.app.appImage = appImage;
|
||||
if (appImage != nil) {
|
||||
@synchronized(self.cache) {
|
||||
[self.cache setObject:appImage forKey:self.app.appId];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[NSThread sleepForTimeInterval:RETRY_DELAY];
|
||||
}
|
||||
[self performSelectorOnMainThread:@selector(sendCallbackForApp:) withObject:self.app waitUntilDone:NO];
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// AppListResponse.h
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 2/1/15.
|
||||
// Copyright (c) 2015 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2015 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "HttpResponse.h"
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
//
|
||||
// AppListResponse.m
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 2/1/15.
|
||||
// Copyright (c) 2015 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2015 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "AppListResponse.h"
|
||||
#import "App.h"
|
||||
#import "DataManager.h"
|
||||
#import <libxml2/libxml/xmlreader.h>
|
||||
|
||||
@implementation AppListResponse {
|
||||
@@ -59,13 +60,14 @@ static const char* TAG_APP_IS_RUNNING = "IsRunning";
|
||||
self.statusMessage = statusMsg;
|
||||
|
||||
node = node->children;
|
||||
DataManager* dataMan = [[DataManager alloc] init];
|
||||
|
||||
while (node != NULL) {
|
||||
//Log(LOG_D, @"node: %s", node->name);
|
||||
if (!xmlStrcmp(node->name, (xmlChar*)TAG_APP)) {
|
||||
xmlNodePtr appInfoNode = node->xmlChildrenNode;
|
||||
NSString* appName;
|
||||
NSString* appId;
|
||||
NSString* appName = @"";
|
||||
NSString* appId = nil;
|
||||
BOOL appIsRunning = NO;
|
||||
while (appInfoNode != NULL) {
|
||||
if (!xmlStrcmp(appInfoNode->name, (xmlChar*)TAG_APP_TITLE)) {
|
||||
@@ -93,11 +95,11 @@ static const char* TAG_APP_IS_RUNNING = "IsRunning";
|
||||
}
|
||||
appInfoNode = appInfoNode->next;
|
||||
}
|
||||
App* app = [[App alloc] init];
|
||||
app.appName = appName;
|
||||
app.appId = appId;
|
||||
app.isRunning = appIsRunning;
|
||||
if (app.appId != nil) {
|
||||
if (appId != nil) {
|
||||
App* app = [dataMan createApp];
|
||||
app.name = appName;
|
||||
app.id = appId;
|
||||
app.isRunning = appIsRunning;
|
||||
[_appList addObject:app];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// DiscoveryManager.h
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 1/1/15.
|
||||
// Copyright (c) 2015 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2015 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// DiscoveryManager.m
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 1/1/15.
|
||||
// Copyright (c) 2015 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2015 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "DiscoveryManager.h"
|
||||
@@ -41,13 +41,13 @@
|
||||
- (void) discoverHost:(NSString *)hostAddress withCallback:(void (^)(Host *, NSString*))callback {
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:hostAddress uniqueId:_uniqueId deviceName:deviceName cert:_cert];
|
||||
ServerInfoResponse* serverInfoResponse = [[ServerInfoResponse alloc] init];
|
||||
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:serverInfoResponse withUrlRequest:[hMan newServerInfoRequest]]];
|
||||
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:serverInfoResponse withUrlRequest:[hMan newServerInfoRequest] fallbackError:401 fallbackRequest:[hMan newHttpServerInfoRequest]]];
|
||||
|
||||
Host* host = nil;
|
||||
if ([serverInfoResponse isStatusOk]) {
|
||||
DataManager* dataMan = [[DataManager alloc] init];
|
||||
host = [dataMan createHost];
|
||||
host.address = hostAddress;
|
||||
host.activeAddress = host.address = hostAddress;
|
||||
host.online = YES;
|
||||
[serverInfoResponse populateHost:host];
|
||||
if (![self addHostToDiscovery:host]) {
|
||||
@@ -88,7 +88,7 @@
|
||||
}
|
||||
|
||||
- (BOOL) addHostToDiscovery:(Host *)host {
|
||||
if (![self isHostInDiscovery:host]) {
|
||||
if (host.uuid.length > 0 && ![self isHostInDiscovery:host]) {
|
||||
[_hostQueue addObject:host];
|
||||
if (shouldDiscover) {
|
||||
[_opQueue addOperation:[self createWorkerForHost:host]];
|
||||
@@ -125,6 +125,7 @@
|
||||
[dataMan removeHost:host];
|
||||
}
|
||||
}
|
||||
[dataMan saveData];
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// DiscoveryWorker.h
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 1/2/15.
|
||||
// Copyright (c) 2015 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2015 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// DiscoveryWorker.m
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 1/2/15.
|
||||
// Copyright (c) 2015 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2015 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "DiscoveryWorker.h"
|
||||
@@ -41,23 +41,71 @@ static const float POLL_RATE = 2.0f; // Poll every 2 seconds
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray*) getHostAddressList {
|
||||
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:3];
|
||||
|
||||
if (_host.localAddress != nil) {
|
||||
[array addObject:_host.localAddress];
|
||||
}
|
||||
if (_host.externalAddress != nil) {
|
||||
[array addObject:_host.externalAddress];
|
||||
}
|
||||
if (_host.address != nil) {
|
||||
[array addObject:_host.address];
|
||||
}
|
||||
|
||||
// Remove duplicate addresses from the list.
|
||||
// This is done using an array rather than a set
|
||||
// to preserve insertion order of addresses.
|
||||
for (int i = 0; i < [array count]; i++) {
|
||||
NSString *addr1 = [array objectAtIndex:i];
|
||||
|
||||
for (int j = 1; j < [array count]; j++) {
|
||||
if (i == j) {
|
||||
continue;
|
||||
}
|
||||
|
||||
NSString *addr2 = [array objectAtIndex:j];
|
||||
|
||||
if ([addr1 isEqualToString:addr2]) {
|
||||
// Remove the last address
|
||||
[array removeObjectAtIndex:j];
|
||||
|
||||
// Begin searching again from the start
|
||||
i = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
- (void) discoverHost {
|
||||
BOOL receivedResponse = NO;
|
||||
if (!self.cancelled && _host.localAddress != nil) {
|
||||
ServerInfoResponse* serverInfoResp = [self requestInfoAtAddress:_host.localAddress];
|
||||
receivedResponse = [self checkResponse:serverInfoResp];
|
||||
}
|
||||
if (!self.cancelled && !receivedResponse && _host.externalAddress != nil) {
|
||||
ServerInfoResponse* serverInfoResp = [self requestInfoAtAddress:_host.externalAddress];
|
||||
receivedResponse = [self checkResponse:serverInfoResp];
|
||||
}
|
||||
if (!self.cancelled && !receivedResponse && _host.address != nil) {
|
||||
ServerInfoResponse* serverInfoResp = [self requestInfoAtAddress:_host.address];
|
||||
NSArray *addresses = [self getHostAddressList];
|
||||
|
||||
Log(LOG_D, @"%@ has %d unique addresses", _host.name, [addresses count]);
|
||||
|
||||
for (NSString *address in addresses) {
|
||||
if (self.cancelled) {
|
||||
// Get out without updating the status because
|
||||
// it might not have finished checking the various
|
||||
// addresses
|
||||
return;
|
||||
}
|
||||
|
||||
ServerInfoResponse* serverInfoResp = [self requestInfoAtAddress:address];
|
||||
receivedResponse = [self checkResponse:serverInfoResp];
|
||||
if (receivedResponse) {
|
||||
_host.activeAddress = address;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_host.online = receivedResponse;
|
||||
if (receivedResponse) {
|
||||
Log(LOG_D, @"Received response from: %@\n{\n\t address:%@ \n\t localAddress:%@ \n\t externalAddress:%@ \n\t uuid:%@ \n\t mac:%@ \n\t pairState:%d \n\t online:%d \n}", _host.name, _host.address, _host.localAddress, _host.externalAddress, _host.uuid, _host.mac, _host.pairState, _host.online);
|
||||
Log(LOG_D, @"Received response from: %@\n{\n\t address:%@ \n\t localAddress:%@ \n\t externalAddress:%@ \n\t uuid:%@ \n\t mac:%@ \n\t pairState:%d \n\t online:%d \n\t activeAddress:%@ \n}", _host.name, _host.address, _host.localAddress, _host.externalAddress, _host.uuid, _host.mac, _host.pairState, _host.online, _host.activeAddress);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +116,8 @@ static const float POLL_RATE = 2.0f; // Poll every 2 seconds
|
||||
cert:_cert];
|
||||
ServerInfoResponse* response = [[ServerInfoResponse alloc] init];
|
||||
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:response
|
||||
withUrlRequest:[hMan newServerInfoRequest]]];
|
||||
withUrlRequest:[hMan newServerInfoRequest]
|
||||
fallbackError:401 fallbackRequest:[hMan newHttpServerInfoRequest]]];
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// HttpManager.h
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/16/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
@@ -11,7 +11,7 @@
|
||||
#import "HttpResponse.h"
|
||||
#import "HttpRequest.h"
|
||||
|
||||
@interface HttpManager : NSObject <NSURLConnectionDelegate, NSURLConnectionDataDelegate>
|
||||
@interface HttpManager : NSObject <NSURLSessionDelegate>
|
||||
|
||||
- (id) initWithHost:(NSString*) host uniqueId:(NSString*) uniqueId deviceName:(NSString*) deviceName cert:(NSData*) cert;
|
||||
- (NSURLRequest*) newPairRequest:(NSData*)salt;
|
||||
@@ -22,12 +22,12 @@
|
||||
- (NSURLRequest*) newPairChallenge;
|
||||
- (NSURLRequest*) newAppListRequest;
|
||||
- (NSURLRequest*) newServerInfoRequest;
|
||||
- (NSURLRequest*) newHttpServerInfoRequest;
|
||||
- (NSURLRequest*) newLaunchRequest:(NSString*)appId width:(int)width height:(int)height refreshRate:(int)refreshRate rikey:(NSString*)rikey rikeyid:(int)rikeyid;
|
||||
- (NSURLRequest*) newResumeRequestWithRiKey:(NSString*)riKey riKeyId:(int)riKeyId;
|
||||
- (NSURLRequest*) newQuitAppRequest;
|
||||
- (NSURLRequest*) newAppAssetRequestWithAppId:(NSString*)appId;
|
||||
- (void) executeRequestSynchronously:(HttpRequest*)request;
|
||||
- (void) executeRequest:(HttpRequest*)request;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// HttpManager.m
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/16/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "HttpManager.h"
|
||||
@@ -15,7 +15,9 @@
|
||||
#include <string.h>
|
||||
|
||||
@implementation HttpManager {
|
||||
NSString* _baseURL;
|
||||
NSURLSession* _urlSession;
|
||||
NSString* _baseHTTPURL;
|
||||
NSString* _baseHTTPSURL;
|
||||
NSString* _host;
|
||||
NSString* _uniqueId;
|
||||
NSString* _deviceName;
|
||||
@@ -23,9 +25,12 @@
|
||||
NSMutableData* _respData;
|
||||
NSData* _requestResp;
|
||||
dispatch_semaphore_t _requestLock;
|
||||
|
||||
BOOL _errorOccurred;
|
||||
}
|
||||
|
||||
static const NSString* PORT = @"47984";
|
||||
static const NSString* HTTP_PORT = @"47989";
|
||||
static const NSString* HTTPS_PORT = @"47984";
|
||||
|
||||
+ (NSData*) fixXmlVersion:(NSData*) xmlData {
|
||||
NSString* dataString = [[NSString alloc] initWithData:xmlData encoding:NSUTF8StringEncoding];
|
||||
@@ -40,32 +45,59 @@ static const NSString* PORT = @"47984";
|
||||
_uniqueId = uniqueId;
|
||||
_deviceName = deviceName;
|
||||
_cert = cert;
|
||||
_baseURL = [[NSString stringWithFormat:@"https://%@:%@", host, PORT]
|
||||
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
_baseHTTPURL = [NSString stringWithFormat:@"http://%@:%@", host, HTTP_PORT];
|
||||
_baseHTTPSURL = [NSString stringWithFormat:@"https://%@:%@", host, HTTPS_PORT];
|
||||
_requestLock = dispatch_semaphore_create(0);
|
||||
_respData = [[NSMutableData alloc] init];
|
||||
NSURLSessionConfiguration* config = [NSURLSessionConfiguration ephemeralSessionConfiguration];
|
||||
_urlSession = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) executeRequestSynchronously:(HttpRequest*)request {
|
||||
Log(LOG_D, @"Making Request: %@", request);
|
||||
[_respData setLength:0];
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
[NSURLConnection connectionWithRequest:request.request delegate:self];
|
||||
});
|
||||
dispatch_semaphore_wait(_requestLock, DISPATCH_TIME_FOREVER);
|
||||
if (request.response) {
|
||||
[request.response populateWithData:_requestResp];
|
||||
}
|
||||
}
|
||||
[[_urlSession dataTaskWithRequest:request.request completionHandler:^(NSData * __nullable data, NSURLResponse * __nullable response, NSError * __nullable error) {
|
||||
|
||||
if (error != NULL) {
|
||||
Log(LOG_D, @"Connection error: %@", error);
|
||||
_errorOccurred = true;
|
||||
}
|
||||
else {
|
||||
Log(LOG_D, @"Received response: %@", response);
|
||||
|
||||
- (void) executeRequest:(HttpRequest*)request {
|
||||
[NSURLConnection connectionWithRequest:request.request delegate:self];
|
||||
if (data != NULL) {
|
||||
Log(LOG_D, @"\n\nReceived data: %@\n\n", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
|
||||
[_respData appendData:data];
|
||||
if ([[NSString alloc] initWithData:_respData encoding:NSUTF8StringEncoding] != nil) {
|
||||
_requestResp = [HttpManager fixXmlVersion:_respData];
|
||||
} else {
|
||||
_requestResp = _respData;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dispatch_semaphore_signal(_requestLock);
|
||||
}] resume];
|
||||
dispatch_semaphore_wait(_requestLock, DISPATCH_TIME_FOREVER);
|
||||
|
||||
if (!_errorOccurred && request.response) {
|
||||
[request.response populateWithData:_requestResp];
|
||||
|
||||
// If the fallback error code was detected, issue the fallback request
|
||||
if (request.response.statusCode == request.fallbackError && request.fallbackRequest != NULL) {
|
||||
Log(LOG_D, @"Request failed with fallback error code: %d", request.fallbackError);
|
||||
request.request = request.fallbackRequest;
|
||||
request.fallbackError = 0;
|
||||
request.fallbackRequest = NULL;
|
||||
[self executeRequestSynchronously:request];
|
||||
}
|
||||
}
|
||||
_errorOccurred = false;
|
||||
}
|
||||
|
||||
- (NSURLRequest*) createRequestFromString:(NSString*) urlString enableTimeout:(BOOL)normalTimeout {
|
||||
NSString* escapedUrl = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
NSURL* url = [[NSURL alloc] initWithString:escapedUrl];
|
||||
NSURL* url = [[NSURL alloc] initWithString:urlString];
|
||||
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url];
|
||||
if (normalTimeout) {
|
||||
// Timeout the request after 5 seconds
|
||||
@@ -80,67 +112,72 @@ static const NSString* PORT = @"47984";
|
||||
|
||||
- (NSURLRequest*) newPairRequest:(NSData*)salt {
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&phrase=getservercert&salt=%@&clientcert=%@",
|
||||
_baseURL, _uniqueId, _deviceName, [self bytesToHex:salt], [self bytesToHex:_cert]];
|
||||
_baseHTTPSURL, _uniqueId, _deviceName, [self bytesToHex:salt], [self bytesToHex:_cert]];
|
||||
// This call blocks while waiting for the user to input the PIN on the PC
|
||||
return [self createRequestFromString:urlString enableTimeout:FALSE];
|
||||
}
|
||||
|
||||
- (NSURLRequest*) newUnpairRequest {
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/unpair?uniqueid=%@", _baseURL, _uniqueId];
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/unpair?uniqueid=%@", _baseHTTPSURL, _uniqueId];
|
||||
return [self createRequestFromString:urlString enableTimeout:TRUE];
|
||||
}
|
||||
|
||||
- (NSURLRequest*) newChallengeRequest:(NSData*)challenge {
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&clientchallenge=%@",
|
||||
_baseURL, _uniqueId, _deviceName, [self bytesToHex:challenge]];
|
||||
_baseHTTPSURL, _uniqueId, _deviceName, [self bytesToHex:challenge]];
|
||||
return [self createRequestFromString:urlString enableTimeout:TRUE];
|
||||
}
|
||||
|
||||
- (NSURLRequest*) newChallengeRespRequest:(NSData*)challengeResp {
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&serverchallengeresp=%@",
|
||||
_baseURL, _uniqueId, _deviceName, [self bytesToHex:challengeResp]];
|
||||
_baseHTTPSURL, _uniqueId, _deviceName, [self bytesToHex:challengeResp]];
|
||||
return [self createRequestFromString:urlString enableTimeout:TRUE];
|
||||
}
|
||||
|
||||
- (NSURLRequest*) newClientSecretRespRequest:(NSString*)clientPairSecret {
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&clientpairingsecret=%@", _baseURL, _uniqueId, _deviceName, clientPairSecret];
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&clientpairingsecret=%@", _baseHTTPSURL, _uniqueId, _deviceName, clientPairSecret];
|
||||
return [self createRequestFromString:urlString enableTimeout:TRUE];
|
||||
}
|
||||
|
||||
- (NSURLRequest*) newPairChallenge {
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&phrase=pairchallenge", _baseURL, _uniqueId, _deviceName];
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&phrase=pairchallenge", _baseHTTPSURL, _uniqueId, _deviceName];
|
||||
return [self createRequestFromString:urlString enableTimeout:TRUE];
|
||||
}
|
||||
|
||||
- (NSURLRequest *)newAppListRequest {
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/applist?uniqueid=%@", _baseURL, _uniqueId];
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/applist?uniqueid=%@", _baseHTTPSURL, _uniqueId];
|
||||
return [self createRequestFromString:urlString enableTimeout:TRUE];
|
||||
}
|
||||
|
||||
- (NSURLRequest *)newServerInfoRequest {
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/serverinfo?uniqueid=%@", _baseURL, _uniqueId];
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/serverinfo?uniqueid=%@", _baseHTTPSURL, _uniqueId];
|
||||
return [self createRequestFromString:urlString enableTimeout:TRUE];
|
||||
}
|
||||
|
||||
- (NSURLRequest *)newHttpServerInfoRequest {
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/serverinfo", _baseHTTPURL];
|
||||
return [self createRequestFromString:urlString enableTimeout:TRUE];
|
||||
}
|
||||
|
||||
- (NSURLRequest*) newLaunchRequest:(NSString*)appId width:(int)width height:(int)height refreshRate:(int)refreshRate rikey:(NSString*)rikey rikeyid:(int)rikeyid {
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/launch?uniqueid=%@&appid=%@&mode=%dx%dx%d&additionalStates=1&sops=1&rikey=%@&rikeyid=%d", _baseURL, _uniqueId, appId, width, height, refreshRate, rikey, rikeyid];
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/launch?uniqueid=%@&appid=%@&mode=%dx%dx%d&additionalStates=1&sops=1&rikey=%@&rikeyid=%d", _baseHTTPSURL, _uniqueId, appId, width, height, refreshRate, rikey, rikeyid];
|
||||
// This blocks while the app is launching
|
||||
return [self createRequestFromString:urlString enableTimeout:FALSE];
|
||||
}
|
||||
|
||||
- (NSURLRequest*) newResumeRequestWithRiKey:(NSString*)riKey riKeyId:(int)riKeyId {
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/resume?uniqueid=%@&rikey=%@&rikeyid=%d", _baseURL, _uniqueId, riKey, riKeyId];
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/resume?uniqueid=%@&rikey=%@&rikeyid=%d", _baseHTTPSURL, _uniqueId, riKey, riKeyId];
|
||||
// This blocks while the app is resuming
|
||||
return [self createRequestFromString:urlString enableTimeout:FALSE];
|
||||
}
|
||||
|
||||
- (NSURLRequest*) newQuitAppRequest {
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/cancel?uniqueid=%@", _baseURL, _uniqueId];
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/cancel?uniqueid=%@", _baseHTTPSURL, _uniqueId];
|
||||
return [self createRequestFromString:urlString enableTimeout:FALSE];
|
||||
}
|
||||
|
||||
- (NSURLRequest*) newAppAssetRequestWithAppId:(NSString *)appId {
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/appasset?uniqueid=%@&appid=%@&AssetType=2&AssetIdx=0", _baseURL, _uniqueId, appId];
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/appasset?uniqueid=%@&appid=%@&AssetType=2&AssetIdx=0", _baseHTTPSURL, _uniqueId, appId];
|
||||
return [self createRequestFromString:urlString enableTimeout:FALSE];
|
||||
}
|
||||
|
||||
@@ -153,33 +190,6 @@ static const NSString* PORT = @"47984";
|
||||
return hex;
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
|
||||
Log(LOG_D, @"Received response: %@", response);
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
|
||||
Log(LOG_D, @"\n\nReceived data: %@\n\n", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
|
||||
[_respData appendData:data];
|
||||
}
|
||||
|
||||
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
|
||||
if ([[NSString alloc] initWithData:_respData encoding:NSUTF8StringEncoding] != nil) {
|
||||
_requestResp = [HttpManager fixXmlVersion:_respData];
|
||||
} else {
|
||||
_requestResp = _respData;
|
||||
}
|
||||
dispatch_semaphore_signal(_requestLock);
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
|
||||
SecIdentityRef identity = [self getClientCertificate];
|
||||
NSArray *certArray = [self getCertificate:identity];
|
||||
|
||||
NSURLCredential *newCredential = [NSURLCredential credentialWithIdentity:identity certificates:certArray persistence:NSURLCredentialPersistencePermanent];
|
||||
|
||||
[challenge.sender useCredential:newCredential forAuthenticationChallenge:challenge];
|
||||
}
|
||||
|
||||
// Returns an array containing the certificate
|
||||
- (NSArray*)getCertificate:(SecIdentityRef) identity {
|
||||
SecCertificateRef certificate = nil;
|
||||
@@ -215,9 +225,25 @@ static const NSString* PORT = @"47984";
|
||||
return identityApp;
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
|
||||
Log(LOG_D, @"connection error: %@", error);
|
||||
dispatch_semaphore_signal(_requestLock);
|
||||
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(nonnull void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * __nullable))completionHandler {
|
||||
// Allow untrusted server certificates
|
||||
if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
|
||||
{
|
||||
completionHandler(NSURLSessionAuthChallengeUseCredential,
|
||||
[NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust]);
|
||||
}
|
||||
// Respond to client certificate challenge with our certificate
|
||||
else if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodClientCertificate])
|
||||
{
|
||||
SecIdentityRef identity = [self getClientCertificate];
|
||||
NSArray* certArray = [self getCertificate:identity];
|
||||
NSURLCredential* newCredential = [NSURLCredential credentialWithIdentity:identity certificates:certArray persistence:NSURLCredentialPersistencePermanent];
|
||||
completionHandler(NSURLSessionAuthChallengeUseCredential, newCredential);
|
||||
}
|
||||
else
|
||||
{
|
||||
completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// HttpRequest.h
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 2/1/15.
|
||||
// Copyright (c) 2015 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2015 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
@@ -13,7 +13,10 @@
|
||||
|
||||
@property (nonatomic) id<Response> response;
|
||||
@property (nonatomic) NSURLRequest* request;
|
||||
@property (nonatomic) int fallbackError;
|
||||
@property (nonatomic) NSURLRequest* fallbackRequest;
|
||||
|
||||
+ (instancetype) requestForResponse:(id<Response>)response withUrlRequest:(NSURLRequest*)req fallbackError:(int)error fallbackRequest:(NSURLRequest*) fallbackReq;
|
||||
+ (instancetype) requestForResponse:(id<Response>)response withUrlRequest:(NSURLRequest*)req;
|
||||
+ (instancetype) requestWithUrlRequest:(NSURLRequest*)req;
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// HttpRequest.m
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 2/1/15.
|
||||
// Copyright (c) 2015 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2015 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "HttpRequest.h"
|
||||
@@ -25,4 +25,13 @@
|
||||
return request;
|
||||
}
|
||||
|
||||
+ (HttpRequest*) requestForResponse:(id<Response>)response withUrlRequest:(NSURLRequest*)req fallbackError:(int)error fallbackRequest:(NSURLRequest*) fallbackReq {
|
||||
HttpRequest* request = [[HttpRequest alloc] init];
|
||||
request.request = req;
|
||||
request.response = response;
|
||||
request.fallbackError = error;
|
||||
request.fallbackRequest = fallbackReq;
|
||||
return request;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// HttpResponse.h
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 1/30/15.
|
||||
// Copyright (c) 2015 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2015 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// HttpResponse.m
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 1/30/15.
|
||||
// Copyright (c) 2015 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2015 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "HttpResponse.h"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// MDNSManager.h
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/14/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// MDNSManager.m
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/14/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MDNSManager.h"
|
||||
@@ -51,7 +51,7 @@ static NSString* NV_SERVICE_TYPE = @"_nvstream._tcp";
|
||||
for (NSNetService* service in services) {
|
||||
if (service.hostName != nil) {
|
||||
Host* host = [dataMan createHost];
|
||||
host.address = service.hostName;
|
||||
host.activeAddress = host.address = service.hostName;
|
||||
host.name = host.address;
|
||||
[hosts addObject:host];
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// PairManager.h
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/19/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// PairManager.m
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/19/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "PairManager.h"
|
||||
@@ -31,7 +31,8 @@
|
||||
|
||||
- (void) main {
|
||||
ServerInfoResponse* serverInfoResp = [[ServerInfoResponse alloc] init];
|
||||
[_httpManager executeRequestSynchronously:[HttpRequest requestForResponse:serverInfoResp withUrlRequest:[_httpManager newServerInfoRequest]]];
|
||||
[_httpManager executeRequestSynchronously:[HttpRequest requestForResponse:serverInfoResp withUrlRequest:[_httpManager newServerInfoRequest]
|
||||
fallbackError:401 fallbackRequest:[_httpManager newHttpServerInfoRequest]]];
|
||||
if (serverInfoResp == nil) {
|
||||
[_callback pairFailed:@"Unable to connect to PC"];
|
||||
return;
|
||||
@@ -60,7 +61,7 @@
|
||||
}
|
||||
NSInteger pairedStatus;
|
||||
if (![pairResp getIntTag:@"paired" value:&pairedStatus] || !pairedStatus) {
|
||||
[_httpManager executeRequest:[HttpRequest requestWithUrlRequest:[_httpManager newUnpairRequest]]];
|
||||
[_httpManager executeRequestSynchronously:[HttpRequest requestWithUrlRequest:[_httpManager newUnpairRequest]]];
|
||||
[_callback pairFailed:@"Pairing was declined by the target."];
|
||||
return;
|
||||
}
|
||||
@@ -78,8 +79,8 @@
|
||||
if (![self verifyResponseStatus:challengeResp]) {
|
||||
return;
|
||||
}
|
||||
if (![challengeResp getIntTag:@"paired" value:&pairedStatus] || !pairedStatus) {
|
||||
[_httpManager executeRequest:[HttpRequest requestWithUrlRequest:[_httpManager newUnpairRequest]]];
|
||||
if (![challengeResp getIntTag:@"paired" value:&pairedStatus] || pairedStatus != 1) {
|
||||
[_httpManager executeRequestSynchronously:[HttpRequest requestWithUrlRequest:[_httpManager newUnpairRequest]]];
|
||||
[_callback pairFailed:@"Pairing stage #2 failed"];
|
||||
return;
|
||||
}
|
||||
@@ -99,8 +100,8 @@
|
||||
if (![self verifyResponseStatus:secretResp]) {
|
||||
return;
|
||||
}
|
||||
if (![secretResp getIntTag:@"paired" value:&pairedStatus] || !pairedStatus) {
|
||||
[_httpManager executeRequest:[HttpRequest requestWithUrlRequest:[_httpManager newUnpairRequest]]];
|
||||
if (![secretResp getIntTag:@"paired" value:&pairedStatus] || pairedStatus != 1) {
|
||||
[_httpManager executeRequestSynchronously:[HttpRequest requestWithUrlRequest:[_httpManager newUnpairRequest]]];
|
||||
[_callback pairFailed:@"Pairing stage #3 failed"];
|
||||
return;
|
||||
}
|
||||
@@ -110,14 +111,14 @@
|
||||
NSData* serverSignature = [serverSecretResp subdataWithRange:NSMakeRange(16, 256)];
|
||||
|
||||
if (![cryptoMan verifySignature:serverSecret withSignature:serverSignature andCert:[Utils hexToBytes:plainCert]]) {
|
||||
[_httpManager executeRequest:[HttpRequest requestWithUrlRequest:[_httpManager newUnpairRequest]]];
|
||||
[_httpManager executeRequestSynchronously:[HttpRequest requestWithUrlRequest:[_httpManager newUnpairRequest]]];
|
||||
[_callback pairFailed:@"Server certificate invalid"];
|
||||
return;
|
||||
}
|
||||
|
||||
NSData* serverChallengeRespHash = [cryptoMan SHA1HashData:[self concatData:[self concatData:randomChallenge with:[CryptoManager getSignatureFromCert:[Utils hexToBytes:plainCert]]] with:serverSecret]];
|
||||
if (![serverChallengeRespHash isEqual:serverResponse]) {
|
||||
[_httpManager executeRequest:[HttpRequest requestWithUrlRequest:[_httpManager newUnpairRequest]]];
|
||||
[_httpManager executeRequestSynchronously:[HttpRequest requestWithUrlRequest:[_httpManager newUnpairRequest]]];
|
||||
[_callback pairFailed:@"Incorrect PIN"];
|
||||
return;
|
||||
}
|
||||
@@ -128,8 +129,8 @@
|
||||
if (![self verifyResponseStatus:clientSecretResp]) {
|
||||
return;
|
||||
}
|
||||
if (![clientSecretResp getIntTag:@"paired" value:&pairedStatus] || !pairedStatus) {
|
||||
[_httpManager executeRequest:[HttpRequest requestWithUrlRequest:[_httpManager newUnpairRequest]]];
|
||||
if (![clientSecretResp getIntTag:@"paired" value:&pairedStatus] || pairedStatus != 1) {
|
||||
[_httpManager executeRequestSynchronously:[HttpRequest requestWithUrlRequest:[_httpManager newUnpairRequest]]];
|
||||
[_callback pairFailed:@"Pairing stage #4 failed"];
|
||||
return;
|
||||
}
|
||||
@@ -139,8 +140,8 @@
|
||||
if (![self verifyResponseStatus:clientPairChallengeResp]) {
|
||||
return;
|
||||
}
|
||||
if (![clientPairChallengeResp getIntTag:@"paired" value:&pairedStatus] || !pairedStatus) {
|
||||
[_httpManager executeRequest:[HttpRequest requestWithUrlRequest:[_httpManager newUnpairRequest]]];
|
||||
if (![clientPairChallengeResp getIntTag:@"paired" value:&pairedStatus] || pairedStatus != 1) {
|
||||
[_httpManager executeRequestSynchronously:[HttpRequest requestWithUrlRequest:[_httpManager newUnpairRequest]]];
|
||||
[_callback pairFailed:@"Pairing stage #5 failed"];
|
||||
return;
|
||||
}
|
||||
@@ -149,11 +150,11 @@
|
||||
|
||||
- (BOOL) verifyResponseStatus:(HttpResponse*)resp {
|
||||
if (resp == nil) {
|
||||
[_httpManager executeRequest:[HttpRequest requestWithUrlRequest:[_httpManager newUnpairRequest]]];
|
||||
[_httpManager executeRequestSynchronously:[HttpRequest requestWithUrlRequest:[_httpManager newUnpairRequest]]];
|
||||
[_callback pairFailed:@"Network error occured."];
|
||||
return false;
|
||||
} else if (![resp isStatusOk]) {
|
||||
[_httpManager executeRequest:[HttpRequest requestWithUrlRequest:[_httpManager newUnpairRequest]]];
|
||||
[_httpManager executeRequestSynchronously:[HttpRequest requestWithUrlRequest:[_httpManager newUnpairRequest]]];
|
||||
[_callback pairFailed:resp.statusMessage];
|
||||
return false;
|
||||
} else {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// ServerInfoResponse.h
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 2/1/15.
|
||||
// Copyright (c) 2015 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2015 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "HttpResponse.h"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// ServerInfoResponse.m
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 2/1/15.
|
||||
// Copyright (c) 2015 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2015 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "ServerInfoResponse.h"
|
||||
@@ -18,11 +18,11 @@
|
||||
}
|
||||
|
||||
- (void) populateHost:(Host*)host {
|
||||
host.name = [self getStringTag:TAG_HOSTNAME];
|
||||
host.externalAddress = [self getStringTag:TAG_EXTERNAL_IP];
|
||||
host.localAddress = [self getStringTag:TAG_LOCAL_IP];
|
||||
host.uuid = [self getStringTag:TAG_UNIQUE_ID];
|
||||
host.mac = [self getStringTag:TAG_MAC_ADDRESS];
|
||||
host.name = [[self getStringTag:TAG_HOSTNAME] trim];
|
||||
host.externalAddress = [[self getStringTag:TAG_EXTERNAL_IP] trim];
|
||||
host.localAddress = [[self getStringTag:TAG_LOCAL_IP] trim];
|
||||
host.uuid = [[self getStringTag:TAG_UNIQUE_ID] trim];
|
||||
host.mac = [[self getStringTag:TAG_MAC_ADDRESS] trim];
|
||||
|
||||
NSInteger pairStatus;
|
||||
if ([self getIntTag:TAG_PAIR_STATUS value:&pairStatus]) {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// WakeOnLanManager.h
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 1/2/15.
|
||||
// Copyright (c) 2015 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2015 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// WakeOnLanManager.m
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 1/2/15.
|
||||
// Copyright (c) 2015 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2015 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "WakeOnLanManager.h"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// Connection.h
|
||||
// Limelight-iOS
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 1/19/14.
|
||||
// Copyright (c) 2014 Diego Waxemberg. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// Connection.m
|
||||
// Limelight-iOS
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 1/19/14.
|
||||
// Copyright (c) 2014 Diego Waxemberg. All rights reserved.
|
||||
// Copyright (c) 2015 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Connection.h"
|
||||
@@ -15,7 +15,7 @@
|
||||
#include "opus.h"
|
||||
|
||||
@implementation Connection {
|
||||
IP_ADDRESS _host;
|
||||
const char* _host;
|
||||
STREAM_CONFIGURATION _streamConfig;
|
||||
CONNECTION_LISTENER_CALLBACKS _clCallbacks;
|
||||
DECODER_RENDERER_CALLBACKS _drCallbacks;
|
||||
@@ -45,10 +45,6 @@ static int audioBufferQueueLength;
|
||||
static AudioComponentInstance audioUnit;
|
||||
static VideoDecoderRenderer* renderer;
|
||||
|
||||
void DrSetup(int width, int height, int fps, void* context, int drFlags)
|
||||
{
|
||||
}
|
||||
|
||||
int DrSubmitDecodeUnit(PDECODE_UNIT decodeUnit)
|
||||
{
|
||||
int offset = 0;
|
||||
@@ -69,18 +65,6 @@ int DrSubmitDecodeUnit(PDECODE_UNIT decodeUnit)
|
||||
return [renderer submitDecodeBuffer:data length:decodeUnit->fullLength];
|
||||
}
|
||||
|
||||
void DrStart(void)
|
||||
{
|
||||
}
|
||||
|
||||
void DrStop(void)
|
||||
{
|
||||
}
|
||||
|
||||
void DrRelease(void)
|
||||
{
|
||||
}
|
||||
|
||||
void ArInit(void)
|
||||
{
|
||||
int err;
|
||||
@@ -153,16 +137,26 @@ void ArInit(void)
|
||||
if (status) {
|
||||
Log(LOG_E, @"Unable to initialize audioUnit: %d", (int32_t)status);
|
||||
}
|
||||
|
||||
status = AudioOutputUnitStart(audioUnit);
|
||||
if (status) {
|
||||
Log(LOG_E, @"Unable to start audioUnit: %d", (int32_t)status);
|
||||
}
|
||||
}
|
||||
|
||||
void ArRelease(void)
|
||||
void ArCleanup(void)
|
||||
{
|
||||
if (opusDecoder != NULL) {
|
||||
opus_decoder_destroy(opusDecoder);
|
||||
opusDecoder = NULL;
|
||||
}
|
||||
|
||||
OSStatus status = AudioUnitUninitialize(audioUnit);
|
||||
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);
|
||||
}
|
||||
@@ -182,22 +176,6 @@ void ArRelease(void)
|
||||
}
|
||||
}
|
||||
|
||||
void ArStart(void)
|
||||
{
|
||||
OSStatus status = AudioOutputUnitStart(audioUnit);
|
||||
if (status) {
|
||||
Log(LOG_E, @"Unable to start audioUnit: %d", (int32_t)status);
|
||||
}
|
||||
}
|
||||
|
||||
void ArStop(void)
|
||||
{
|
||||
OSStatus status = AudioOutputUnitStop(audioUnit);
|
||||
if (status) {
|
||||
Log(LOG_E, @"Unable to stop audioUnit: %d", (int32_t)status);
|
||||
}
|
||||
}
|
||||
|
||||
void ArDecodeAndPlaySample(char* sampleData, int sampleLength)
|
||||
{
|
||||
int decodedLength = opus_decode(opusDecoder, (unsigned char*)sampleData, sampleLength, decodedPcmBuffer, PCM_BUFFER_SIZE / 2, 0);
|
||||
@@ -290,7 +268,7 @@ void ClDisplayTransientMessage(char* message)
|
||||
|
||||
-(void) terminate
|
||||
{
|
||||
// We're guaranteed to not be on a limelight-common thread
|
||||
// We're guaranteed to not be on a moonlight-common thread
|
||||
// here so it's safe to call stop directly
|
||||
LiStopConnection();
|
||||
}
|
||||
@@ -298,7 +276,7 @@ void ClDisplayTransientMessage(char* message)
|
||||
-(id) initWithConfig:(StreamConfiguration*)config renderer:(VideoDecoderRenderer*)myRenderer connectionCallbacks:(id<ConnectionCallbacks>)callbacks serverMajorVersion:(int)serverMajorVersion
|
||||
{
|
||||
self = [super init];
|
||||
_host = config.hostAddr;
|
||||
_host = [config.host cStringUsingEncoding:NSUTF8StringEncoding];
|
||||
renderer = myRenderer;
|
||||
_callbacks = callbacks;
|
||||
_serverMajorVersion = serverMajorVersion;
|
||||
@@ -315,16 +293,11 @@ void ClDisplayTransientMessage(char* message)
|
||||
int riKeyId = htonl(config.riKeyId);
|
||||
memcpy(_streamConfig.remoteInputAesIv, &riKeyId, sizeof(riKeyId));
|
||||
|
||||
_drCallbacks.setup = DrSetup;
|
||||
_drCallbacks.start = DrStart;
|
||||
_drCallbacks.stop = DrStop;
|
||||
_drCallbacks.release = DrRelease;
|
||||
memset(&_drCallbacks, 0, sizeof(_drCallbacks));
|
||||
_drCallbacks.submitDecodeUnit = DrSubmitDecodeUnit;
|
||||
|
||||
_arCallbacks.init = ArInit;
|
||||
_arCallbacks.start = ArStart;
|
||||
_arCallbacks.stop = ArStop;
|
||||
_arCallbacks.release = ArRelease;
|
||||
_arCallbacks.cleanup = ArCleanup;
|
||||
_arCallbacks.decodeAndPlaySample = ArDecodeAndPlaySample;
|
||||
|
||||
_clCallbacks.stageStarting = ClStageStarting;
|
||||
@@ -421,21 +394,12 @@ static OSStatus playbackCallback(void *inRefCon,
|
||||
|
||||
-(void) main
|
||||
{
|
||||
PLATFORM_CALLBACKS dummyPlCallbacks;
|
||||
|
||||
// Only used on Windows
|
||||
dummyPlCallbacks.threadStart = NULL;
|
||||
dummyPlCallbacks.debugPrint = NULL;
|
||||
|
||||
LiStartConnection(_host,
|
||||
&_streamConfig,
|
||||
&_clCallbacks,
|
||||
&_drCallbacks,
|
||||
&_arCallbacks,
|
||||
&dummyPlCallbacks,
|
||||
NULL, 0, _serverMajorVersion);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// StreamConfiguration.h
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/20/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
@@ -12,7 +12,6 @@
|
||||
|
||||
@property NSString* host;
|
||||
@property NSString* appID;
|
||||
@property int hostAddr;
|
||||
@property int width;
|
||||
@property int height;
|
||||
@property int frameRate;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
//
|
||||
// StreamConfiguration.m
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/20/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "StreamConfiguration.h"
|
||||
|
||||
@implementation StreamConfiguration
|
||||
@synthesize host, appID, hostAddr, width, height, frameRate, bitRate, riKeyId, riKey;
|
||||
@synthesize host, appID, width, height, frameRate, bitRate, riKeyId, riKey;
|
||||
@end
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// StreamManager.h
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/20/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// StreamManager.m
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/20/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "StreamManager.h"
|
||||
@@ -45,7 +45,8 @@
|
||||
cert:cert];
|
||||
|
||||
ServerInfoResponse* serverInfoResp = [[ServerInfoResponse alloc] init];
|
||||
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:serverInfoResp withUrlRequest:[hMan newServerInfoRequest]]];
|
||||
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:serverInfoResp withUrlRequest:[hMan newServerInfoRequest]
|
||||
fallbackError:401 fallbackRequest:[hMan newHttpServerInfoRequest]]];
|
||||
NSString* currentGame = [serverInfoResp getStringTag:@"currentgame"];
|
||||
NSString* pairStatus = [serverInfoResp getStringTag:@"PairStatus"];
|
||||
NSString* currentClient = [serverInfoResp getStringTag:@"CurrentClient"];
|
||||
@@ -96,14 +97,14 @@
|
||||
}
|
||||
|
||||
// This should NEVER be called from within a thread
|
||||
// owned by limelight-common
|
||||
// owned by moonlight-common
|
||||
- (void) stopStream
|
||||
{
|
||||
[_connection terminate];
|
||||
}
|
||||
|
||||
// This should only be called from within a thread
|
||||
// owned by limelight-common
|
||||
// owned by moonlight-common
|
||||
- (void) stopStreamInternal
|
||||
{
|
||||
[_connection terminateInternal];
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// VideoDecoderRenderer.h
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Cameron Gutman on 10/18/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// VideoDecoderRenderer.m
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Cameron Gutman on 10/18/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "VideoDecoderRenderer.h"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// UIAppView.h
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/22/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// UIAppView.m
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/22/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UIAppView.h"
|
||||
@@ -12,9 +12,9 @@
|
||||
App* _app;
|
||||
UIButton* _appButton;
|
||||
UILabel* _appLabel;
|
||||
UIImageView* _appOverlay;
|
||||
id<AppCallback> _callback;
|
||||
}
|
||||
static int LABEL_DY = 20;
|
||||
|
||||
- (id) initWithApp:(App*)app andCallback:(id<AppCallback>)callback {
|
||||
self = [super init];
|
||||
@@ -24,39 +24,58 @@ static int LABEL_DY = 20;
|
||||
_appButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
UIImage* noImage = [UIImage imageNamed:@"NoAppImage"];
|
||||
[_appButton setBackgroundImage:noImage forState:UIControlStateNormal];
|
||||
[_appButton setContentEdgeInsets:UIEdgeInsetsMake(0, 4, 0, 4)];
|
||||
[_appButton setContentEdgeInsets:UIEdgeInsetsMake(0, 4, 0, 4)];
|
||||
[_appButton sizeToFit];
|
||||
[_appButton addTarget:self action:@selector(appClicked) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
_appOverlay = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Play"]];
|
||||
_appOverlay.layer.shadowColor = [UIColor blackColor].CGColor;
|
||||
_appOverlay.layer.shadowOffset = CGSizeMake(0, 0);
|
||||
_appOverlay.layer.shadowOpacity = 1;
|
||||
_appOverlay.layer.shadowRadius = 2.0;
|
||||
[_appOverlay setHidden: YES];
|
||||
|
||||
[self addSubview:_appButton];
|
||||
[self addSubview:_appOverlay];
|
||||
[self sizeToFit];
|
||||
|
||||
_appButton.frame = CGRectMake(0, 0, noImage.size.width, noImage.size.height);
|
||||
_appOverlay.frame = CGRectMake(0, 0, noImage.size.width / 2.f, noImage.size.height / 4.f);
|
||||
self.frame = CGRectMake(0, 0, noImage.size.width, noImage.size.height);
|
||||
[_appOverlay setCenter:CGPointMake(self.frame.size.width/2, self.frame.size.height/6)];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) updateBounds {
|
||||
float x = _appButton.frame.origin.x < _appLabel.frame.origin.x ? _appButton.frame.origin.x : _appLabel.frame.origin.x;
|
||||
float y = _appButton.frame.origin.y < _appLabel.frame.origin.y ? _appButton.frame.origin.y : _appLabel.frame.origin.y;
|
||||
self.bounds = CGRectMake(x , y, _appButton.frame.size.width > _appLabel.frame.size.width ? _appButton.frame.size.width : _appLabel.frame.size.width, _appButton.frame.size.height + _appLabel.frame.size.height + LABEL_DY / 2);
|
||||
self.frame = CGRectMake(x , y, _appButton.frame.size.width > _appLabel.frame.size.width ? _appButton.frame.size.width : _appLabel.frame.size.width, _appButton.frame.size.height + _appLabel.frame.size.height + LABEL_DY / 2);
|
||||
}
|
||||
|
||||
- (void) appClicked {
|
||||
[_callback appClicked:_app];
|
||||
}
|
||||
|
||||
- (void) updateAppImage {
|
||||
if (_app.appImage != nil) {
|
||||
_appButton.frame = CGRectMake(0, 0, _app.appImage.size.width / 2, _app.appImage.size.height / 2);
|
||||
self.frame = CGRectMake(0, 0, _app.appImage.size.width / 2, _app.appImage.size.height / 2);
|
||||
[_appButton setBackgroundImage:_app.appImage forState:UIControlStateNormal];
|
||||
[self setNeedsDisplay];
|
||||
}
|
||||
|
||||
[_appOverlay setHidden:!_app.isRunning];
|
||||
|
||||
// TODO: Improve no-app image detection
|
||||
if (_app.appImage == nil || (_app.appImage.size.width == 130.f && _app.appImage.size.height == 180.f)) { // This size of image might be blank image received from GameStream.
|
||||
BOOL noAppImage = false;
|
||||
|
||||
if (_app.image != nil) {
|
||||
UIImage* appImage = [UIImage imageWithData:_app.image];
|
||||
// This size of image might be blank image received from GameStream.
|
||||
if (!(appImage.size.width == 130.f && appImage.size.height == 180.f)) {
|
||||
_appButton.frame = CGRectMake(0, 0, appImage.size.width / 2, appImage.size.height / 2);
|
||||
self.frame = CGRectMake(0, 0, appImage.size.width / 2, appImage.size.height / 2);
|
||||
_appOverlay.frame = CGRectMake(0, 0, self.frame.size.width / 2.f, self.frame.size.height / 4.f);
|
||||
_appOverlay.layer.shadowRadius = 4.0;
|
||||
[_appOverlay setCenter:CGPointMake(self.frame.size.width/2, self.frame.size.height/6)];
|
||||
[_appButton setBackgroundImage:appImage forState:UIControlStateNormal];
|
||||
[self setNeedsDisplay];
|
||||
} else {
|
||||
noAppImage = true;
|
||||
}
|
||||
} else {
|
||||
noAppImage = true;
|
||||
}
|
||||
|
||||
if (noAppImage) {
|
||||
_appLabel = [[UILabel alloc] init];
|
||||
CGFloat padding = 4.f;
|
||||
[_appLabel setFrame: CGRectMake(padding, padding, _appButton.frame.size.width - 2 * padding, _appButton.frame.size.height - 2 * padding)];
|
||||
@@ -66,18 +85,10 @@ static int LABEL_DY = 20;
|
||||
[_appLabel setTextAlignment:NSTextAlignmentCenter];
|
||||
[_appLabel setLineBreakMode:NSLineBreakByWordWrapping];
|
||||
[_appLabel setNumberOfLines:0];
|
||||
[_appLabel setText:_app.appName];
|
||||
[_appLabel setText:_app.name];
|
||||
[_appButton addSubview:_appLabel];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
// Only override drawRect: if you perform custom drawing.
|
||||
// An empty implementation adversely affects performance during animation.
|
||||
- (void)drawRect:(CGRect)rect {
|
||||
// Drawing code
|
||||
}
|
||||
*/
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// UIComputerView.h
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/22/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
@protocol HostCallback <NSObject>
|
||||
|
||||
- (void) hostClicked:(Host*)host;
|
||||
- (void) hostClicked:(Host*)host view:(UIView*)view;
|
||||
- (void) hostLongClicked:(Host*)host view:(UIView*)view;
|
||||
- (void) addHostClicked;
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// UIComputerView.m
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/22/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UIComputerView.h"
|
||||
@@ -171,7 +171,7 @@ static const int LABEL_DY = 20;
|
||||
}
|
||||
|
||||
- (void) hostClicked {
|
||||
[_callback hostClicked:_host];
|
||||
[_callback hostClicked:_host view:self];
|
||||
}
|
||||
|
||||
- (void) addClicked {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// Logger.h
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 2/10/15.
|
||||
// Copyright (c) 2015 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2015 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef Limelight_Logger_h
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// Logger.m
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 2/10/15.
|
||||
// Copyright (c) 2015 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2015 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Logger.h"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// Utils.h
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/20/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
@@ -24,3 +24,9 @@ FOUNDATION_EXPORT NSString *const deviceName;
|
||||
+ (int) resolveHost:(NSString*)host;
|
||||
|
||||
@end
|
||||
|
||||
@interface NSString (NSStringWithTrim)
|
||||
|
||||
- (NSString*) trim;
|
||||
|
||||
@end
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// Utils.m
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/20/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Utils.h"
|
||||
@@ -73,5 +73,12 @@ NSString *const deviceName = @"roth";
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSString (NSStringWithTrim)
|
||||
|
||||
- (NSString *)trim {
|
||||
return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// LoadingFrameViewController.h
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 2/24/15.
|
||||
// Copyright (c) 2015 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2015 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// LoadingFrameViewController.m
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 2/24/15.
|
||||
// Copyright (c) 2015 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2015 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "LoadingFrameViewController.h"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// MainFrameViewController.h
|
||||
// Limelight-iOS
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 1/17/14.
|
||||
// Copyright (c) 2014 Diego Waxemberg. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// MainFrameViewController.m
|
||||
// Limelight-iOS
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 1/17/14.
|
||||
// Copyright (c) 2014 Diego Waxemberg. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MainFrameViewController.h"
|
||||
@@ -28,83 +28,164 @@
|
||||
Host* _selectedHost;
|
||||
NSString* _uniqueId;
|
||||
NSData* _cert;
|
||||
NSString* _currentGame;
|
||||
DiscoveryManager* _discMan;
|
||||
AppAssetManager* _appManager;
|
||||
StreamConfiguration* _streamConfig;
|
||||
UIAlertView* _pairAlert;
|
||||
UIAlertController* _pairAlert;
|
||||
UIScrollView* hostScrollView;
|
||||
int currentPosition;
|
||||
NSArray* _sortedAppList;
|
||||
}
|
||||
static NSMutableSet* hostList;
|
||||
static NSArray* appList;
|
||||
|
||||
- (void)showPIN:(NSString *)PIN {
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
_pairAlert = [[UIAlertView alloc] initWithTitle:@"Pairing" message:[NSString stringWithFormat:@"Enter the following PIN on the host machine: %@", PIN]delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
|
||||
[_pairAlert show];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
_pairAlert = [UIAlertController alertControllerWithTitle:@"Pairing"
|
||||
message:[NSString stringWithFormat:@"Enter the following PIN on the host machine: %@", PIN]
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
[self presentViewController:_pairAlert animated:YES completion:nil];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)pairFailed:(NSString *)message {
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
[_pairAlert dismissWithClickedButtonIndex:0 animated:NO];
|
||||
_pairAlert = [[UIAlertView alloc] initWithTitle:@"Pairing Failed" message:message delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
|
||||
[_pairAlert show];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[_pairAlert dismissViewControllerAnimated:YES completion:nil];
|
||||
_pairAlert = [UIAlertController alertControllerWithTitle:@"Pairing Failed"
|
||||
message:message
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
[_pairAlert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDestructive handler:nil]];
|
||||
[self presentViewController:_pairAlert animated:YES completion:nil];
|
||||
|
||||
[_discMan startDiscovery];
|
||||
[self hideLoadingFrame];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)pairSuccessful {
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
[_pairAlert dismissWithClickedButtonIndex:0 animated:NO];
|
||||
_pairAlert = [[UIAlertView alloc] initWithTitle:@"Pairing Succesful" message:@"Successfully paired to host" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
|
||||
[_pairAlert show];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[_pairAlert dismissViewControllerAnimated:YES completion:nil];
|
||||
[_discMan startDiscovery];
|
||||
[self hideLoadingFrame];
|
||||
[self alreadyPaired];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)alreadyPaired {
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
BOOL usingCachedAppList = false;
|
||||
|
||||
// Capture the host here because it can change once we
|
||||
// leave the main thread
|
||||
Host* host = _selectedHost;
|
||||
|
||||
if ([host.appList count] > 0) {
|
||||
usingCachedAppList = true;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
_computerNameButton.title = _selectedHost.name;
|
||||
if (host != _selectedHost) {
|
||||
return;
|
||||
}
|
||||
|
||||
_computerNameButton.title = host.name;
|
||||
[self.navigationController.navigationBar setNeedsLayout];
|
||||
|
||||
[self updateAppsForHost:host];
|
||||
[self hideLoadingFrame];
|
||||
});
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:_selectedHost.address uniqueId:_uniqueId deviceName:deviceName cert:_cert];
|
||||
}
|
||||
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];
|
||||
|
||||
AppListResponse* appListResp = [[AppListResponse alloc] init];
|
||||
|
||||
// Exempt this host from discovery while handling the applist query
|
||||
[_discMan removeHostFromDiscovery:host];
|
||||
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:appListResp withUrlRequest:[hMan newAppListRequest]]];
|
||||
if (appListResp == nil || ![appListResp isStatusOk]) {
|
||||
[_discMan addHostToDiscovery:host];
|
||||
|
||||
if (appListResp == nil || ![appListResp isStatusOk] || [appListResp getAppList] == nil) {
|
||||
Log(LOG_W, @"Failed to get applist: %@", appListResp.statusMessage);
|
||||
} else {
|
||||
appList = [appListResp getAppList];
|
||||
if (appList == nil) {
|
||||
Log(LOG_W, @"Failed to parse applist");
|
||||
} else {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self updateApps];
|
||||
});
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self hideLoadingFrame];
|
||||
|
||||
if (host != _selectedHost) {
|
||||
return;
|
||||
}
|
||||
|
||||
UIAlertController* applistAlert = [UIAlertController alertControllerWithTitle:@"Fetching App List Failed"
|
||||
message:@"The connection to the PC was interrupted."
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
[applistAlert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDestructive handler:nil]];
|
||||
[self presentViewController:applistAlert animated:YES completion:nil];
|
||||
host.online = NO;
|
||||
[self showHostSelectionView];
|
||||
});
|
||||
} else {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self mergeAppLists:[appListResp getAppList] forHost:host];
|
||||
|
||||
if (host != _selectedHost) {
|
||||
return;
|
||||
}
|
||||
|
||||
_computerNameButton.title = host.name;
|
||||
[self.navigationController.navigationBar setNeedsLayout];
|
||||
|
||||
[self updateAppsForHost:host];
|
||||
[_appManager stopRetrieving];
|
||||
[_appManager retrieveAssets:appList fromHost:_selectedHost];
|
||||
}
|
||||
[_appManager retrieveAssetsFromHost:host];
|
||||
[self hideLoadingFrame];
|
||||
});
|
||||
}
|
||||
[self hideLoadingFrame];
|
||||
});
|
||||
}
|
||||
|
||||
- (void) mergeAppLists:(NSArray*) newList forHost:(Host*)host {
|
||||
DataManager* database = [[DataManager alloc] init];
|
||||
for (App* app in newList) {
|
||||
BOOL appAlreadyInList = NO;
|
||||
for (App* savedApp in host.appList) {
|
||||
if ([app.id isEqualToString:savedApp.id]) {
|
||||
savedApp.isRunning = app.isRunning;
|
||||
appAlreadyInList = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!appAlreadyInList) {
|
||||
app.host = host;
|
||||
[host addAppListObject:app];
|
||||
} else {
|
||||
[database removeApp:app];
|
||||
}
|
||||
}
|
||||
|
||||
for (App* app in host.appList) {
|
||||
BOOL appWasRemoved = YES;
|
||||
for (App* mergedApp in newList) {
|
||||
if ([mergedApp.id isEqualToString:app.id]) {
|
||||
appWasRemoved = NO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (appWasRemoved) {
|
||||
[host removeAppListObject:app];
|
||||
[database removeApp:app];
|
||||
}
|
||||
}
|
||||
[database saveData];
|
||||
}
|
||||
|
||||
- (void)showHostSelectionView {
|
||||
appList = [[NSArray alloc] init];
|
||||
[_appManager stopRetrieving];
|
||||
[[[DataManager alloc] init] saveData];
|
||||
_selectedHost = nil;
|
||||
_computerNameButton.title = @"No Host Selected";
|
||||
[self.collectionView reloadData];
|
||||
[self.view addSubview:hostScrollView];
|
||||
}
|
||||
|
||||
- (void) receivedAssetForApp:(App*)app {
|
||||
[self.collectionView reloadData];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self.collectionView reloadData];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)displayDnsFailedDialog {
|
||||
@@ -115,17 +196,56 @@ static NSArray* appList;
|
||||
[self presentViewController:alert animated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (void) hostClicked:(Host *)host {
|
||||
- (void) hostClicked:(Host *)host view:(UIView *)view {
|
||||
// Treat clicks on offline hosts to be long clicks
|
||||
// This shows the context menu with wake, delete, etc. rather
|
||||
// than just hanging for a while and failing as we would in this
|
||||
// code path.
|
||||
if (!host.online && view != nil) {
|
||||
[self hostLongClicked:host view:view];
|
||||
return;
|
||||
}
|
||||
|
||||
Log(LOG_D, @"Clicked host: %@", host.name);
|
||||
[self showLoadingFrame];
|
||||
_selectedHost = host;
|
||||
[self disableNavigation];
|
||||
|
||||
// If we are online, paired, and have a cached app list, skip straight
|
||||
// to the app grid without a loading frame. This is the fast path that users
|
||||
// should hit most.
|
||||
if (host.online && host.pairState == PairStatePaired && host.appList.count > 0) {
|
||||
[self alreadyPaired];
|
||||
return;
|
||||
}
|
||||
|
||||
[self showLoadingFrame];
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:host.address uniqueId:_uniqueId deviceName:deviceName cert:_cert];
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:host.activeAddress uniqueId:_uniqueId deviceName:deviceName cert:_cert];
|
||||
ServerInfoResponse* serverInfoResp = [[ServerInfoResponse alloc] init];
|
||||
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:serverInfoResp withUrlRequest:[hMan newServerInfoRequest]]];
|
||||
|
||||
// Exempt this host from discovery while handling the serverinfo request
|
||||
[_discMan removeHostFromDiscovery:host];
|
||||
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:serverInfoResp withUrlRequest:[hMan newServerInfoRequest]
|
||||
fallbackError:401 fallbackRequest:[hMan newHttpServerInfoRequest]]];
|
||||
[_discMan addHostToDiscovery:host];
|
||||
|
||||
if (serverInfoResp == nil || ![serverInfoResp isStatusOk]) {
|
||||
Log(LOG_W, @"Failed to get server info: %@", serverInfoResp.statusMessage);
|
||||
[self hideLoadingFrame];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self hideLoadingFrame];
|
||||
|
||||
if (host != _selectedHost) {
|
||||
return;
|
||||
}
|
||||
|
||||
UIAlertController* applistAlert = [UIAlertController alertControllerWithTitle:@"Fetching Server Info Failed"
|
||||
message:@"The connection to the PC was interrupted."
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
[applistAlert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDestructive handler:nil]];
|
||||
[self presentViewController:applistAlert animated:YES completion:nil];
|
||||
host.online = NO;
|
||||
[self showHostSelectionView];
|
||||
});
|
||||
} else {
|
||||
Log(LOG_D, @"server info pair status: %@", [serverInfoResp getStringTag:@"PairStatus"]);
|
||||
if ([[serverInfoResp getStringTag:@"PairStatus"] isEqualToString:@"1"]) {
|
||||
@@ -145,14 +265,7 @@ static NSArray* appList;
|
||||
- (void)hostLongClicked:(Host *)host view:(UIView *)view {
|
||||
Log(LOG_D, @"Long clicked host: %@", host.name);
|
||||
UIAlertController* longClickAlert = [UIAlertController alertControllerWithTitle:host.name message:@"" preferredStyle:UIAlertControllerStyleActionSheet];
|
||||
if (host.online) {
|
||||
[longClickAlert addAction:[UIAlertAction actionWithTitle:@"Unpair" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:host.address uniqueId:_uniqueId deviceName:deviceName cert:_cert];
|
||||
[hMan executeRequest:[HttpRequest requestWithUrlRequest:[hMan newUnpairRequest]]];
|
||||
});
|
||||
}]];
|
||||
} else {
|
||||
if (!host.online) {
|
||||
[longClickAlert addAction:[UIAlertAction actionWithTitle:@"Wake" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){
|
||||
UIAlertController* wolAlert = [UIAlertController alertControllerWithTitle:@"Wake On Lan" message:@"" preferredStyle:UIAlertControllerStyleAlert];
|
||||
[wolAlert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];
|
||||
@@ -201,7 +314,7 @@ static NSArray* appList;
|
||||
[_discMan discoverHost:hostAddress withCallback:^(Host* host, NSString* error){
|
||||
if (host != nil) {
|
||||
DataManager* dataMan = [[DataManager alloc] init];
|
||||
[dataMan saveHosts];
|
||||
[dataMan saveData];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
@synchronized(hostList) {
|
||||
[hostList addObject:host];
|
||||
@@ -223,15 +336,10 @@ static NSArray* appList;
|
||||
}
|
||||
|
||||
- (void) appClicked:(App *)app {
|
||||
Log(LOG_D, @"Clicked app: %@", app.appName);
|
||||
Log(LOG_D, @"Clicked app: %@", app.name);
|
||||
_streamConfig = [[StreamConfiguration alloc] init];
|
||||
_streamConfig.host = _selectedHost.address;
|
||||
_streamConfig.hostAddr = [Utils resolveHost:_selectedHost.address];
|
||||
_streamConfig.appID = app.appId;
|
||||
if (_streamConfig.hostAddr == 0) {
|
||||
[self displayDnsFailedDialog];
|
||||
return;
|
||||
}
|
||||
_streamConfig.host = app.host.activeAddress;
|
||||
_streamConfig.appID = app.id;
|
||||
|
||||
DataManager* dataMan = [[DataManager alloc] init];
|
||||
Settings* streamSettings = [dataMan retrieveSettings];
|
||||
@@ -241,35 +349,69 @@ static NSArray* appList;
|
||||
_streamConfig.height = [streamSettings.height intValue];
|
||||
_streamConfig.width = [streamSettings.width intValue];
|
||||
|
||||
[_appManager stopRetrieving];
|
||||
|
||||
if (currentPosition != FrontViewPositionLeft) {
|
||||
[[self revealViewController] revealToggle:self];
|
||||
}
|
||||
|
||||
App* currentApp = [self findRunningApp];
|
||||
App* currentApp = [self findRunningApp:app.host];
|
||||
if (currentApp != nil) {
|
||||
UIAlertController* alertController = [UIAlertController
|
||||
alertControllerWithTitle: app.appName
|
||||
message: [app.appId isEqualToString:currentApp.appId] ? @"" : [NSString stringWithFormat:@"%@ is currently running", currentApp.appName]preferredStyle:UIAlertControllerStyleAlert];
|
||||
alertControllerWithTitle: app.name
|
||||
message: [app.id isEqualToString:currentApp.id] ? @"" : [NSString stringWithFormat:@"%@ is currently running", currentApp.name]preferredStyle:UIAlertControllerStyleAlert];
|
||||
[alertController addAction:[UIAlertAction
|
||||
actionWithTitle:[app.appId isEqualToString:currentApp.appId] ? @"Resume App" : @"Resume Running App" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){
|
||||
Log(LOG_I, @"Resuming application: %@", currentApp.appName);
|
||||
actionWithTitle:[app.id isEqualToString:currentApp.id] ? @"Resume App" : @"Resume Running App" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){
|
||||
Log(LOG_I, @"Resuming application: %@", currentApp.name);
|
||||
[self performSegueWithIdentifier:@"createStreamFrame" sender:nil];
|
||||
}]];
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:
|
||||
[app.appId isEqualToString:currentApp.appId] ? @"Quit App" : @"Quit Running App and Start" style:UIAlertActionStyleDestructive handler:^(UIAlertAction* action){
|
||||
Log(LOG_I, @"Quitting application: %@", currentApp.appName);
|
||||
[app.id isEqualToString:currentApp.id] ? @"Quit App" : @"Quit Running App and Start" style:UIAlertActionStyleDestructive handler:^(UIAlertAction* action){
|
||||
Log(LOG_I, @"Quitting application: %@", currentApp.name);
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:_selectedHost.address uniqueId:_uniqueId deviceName:deviceName cert:_cert];
|
||||
[hMan executeRequestSynchronously:[HttpRequest requestWithUrlRequest:[hMan newQuitAppRequest]]];
|
||||
// TODO: handle failure to quit app
|
||||
currentApp.isRunning = NO;
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:app.host.activeAddress uniqueId:_uniqueId deviceName:deviceName cert:_cert];
|
||||
HttpResponse* quitResponse = [[HttpResponse alloc] init];
|
||||
HttpRequest* quitRequest = [HttpRequest requestForResponse: quitResponse withUrlRequest:[hMan newQuitAppRequest]];
|
||||
|
||||
if (![app.appId isEqualToString:currentApp.appId]) {
|
||||
// Exempt this host from discovery while handling the quit operation
|
||||
[_discMan removeHostFromDiscovery:app.host];
|
||||
[hMan executeRequestSynchronously:quitRequest];
|
||||
[_discMan addHostToDiscovery:app.host];
|
||||
|
||||
UIAlertController* alert;
|
||||
|
||||
// If it fails, display an error and stop the current operation
|
||||
if (quitResponse.statusCode != 200) {
|
||||
alert = [UIAlertController alertControllerWithTitle:@"Quitting App Failed"
|
||||
message:@"Failed to quit app. If this app was started by "
|
||||
"another device, you'll need to quit from that device."
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
}
|
||||
// If it succeeds and we're to start streaming, segue to the stream and return
|
||||
else if (![app.id isEqualToString:currentApp.id]) {
|
||||
currentApp.isRunning = NO;
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self updateAppsForHost:app.host];
|
||||
[self performSegueWithIdentifier:@"createStreamFrame" sender:nil];
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
// Otherwise, display a dialog to notify the user that the app was quit
|
||||
else {
|
||||
currentApp.isRunning = NO;
|
||||
|
||||
alert = [UIAlertController alertControllerWithTitle:@"Quitting App"
|
||||
message:@"The app was quit successfully."
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
}
|
||||
|
||||
[alert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDestructive handler:nil]];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self updateAppsForHost:app.host];
|
||||
[self presentViewController:alert animated:YES completion:nil];
|
||||
});
|
||||
});
|
||||
}]];
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]];
|
||||
@@ -279,8 +421,8 @@ static NSArray* appList;
|
||||
}
|
||||
}
|
||||
|
||||
- (App*) findRunningApp {
|
||||
for (App* app in appList) {
|
||||
- (App*) findRunningApp:(Host*)host {
|
||||
for (App* app in host.appList) {
|
||||
if (app.isRunning) {
|
||||
return app;
|
||||
}
|
||||
@@ -310,6 +452,7 @@ static NSArray* appList;
|
||||
|
||||
- (void) hideLoadingFrame {
|
||||
[self dismissViewControllerAnimated:YES completion:nil];
|
||||
[self enableNavigation];
|
||||
}
|
||||
|
||||
- (void)viewDidLoad
|
||||
@@ -372,7 +515,7 @@ static NSArray* appList;
|
||||
|
||||
// This will refresh the applist
|
||||
if (_selectedHost != nil) {
|
||||
[self hostClicked:_selectedHost];
|
||||
[self hostClicked:_selectedHost view:nil];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -383,7 +526,7 @@ static NSArray* appList;
|
||||
[_discMan stopDiscovery];
|
||||
|
||||
// In case the host objects were updated in the background
|
||||
[[[DataManager alloc] init] saveHosts];
|
||||
[[[DataManager alloc] init] saveData];
|
||||
}
|
||||
|
||||
- (void) retrieveSavedHosts {
|
||||
@@ -391,6 +534,19 @@ static NSArray* appList;
|
||||
NSArray* hosts = [dataMan retrieveHosts];
|
||||
@synchronized(hostList) {
|
||||
[hostList addObjectsFromArray:hosts];
|
||||
|
||||
// Initialize the non-persistent host state
|
||||
for (Host* host in hostList) {
|
||||
if (host.activeAddress == nil) {
|
||||
host.activeAddress = host.localAddress;
|
||||
}
|
||||
if (host.activeAddress == nil) {
|
||||
host.activeAddress = host.externalAddress;
|
||||
}
|
||||
if (host.activeAddress == nil) {
|
||||
host.activeAddress = host.address;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -398,7 +554,7 @@ static NSArray* appList;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
Log(LOG_D, @"New host list:");
|
||||
for (Host* host in hosts) {
|
||||
Log(LOG_D, @"Host: \n{\n\t name:%@ \n\t address:%@ \n\t localAddress:%@ \n\t externalAddress:%@ \n\t uuid:%@ \n\t mac:%@ \n\t pairState:%d \n\t online:%d \n}", host.name, host.address, host.localAddress, host.externalAddress, host.uuid, host.mac, host.pairState, host.online);
|
||||
Log(LOG_D, @"Host: \n{\n\t name:%@ \n\t address:%@ \n\t localAddress:%@ \n\t externalAddress:%@ \n\t uuid:%@ \n\t mac:%@ \n\t pairState:%d \n\t online:%d \n\t activeAddress:%@ \n}", host.name, host.address, host.localAddress, host.externalAddress, host.uuid, host.mac, host.pairState, host.online, host.activeAddress);
|
||||
}
|
||||
@synchronized(hostList) {
|
||||
[hostList removeAllObjects];
|
||||
@@ -437,7 +593,15 @@ static NSArray* appList;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) updateApps {
|
||||
- (void) updateAppsForHost:(Host*)host {
|
||||
if (host != _selectedHost) {
|
||||
Log(LOG_W, @"Mismatched host during app update");
|
||||
return;
|
||||
}
|
||||
|
||||
_sortedAppList = [host.appList allObjects];
|
||||
_sortedAppList = [_sortedAppList sortedArrayUsingSelector:@selector(compareName:)];
|
||||
|
||||
[hostScrollView removeFromSuperview];
|
||||
[self.collectionView reloadData];
|
||||
}
|
||||
@@ -445,7 +609,7 @@ static NSArray* appList;
|
||||
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||
UICollectionViewCell* cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"AppCell" forIndexPath:indexPath];
|
||||
|
||||
App* app = appList[indexPath.row];
|
||||
App* app = _sortedAppList[indexPath.row];
|
||||
UIAppView* appView = [[UIAppView alloc] initWithApp:app andCallback:self];
|
||||
[appView updateAppImage];
|
||||
|
||||
@@ -466,7 +630,12 @@ static NSArray* appList;
|
||||
}
|
||||
|
||||
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
|
||||
return appList.count;
|
||||
if (_selectedHost != nil) {
|
||||
return _selectedHost.appList.count;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning
|
||||
@@ -488,4 +657,12 @@ static NSArray* appList;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void) disableNavigation {
|
||||
self.navigationController.navigationBar.topItem.rightBarButtonItem.enabled = NO;
|
||||
}
|
||||
|
||||
- (void) enableNavigation {
|
||||
self.navigationController.navigationBar.topItem.rightBarButtonItem.enabled = YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -554,8 +554,8 @@ static CGFloat scaledValue( CGFloat v1, CGFloat min2, CGFloat max2, CGFloat min1
|
||||
UITouch *touch = [touches anyObject];
|
||||
CGPoint nowPoint = [touch locationInView:self.view];
|
||||
|
||||
if (abs(nowPoint.x - _beginPoint.x) > kDirectionPanThreshold) _dragging = YES;
|
||||
else if (abs(nowPoint.y - _beginPoint.y) > kDirectionPanThreshold) self.state = UIGestureRecognizerStateFailed;
|
||||
if (fabs(nowPoint.x - _beginPoint.x) > kDirectionPanThreshold) _dragging = YES;
|
||||
else if (fabs(nowPoint.y - _beginPoint.y) > kDirectionPanThreshold) self.state = UIGestureRecognizerStateFailed;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -742,15 +742,6 @@ const int FrontViewPositionNone = 0xff;
|
||||
_userInteractionStore = _contentView.userInteractionEnabled;
|
||||
}
|
||||
|
||||
|
||||
- (NSUInteger)supportedInterfaceOrientations
|
||||
{
|
||||
// we could have simply not implemented this, but we choose to call super to make explicit that we
|
||||
// want the default behavior.
|
||||
return [super supportedInterfaceOrientations];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Public methods and property accessors
|
||||
|
||||
- (void)setFrontViewController:(UIViewController *)frontViewController
|
||||
@@ -1274,7 +1265,7 @@ const int FrontViewPositionNone = 0xff;
|
||||
NSTimeInterval duration = _toggleAnimationDuration;
|
||||
|
||||
// Velocity driven change:
|
||||
if (fabsf(velocity) > _quickFlickVelocity)
|
||||
if (fabs(velocity) > _quickFlickVelocity)
|
||||
{
|
||||
// we may need to set the drag position and to adjust the animation duration
|
||||
CGFloat journey = xLocation;
|
||||
@@ -1292,7 +1283,7 @@ const int FrontViewPositionNone = 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
duration = fabsf(journey/velocity);
|
||||
duration = fabs(journey/velocity);
|
||||
}
|
||||
|
||||
// Position driven change:
|
||||
@@ -1349,7 +1340,7 @@ const int FrontViewPositionNone = 0xff;
|
||||
|
||||
NSTimeInterval duration = animated?_toggleAnimationDuration:0.0;
|
||||
NSTimeInterval firstDuration = duration;
|
||||
int initialPosDif = abs( _frontViewPosition - preReplacementPosition );
|
||||
int initialPosDif = (int) labs( _frontViewPosition - preReplacementPosition );
|
||||
if ( initialPosDif == 1 ) firstDuration *= 0.8;
|
||||
else if ( initialPosDif == 0 ) firstDuration = 0;
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// SettingsViewController.h
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/27/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// SettingsViewController.m
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/27/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "SettingsViewController.h"
|
||||
@@ -40,7 +40,7 @@ static NSString* bitrateFormat = @"Bitrate: %.1f Mbps";
|
||||
[self.resolutionSelector setSelectedSegmentIndex:resolution];
|
||||
[self.framerateSelector setSelectedSegmentIndex:framerate];
|
||||
[self.onscreenControlSelector setSelectedSegmentIndex:onscreenControls];
|
||||
[self.bitrateSlider setValue:(_bitrate / 1000) animated:YES];
|
||||
[self.bitrateSlider setValue:(_bitrate / BITRATE_INTERVAL) animated:YES];
|
||||
[self.bitrateSlider addTarget:self action:@selector(bitrateSliderMoved) forControlEvents:UIControlEventValueChanged];
|
||||
[self updateBitrateText];
|
||||
}
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
//
|
||||
// StreamFrameViewController.h
|
||||
// Limelight-iOS
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 1/18/14.
|
||||
// Copyright (c) 2014 Diego Waxemberg. All rights reserved.
|
||||
// Copyright (c) 2015 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Connection.h"
|
||||
#import "StreamConfiguration.h"
|
||||
#import "StreamView.h"
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface StreamFrameViewController : UIViewController <ConnectionCallbacks>
|
||||
@interface StreamFrameViewController : UIViewController <ConnectionCallbacks, EdgeDetectionDelegate>
|
||||
@property (strong, nonatomic) IBOutlet UILabel *stageLabel;
|
||||
@property (strong, nonatomic) IBOutlet UIActivityIndicatorView *spinner;
|
||||
@property (nonatomic) StreamConfiguration* streamConfig;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// StreamFrameViewController.m
|
||||
// Limelight-iOS
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 1/18/14.
|
||||
// Copyright (c) 2014 Diego Waxemberg. All rights reserved.
|
||||
// Copyright (c) 2015 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "StreamFrameViewController.h"
|
||||
@@ -11,7 +11,6 @@
|
||||
#import "VideoDecoderRenderer.h"
|
||||
#import "StreamManager.h"
|
||||
#import "ControllerSupport.h"
|
||||
#import "StreamView.h"
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
@@ -70,14 +69,7 @@
|
||||
[self.spinner stopAnimating];
|
||||
[self.stageLabel setText:@"Waiting for first frame..."];
|
||||
[self.stageLabel sizeToFit];
|
||||
[(StreamView*)self.view setupOnScreenControls: _controllerSupport];
|
||||
UIScreenEdgePanGestureRecognizer* swipeGesture = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:@selector(edgeSwiped)];
|
||||
swipeGesture.edges = UIRectEdgeLeft;
|
||||
if (swipeGesture == nil) {
|
||||
Log(LOG_E, @"An error occured trying to create UIScreenEdgePanGestureRecognizer");
|
||||
} else {
|
||||
[self.view addGestureRecognizer:swipeGesture];
|
||||
}
|
||||
[(StreamView*)self.view setupOnScreenControls: _controllerSupport swipeDelegate:self];
|
||||
});
|
||||
}
|
||||
|
||||
@@ -110,24 +102,32 @@
|
||||
}
|
||||
|
||||
- (void) stageFailed:(char*)stageName withError:(long)errorCode {
|
||||
UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"Connection Failed"
|
||||
message:[NSString stringWithFormat:@"%s failed with error %ld",
|
||||
stageName, errorCode]
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
[alert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDestructive handler:^(UIAlertAction* action){
|
||||
[self returnToMainFrame];
|
||||
}]];
|
||||
[self presentViewController:alert animated:YES completion:nil];
|
||||
Log(LOG_I, @"Stage %s failed: %ld", stageName, errorCode);
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"Connection Failed"
|
||||
message:[NSString stringWithFormat:@"%s failed with error %ld",
|
||||
stageName, errorCode]
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
[alert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDestructive handler:^(UIAlertAction* action){
|
||||
[self returnToMainFrame];
|
||||
}]];
|
||||
[self presentViewController:alert animated:YES completion:nil];
|
||||
});
|
||||
}
|
||||
|
||||
- (void) launchFailed:(NSString*)message {
|
||||
UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"Connection Failed"
|
||||
message:message
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
[alert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDestructive handler:^(UIAlertAction* action){
|
||||
[self returnToMainFrame];
|
||||
}]];
|
||||
[self presentViewController:alert animated:YES completion:nil];
|
||||
Log(LOG_I, @"Launch failed: %@", message);
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"Connection Failed"
|
||||
message:message
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
[alert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDestructive handler:^(UIAlertAction* action){
|
||||
[self returnToMainFrame];
|
||||
}]];
|
||||
[self presentViewController:alert animated:YES completion:nil];
|
||||
});
|
||||
}
|
||||
|
||||
- (void) displayMessage:(char*)message {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// main.m
|
||||
// Limelight
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Diego Waxemberg on 8/30/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
<?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>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.limelight-stream.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,34 +0,0 @@
|
||||
//
|
||||
// LimelightTests.m
|
||||
// LimelightTests
|
||||
//
|
||||
// Created by Diego Waxemberg on 8/30/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
@interface LimelightTests : XCTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation LimelightTests
|
||||
|
||||
- (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
|
||||
{
|
||||
XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,2 +0,0 @@
|
||||
/* Localized versions of Info.plist keys */
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
98A03B4D19F352EB00861ACA /* liblimelight-common.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 98A03B4A19F3514B00861ACA /* liblimelight-common.a */; };
|
||||
987140041B04542F00AB57D5 /* libmoonlight-common.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FB1E43101AE8B0F200AFF679 /* libmoonlight-common.a */; };
|
||||
9E5D600B1A5A5A3900689918 /* Apache License.txt in Resources */ = {isa = PBXBuildFile; fileRef = 9E5D5FF81A5A5A3900689918 /* Apache License.txt */; };
|
||||
9E5D600C1A5A5A3900689918 /* Roboto-Black.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9E5D5FF91A5A5A3900689918 /* Roboto-Black.ttf */; };
|
||||
9E5D600E1A5A5A3900689918 /* Roboto-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9E5D5FFB1A5A5A3900689918 /* Roboto-Bold.ttf */; };
|
||||
@@ -24,11 +24,6 @@
|
||||
FB290D0419B2C406004C83CF /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = FB290D0319B2C406004C83CF /* AppDelegate.m */; };
|
||||
FB290D0719B2C406004C83CF /* Limelight.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = FB290D0519B2C406004C83CF /* Limelight.xcdatamodeld */; };
|
||||
FB290D0919B2C406004C83CF /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FB290D0819B2C406004C83CF /* Images.xcassets */; };
|
||||
FB290D1119B2C406004C83CF /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB290CF119B2C406004C83CF /* Foundation.framework */; };
|
||||
FB290D1219B2C406004C83CF /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB290CF519B2C406004C83CF /* UIKit.framework */; };
|
||||
FB290D1319B2C406004C83CF /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB290CF719B2C406004C83CF /* CoreData.framework */; };
|
||||
FB290D1B19B2C406004C83CF /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = FB290D1919B2C406004C83CF /* InfoPlist.strings */; };
|
||||
FB290D1D19B2C406004C83CF /* LimelightTests.m in Sources */ = {isa = PBXBuildFile; fileRef = FB290D1C19B2C406004C83CF /* LimelightTests.m */; };
|
||||
FB290DB719B2C870004C83CF /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FB290DB619B2C870004C83CF /* libz.dylib */; };
|
||||
FB290DB919B2C877004C83CF /* libbz2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FB290DB819B2C877004C83CF /* libbz2.dylib */; };
|
||||
FB290DC419B2E98F004C83CF /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FB290DC319B2E98F004C83CF /* libxml2.dylib */; };
|
||||
@@ -70,40 +65,33 @@
|
||||
FBD3494319FC9C04002D2A60 /* AppAssetManager.m in Sources */ = {isa = PBXBuildFile; fileRef = FBD3494219FC9C04002D2A60 /* AppAssetManager.m */; };
|
||||
FBD3495019FF2174002D2A60 /* SettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FBD3494F19FF2174002D2A60 /* SettingsViewController.m */; };
|
||||
FBD3495319FF36FB002D2A60 /* SWRevealViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FBD3495219FF36FB002D2A60 /* SWRevealViewController.m */; };
|
||||
FBD3495B1A004411002D2A60 /* Host.m in Sources */ = {isa = PBXBuildFile; fileRef = FBD3495A1A004411002D2A60 /* Host.m */; };
|
||||
FBD3495E1A004412002D2A60 /* Settings.m in Sources */ = {isa = PBXBuildFile; fileRef = FBD3495D1A004412002D2A60 /* Settings.m */; };
|
||||
FBD349621A0089F6002D2A60 /* DataManager.m in Sources */ = {isa = PBXBuildFile; fileRef = FBD349611A0089F6002D2A60 /* DataManager.m */; };
|
||||
FBDE86E019F7A837001C18A8 /* UIComputerView.m in Sources */ = {isa = PBXBuildFile; fileRef = FBDE86DF19F7A837001C18A8 /* UIComputerView.m */; };
|
||||
FBDE86E619F82297001C18A8 /* UIAppView.m in Sources */ = {isa = PBXBuildFile; fileRef = FBDE86E519F82297001C18A8 /* UIAppView.m */; };
|
||||
FBDE86E919F82315001C18A8 /* App.m in Sources */ = {isa = PBXBuildFile; fileRef = FBDE86E819F82315001C18A8 /* App.m */; };
|
||||
FBFCB3311B50B29400089F8A /* Host.m in Sources */ = {isa = PBXBuildFile; fileRef = FBFCB3301B50B29400089F8A /* Host.m */; };
|
||||
FBFCB3351B50B29400089F8A /* App.m in Sources */ = {isa = PBXBuildFile; fileRef = FBFCB3341B50B29400089F8A /* App.m */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
98A03B4919F3514B00861ACA /* PBXContainerItemProxy */ = {
|
||||
987140011B04541A00AB57D5 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 98A03B4519F3514B00861ACA /* limelight-common.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = FB290E2E19B37A4E004C83CF;
|
||||
remoteInfo = "limelight-common";
|
||||
};
|
||||
98A03B4B19F3517100861ACA /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 98A03B4519F3514B00861ACA /* limelight-common.xcodeproj */;
|
||||
containerPortal = 98A03B4519F3514B00861ACA /* moonlight-common.xcodeproj */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = FB290E2D19B37A4E004C83CF;
|
||||
remoteInfo = "limelight-common";
|
||||
remoteInfo = "moonlight-common";
|
||||
};
|
||||
FB290D1419B2C406004C83CF /* PBXContainerItemProxy */ = {
|
||||
FB1E430F1AE8B0F200AFF679 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = FB290CE619B2C406004C83CF /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = FB290CED19B2C406004C83CF;
|
||||
remoteInfo = Limelight;
|
||||
containerPortal = 98A03B4519F3514B00861ACA /* moonlight-common.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = FB290E2E19B37A4E004C83CF;
|
||||
remoteInfo = "moonlight-common";
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
98A03B4519F3514B00861ACA /* limelight-common.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "limelight-common.xcodeproj"; path = "limelight-common-c/limelight-common.xcodeproj"; sourceTree = "<group>"; };
|
||||
98A03B4519F3514B00861ACA /* moonlight-common.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "moonlight-common.xcodeproj"; path = "limelight-common-c/moonlight-common.xcodeproj"; sourceTree = "<group>"; };
|
||||
9E5D5FF81A5A5A3900689918 /* Apache License.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "Apache License.txt"; sourceTree = "<group>"; };
|
||||
9E5D5FF91A5A5A3900689918 /* Roboto-Black.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Roboto-Black.ttf"; sourceTree = "<group>"; };
|
||||
9E5D5FFB1A5A5A3900689918 /* Roboto-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Roboto-Bold.ttf"; sourceTree = "<group>"; };
|
||||
@@ -111,7 +99,7 @@
|
||||
9E5D60001A5A5A3900689918 /* Roboto-Medium.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Roboto-Medium.ttf"; sourceTree = "<group>"; };
|
||||
9E5D60021A5A5A3900689918 /* Roboto-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Roboto-Regular.ttf"; sourceTree = "<group>"; };
|
||||
9E5D60031A5A5A3900689918 /* Roboto-Thin.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Roboto-Thin.ttf"; sourceTree = "<group>"; };
|
||||
FB290CEE19B2C406004C83CF /* Limelight.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Limelight.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
FB290CEE19B2C406004C83CF /* Moonlight.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Moonlight.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
FB290CF119B2C406004C83CF /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
FB290CF319B2C406004C83CF /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
|
||||
FB290CF519B2C406004C83CF /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
|
||||
@@ -124,10 +112,6 @@
|
||||
FB290D0319B2C406004C83CF /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
|
||||
FB290D0619B2C406004C83CF /* Limelight.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Limelight.xcdatamodel; sourceTree = "<group>"; };
|
||||
FB290D0819B2C406004C83CF /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
|
||||
FB290D0E19B2C406004C83CF /* LimelightTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = LimelightTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
FB290D1819B2C406004C83CF /* LimelightTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "LimelightTests-Info.plist"; sourceTree = "<group>"; };
|
||||
FB290D1A19B2C406004C83CF /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
FB290D1C19B2C406004C83CF /* LimelightTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LimelightTests.m; sourceTree = "<group>"; };
|
||||
FB290DB619B2C870004C83CF /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
|
||||
FB290DB819B2C877004C83CF /* libbz2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbz2.dylib; path = usr/lib/libbz2.dylib; sourceTree = SDKROOT; };
|
||||
FB290DC319B2E98F004C83CF /* libxml2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libxml2.dylib; path = usr/lib/libxml2.dylib; sourceTree = SDKROOT; };
|
||||
@@ -146,6 +130,7 @@
|
||||
FB6549541A57907E001C8F39 /* DiscoveryWorker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiscoveryWorker.h; sourceTree = "<group>"; };
|
||||
FB6549551A57907E001C8F39 /* DiscoveryWorker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DiscoveryWorker.m; sourceTree = "<group>"; };
|
||||
FB6549621A60B4A9001C8F39 /* Limelight 0.3.1.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Limelight 0.3.1.xcdatamodel"; sourceTree = "<group>"; };
|
||||
FB6DDEF31AE739100096499A /* libmoonlight-common.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libmoonlight-common.a"; path = "limelight-common-c/build/Debug-iphoneos/libmoonlight-common.a"; sourceTree = "<group>"; };
|
||||
FB7E794319C8B71B00A15F68 /* libiconv.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libiconv.dylib; path = usr/lib/libiconv.dylib; sourceTree = SDKROOT; };
|
||||
FB89460519F646E200339C8A /* CryptoManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoManager.h; sourceTree = "<group>"; };
|
||||
FB89460619F646E200339C8A /* CryptoManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CryptoManager.m; sourceTree = "<group>"; };
|
||||
@@ -272,6 +257,7 @@
|
||||
FB9AFD3F1A7E127D00872C98 /* AppListResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppListResponse.m; sourceTree = "<group>"; };
|
||||
FB9AFD411A7F0C6900872C98 /* Controller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Controller.h; sourceTree = "<group>"; };
|
||||
FB9AFD421A7F0C6900872C98 /* Controller.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Controller.m; sourceTree = "<group>"; };
|
||||
FBB460391B50ACE400F3099C /* Moonlight v1.0.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Moonlight v1.0.xcdatamodel"; sourceTree = "<group>"; };
|
||||
FBD1C8E01A8AD69E00C6703C /* Logger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Logger.h; sourceTree = "<group>"; };
|
||||
FBD1C8E11A8AD71400C6703C /* Logger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Logger.m; sourceTree = "<group>"; };
|
||||
FBD3494119FC9C04002D2A60 /* AppAssetManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppAssetManager.h; sourceTree = "<group>"; };
|
||||
@@ -281,8 +267,6 @@
|
||||
FBD3495119FF36FB002D2A60 /* SWRevealViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SWRevealViewController.h; sourceTree = "<group>"; };
|
||||
FBD3495219FF36FB002D2A60 /* SWRevealViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SWRevealViewController.m; sourceTree = "<group>"; };
|
||||
FBD349571A003F05002D2A60 /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = usr/lib/libsqlite3.dylib; sourceTree = SDKROOT; };
|
||||
FBD349591A004411002D2A60 /* Host.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Host.h; path = Database/Host.h; sourceTree = "<group>"; };
|
||||
FBD3495A1A004411002D2A60 /* Host.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Host.m; path = Database/Host.m; sourceTree = "<group>"; };
|
||||
FBD3495C1A004412002D2A60 /* Settings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Settings.h; path = Database/Settings.h; sourceTree = "<group>"; };
|
||||
FBD3495D1A004412002D2A60 /* Settings.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Settings.m; path = Database/Settings.m; sourceTree = "<group>"; };
|
||||
FBD349601A0089F6002D2A60 /* DataManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DataManager.h; path = Database/DataManager.h; sourceTree = "<group>"; };
|
||||
@@ -291,8 +275,12 @@
|
||||
FBDE86DF19F7A837001C18A8 /* UIComputerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIComputerView.m; sourceTree = "<group>"; };
|
||||
FBDE86E419F82297001C18A8 /* UIAppView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIAppView.h; sourceTree = "<group>"; };
|
||||
FBDE86E519F82297001C18A8 /* UIAppView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIAppView.m; sourceTree = "<group>"; };
|
||||
FBDE86E719F82315001C18A8 /* App.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = App.h; path = ../App.h; sourceTree = "<group>"; };
|
||||
FBDE86E819F82315001C18A8 /* App.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = App.m; path = ../App.m; sourceTree = "<group>"; };
|
||||
FBFCB32E1B50B29400089F8A /* Host+CoreDataProperties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "Host+CoreDataProperties.h"; path = "Database/Host+CoreDataProperties.h"; sourceTree = "<group>"; };
|
||||
FBFCB32F1B50B29400089F8A /* Host.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Host.h; path = Database/Host.h; sourceTree = "<group>"; };
|
||||
FBFCB3301B50B29400089F8A /* Host.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Host.m; path = Database/Host.m; sourceTree = "<group>"; };
|
||||
FBFCB3321B50B29400089F8A /* App+CoreDataProperties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "App+CoreDataProperties.h"; path = "Database/App+CoreDataProperties.h"; sourceTree = "<group>"; };
|
||||
FBFCB3331B50B29400089F8A /* App.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = App.h; path = Database/App.h; sourceTree = "<group>"; };
|
||||
FBFCB3341B50B29400089F8A /* App.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = App.m; path = Database/App.m; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -300,7 +288,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
98A03B4D19F352EB00861ACA /* liblimelight-common.a in Frameworks */,
|
||||
987140041B04542F00AB57D5 /* libmoonlight-common.a in Frameworks */,
|
||||
FB8946ED19F6AFE800339C8A /* libopus.a in Frameworks */,
|
||||
FB8946EB19F6AFE100339C8A /* libcrypto.a in Frameworks */,
|
||||
FB8946EC19F6AFE400339C8A /* libssl.a in Frameworks */,
|
||||
@@ -316,27 +304,9 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
FB290D0B19B2C406004C83CF /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
FB290D1319B2C406004C83CF /* CoreData.framework in Frameworks */,
|
||||
FB290D1219B2C406004C83CF /* UIKit.framework in Frameworks */,
|
||||
FB290D1119B2C406004C83CF /* Foundation.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
98A03B4619F3514B00861ACA /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
98A03B4A19F3514B00861ACA /* liblimelight-common.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9E5D5FF61A5A5A3900689918 /* Font */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -359,12 +329,19 @@
|
||||
path = Roboto;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FB1E430C1AE8B0F200AFF679 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FB1E43101AE8B0F200AFF679 /* libmoonlight-common.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FB290CE519B2C406004C83CF = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
98A03B4519F3514B00861ACA /* limelight-common.xcodeproj */,
|
||||
98A03B4519F3514B00861ACA /* moonlight-common.xcodeproj */,
|
||||
FB290CF919B2C406004C83CF /* Limelight */,
|
||||
FB290D1619B2C406004C83CF /* LimelightTests */,
|
||||
FB290CF019B2C406004C83CF /* Frameworks */,
|
||||
FB290CEF19B2C406004C83CF /* Products */,
|
||||
);
|
||||
@@ -373,8 +350,7 @@
|
||||
FB290CEF19B2C406004C83CF /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FB290CEE19B2C406004C83CF /* Limelight.app */,
|
||||
FB290D0E19B2C406004C83CF /* LimelightTests.xctest */,
|
||||
FB290CEE19B2C406004C83CF /* Moonlight.app */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@@ -382,6 +358,7 @@
|
||||
FB290CF019B2C406004C83CF /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FB6DDEF31AE739100096499A /* libmoonlight-common.a */,
|
||||
FB4679001A57048000377732 /* CoreFoundation.framework */,
|
||||
FBD349571A003F05002D2A60 /* libsqlite3.dylib */,
|
||||
FB89468F19F6AFB800339C8A /* libs */,
|
||||
@@ -435,24 +412,6 @@
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FB290D1619B2C406004C83CF /* LimelightTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FB290D1C19B2C406004C83CF /* LimelightTests.m */,
|
||||
FB290D1719B2C406004C83CF /* Supporting Files */,
|
||||
);
|
||||
path = LimelightTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FB290D1719B2C406004C83CF /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FB290D1819B2C406004C83CF /* LimelightTests-Info.plist */,
|
||||
FB290D1919B2C406004C83CF /* InfoPlist.strings */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FB89460419F646E200339C8A /* Crypto */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -484,7 +443,7 @@
|
||||
children = (
|
||||
FB9AFD2F1A7C979700872C98 /* Http */,
|
||||
FB9AFD341A7D877B00872C98 /* Discovery */,
|
||||
FB9AFD331A7D876F00872C98 /* AppAsset */,
|
||||
FB9AFD331A7D876F00872C98 /* AppList */,
|
||||
FB89461319F646E200339C8A /* PairManager.h */,
|
||||
FB89461419F646E200339C8A /* PairManager.m */,
|
||||
FB4678FD1A565DAC00377732 /* WakeOnLanManager.h */,
|
||||
@@ -511,8 +470,6 @@
|
||||
FB89461E19F646E200339C8A /* Utility */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FBDE86E719F82315001C18A8 /* App.h */,
|
||||
FBDE86E819F82315001C18A8 /* App.m */,
|
||||
FB89462119F646E200339C8A /* Utils.h */,
|
||||
FB89462219F646E200339C8A /* Utils.m */,
|
||||
FBD1C8E01A8AD69E00C6703C /* Logger.h */,
|
||||
@@ -718,7 +675,7 @@
|
||||
name = Http;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FB9AFD331A7D876F00872C98 /* AppAsset */ = {
|
||||
FB9AFD331A7D876F00872C98 /* AppList */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FBD3494119FC9C04002D2A60 /* AppAssetManager.h */,
|
||||
@@ -726,7 +683,7 @@
|
||||
FB9AFD301A7D867C00872C98 /* AppAssetRetriever.h */,
|
||||
FB9AFD311A7D867C00872C98 /* AppAssetRetriever.m */,
|
||||
);
|
||||
name = AppAsset;
|
||||
name = AppList;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FB9AFD341A7D877B00872C98 /* Discovery */ = {
|
||||
@@ -745,10 +702,14 @@
|
||||
FBD3495F1A004453002D2A60 /* Database */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FBFCB3321B50B29400089F8A /* App+CoreDataProperties.h */,
|
||||
FBFCB3331B50B29400089F8A /* App.h */,
|
||||
FBFCB3341B50B29400089F8A /* App.m */,
|
||||
FBFCB32E1B50B29400089F8A /* Host+CoreDataProperties.h */,
|
||||
FBFCB32F1B50B29400089F8A /* Host.h */,
|
||||
FBFCB3301B50B29400089F8A /* Host.m */,
|
||||
FBD3495C1A004412002D2A60 /* Settings.h */,
|
||||
FBD3495D1A004412002D2A60 /* Settings.m */,
|
||||
FBD349591A004411002D2A60 /* Host.h */,
|
||||
FBD3495A1A004411002D2A60 /* Host.m */,
|
||||
FBD349601A0089F6002D2A60 /* DataManager.h */,
|
||||
FBD349611A0089F6002D2A60 /* DataManager.m */,
|
||||
);
|
||||
@@ -758,9 +719,9 @@
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
FB290CED19B2C406004C83CF /* Limelight */ = {
|
||||
FB290CED19B2C406004C83CF /* Moonlight */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = FB290D2019B2C406004C83CF /* Build configuration list for PBXNativeTarget "Limelight" */;
|
||||
buildConfigurationList = FB290D2019B2C406004C83CF /* Build configuration list for PBXNativeTarget "Moonlight" */;
|
||||
buildPhases = (
|
||||
FB290CEA19B2C406004C83CF /* Sources */,
|
||||
FB290CEB19B2C406004C83CF /* Frameworks */,
|
||||
@@ -769,49 +730,28 @@
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
98A03B4C19F3517100861ACA /* PBXTargetDependency */,
|
||||
987140021B04541A00AB57D5 /* PBXTargetDependency */,
|
||||
);
|
||||
name = Limelight;
|
||||
name = Moonlight;
|
||||
productName = Limelight;
|
||||
productReference = FB290CEE19B2C406004C83CF /* Limelight.app */;
|
||||
productReference = FB290CEE19B2C406004C83CF /* Moonlight.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
FB290D0D19B2C406004C83CF /* LimelightTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = FB290D2319B2C406004C83CF /* Build configuration list for PBXNativeTarget "LimelightTests" */;
|
||||
buildPhases = (
|
||||
FB290D0A19B2C406004C83CF /* Sources */,
|
||||
FB290D0B19B2C406004C83CF /* Frameworks */,
|
||||
FB290D0C19B2C406004C83CF /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
FB290D1519B2C406004C83CF /* PBXTargetDependency */,
|
||||
);
|
||||
name = LimelightTests;
|
||||
productName = LimelightTests;
|
||||
productReference = FB290D0E19B2C406004C83CF /* LimelightTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
FB290CE619B2C406004C83CF /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0510;
|
||||
LastUpgradeCheck = 0700;
|
||||
ORGANIZATIONNAME = "Limelight Stream";
|
||||
TargetAttributes = {
|
||||
FB290CED19B2C406004C83CF = {
|
||||
DevelopmentTeam = DM46QST4M7;
|
||||
};
|
||||
FB290D0D19B2C406004C83CF = {
|
||||
TestTargetID = FB290CED19B2C406004C83CF;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = FB290CE919B2C406004C83CF /* Build configuration list for PBXProject "Limelight" */;
|
||||
buildConfigurationList = FB290CE919B2C406004C83CF /* Build configuration list for PBXProject "Moonlight" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
@@ -823,24 +763,23 @@
|
||||
projectDirPath = "";
|
||||
projectReferences = (
|
||||
{
|
||||
ProductGroup = 98A03B4619F3514B00861ACA /* Products */;
|
||||
ProjectRef = 98A03B4519F3514B00861ACA /* limelight-common.xcodeproj */;
|
||||
ProductGroup = FB1E430C1AE8B0F200AFF679 /* Products */;
|
||||
ProjectRef = 98A03B4519F3514B00861ACA /* moonlight-common.xcodeproj */;
|
||||
},
|
||||
);
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
FB290CED19B2C406004C83CF /* Limelight */,
|
||||
FB290D0D19B2C406004C83CF /* LimelightTests */,
|
||||
FB290CED19B2C406004C83CF /* Moonlight */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXReferenceProxy section */
|
||||
98A03B4A19F3514B00861ACA /* liblimelight-common.a */ = {
|
||||
FB1E43101AE8B0F200AFF679 /* libmoonlight-common.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = "liblimelight-common.a";
|
||||
remoteRef = 98A03B4919F3514B00861ACA /* PBXContainerItemProxy */;
|
||||
path = "libmoonlight-common.a";
|
||||
remoteRef = FB1E430F1AE8B0F200AFF679 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
/* End PBXReferenceProxy section */
|
||||
@@ -865,14 +804,6 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
FB290D0C19B2C406004C83CF /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
FB290D1B19B2C406004C83CF /* InfoPlist.strings in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
@@ -893,15 +824,14 @@
|
||||
FB89462919F646E200339C8A /* mkcert.c in Sources */,
|
||||
FB9AFD281A7C84ED00872C98 /* HttpResponse.m in Sources */,
|
||||
FBDE86E019F7A837001C18A8 /* UIComputerView.m in Sources */,
|
||||
FBDE86E919F82315001C18A8 /* App.m in Sources */,
|
||||
FB89463019F646E200339C8A /* StreamConfiguration.m in Sources */,
|
||||
FBFCB3311B50B29400089F8A /* Host.m in Sources */,
|
||||
FBD3495319FF36FB002D2A60 /* SWRevealViewController.m in Sources */,
|
||||
FBD3495019FF2174002D2A60 /* SettingsViewController.m in Sources */,
|
||||
FB89462C19F646E200339C8A /* HttpManager.m in Sources */,
|
||||
FB89462D19F646E200339C8A /* MDNSManager.m in Sources */,
|
||||
FB89462B19F646E200339C8A /* StreamView.m in Sources */,
|
||||
FB4678FA1A55FFAD00377732 /* DiscoveryManager.m in Sources */,
|
||||
FBD3495B1A004411002D2A60 /* Host.m in Sources */,
|
||||
FB89463519F646E200339C8A /* MainFrameViewController.m in Sources */,
|
||||
FBD1C8E21A8AD71400C6703C /* Logger.m in Sources */,
|
||||
FB89463619F646E200339C8A /* StreamFrameViewController.m in Sources */,
|
||||
@@ -916,32 +846,20 @@
|
||||
FB89462A19F646E200339C8A /* ControllerSupport.m in Sources */,
|
||||
FB9AFD3D1A7E111600872C98 /* AppAssetResponse.m in Sources */,
|
||||
FBD349621A0089F6002D2A60 /* DataManager.m in Sources */,
|
||||
FBFCB3351B50B29400089F8A /* App.m in Sources */,
|
||||
FB4A23B81A9D3637004D2EF2 /* LoadingFrameViewController.m in Sources */,
|
||||
FB9AFD3A1A7E05CE00872C98 /* ServerInfoResponse.m in Sources */,
|
||||
FB89463119F646E200339C8A /* StreamManager.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
FB290D0A19B2C406004C83CF /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
FB290D1D19B2C406004C83CF /* LimelightTests.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
98A03B4C19F3517100861ACA /* PBXTargetDependency */ = {
|
||||
987140021B04541A00AB57D5 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
name = "limelight-common";
|
||||
targetProxy = 98A03B4B19F3517100861ACA /* PBXContainerItemProxy */;
|
||||
};
|
||||
FB290D1519B2C406004C83CF /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = FB290CED19B2C406004C83CF /* Limelight */;
|
||||
targetProxy = FB290D1419B2C406004C83CF /* PBXContainerItemProxy */;
|
||||
name = "moonlight-common";
|
||||
targetProxy = 987140011B04541A00AB57D5 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
@@ -954,14 +872,6 @@
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FB290D1919B2C406004C83CF /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
FB290D1A19B2C406004C83CF /* en */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
@@ -984,6 +894,7 @@
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
@@ -1046,6 +957,7 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
ENABLE_BITCODE = NO;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "Limelight/Limelight-Prefix.pch";
|
||||
HEADER_SEARCH_PATHS = (
|
||||
@@ -1061,6 +973,7 @@
|
||||
"$(PROJECT_DIR)/libs/opus/lib",
|
||||
"$(PROJECT_DIR)/libs/openssl/lib",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.moonlight-stream.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE = "";
|
||||
SKIP_INSTALL = NO;
|
||||
@@ -1072,8 +985,9 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
ENABLE_BITCODE = NO;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "Limelight/Limelight-Prefix.pch";
|
||||
HEADER_SEARCH_PATHS = (
|
||||
@@ -1089,6 +1003,7 @@
|
||||
"$(PROJECT_DIR)/libs/opus/lib",
|
||||
"$(PROJECT_DIR)/libs/openssl/lib",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.moonlight-stream.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE = "";
|
||||
SKIP_INSTALL = NO;
|
||||
@@ -1096,50 +1011,10 @@
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
FB290D2419B2C406004C83CF /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/Limelight.app/Limelight";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(SDKROOT)/Developer/Library/Frameworks",
|
||||
"$(inherited)",
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
);
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "Limelight/Limelight-Prefix.pch";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
INFOPLIST_FILE = "LimelightTests/LimelightTests-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUNDLE_LOADER)";
|
||||
WRAPPER_EXTENSION = xctest;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
FB290D2519B2C406004C83CF /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/Limelight.app/Limelight";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(SDKROOT)/Developer/Library/Frameworks",
|
||||
"$(inherited)",
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
);
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "Limelight/Limelight-Prefix.pch";
|
||||
INFOPLIST_FILE = "LimelightTests/LimelightTests-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUNDLE_LOADER)";
|
||||
WRAPPER_EXTENSION = xctest;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
FB290CE919B2C406004C83CF /* Build configuration list for PBXProject "Limelight" */ = {
|
||||
FB290CE919B2C406004C83CF /* Build configuration list for PBXProject "Moonlight" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
FB290D1E19B2C406004C83CF /* Debug */,
|
||||
@@ -1148,7 +1023,7 @@
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
FB290D2019B2C406004C83CF /* Build configuration list for PBXNativeTarget "Limelight" */ = {
|
||||
FB290D2019B2C406004C83CF /* Build configuration list for PBXNativeTarget "Moonlight" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
FB290D2119B2C406004C83CF /* Debug */,
|
||||
@@ -1157,26 +1032,18 @@
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
FB290D2319B2C406004C83CF /* Build configuration list for PBXNativeTarget "LimelightTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
FB290D2419B2C406004C83CF /* Debug */,
|
||||
FB290D2519B2C406004C83CF /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
|
||||
/* Begin XCVersionGroup section */
|
||||
FB290D0519B2C406004C83CF /* Limelight.xcdatamodeld */ = {
|
||||
isa = XCVersionGroup;
|
||||
children = (
|
||||
FBB460391B50ACE400F3099C /* Moonlight v1.0.xcdatamodel */,
|
||||
FB6549621A60B4A9001C8F39 /* Limelight 0.3.1.xcdatamodel */,
|
||||
FB4678F21A51BDCB00377732 /* Limelight 0.3.0.xcdatamodel */,
|
||||
FB290D0619B2C406004C83CF /* Limelight.xcdatamodel */,
|
||||
);
|
||||
currentVersion = FB6549621A60B4A9001C8F39 /* Limelight 0.3.1.xcdatamodel */;
|
||||
currentVersion = FBB460391B50ACE400F3099C /* Moonlight v1.0.xcdatamodel */;
|
||||
path = Limelight.xcdatamodeld;
|
||||
sourceTree = "<group>";
|
||||
versionGroupType = wrapper.xcdatamodel;
|
||||
@@ -2,6 +2,6 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:Limelight.xcodeproj">
|
||||
location = "self:Moonlight.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -0,0 +1,53 @@
|
||||
<?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>AD7C6582-F39A-441A-A7FD-9EBF143920BA</string>
|
||||
<key>IDESourceControlProjectName</key>
|
||||
<string>Moonlight</string>
|
||||
<key>IDESourceControlProjectOriginsDictionary</key>
|
||||
<dict>
|
||||
<key>A4B0849259F9566B0CBA84A6D3D4A0F895C03123</key>
|
||||
<string>github.com:limelight-stream/limelight-ios.git</string>
|
||||
<key>EB99D631D5149240E91F8D168F0F298D7A5BAA89</key>
|
||||
<string>github.com:limelight-stream/limelight-common-c.git</string>
|
||||
</dict>
|
||||
<key>IDESourceControlProjectPath</key>
|
||||
<string>Moonlight.xcodeproj</string>
|
||||
<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
|
||||
<dict>
|
||||
<key>A4B0849259F9566B0CBA84A6D3D4A0F895C03123</key>
|
||||
<string>../..</string>
|
||||
<key>EB99D631D5149240E91F8D168F0F298D7A5BAA89</key>
|
||||
<string>../../limelight-common-c</string>
|
||||
</dict>
|
||||
<key>IDESourceControlProjectURL</key>
|
||||
<string>github.com:limelight-stream/limelight-ios.git</string>
|
||||
<key>IDESourceControlProjectVersion</key>
|
||||
<integer>111</integer>
|
||||
<key>IDESourceControlProjectWCCIdentifier</key>
|
||||
<string>A4B0849259F9566B0CBA84A6D3D4A0F895C03123</string>
|
||||
<key>IDESourceControlProjectWCConfigurations</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
|
||||
<string>public.vcs.git</string>
|
||||
<key>IDESourceControlWCCIdentifierKey</key>
|
||||
<string>EB99D631D5149240E91F8D168F0F298D7A5BAA89</string>
|
||||
<key>IDESourceControlWCCName</key>
|
||||
<string>limelight-common-c</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
|
||||
<string>public.vcs.git</string>
|
||||
<key>IDESourceControlWCCIdentifierKey</key>
|
||||
<string>A4B0849259F9566B0CBA84A6D3D4A0F895C03123</string>
|
||||
<key>IDESourceControlWCCName</key>
|
||||
<string>moonlight-ios</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,53 @@
|
||||
<?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>6524503E-ED62-4E8E-8A67-B6DFB5A532FD</string>
|
||||
<key>IDESourceControlProjectName</key>
|
||||
<string>project</string>
|
||||
<key>IDESourceControlProjectOriginsDictionary</key>
|
||||
<dict>
|
||||
<key>A4B0849259F9566B0CBA84A6D3D4A0F895C03123</key>
|
||||
<string>github.com:limelight-stream/limelight-ios.git</string>
|
||||
<key>EB99D631D5149240E91F8D168F0F298D7A5BAA89</key>
|
||||
<string>github.com:limelight-stream/limelight-common-c.git</string>
|
||||
</dict>
|
||||
<key>IDESourceControlProjectPath</key>
|
||||
<string>Moonlight.xcodeproj/project.xcworkspace</string>
|
||||
<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
|
||||
<dict>
|
||||
<key>A4B0849259F9566B0CBA84A6D3D4A0F895C03123</key>
|
||||
<string>../..</string>
|
||||
<key>EB99D631D5149240E91F8D168F0F298D7A5BAA89</key>
|
||||
<string>../..limelight-common-c/</string>
|
||||
</dict>
|
||||
<key>IDESourceControlProjectURL</key>
|
||||
<string>github.com:limelight-stream/limelight-ios.git</string>
|
||||
<key>IDESourceControlProjectVersion</key>
|
||||
<integer>111</integer>
|
||||
<key>IDESourceControlProjectWCCIdentifier</key>
|
||||
<string>A4B0849259F9566B0CBA84A6D3D4A0F895C03123</string>
|
||||
<key>IDESourceControlProjectWCConfigurations</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
|
||||
<string>public.vcs.git</string>
|
||||
<key>IDESourceControlWCCIdentifierKey</key>
|
||||
<string>EB99D631D5149240E91F8D168F0F298D7A5BAA89</string>
|
||||
<key>IDESourceControlWCCName</key>
|
||||
<string>limelight-common-c</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
|
||||
<string>public.vcs.git</string>
|
||||
<key>IDESourceControlWCCIdentifierKey</key>
|
||||
<string>A4B0849259F9566B0CBA84A6D3D4A0F895C03123</string>
|
||||
<key>IDESourceControlWCCName</key>
|
||||
<string>limelight-ios</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,12 +1,12 @@
|
||||
#Limelight iOS
|
||||
#Moonlight iOS
|
||||
|
||||
[Limelight](https://github.com/limelight-stream) is an open source implementation of NVIDIA's GameStream, as used by the NVIDIA Shield, but built for iOS. Limelight iOS allows you to stream your full collection of Steam games from
|
||||
[Moonlight](https://github.com/moonlight-stream) is an open source implementation of NVIDIA's GameStream, as used by the NVIDIA Shield, but built for iOS. Moonlight iOS allows you to stream your full collection of Steam games from
|
||||
your powerful desktop computer to your iOS Device.
|
||||
|
||||
This is actively being developed and will be available on the App Store soon - check back here or on [our website](http://limelight-stream.com) for updates.
|
||||
This is actively being developed and will be available on the App Store soon - check back here or on [our website](http://moonlight-stream.com) for updates.
|
||||
|
||||
We understand that Limelight users are eager for the opportunity to stream their Steam collection to their iOS devices. Limelight for iOS is in the testing stage and preliminary versions are available for beta testers.
|
||||
We understand that Moonlight users are eager for the opportunity to stream their Steam collection to their iOS devices. Moonlight for iOS is in the testing stage and preliminary versions are available for beta testers.
|
||||
|
||||
In the meantime, check out the existing versions for [Android](https://github.com/limelight-stream/limelight-android) and [PC](https://github.com/limelight-stream/limelight-pc). Also, a client for [Windows and Windows Phone](https://github.com/limelight-stream/limelight-windows) is in the works and actively being developed.
|
||||
In the meantime, check out the existing versions for [Android](https://github.com/moonlight-stream/moonlight-android) and [PC](https://github.com/moonlight-stream/moonlight-pc). Also, a client for [Windows and Windows Phone](https://github.com/moonlight-stream/moonlight-windows) is in the works and actively being developed.
|
||||
|
||||
Please be patient as we work to bring Limelight to more platforms.
|
||||
Please be patient as we work to bring Moonlight to more platforms.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6254" systemVersion="14C109" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" initialViewController="EVd-wq-ego">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="7706" systemVersion="14D136" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" initialViewController="EVd-wq-ego">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6247"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/>
|
||||
</dependencies>
|
||||
<customFonts key="customFonts">
|
||||
<mutableArray key="Roboto-Regular.ttf">
|
||||
@@ -14,7 +14,7 @@
|
||||
<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">
|
||||
<rect key="frame" x="0.0" y="0.0" width="1024" height="704"/>
|
||||
<rect key="frame" x="0.0" y="64" width="1024" height="704"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<inset key="contentInset" minX="40" minY="20" maxX="40" maxY="20"/>
|
||||
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="20" minimumInteritemSpacing="20" id="f7l-kG-hJc">
|
||||
@@ -25,7 +25,7 @@
|
||||
</collectionViewFlowLayout>
|
||||
<cells>
|
||||
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="AppCell" id="fv6-NS-qsK">
|
||||
<rect key="frame" x="0.0" y="0.0" width="50" height="50"/>
|
||||
<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"/>
|
||||
@@ -45,8 +45,8 @@
|
||||
<rect key="frame" x="101" y="236" width="109" height="46"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" name="Roboto-Regular" family="Roboto" pointSize="16"/>
|
||||
<state key="normal" title="Limelight" image="Logo">
|
||||
<color key="titleColor" red="0.3921568627" green="0.91372549020000005" blue="0.17254901959999999" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<state key="normal" title="Moonlight" image="Logo">
|
||||
<color key="titleColor" red="0.81533776120000001" green="0.85979419950000002" blue="0.91372549020000005" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
</button>
|
||||
@@ -77,6 +77,7 @@
|
||||
<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"/>
|
||||
<color key="tintColor" red="0.81533776120000001" green="0.85979419950000002" blue="0.91372549020000005" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<nil key="highlightedColor"/>
|
||||
@@ -84,11 +85,12 @@
|
||||
<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"/>
|
||||
<color key="tintColor" red="0.3921568627" green="0.91372549020000005" blue="0.17254901959999999" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="tintColor" red="0.72941176470000002" green="0.69411764710000001" blue="1" 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"/>
|
||||
<color key="tintColor" red="0.81533776120000001" green="0.85979419950000002" blue="0.91372549020000005" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<nil key="highlightedColor"/>
|
||||
@@ -96,6 +98,7 @@
|
||||
<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"/>
|
||||
<color key="tintColor" red="0.81533776120000001" green="0.85979419950000002" blue="0.91372549020000005" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<nil key="highlightedColor"/>
|
||||
@@ -108,20 +111,12 @@
|
||||
<segment title="1080p"/>
|
||||
<segment title="Native"/>
|
||||
</segments>
|
||||
<color key="tintColor" red="0.3921568627" green="0.91372549020000005" blue="0.17254901959999999" alpha="1" colorSpace="calibratedRGB"/>
|
||||
</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"/>
|
||||
<segments>
|
||||
<segment title="30 Hz"/>
|
||||
<segment title="60 Hz"/>
|
||||
</segments>
|
||||
<color key="tintColor" red="0.3921568627" green="0.91372549020000005" blue="0.17254901959999999" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="tintColor" red="0.72941176470000002" green="0.69411764710000001" blue="1" 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"/>
|
||||
<color key="tintColor" red="0.81533776120000001" green="0.85979419950000002" blue="0.91372549020000005" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<nil key="highlightedColor"/>
|
||||
@@ -135,7 +130,16 @@
|
||||
<segment title="Simple"/>
|
||||
<segment title="Full"/>
|
||||
</segments>
|
||||
<color key="tintColor" red="0.3803921569" green="0.92156862750000001" blue="0.25882352939999997" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="tintColor" red="0.72941176470000002" green="0.69411764710000001" blue="1" 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"/>
|
||||
<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"/>
|
||||
</segmentedControl>
|
||||
</subviews>
|
||||
<color key="backgroundColor" cocoaTouchSystemColor="viewFlipsideBackgroundColor"/>
|
||||
@@ -252,7 +256,7 @@
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="Logo" width="36" height="36"/>
|
||||
<image name="Logo" width="32" height="32"/>
|
||||
</resources>
|
||||
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
||||
<simulatedStatusBarMetrics key="statusBar" statusBarStyle="lightContent"/>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6254" systemVersion="14C109" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" initialViewController="DL0-L5-LOv">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="7706" systemVersion="14D136" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" initialViewController="DL0-L5-LOv">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6247"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/>
|
||||
</dependencies>
|
||||
<customFonts key="customFonts">
|
||||
<mutableArray key="Roboto-Regular.ttf">
|
||||
@@ -14,7 +14,7 @@
|
||||
<objects>
|
||||
<viewController id="dgh-JZ-Q7z" customClass="MainFrameViewController" sceneMemberID="viewController">
|
||||
<collectionView key="view" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" indicatorStyle="black" dataMode="prototypes" id="Rtu-AT-Alw">
|
||||
<rect key="frame" x="0.0" y="0.0" width="568" height="256"/>
|
||||
<rect key="frame" x="0.0" y="64" width="568" height="256"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<inset key="contentInset" minX="40" minY="20" maxX="40" maxY="20"/>
|
||||
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="20" minimumInteritemSpacing="20" id="YcZ-cR-3tK">
|
||||
@@ -25,7 +25,7 @@
|
||||
</collectionViewFlowLayout>
|
||||
<cells>
|
||||
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="AppCell" id="Uqv-Di-fzX">
|
||||
<rect key="frame" x="0.0" y="0.0" width="50" height="50"/>
|
||||
<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"/>
|
||||
@@ -46,14 +46,14 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="109" height="46"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" name="Roboto-Regular" family="Roboto" pointSize="16"/>
|
||||
<state key="normal" title="Limelight" image="Logo">
|
||||
<color key="titleColor" red="0.3921568627" green="0.91372549020000005" blue="0.17254901959999999" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<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"/>
|
||||
</state>
|
||||
</button>
|
||||
</barButtonItem>
|
||||
<barButtonItem key="rightBarButtonItem" title="No Host Selected" id="L1H-n4-HB7">
|
||||
<color key="tintColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="tintColor" red="0.96078431372549022" green="0.98039215686274506" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
||||
@@ -97,13 +97,13 @@
|
||||
<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"/>
|
||||
<color key="tintColor" red="0.39215686274509803" green="0.9137254901960784" blue="0.17254901960784313" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="tintColor" red="0.72941176470588232" green="0.69411764705882351" blue="1" 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"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="textColor" red="0.96078431372549022" green="0.98039215686274506" 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="dLF-qJ-2nY">
|
||||
@@ -113,20 +113,20 @@
|
||||
<segment title="30 Hz"/>
|
||||
<segment title="60 Hz"/>
|
||||
</segments>
|
||||
<color key="tintColor" red="0.39215686274509803" green="0.9137254901960784" blue="0.17254901960784313" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="tintColor" red="0.72941176470588232" green="0.69411764705882351" blue="1" 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"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="textColor" red="0.96078431372549022" green="0.98039215686274506" 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="8zy-ri-Dqc">
|
||||
<rect key="frame" x="16" y="152" width="82" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="textColor" red="0.96078431372549022" green="0.98039215686274506" 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="PCM-t4-Sha">
|
||||
@@ -137,13 +137,13 @@
|
||||
<segment title="1080p"/>
|
||||
<segment title="Native"/>
|
||||
</segments>
|
||||
<color key="tintColor" red="0.39215686274509803" green="0.9137254901960784" blue="0.17254901960784313" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="tintColor" red="0.72941176470588232" green="0.69411764705882351" blue="1" 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"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="textColor" red="0.96078431372549022" green="0.98039215686274506" 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="WGf-9d-eAm">
|
||||
@@ -155,10 +155,10 @@
|
||||
<segment title="Simple"/>
|
||||
<segment title="Full"/>
|
||||
</segments>
|
||||
<color key="tintColor" red="0.38039215686274508" green="0.92156862745098034" blue="0.25882352941176467" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="tintColor" red="0.72941176470588232" green="0.69411764705882351" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</segmentedControl>
|
||||
</subviews>
|
||||
<color key="backgroundColor" cocoaTouchSystemColor="viewFlipsideBackgroundColor"/>
|
||||
<color key="backgroundColor" red="0.12156862745098039" green="0.12941176470588237" blue="0.14117647058823529" alpha="1" colorSpace="calibratedRGB"/>
|
||||
</view>
|
||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
||||
<connections>
|
||||
@@ -254,7 +254,7 @@
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="Logo" width="36" height="36"/>
|
||||
<image name="Logo" width="32" height="32"/>
|
||||
</resources>
|
||||
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
||||
<simulatedStatusBarMetrics key="statusBar"/>
|
||||
|
||||
@@ -616,7 +616,10 @@ OPUS_EXPORT void opus_pcm_soft_clip(float *pcm, int frame_size, int channels, fl
|
||||
* merged. Splitting valid Opus packets is always guaranteed to succeed,
|
||||
* whereas merging valid packets only succeeds if all frames have the same
|
||||
* mode, bandwidth, and frame size, and when the total duration of the merged
|
||||
* packet is no more than 120 ms.
|
||||
* packet is no more than 120 ms. The 120 ms limit comes from the
|
||||
* specification and limits decoder memory requirements at a point where
|
||||
* framing overhead becomes negligible.
|
||||
*
|
||||
* The repacketizer currently only operates on elementary Opus
|
||||
* streams. It will not manipualte multistream packets successfully, except in
|
||||
* the degenerate case where they consist of data from a single stream.
|
||||
|
||||
@@ -713,6 +713,10 @@ extern "C" {
|
||||
OPUS_EXPORT const char *opus_strerror(int error);
|
||||
|
||||
/** Gets the libopus version string.
|
||||
*
|
||||
* Applications may look for the substring "-fixed" in the version string to
|
||||
* determine whether they have a fixed-point or floating-point build at
|
||||
* runtime.
|
||||
*
|
||||
* @returns Version string
|
||||
*/
|
||||
|
||||