Blame client/iOS/Misc/Utils.m

Packit 1fb8d4
/*
Packit 1fb8d4
 Utility functions
Packit 1fb8d4
Packit 1fb8d4
 Copyright 2013 Thincast Technologies GmbH, Authors: Martin Fleisz, Dorian Johnson
Packit 1fb8d4
Packit 1fb8d4
 This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
Packit 1fb8d4
 If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
#import "Utils.h"
Packit 1fb8d4
#import "OrderedDictionary.h"
Packit 1fb8d4
#import "TSXAdditions.h"
Packit 1fb8d4
Packit 1fb8d4
#import <freerdp/input.h>
Packit 1fb8d4
#import <freerdp/version.h>
Packit 1fb8d4
#import "config.h"
Packit 1fb8d4
Packit 1fb8d4
#include <sys/types.h>
Packit 1fb8d4
#include <sys/sysctl.h>
Packit 1fb8d4
#include <sys/socket.h>
Packit 1fb8d4
#include <ifaddrs.h>
Packit 1fb8d4
#include <net/if_dl.h>
Packit 1fb8d4
Packit 1fb8d4
BOOL ScanHostNameAndPort(NSString* address, NSString** host,
Packit 1fb8d4
                         unsigned short* port)
Packit 1fb8d4
{
Packit 1fb8d4
	*host = @"";
Packit 1fb8d4
	*port = 0;
Packit 1fb8d4
Packit 1fb8d4
	if (![address length])
Packit 1fb8d4
		return NO;
Packit 1fb8d4
Packit 1fb8d4
	NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:@"rdp://%@",
Packit 1fb8d4
	                                   address]];
Packit 1fb8d4
Packit 1fb8d4
	if (!url || ![[url host] length])
Packit 1fb8d4
		return NO;
Packit 1fb8d4
Packit 1fb8d4
	*host = [url host];
Packit 1fb8d4
	*port = [[url port] unsignedShortValue];
Packit 1fb8d4
	return YES;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#pragma mark -
Packit 1fb8d4
#pragma mark Working with Screen Resolutions
Packit 1fb8d4
Packit 1fb8d4
NSString* LocalizedFitScreen()
Packit 1fb8d4
{
Packit 1fb8d4
	return NSLocalizedString(@"Automatic",
Packit 1fb8d4
	                         @"Screen resolution selector: Automatic resolution (Full Screen on iPad, reasonable size on iPhone)");
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
NSString* LocalizedCustom()
Packit 1fb8d4
{
Packit 1fb8d4
	return NSLocalizedString(@"Custom", @"Screen resolution selector: Custom");
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL ScanScreenResolution(NSString* description, int* width, int* height,
Packit 1fb8d4
                          TSXScreenOptions* type)
Packit 1fb8d4
{
Packit 1fb8d4
	*height = 0;
Packit 1fb8d4
	*width = 0;
Packit 1fb8d4
	*type = TSXScreenOptionFixed;
Packit 1fb8d4
Packit 1fb8d4
	if ([description isEqualToString:LocalizedFitScreen()])
Packit 1fb8d4
	{
Packit 1fb8d4
		*type = TSXScreenOptionFitScreen;
Packit 1fb8d4
		return YES;
Packit 1fb8d4
	}
Packit 1fb8d4
	else if ([description isEqualToString:LocalizedCustom()])
Packit 1fb8d4
	{
Packit 1fb8d4
		*type = TSXScreenOptionCustom;
Packit 1fb8d4
		return YES;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	NSArray* resolution_components = [description
Packit 1fb8d4
	                                  componentsSeparatedByCharactersInSet:[NSCharacterSet
Packit 1fb8d4
	                                          characterSetWithCharactersInString:@"x*×"]];
Packit 1fb8d4
Packit 1fb8d4
	if ([resolution_components count] != 2)
Packit 1fb8d4
		return NO;
Packit 1fb8d4
Packit 1fb8d4
	*width = [[resolution_components objectAtIndex:0] intValue];
Packit 1fb8d4
	*height = [[resolution_components objectAtIndex:1] intValue];
Packit 1fb8d4
	return YES;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
NSString* ScreenResolutionDescription(TSXScreenOptions type, int width,
Packit 1fb8d4
                                      int height)
Packit 1fb8d4
{
Packit 1fb8d4
	if (type == TSXScreenOptionFitScreen)
Packit 1fb8d4
		return LocalizedFitScreen();
Packit 1fb8d4
	else if (type == TSXScreenOptionCustom)
Packit 1fb8d4
		return LocalizedCustom();
Packit 1fb8d4
Packit 1fb8d4
	return [NSString stringWithFormat:@"%dx%d", width, height];
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
Packit 1fb8d4
NSDictionary* SelectionForColorSetting()
Packit 1fb8d4
{
Packit 1fb8d4
	OrderedDictionary* dict = [OrderedDictionary dictionaryWithCapacity:3];
Packit 1fb8d4
	[dict setValue:[NSNumber numberWithInt:8] forKey:NSLocalizedString(
Packit 1fb8d4
	     @"Palette Color (8 Bit)", @"8 bit color selection")];
Packit 1fb8d4
	[dict setValue:[NSNumber numberWithInt:15] forKey:NSLocalizedString(
Packit 1fb8d4
	     @"High Color (15 Bit)", @"15 bit color selection")];
Packit 1fb8d4
	[dict setValue:[NSNumber numberWithInt:16] forKey:NSLocalizedString(
Packit 1fb8d4
	     @"High Color (16 Bit)", @"16 bit color selection")];
Packit 1fb8d4
	[dict setValue:[NSNumber numberWithInt:24] forKey:NSLocalizedString(
Packit 1fb8d4
	     @"True Color (24 Bit)", @"24 bit color selection")];
Packit 1fb8d4
	[dict setValue:[NSNumber numberWithInt:32] forKey:NSLocalizedString(
Packit 1fb8d4
	     @"Highest Quality (32 Bit)", @"32 bit color selection")];
Packit 1fb8d4
	return dict;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
NSArray* ResolutionModes()
Packit 1fb8d4
{
Packit 1fb8d4
	NSArray* array = [NSArray arrayWithObjects:ScreenResolutionDescription(
Packit 1fb8d4
	                      TSXScreenOptionFitScreen, 0, 0),
Packit 1fb8d4
	                  ScreenResolutionDescription(TSXScreenOptionFixed, 640, 480),
Packit 1fb8d4
	                  ScreenResolutionDescription(TSXScreenOptionFixed, 800, 600),
Packit 1fb8d4
	                  ScreenResolutionDescription(TSXScreenOptionFixed, 1024, 768),
Packit 1fb8d4
	                  ScreenResolutionDescription(TSXScreenOptionFixed, 1280, 1024),
Packit 1fb8d4
	                  ScreenResolutionDescription(TSXScreenOptionFixed, 1440, 900),
Packit 1fb8d4
	                  ScreenResolutionDescription(TSXScreenOptionFixed, 1440, 1050),
Packit 1fb8d4
	                  ScreenResolutionDescription(TSXScreenOptionFixed, 1600, 1200),
Packit 1fb8d4
	                  ScreenResolutionDescription(TSXScreenOptionFixed, 1920, 1080),
Packit 1fb8d4
	                  ScreenResolutionDescription(TSXScreenOptionFixed, 1920, 1200),
Packit 1fb8d4
	                  ScreenResolutionDescription(TSXScreenOptionCustom, 0, 0), nil];
Packit 1fb8d4
	return array;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#pragma mark Working with Security Protocols
Packit 1fb8d4
Packit 1fb8d4
NSString* LocalizedAutomaticSecurity()
Packit 1fb8d4
{
Packit 1fb8d4
	return NSLocalizedString(@"Automatic", @"Automatic protocl security selection");
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
NSString* ProtocolSecurityDescription(TSXProtocolSecurityOptions type)
Packit 1fb8d4
{
Packit 1fb8d4
	if (type == TSXProtocolSecurityNLA)
Packit 1fb8d4
		return @"NLA";
Packit 1fb8d4
	else if (type == TSXProtocolSecurityTLS)
Packit 1fb8d4
		return @"TLS";
Packit 1fb8d4
	else if (type == TSXProtocolSecurityRDP)
Packit 1fb8d4
		return @"RDP";
Packit 1fb8d4
Packit 1fb8d4
	return LocalizedAutomaticSecurity();
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL ScanProtocolSecurity(NSString* description,
Packit 1fb8d4
                          TSXProtocolSecurityOptions* type)
Packit 1fb8d4
{
Packit 1fb8d4
	*type = TSXProtocolSecurityRDP;
Packit 1fb8d4
Packit 1fb8d4
	if ([description isEqualToString:@"NLA"])
Packit 1fb8d4
	{
Packit 1fb8d4
		*type = TSXProtocolSecurityNLA;
Packit 1fb8d4
		return YES;
Packit 1fb8d4
	}
Packit 1fb8d4
	else if ([description isEqualToString:@"TLS"])
Packit 1fb8d4
	{
Packit 1fb8d4
		*type = TSXProtocolSecurityTLS;
Packit 1fb8d4
		return YES;
Packit 1fb8d4
	}
Packit 1fb8d4
	else if ([description isEqualToString:@"RDP"])
Packit 1fb8d4
	{
Packit 1fb8d4
		*type = TSXProtocolSecurityRDP;
Packit 1fb8d4
		return YES;
Packit 1fb8d4
	}
Packit 1fb8d4
	else if ([description isEqualToString:LocalizedAutomaticSecurity()])
Packit 1fb8d4
	{
Packit 1fb8d4
		*type = TSXProtocolSecurityAutomatic;
Packit 1fb8d4
		return YES;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return NO;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
NSDictionary* SelectionForSecuritySetting()
Packit 1fb8d4
{
Packit 1fb8d4
	OrderedDictionary* dict = [OrderedDictionary dictionaryWithCapacity:4];
Packit 1fb8d4
	[dict setValue:[NSNumber numberWithInt:TSXProtocolSecurityAutomatic] forKey:
Packit 1fb8d4
	 ProtocolSecurityDescription(TSXProtocolSecurityAutomatic)];
Packit 1fb8d4
	[dict setValue:[NSNumber numberWithInt:TSXProtocolSecurityRDP] forKey:
Packit 1fb8d4
	 ProtocolSecurityDescription(TSXProtocolSecurityRDP)];
Packit 1fb8d4
	[dict setValue:[NSNumber numberWithInt:TSXProtocolSecurityTLS] forKey:
Packit 1fb8d4
	 ProtocolSecurityDescription(TSXProtocolSecurityTLS)];
Packit 1fb8d4
	[dict setValue:[NSNumber numberWithInt:TSXProtocolSecurityNLA] forKey:
Packit 1fb8d4
	 ProtocolSecurityDescription(TSXProtocolSecurityNLA)];
Packit 1fb8d4
	return dict;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
Packit 1fb8d4
#pragma mark -
Packit 1fb8d4
#pragma mark Bookmarks
Packit 1fb8d4
Packit 1fb8d4
#import "Bookmark.h"
Packit 1fb8d4
Packit 1fb8d4
NSMutableArray* FilterBookmarks(NSArray* bookmarks, NSArray* filter_words)
Packit 1fb8d4
{
Packit 1fb8d4
	NSMutableArray* matching_items = [NSMutableArray array];
Packit 1fb8d4
	NSArray* searched_keys = [NSArray arrayWithObjects:@"label", @"params.hostname",
Packit 1fb8d4
	                          @"params.username", @"params.domain", nil];
Packit 1fb8d4
Packit 1fb8d4
	for (ComputerBookmark * cur_bookmark in bookmarks)
Packit 1fb8d4
	{
Packit 1fb8d4
		double match_score = 0.0;
Packit 1fb8d4
Packit 1fb8d4
		for (int i = 0; i < [searched_keys count]; i++)
Packit 1fb8d4
		{
Packit 1fb8d4
			NSString* val = [cur_bookmark valueForKeyPath:[searched_keys objectAtIndex:i]];
Packit 1fb8d4
Packit 1fb8d4
			if (![val isKindOfClass:[NSString class]] || ![val length])
Packit 1fb8d4
				continue;
Packit 1fb8d4
Packit 1fb8d4
			for (NSString * word in filter_words)
Packit 1fb8d4
				if ([val rangeOfString:word options:(NSCaseInsensitiveSearch |
Packit 1fb8d4
				                                     NSWidthInsensitiveSearch)].location != NSNotFound)
Packit 1fb8d4
					match_score += (1.0 / [filter_words count]) * pow(2, [searched_keys count] - i);
Packit 1fb8d4
		}
Packit 1fb8d4
Packit 1fb8d4
		if (match_score > 0.001)
Packit 1fb8d4
			[matching_items addObject:[NSDictionary dictionaryWithObjectsAndKeys:
Packit 1fb8d4
			                           cur_bookmark, @"bookmark",
Packit 1fb8d4
			                           [NSNumber numberWithFloat:match_score], @"score",
Packit 1fb8d4
			                           nil]];
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	[matching_items sortUsingComparator:^NSComparisonResult(NSDictionary * obj1,
Packit 1fb8d4
	        NSDictionary * obj2)
Packit 1fb8d4
	{
Packit 1fb8d4
		return [[obj2 objectForKey:@"score"] compare:[obj1 objectForKey:@"score"]];
Packit 1fb8d4
	}];
Packit 1fb8d4
	return matching_items;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
NSMutableArray* FilterHistory(NSArray* history, NSString* filterStr)
Packit 1fb8d4
{
Packit 1fb8d4
	NSMutableArray* result = [NSMutableArray array];
Packit 1fb8d4
Packit 1fb8d4
	for (NSString * item in history)
Packit 1fb8d4
	{
Packit 1fb8d4
		if ([item rangeOfString:filterStr].location != NSNotFound)
Packit 1fb8d4
			[result addObject:item];
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return result;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#pragma mark Version Info
Packit 1fb8d4
NSString* TSXAppFullVersion()
Packit 1fb8d4
{
Packit 1fb8d4
	return [NSString stringWithUTF8String:GIT_REVISION];
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#pragma mark iPad/iPhone detection
Packit 1fb8d4
Packit 1fb8d4
BOOL IsPad()
Packit 1fb8d4
{
Packit 1fb8d4
#ifdef UI_USER_INTERFACE_IDIOM
Packit 1fb8d4
	return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
Packit 1fb8d4
#else
Packit 1fb8d4
	return NO;
Packit 1fb8d4
#endif
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL IsPhone()
Packit 1fb8d4
{
Packit 1fb8d4
#ifdef UI_USER_INTERFACE_IDIOM
Packit 1fb8d4
	return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone);
Packit 1fb8d4
#else
Packit 1fb8d4
	return NO;
Packit 1fb8d4
#endif
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
// set mouse buttons swapped flag
Packit 1fb8d4
static BOOL g_swap_mouse_buttons = NO;
Packit 1fb8d4
void SetSwapMouseButtonsFlag(BOOL swapped)
Packit 1fb8d4
{
Packit 1fb8d4
	g_swap_mouse_buttons = swapped;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
// set invert scrolling flag
Packit 1fb8d4
static BOOL g_invert_scrolling = NO;
Packit 1fb8d4
void SetInvertScrollingFlag(BOOL invert)
Packit 1fb8d4
{
Packit 1fb8d4
	g_invert_scrolling = invert;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
// return event value for left mouse button
Packit 1fb8d4
int GetLeftMouseButtonClickEvent(BOOL down)
Packit 1fb8d4
{
Packit 1fb8d4
	if (g_swap_mouse_buttons)
Packit 1fb8d4
		return (PTR_FLAGS_BUTTON2 | (down ? PTR_FLAGS_DOWN : 0));
Packit 1fb8d4
	else
Packit 1fb8d4
		return (PTR_FLAGS_BUTTON1 | (down ? PTR_FLAGS_DOWN : 0));
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
// return event value for right mouse button
Packit 1fb8d4
int GetRightMouseButtonClickEvent(BOOL down)
Packit 1fb8d4
{
Packit 1fb8d4
	if (g_swap_mouse_buttons)
Packit 1fb8d4
		return (PTR_FLAGS_BUTTON1 | (down ? PTR_FLAGS_DOWN : 0));
Packit 1fb8d4
	else
Packit 1fb8d4
		return (PTR_FLAGS_BUTTON2 | (down ? PTR_FLAGS_DOWN : 0));
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
// get mouse move event
Packit 1fb8d4
int GetMouseMoveEvent()
Packit 1fb8d4
{
Packit 1fb8d4
	return (PTR_FLAGS_MOVE);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
// return mouse wheel event
Packit 1fb8d4
int GetMouseWheelEvent(BOOL down)
Packit 1fb8d4
{
Packit 1fb8d4
	if (g_invert_scrolling)
Packit 1fb8d4
		down = !down;
Packit 1fb8d4
Packit 1fb8d4
	if (down)
Packit 1fb8d4
		return (PTR_FLAGS_WHEEL | PTR_FLAGS_WHEEL_NEGATIVE | (0x0088));
Packit 1fb8d4
	else
Packit 1fb8d4
		return (PTR_FLAGS_WHEEL | (0x0078));
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
// scrolling gesture detection delta
Packit 1fb8d4
CGFloat GetScrollGestureDelta()
Packit 1fb8d4
{
Packit 1fb8d4
	return 10.0f;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
// this hack activates the iphone's WWAN interface in case it is offline
Packit 1fb8d4
void WakeUpWWAN()
Packit 1fb8d4
{
Packit 1fb8d4
	NSURL* url = [[[NSURL alloc] initWithString:
Packit 1fb8d4
	               @"http://www.nonexistingdummyurl.com"] autorelease];
Packit 1fb8d4
	//NSData * data =
Packit 1fb8d4
	[NSData dataWithContentsOfURL:
Packit 1fb8d4
	 url]; // we don't need data but assigning one causes a "data not used" compiler warning
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
Packit 1fb8d4
#pragma mark System Info functions
Packit 1fb8d4
Packit 1fb8d4
NSString* TSXGetPrimaryMACAddress(NSString* sep)
Packit 1fb8d4
{
Packit 1fb8d4
	NSString* macaddress = @"";
Packit 1fb8d4
	struct ifaddrs* addrs;
Packit 1fb8d4
Packit 1fb8d4
	if (getifaddrs(&addrs) < 0)
Packit 1fb8d4
	{
Packit 1fb8d4
		NSLog(@"getPrimaryMACAddress: getifaddrs failed.");
Packit 1fb8d4
		return macaddress;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	for (struct ifaddrs* cursor = addrs; cursor != NULL; cursor = cursor->ifa_next)
Packit 1fb8d4
	{
Packit 1fb8d4
		if (strcmp(cursor->ifa_name, "en0"))
Packit 1fb8d4
			continue;
Packit 1fb8d4
Packit 1fb8d4
		if ((cursor->ifa_addr->sa_family == AF_LINK)
Packit 1fb8d4
		    && (((struct sockaddr_dl*) cursor->ifa_addr)->sdl_type == 0x6 /*IFT_ETHER*/))
Packit 1fb8d4
		{
Packit 1fb8d4
			struct sockaddr_dl* dlAddr = (struct sockaddr_dl*) cursor->ifa_addr;
Packit 1fb8d4
Packit 1fb8d4
			if (dlAddr->sdl_alen != 6)
Packit 1fb8d4
				continue;
Packit 1fb8d4
Packit 1fb8d4
			unsigned char* base = (unsigned char*) &dlAddr->sdl_data[dlAddr->sdl_nlen];
Packit 1fb8d4
			macaddress = [NSString hexStringFromData:base ofSize:6 withSeparator:sep
Packit 1fb8d4
			              afterNthChar:1];
Packit 1fb8d4
			break;
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	freeifaddrs(addrs);
Packit 1fb8d4
	return macaddress;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL TSXDeviceHasJailBreak()
Packit 1fb8d4
{
Packit 1fb8d4
	if ([[NSFileManager defaultManager] fileExistsAtPath:
Packit 1fb8d4
	     @"/Applications/Cydia.app/"])
Packit 1fb8d4
		return YES;
Packit 1fb8d4
Packit 1fb8d4
	if ([[NSFileManager defaultManager] fileExistsAtPath:@"/etc/apt/"])
Packit 1fb8d4
		return YES;
Packit 1fb8d4
Packit 1fb8d4
	return NO;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
NSString* TSXGetPlatform()
Packit 1fb8d4
{
Packit 1fb8d4
	size_t size;
Packit 1fb8d4
	sysctlbyname("hw.machine", NULL, &size, NULL, 0);
Packit 1fb8d4
	char* machine = malloc(size);
Packit 1fb8d4
	sysctlbyname("hw.machine", machine, &size, NULL, 0);
Packit 1fb8d4
	NSString* platform = [NSString stringWithCString:machine encoding:
Packit 1fb8d4
	                      NSASCIIStringEncoding];
Packit 1fb8d4
	free(machine);
Packit 1fb8d4
	return platform;
Packit 1fb8d4
}
Packit 1fb8d4