iOS: initial release of iFreeRDP
authorBernhard Miklautz <bmiklautz@thinstuff.at>
Thu, 14 Feb 2013 13:59:12 +0000 (14:59 +0100)
committerBernhard Miklautz <bmiklautz@thinstuff.at>
Thu, 14 Feb 2013 13:59:12 +0000 (14:59 +0100)
This is the initial release of iFreeRDP the FreeRDP iOS client.
Build instructions can be found in docs/README.ios.

183 files changed:
.gitignore
CMakeLists.txt
client/.gitignore
client/CMakeLists.txt
client/iOS/.gitignore [new file with mode: 0644]
client/iOS/Additions/OrderedDictionary.h [new file with mode: 0644]
client/iOS/Additions/OrderedDictionary.m [new file with mode: 0644]
client/iOS/Additions/TSXAdditions.h [new file with mode: 0644]
client/iOS/Additions/TSXAdditions.m [new file with mode: 0644]
client/iOS/Additions/Toast+UIView.h [new file with mode: 0644]
client/iOS/Additions/Toast+UIView.m [new file with mode: 0644]
client/iOS/AppDelegate.h [new file with mode: 0644]
client/iOS/AppDelegate.m [new file with mode: 0644]
client/iOS/CMakeLists.txt [new file with mode: 0644]
client/iOS/Controllers/AboutController.h [new file with mode: 0644]
client/iOS/Controllers/AboutController.m [new file with mode: 0644]
client/iOS/Controllers/AdvancedBookmarkEditorController.h [new file with mode: 0644]
client/iOS/Controllers/AdvancedBookmarkEditorController.m [new file with mode: 0644]
client/iOS/Controllers/AppSettingsController.h [new file with mode: 0644]
client/iOS/Controllers/AppSettingsController.m [new file with mode: 0644]
client/iOS/Controllers/BookmarkEditorController.h [new file with mode: 0644]
client/iOS/Controllers/BookmarkEditorController.m [new file with mode: 0644]
client/iOS/Controllers/BookmarkListController.h [new file with mode: 0644]
client/iOS/Controllers/BookmarkListController.m [new file with mode: 0644]
client/iOS/Controllers/CredentialsEditorController.h [new file with mode: 0644]
client/iOS/Controllers/CredentialsEditorController.m [new file with mode: 0644]
client/iOS/Controllers/CredentialsInputController.h [new file with mode: 0644]
client/iOS/Controllers/CredentialsInputController.m [new file with mode: 0644]
client/iOS/Controllers/EditorBaseController.h [new file with mode: 0644]
client/iOS/Controllers/EditorBaseController.m [new file with mode: 0644]
client/iOS/Controllers/EditorSelectionController.h [new file with mode: 0644]
client/iOS/Controllers/EditorSelectionController.m [new file with mode: 0644]
client/iOS/Controllers/EncryptionController.h [new file with mode: 0644]
client/iOS/Controllers/EncryptionController.m [new file with mode: 0644]
client/iOS/Controllers/HelpController.h [new file with mode: 0644]
client/iOS/Controllers/HelpController.m [new file with mode: 0644]
client/iOS/Controllers/MainTabBarController.h [new file with mode: 0644]
client/iOS/Controllers/MainTabBarController.m [new file with mode: 0644]
client/iOS/Controllers/PerformanceEditorController.h [new file with mode: 0644]
client/iOS/Controllers/PerformanceEditorController.m [new file with mode: 0644]
client/iOS/Controllers/RDPSessionViewController.h [new file with mode: 0644]
client/iOS/Controllers/RDPSessionViewController.m [new file with mode: 0644]
client/iOS/Controllers/ScreenSelectionController.h [new file with mode: 0644]
client/iOS/Controllers/ScreenSelectionController.m [new file with mode: 0644]
client/iOS/Controllers/VerifyCertificateController.h [new file with mode: 0644]
client/iOS/Controllers/VerifyCertificateController.m [new file with mode: 0644]
client/iOS/Defaults.plist [new file with mode: 0644]
client/iOS/FreeRDP/ios_freerdp.h [new file with mode: 0644]
client/iOS/FreeRDP/ios_freerdp.m [new file with mode: 0644]
client/iOS/FreeRDP/ios_freerdp_events.h [new file with mode: 0755]
client/iOS/FreeRDP/ios_freerdp_events.m [new file with mode: 0755]
client/iOS/FreeRDP/ios_freerdp_ui.h [new file with mode: 0644]
client/iOS/FreeRDP/ios_freerdp_ui.m [new file with mode: 0644]
client/iOS/Misc/Reachability.h [new file with mode: 0755]
client/iOS/Misc/Reachability.m [new file with mode: 0755]
client/iOS/Misc/SFHFKeychainUtils.h [new file with mode: 0755]
client/iOS/Misc/SFHFKeychainUtils.m [new file with mode: 0755]
client/iOS/Misc/TSXTypes.h [new file with mode: 0644]
client/iOS/Misc/Utils.h [new file with mode: 0644]
client/iOS/Misc/Utils.m [new file with mode: 0644]
client/iOS/Models/Bookmark.h [new file with mode: 0644]
client/iOS/Models/Bookmark.m [new file with mode: 0644]
client/iOS/Models/ConnectionParams.h [new file with mode: 0644]
client/iOS/Models/ConnectionParams.m [new file with mode: 0644]
client/iOS/Models/Encryptor.h [new file with mode: 0644]
client/iOS/Models/Encryptor.m [new file with mode: 0644]
client/iOS/Models/GlobalDefaults.h [new file with mode: 0644]
client/iOS/Models/GlobalDefaults.m [new file with mode: 0644]
client/iOS/Models/RDPKeyboard.h [new file with mode: 0644]
client/iOS/Models/RDPKeyboard.m [new file with mode: 0644]
client/iOS/Models/RDPSession.h [new file with mode: 0644]
client/iOS/Models/RDPSession.m [new file with mode: 0644]
client/iOS/Resources/BookmarkListView.xib [new file with mode: 0644]
client/iOS/Resources/BookmarkTableViewCell.xib [new file with mode: 0644]
client/iOS/Resources/CredentialsInputView.xib [new file with mode: 0644]
client/iOS/Resources/Default-568h@2x.png [new file with mode: 0755]
client/iOS/Resources/Default-Landscape@2x~ipad.png [new file with mode: 0755]
client/iOS/Resources/Default-Landscape~ipad.png [new file with mode: 0755]
client/iOS/Resources/Default-Portrait@2x~ipad.png [new file with mode: 0755]
client/iOS/Resources/Default-Portrait~ipad.png [new file with mode: 0755]
client/iOS/Resources/Default.png [new file with mode: 0755]
client/iOS/Resources/Default@2x.png [new file with mode: 0755]
client/iOS/Resources/EditButtonTableViewCell.xib [new file with mode: 0644]
client/iOS/Resources/EditFlagTableViewCell.xib [new file with mode: 0644]
client/iOS/Resources/EditSecretTextTableViewCell.xib [new file with mode: 0644]
client/iOS/Resources/EditSelectionTableViewCell.xib [new file with mode: 0644]
client/iOS/Resources/EditSubEditTableViewCell.xib [new file with mode: 0644]
client/iOS/Resources/EditTextTableViewCell.xib [new file with mode: 0644]
client/iOS/Resources/Icon-72.png [new file with mode: 0755]
client/iOS/Resources/Icon-72@2x.png [new file with mode: 0755]
client/iOS/Resources/Icon.png [new file with mode: 0755]
client/iOS/Resources/Icon@2x.png [new file with mode: 0755]
client/iOS/Resources/MainWindow.xib [new file with mode: 0644]
client/iOS/Resources/RDPConnectingView.xib [new file with mode: 0644]
client/iOS/Resources/RDPSessionView.xib [new file with mode: 0644]
client/iOS/Resources/SessionTableViewCell.xib [new file with mode: 0644]
client/iOS/Resources/VerifyCertificateView.xib [new file with mode: 0644]
client/iOS/Resources/about_page/FreeRDP_Logo.png [new file with mode: 0755]
client/iOS/Resources/about_page/about.html [new file with mode: 0755]
client/iOS/Resources/about_page/about_phone.html [new file with mode: 0755]
client/iOS/Resources/about_page/back.jpg [new file with mode: 0755]
client/iOS/Resources/about_page/background_transparent.png [new file with mode: 0755]
client/iOS/Resources/cancel_button_background.png [new file with mode: 0644]
client/iOS/Resources/en.lproj/Localizable.strings [new file with mode: 0644]
client/iOS/Resources/help_page/back.jpg [new file with mode: 0755]
client/iOS/Resources/help_page/gestures.html [new file with mode: 0755]
client/iOS/Resources/help_page/gestures.png [new file with mode: 0755]
client/iOS/Resources/help_page/gestures_phone.html [new file with mode: 0755]
client/iOS/Resources/help_page/gestures_phone.png [new file with mode: 0755]
client/iOS/Resources/help_page/nav_gestures.png [new file with mode: 0755]
client/iOS/Resources/help_page/nav_toolbar.png [new file with mode: 0755]
client/iOS/Resources/help_page/nav_touch_pointer.png [new file with mode: 0755]
client/iOS/Resources/help_page/toolbar.html [new file with mode: 0755]
client/iOS/Resources/help_page/toolbar.png [new file with mode: 0755]
client/iOS/Resources/help_page/toolbar_phone.html [new file with mode: 0755]
client/iOS/Resources/help_page/toolbar_phone.png [new file with mode: 0755]
client/iOS/Resources/help_page/touch_pointer.html [new file with mode: 0755]
client/iOS/Resources/help_page/touch_pointer.png [new file with mode: 0755]
client/iOS/Resources/help_page/touch_pointer_phone.html [new file with mode: 0755]
client/iOS/Resources/help_page/touch_pointer_phone.png [new file with mode: 0755]
client/iOS/Resources/icon_accessory_star_off.png [new file with mode: 0755]
client/iOS/Resources/icon_accessory_star_on.png [new file with mode: 0755]
client/iOS/Resources/icon_key_arrow_down.png [new file with mode: 0755]
client/iOS/Resources/icon_key_arrow_left.png [new file with mode: 0755]
client/iOS/Resources/icon_key_arrow_right.png [new file with mode: 0755]
client/iOS/Resources/icon_key_arrow_up.png [new file with mode: 0755]
client/iOS/Resources/icon_key_arrows.png [new file with mode: 0755]
client/iOS/Resources/icon_key_backspace.png [new file with mode: 0755]
client/iOS/Resources/icon_key_menu.png [new file with mode: 0755]
client/iOS/Resources/icon_key_return.png [new file with mode: 0755]
client/iOS/Resources/icon_key_win.png [new file with mode: 0755]
client/iOS/Resources/keyboard_button_background.png [new file with mode: 0755]
client/iOS/Resources/tabbar_icon_about.png [new file with mode: 0755]
client/iOS/Resources/tabbar_icon_help.png [new file with mode: 0755]
client/iOS/Resources/tabbar_icon_settings.png [new file with mode: 0755]
client/iOS/Resources/toolbar_icon_disconnect.png [new file with mode: 0755]
client/iOS/Resources/toolbar_icon_extkeyboad.png [new file with mode: 0755]
client/iOS/Resources/toolbar_icon_home.png [new file with mode: 0755]
client/iOS/Resources/toolbar_icon_keyboard.png [new file with mode: 0755]
client/iOS/Resources/toolbar_icon_touchpointer.png [new file with mode: 0755]
client/iOS/Resources/toolbar_icon_win.png [new file with mode: 0755]
client/iOS/Resources/touch_pointer_active.png [new file with mode: 0755]
client/iOS/Resources/touch_pointer_default.png [new file with mode: 0755]
client/iOS/Resources/touch_pointer_extkeyboard.png [new file with mode: 0755]
client/iOS/Resources/touch_pointer_keyboard.png [new file with mode: 0755]
client/iOS/Resources/touch_pointer_lclick.png [new file with mode: 0755]
client/iOS/Resources/touch_pointer_rclick.png [new file with mode: 0755]
client/iOS/Resources/touch_pointer_reset.png [new file with mode: 0755]
client/iOS/Resources/touch_pointer_scroll.png [new file with mode: 0755]
client/iOS/Views/AdvancedKeyboardView.h [new file with mode: 0644]
client/iOS/Views/AdvancedKeyboardView.m [new file with mode: 0644]
client/iOS/Views/BookmarkTableCell.h [new file with mode: 0644]
client/iOS/Views/BookmarkTableCell.m [new file with mode: 0644]
client/iOS/Views/EditButtonTableViewCell.h [new file with mode: 0644]
client/iOS/Views/EditButtonTableViewCell.m [new file with mode: 0644]
client/iOS/Views/EditFlagTableViewCell.h [new file with mode: 0644]
client/iOS/Views/EditFlagTableViewCell.m [new file with mode: 0644]
client/iOS/Views/EditSecretTextTableViewCell.h [new file with mode: 0644]
client/iOS/Views/EditSecretTextTableViewCell.m [new file with mode: 0644]
client/iOS/Views/EditSelectionTableViewCell.h [new file with mode: 0644]
client/iOS/Views/EditSelectionTableViewCell.m [new file with mode: 0644]
client/iOS/Views/EditSubEditTableViewCell.h [new file with mode: 0644]
client/iOS/Views/EditSubEditTableViewCell.m [new file with mode: 0644]
client/iOS/Views/EditTextTableViewCell.h [new file with mode: 0644]
client/iOS/Views/EditTextTableViewCell.m [new file with mode: 0644]
client/iOS/Views/RDPSessionView.h [new file with mode: 0644]
client/iOS/Views/RDPSessionView.m [new file with mode: 0644]
client/iOS/Views/SessionTableCell.h [new file with mode: 0644]
client/iOS/Views/SessionTableCell.m [new file with mode: 0644]
client/iOS/Views/TouchPointerView.h [new file with mode: 0644]
client/iOS/Views/TouchPointerView.m [new file with mode: 0644]
client/iOS/iFreeRDP-Prefix.pch [new file with mode: 0644]
client/iOS/iFreeRDP.plist [new file with mode: 0644]
client/iOS/iFreeRDP.xcodeproj/project.pbxproj.cmake [new file with mode: 0644]
client/iOS/main.m [new file with mode: 0644]
cmake/CheckCmakeCompat.cmake
cmake/ConfigOptions.cmake
cmake/ConfigOptionsiOS.cmake [new file with mode: 0644]
cmake/iOSToolchain.cmake
docs/README.ios [new file with mode: 0644]
scripts/OpenSSL-DownloadAndBuild.command [new file with mode: 0755]
scripts/OpenSSL-iFreeRDP.diff [new file with mode: 0644]
winpr/include/winpr/wtypes.h

index 9eae137..10fe973 100644 (file)
@@ -13,6 +13,8 @@ CPackConfig.cmake
 CPackSourceConfig.cmake
 DartConfiguration.tcl
 _CPack_Packages
+external/*
+!external/README
 
 # Packages
 *.zip
index 98c2317..290b7d6 100644 (file)
@@ -60,13 +60,13 @@ else()
 endif()
 
 # Allow to search the host machine for git
-if(ANDROID)
+if(ANDROID OR IOS)
        SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER, BOTH)
-endif(ANDROID)
+endif(ANDROID OR IOS)
 include(GetGitRevisionDescription)
-if(ANDROID)
+if(ANDROID OR IOS)
        SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER, ONLY)
-endif(ANDROID)
+endif(ANDROID OR IOS)
 
 git_describe(GIT_REVISION --match "[0-9]*" --abbrev=4 --tags --always)
 message(STATUS "Git Revision ${GIT_REVISION}")
@@ -74,14 +74,13 @@ message(STATUS "Git Revision ${GIT_REVISION}")
 # Turn on solution folders (2.8.4+)
 set_property(GLOBAL PROPERTY USE_FOLDERS ON)
 
-
 # Default to release build type
 if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE "Release")
 endif()
 
 if(NOT DEFINED BUILD_SHARED_LIBS)
-       if(ANDROID)
+       if(ANDROID OR IOS)
                set(BUILD_SHARED_LIBS OFF)
        else()
                set(BUILD_SHARED_LIBS ON)
@@ -167,6 +166,10 @@ if(MSVC)
        SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR})
 endif()
 
+if(IOS)
+       set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -isysroot ${CMAKE_IOS_SDK_ROOT}")
+endif()
+
 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWINPR_EXPORTS")
 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFREERDP_EXPORTS")
 
@@ -183,14 +186,21 @@ check_struct_has_member("struct tm" tm_gmtoff time.h HAVE_TM_GMTOFF)
 
 # Mac OS X
 if(APPLE)
-       if(IS_DIRECTORY /opt/local/include)
-               include_directories(/opt/local/include)
-               link_directories(/opt/local/lib)
-       endif()
-       if(WITH_CLANG)
-               set(CMAKE_C_COMPILER "clang")
-       endif()
-       set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mmacosx-version-min=10.4")
+        if(IOS)
+                if (NOT FREERDP_IOS_EXTERNAL_SSL_PATH)
+                        message(STATUS "FREERDP_IOS_EXTERNAL_SSL_PATH not set! Required if openssl is not found in the iOS SDK (which usually isn't")
+                endif()
+                set(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} ${FREERDP_IOS_EXTERNAL_SSL_PATH})
+        else()
+                if(IS_DIRECTORY /opt/local/include)
+                        include_directories(/opt/local/include)
+                        link_directories(/opt/local/lib)
+                endif()
+                set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mmacosx-version-min=10.4")
+        endif()
+        if(WITH_CLANG)
+                set(CMAKE_C_COMPILER "clang")
+        endif()
 endif()
 
 # Android
@@ -272,6 +282,14 @@ endif()
 if(APPLE)
        set(DIRECTFB_FEATURE_TYPE "DISABLED")
        set(FFMPEG_FEATURE_TYPE "OPTIONAL")
+       if(IOS)
+               set(X11_FEATURE_TYPE "DISABLED")
+               set(ALSA_FEATURE_TYPE "DISABLED")
+               set(PULSE_FEATURE_TYPE "DISABLED")
+               set(CUPS_FEATURE_TYPE "DISABLED")
+               set(PCSC_FEATURE_TYPE "DISABLED")
+               set(GSTREAMER_FEATURE_TYPE "DISABLED")
+       endif()
 endif()
 
 if(ANDROID)
@@ -285,17 +303,6 @@ if(ANDROID)
        set(GSTREAMER_FEATURE_TYPE "DISABLED")
 endif()
 
-if(IOS)
-       set(X11_FEATURE_TYPE "DISABLED")
-       set(DIRECTFB_FEATURE_TYPE "DISABLED")
-       set(ALSA_FEATURE_TYPE "DISABLED")
-       set(PULSE_FEATURE_TYPE "DISABLED")
-       set(CUPS_FEATURE_TYPE "DISABLED")
-       set(PCSC_FEATURE_TYPE "DISABLED")
-       set(FFMPEG_FEATURE_TYPE "DISABLED")
-       set(GSTREAMER_FEATURE_TYPE "DISABLED")
-endif()
-
 find_feature(X11 ${X11_FEATURE_TYPE} ${X11_FEATURE_PURPOSE} ${X11_FEATURE_DESCRIPTION})
 find_feature(DirectFB ${DIRECTFB_FEATURE_TYPE} ${DIRECTFB_FEATURE_PURPOSE} ${DIRECTFB_FEATURE_DESCRIPTION})
 
index 76a6d8d..e69de29 100644 (file)
@@ -1 +0,0 @@
-iOS
index a5eb5b3..68aefcb 100644 (file)
@@ -35,8 +35,15 @@ if(WITH_X11)
        add_subdirectory(X11)
 endif()
 
-if(APPLE AND (NOT IOS))
-       add_subdirectory(Mac)
+if(APPLE)
+       if(IOS)
+               if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/iOS")
+                       message(STATUS "Adding iOS client")
+                       add_subdirectory(iOS)
+               endif()
+       else()
+               add_subdirectory(Mac)
+       endif()
 endif()
 
 if(ANDROID)
diff --git a/client/iOS/.gitignore b/client/iOS/.gitignore
new file mode 100644 (file)
index 0000000..fe0e7b0
--- /dev/null
@@ -0,0 +1,7 @@
+# XCode files
+project.xcworkspace/
+xcuserdata/
+bin/
+build/
+project.pbxproj
+!iFreeRDP.xcodeproj/
diff --git a/client/iOS/Additions/OrderedDictionary.h b/client/iOS/Additions/OrderedDictionary.h
new file mode 100644 (file)
index 0000000..ce741fb
--- /dev/null
@@ -0,0 +1,40 @@
+//
+//  OrderedDictionary.h
+//  OrderedDictionary
+//
+//  Modified version (Added indexForKey/Value functions)
+//
+//  Created by Matt Gallagher on 19/12/08.
+//  Copyright 2008 Matt Gallagher. All rights reserved.
+//
+//  This software is provided 'as-is', without any express or implied
+//  warranty. In no event will the authors be held liable for any damages
+//  arising from the use of this software. Permission is granted to anyone to
+//  use this software for any purpose, including commercial applications, and to
+//  alter it and redistribute it freely, subject to the following restrictions:
+//
+//  1. The origin of this software must not be misrepresented; you must not
+//     claim that you wrote the original software. If you use this software
+//     in a product, an acknowledgment in the product documentation would be
+//     appreciated but is not required.
+//  2. Altered source versions must be plainly marked as such, and must not be
+//     misrepresented as being the original software.
+//  3. This notice may not be removed or altered from any source
+//     distribution.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface OrderedDictionary : NSMutableDictionary
+{
+       NSMutableDictionary *dictionary;
+       NSMutableArray *array;
+}
+
+- (void)insertObject:(id)anObject forKey:(id)aKey atIndex:(NSUInteger)anIndex;
+- (id)keyAtIndex:(NSUInteger)anIndex;
+- (NSUInteger)indexForValue:(id)value;
+- (NSUInteger)indexForKey:(id)key;
+- (NSEnumerator *)reverseKeyEnumerator;
+
+@end
diff --git a/client/iOS/Additions/OrderedDictionary.m b/client/iOS/Additions/OrderedDictionary.m
new file mode 100644 (file)
index 0000000..63b8cff
--- /dev/null
@@ -0,0 +1,168 @@
+//
+//  OrderedDictionary.m
+//  OrderedDictionary
+//
+//  Modified version (Added indexForKey/Value functions)
+//
+//  Created by Matt Gallagher on 19/12/08.
+//  Copyright 2008 Matt Gallagher. All rights reserved.
+//
+//  This software is provided 'as-is', without any express or implied
+//  warranty. In no event will the authors be held liable for any damages
+//  arising from the use of this software. Permission is granted to anyone to
+//  use this software for any purpose, including commercial applications, and to
+//  alter it and redistribute it freely, subject to the following restrictions:
+//
+//  1. The origin of this software must not be misrepresented; you must not
+//     claim that you wrote the original software. If you use this software
+//     in a product, an acknowledgment in the product documentation would be
+//     appreciated but is not required.
+//  2. Altered source versions must be plainly marked as such, and must not be
+//     misrepresented as being the original software.
+//  3. This notice may not be removed or altered from any source
+//     distribution.
+//
+
+#import "OrderedDictionary.h"
+
+NSString *DescriptionForObject(NSObject *object, id locale, NSUInteger indent)
+{
+       NSString *objectString;
+       if ([object isKindOfClass:[NSString class]])
+       {
+               objectString = (NSString *)[[object retain] autorelease];
+       }
+       else if ([object respondsToSelector:@selector(descriptionWithLocale:indent:)])
+       {
+               objectString = [(NSDictionary *)object descriptionWithLocale:locale indent:indent];
+       }
+       else if ([object respondsToSelector:@selector(descriptionWithLocale:)])
+       {
+               objectString = [(NSSet *)object descriptionWithLocale:locale];
+       }
+       else
+       {
+               objectString = [object description];
+       }
+       return objectString;
+}
+
+@implementation OrderedDictionary
+
+- (id)init
+{
+       return [self initWithCapacity:0];
+}
+
+- (id)initWithCapacity:(NSUInteger)capacity
+{
+       self = [super init];
+       if (self != nil)
+       {
+               dictionary = [[NSMutableDictionary alloc] initWithCapacity:capacity];
+               array = [[NSMutableArray alloc] initWithCapacity:capacity];
+       }
+       return self;
+}
+
+- (void)dealloc
+{
+       [dictionary release];
+       [array release];
+       [super dealloc];
+}
+
+- (id)copy
+{
+       return [self mutableCopy];
+}
+
+- (void)setObject:(id)anObject forKey:(id)aKey
+{
+       if (![dictionary objectForKey:aKey])
+       {
+               [array addObject:aKey];
+       }
+       [dictionary setObject:anObject forKey:aKey];
+}
+
+- (void)removeObjectForKey:(id)aKey
+{
+       [dictionary removeObjectForKey:aKey];
+       [array removeObject:aKey];
+}
+
+- (NSUInteger)count
+{
+       return [dictionary count];
+}
+
+- (id)objectForKey:(id)aKey
+{
+       return [dictionary objectForKey:aKey];
+}
+
+- (NSEnumerator *)keyEnumerator
+{
+       return [array objectEnumerator];
+}
+
+- (NSEnumerator *)reverseKeyEnumerator
+{
+       return [array reverseObjectEnumerator];
+}
+
+- (void)insertObject:(id)anObject forKey:(id)aKey atIndex:(NSUInteger)anIndex
+{
+       if ([dictionary objectForKey:aKey])
+       {
+               [self removeObjectForKey:aKey];
+       }
+       [array insertObject:aKey atIndex:anIndex];
+       [dictionary setObject:anObject forKey:aKey];
+}
+
+- (id)keyAtIndex:(NSUInteger)anIndex
+{
+       return [array objectAtIndex:anIndex];
+}
+
+- (NSUInteger)indexForKey:(id)key
+{
+    return [array indexOfObject:key];
+}
+
+- (NSUInteger)indexForValue:(id)value
+{
+    NSArray* keys = [self allKeysForObject:value];
+    if ([keys count] > 0)
+    {
+        return [self indexForKey:[keys objectAtIndex:0]];
+    }
+    
+    return NSNotFound;
+}
+
+- (NSString *)descriptionWithLocale:(id)locale indent:(NSUInteger)level
+{
+       NSMutableString *indentString = [NSMutableString string];
+       NSUInteger i, count = level;
+       for (i = 0; i < count; i++)
+       {
+               [indentString appendFormat:@"    "];
+       }
+       
+       NSMutableString *description = [NSMutableString string];
+       [description appendFormat:@"%@{\n", indentString];
+       for (NSObject *key in self)
+       {
+               [description appendFormat:@"%@    %@ = %@;\n",
+                       indentString,
+                       DescriptionForObject(key, locale, level),
+                       DescriptionForObject([self objectForKey:key], locale, level)];
+       }
+       [description appendFormat:@"%@}\n", indentString];
+       return description;
+}
+
+@end
diff --git a/client/iOS/Additions/TSXAdditions.h b/client/iOS/Additions/TSXAdditions.h
new file mode 100644 (file)
index 0000000..7f00378
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ Additions to Cocoa touch classes
+ Copyright 2013 Thinstuff Technologies GmbH, Authors: Dorian Johnson, Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import <Foundation/Foundation.h>
+
+@interface NSObject (TSXAdditions)
+- (void)setValuesForKeyPathsWithDictionary:(NSDictionary *)keyedValues;
+@end
+
+#pragma mark -
+@interface NSString (TSXAdditions)
++ (NSString*)stringWithUUID;
+- (NSData*)dataFromHexString;
++ (NSString*)hexStringFromData:(const unsigned char *)data ofSize:(unsigned int)size withSeparator:(NSString *)sep afterNthChar:(int)sepnth;
+@end
+
+@interface NSDictionary (TSXAdditions)
+- (id)mutableDeepCopy;
+@end
+
+@interface NSData (TSXAdditions)
+- (NSString *)hexadecimalString;
+- (NSString *)base64EncodedString;
+@end
diff --git a/client/iOS/Additions/TSXAdditions.m b/client/iOS/Additions/TSXAdditions.m
new file mode 100644 (file)
index 0000000..99afc62
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ Additions to Cocoa touch classes
+ Copyright 2013 Thinstuff Technologies GmbH, Authors: Dorian Johnson, Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "TSXAdditions.h"
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+
+@implementation NSObject (TSXAdditions)
+
+- (void)setValuesForKeyPathsWithDictionary:(NSDictionary *)keyedValues
+{
+       for (id keyPath in keyedValues)
+               [self setValue:[keyedValues objectForKey:keyPath] forKeyPath:keyPath];
+}
+
+- mutableDeepCopy
+{
+    if([self respondsToSelector:@selector(mutableCopyWithZone:)])
+        return [self mutableCopy];
+    else if([self respondsToSelector:@selector(copyWithZone:)])
+        return [self copy];
+    else
+        return [self retain];
+}
+
+@end
+
+#pragma mark -
+
+@implementation NSString (TSXAdditions)
+
+#pragma mark Creation routines
++ (NSString*)stringWithUUID
+{
+       CFUUIDRef uuidObj = CFUUIDCreate(nil);
+       NSString* uuidString = (NSString*)CFUUIDCreateString(nil, uuidObj);
+       CFRelease(uuidObj);
+       return [uuidString autorelease];
+}
+
+/* Code from http://code.google.com/p/google-toolbox-for-mac/source/browse/trunk/Foundation/GTMNSData%2BHex.m?r=344 */ 
+- (NSData*)dataFromHexString
+{
+    NSData *hexData = [self dataUsingEncoding:NSASCIIStringEncoding];
+    const char *hexBuf = [hexData bytes];
+    NSUInteger hexLen = [hexData length];
+    
+    // This indicates an error converting to ASCII.
+    if (!hexData)
+        return nil;
+    
+    if ((hexLen % 2) != 0) {
+        return nil;
+    }
+    
+    NSMutableData *binaryData = [NSMutableData dataWithLength:(hexLen / 2)];
+    unsigned char *binaryPtr = [binaryData mutableBytes];
+    unsigned char value = 0;
+    for (NSUInteger i = 0; i < hexLen; i++) {
+        char c = hexBuf[i];
+        
+        if (!isxdigit(c)) {
+            return nil;
+        }
+        
+        if (isdigit(c)) {
+            value += c - '0';
+        } else if (islower(c)) {
+            value += 10 + c - 'a';
+        } else {
+            value += 10 + c - 'A';
+        }
+        
+        if (i & 1) {
+            *binaryPtr++ = value;
+            value = 0;
+        } else {
+            value <<= 4;
+        }
+    }
+    
+    return [NSData dataWithData:binaryData];    
+}
+
++ (NSString*)hexStringFromData:(const unsigned char *)data ofSize:(unsigned int)size withSeparator:(NSString *)sep afterNthChar:(int)sepnth
+{
+       int i;
+       NSMutableString *result;
+       NSString *immutableResult;
+       
+       result = [[NSMutableString alloc] init];
+       for (i = 0; i < size; i++) {
+               if(i && sep && sepnth && i%sepnth==0)
+                       [result appendString:sep];
+               [result appendFormat:@"%02X", data[i]];
+       }
+       
+       immutableResult = [NSString stringWithString:result];
+       [result release];
+       return immutableResult;
+}
+
+@end
+
+#pragma mark Mutable deep copy for dicionary, array and set
+
+@implementation NSDictionary (TSXAdditions)
+
+- mutableDeepCopy
+{
+    NSMutableDictionary *newDictionary = [[NSMutableDictionary alloc] init];
+    NSEnumerator *enumerator = [self keyEnumerator];
+    id key;
+    while((key = [enumerator nextObject]))
+    {
+        id obj = [[self objectForKey:key] mutableDeepCopy];
+        [newDictionary setObject:obj forKey:key];
+        [obj release];
+    }
+    return newDictionary;
+}
+
+@end
+
+@implementation NSArray (TSXAdditions)
+
+- mutableDeepCopy
+{
+    NSMutableArray *newArray = [[NSMutableArray alloc] init];
+    NSEnumerator *enumerator = [self objectEnumerator];
+    id obj;
+    while((obj = [enumerator nextObject]))
+    {
+        obj = [obj mutableDeepCopy];
+        [newArray addObject:obj];
+        [obj release];
+    }
+    return newArray;
+}
+
+@end
+
+@implementation NSSet (TSXAdditions)
+
+- mutableDeepCopy
+{
+    NSMutableSet *newSet = [[NSMutableSet alloc] init];
+    NSEnumerator *enumerator = [self objectEnumerator];
+    id obj;
+    while((obj = [enumerator nextObject]))
+    {
+        obj = [obj mutableDeepCopy];
+        [newSet addObject:obj];
+        [obj release];
+    }
+    return newSet;
+}
+
+@end
+
+
+#pragma mark -
+
+/* Code from http://stackoverflow.com/questions/1305225/best-way-to-serialize-a-nsdata-into-an-hexadeximal-string */
+@implementation NSData (TSXAdditions)
+
+#pragma mark - String Conversion
+- (NSString *)hexadecimalString {
+    /* Returns hexadecimal string of NSData. Empty string if data is empty.   */
+    
+    const unsigned char *dataBuffer = (const unsigned char *)[self bytes];
+    
+    if (!dataBuffer)
+        return [NSString string];
+    
+    NSUInteger          dataLength  = [self length];
+    NSMutableString     *hexString  = [NSMutableString stringWithCapacity:(dataLength * 2)];
+    
+    for (int i = 0; i < dataLength; ++i)
+        [hexString appendString:[NSString stringWithFormat:@"%02lx", (unsigned long)dataBuffer[i]]];
+    
+    return [NSString stringWithString:hexString];
+}
+
+/* Code from http://cocoawithlove.com/2009/06/base64-encoding-options-on-mac-and.html */
+- (NSString *)base64EncodedString
+{
+    // Construct an OpenSSL context
+    BIO *context = BIO_new(BIO_s_mem());
+    
+    // Tell the context to encode base64
+    BIO *command = BIO_new(BIO_f_base64());
+    context = BIO_push(command, context);
+    BIO_set_flags(context, BIO_FLAGS_BASE64_NO_NL);
+    
+    // Encode all the data
+    BIO_write(context, [self bytes], [self length]);
+    (void)BIO_flush(context);
+    
+    // Get the data out of the context
+    char *outputBuffer;
+    long outputLength = BIO_get_mem_data(context, &outputBuffer);
+    NSString *encodedString = [[NSString alloc] initWithBytes:outputBuffer length:outputLength encoding:NSASCIIStringEncoding];
+    
+    BIO_free_all(context);
+    
+    return encodedString;
+}
+
+@end
+
diff --git a/client/iOS/Additions/Toast+UIView.h b/client/iOS/Additions/Toast+UIView.h
new file mode 100644 (file)
index 0000000..012d441
--- /dev/null
@@ -0,0 +1,50 @@
+/***************************************************************************
+    Toast+UIView.h
+    Toast
+    Version 0.1
+
+    Copyright (c) 2011 Charles Scalesse.
+    Permission is hereby granted, free of charge, to any person obtaining a
+    copy of this software and associated documentation files (the
+    "Software"), to deal in the Software without restriction, including
+    without limitation the rights to use, copy, modify, merge, publish,
+    distribute, sublicense, and/or sell copies of the Software, and to
+    permit persons to whom the Software is furnished to do so, subject to
+    the following conditions:
+    The above copyright notice and this permission notice shall be included
+    in all copies or substantial portions of the Software.
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+***************************************************************************/
+
+
+#import <Foundation/Foundation.h>
+
+@interface UIView (Toast)
+
+#define ToastDurationLong 5.0
+#define ToastDurationNormal 3.0
+#define ToastDurationShort 1.0
+
+// each makeToast method creates a view and displays it as toast
+-(void)makeToast:(NSString *)message;
+-(void)makeToast:(NSString *)message duration:(float)interval position:(id)point;
+-(void)makeToast:(NSString *)message duration:(float)interval position:(id)point title:(NSString *)title;
+-(void)makeToast:(NSString *)message duration:(float)interval position:(id)point title:(NSString *)title image:(UIImage *)image;
+-(void)makeToast:(NSString *)message duration:(float)interval position:(id)point image:(UIImage *)image;
+
+// the showToast method displays an existing view as toast
+-(void)showToast:(UIView *)toast;
+-(void)showToast:(UIView *)toast duration:(float)interval position:(id)point;
+
+@end
diff --git a/client/iOS/Additions/Toast+UIView.m b/client/iOS/Additions/Toast+UIView.m
new file mode 100644 (file)
index 0000000..649add3
--- /dev/null
@@ -0,0 +1,307 @@
+/***************************************************************************
+ Toast+UIView.h
+ Toast
+ Version 0.1
+ Copyright (c) 2011 Charles Scalesse.
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ ***************************************************************************/
+
+#import "Toast+UIView.h"
+#import <QuartzCore/QuartzCore.h>
+#import <objc/runtime.h>
+
+#define kMaxWidth           0.8
+#define kMaxHeight          0.8
+
+#define kHorizontalPadding  10.0
+#define kVerticalPadding    10.0
+#define kCornerRadius       10.0
+#define kOpacity            0.8
+#define kFontSize           16.0
+#define kMaxTitleLines      999
+#define kMaxMessageLines    999
+
+#define kFadeDuration       0.2
+
+#define kDefaultLength      3
+#define kDefaultPosition    @"bottom"
+
+#define kImageWidth         80.0
+#define kImageHeight        80.0
+
+static NSString *kDurationKey = @"duration";
+
+
+@interface UIView (ToastPrivate)
+
+-(CGPoint)getPositionFor:(id)position toast:(UIView *)toast;
+-(UIView *)makeViewForMessage:(NSString *)message title:(NSString *)title image:(UIImage *)image;
+
+@end
+
+
+@implementation UIView (Toast)
+
+#pragma mark -
+#pragma mark Toast Methods
+
+-(void)makeToast:(NSString *)message {
+    [self makeToast:message duration:kDefaultLength position:kDefaultPosition];
+}
+
+-(void)makeToast:(NSString *)message duration:(float)interval position:(id)point {
+    UIView *toast = [self makeViewForMessage:message title:nil image:nil];
+    [self showToast:toast duration:interval position:point];  
+}
+
+-(void)makeToast:(NSString *)message duration:(float)interval position:(id)point title:(NSString *)title {
+    UIView *toast = [self makeViewForMessage:message title:title image:nil];
+    [self showToast:toast duration:interval position:point];  
+}
+
+-(void)makeToast:(NSString *)message duration:(float)interval position:(id)point image:(UIImage *)image {
+    UIView *toast = [self makeViewForMessage:message title:nil image:image];
+    [self showToast:toast duration:interval position:point];  
+}
+
+-(void)makeToast:(NSString *)message duration:(float)interval  position:(id)point title:(NSString *)title image:(UIImage *)image {
+    UIView *toast = [self makeViewForMessage:message title:title image:image];
+    [self showToast:toast duration:interval position:point];  
+}
+
+-(void)showToast:(UIView *)toast {
+    [self showToast:toast duration:kDefaultLength position:kDefaultPosition];
+}
+
+-(void)showToast:(UIView *)toast duration:(float)interval position:(id)point {
+    
+    /****************************************************
+     *                                                  *
+     * Displays a view for a given duration & position. *
+     *                                                  *
+     ****************************************************/
+    
+    CGPoint toastPoint = [self getPositionFor:point toast:toast];
+    
+    //use an associative reference to associate the toast view with the display interval
+    objc_setAssociatedObject (toast, &kDurationKey, [NSNumber numberWithFloat:interval], OBJC_ASSOCIATION_RETAIN);
+    
+    [toast setCenter:toastPoint];
+    [toast setAlpha:0.0];
+    [self addSubview:toast];
+    
+    [UIView beginAnimations:@"fade_in" context:toast];
+    [UIView setAnimationDuration:kFadeDuration];
+    [UIView setAnimationDelegate:self];
+    [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
+    [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
+    [toast setAlpha:1.0];
+    [UIView commitAnimations];
+    
+}
+
+#pragma mark -
+#pragma mark Animation Delegate Method
+
+- (void)animationDidStop:(NSString*)animationID finished:(BOOL)finished context:(void *)context {
+    
+    UIView *toast = (UIView *)context;
+    
+    // retrieve the display interval associated with the view
+    float interval = [(NSNumber *)objc_getAssociatedObject(toast, &kDurationKey) floatValue];
+    
+    if([animationID isEqualToString:@"fade_in"]) {
+        
+        [UIView beginAnimations:@"fade_out" context:toast];
+        [UIView setAnimationDelay:interval];
+        [UIView setAnimationDuration:kFadeDuration];
+        [UIView setAnimationDelegate:self];
+        [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
+        [UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
+        [toast setAlpha:0.0];
+        [UIView commitAnimations];
+        
+    } else if ([animationID isEqualToString:@"fade_out"]) {
+        
+        [toast removeFromSuperview];
+        
+    }
+    
+}
+
+#pragma mark -
+#pragma mark Private Methods
+
+-(CGPoint)getPositionFor:(id)point toast:(UIView *)toast {
+    
+    /*************************************************************************************
+     *                                                                                   *
+     * Converts string literals @"top", @"bottom", @"center", or any point wrapped in an *
+     * NSValue object into a CGPoint                                                     *
+     *                                                                                   *
+     *************************************************************************************/
+    
+    if([point isKindOfClass:[NSString class]]) {
+        
+        if( [point caseInsensitiveCompare:@"top"] == NSOrderedSame ) {
+            return CGPointMake(self.bounds.size.width/2, (toast.frame.size.height / 2) + kVerticalPadding);
+        } else if( [point caseInsensitiveCompare:@"bottom"] == NSOrderedSame ) {
+            return CGPointMake(self.bounds.size.width/2, (self.bounds.size.height - (toast.frame.size.height / 2)) - kVerticalPadding);
+        } else if( [point caseInsensitiveCompare:@"center"] == NSOrderedSame ) {
+            return CGPointMake(self.bounds.size.width / 2, self.bounds.size.height / 2);
+        }
+        
+    } else if ([point isKindOfClass:[NSValue class]]) {
+        return [point CGPointValue];
+    }
+    
+    NSLog(@"Error: Invalid position for toast.");
+    return [self getPositionFor:kDefaultPosition toast:toast];
+}
+
+-(UIView *)makeViewForMessage:(NSString *)message title:(NSString *)title image:(UIImage *)image {
+    
+    /***********************************************************************************
+     *                                                                                 *
+     * Dynamically build a toast view with any combination of message, title, & image. *
+     *                                                                                 *
+     ***********************************************************************************/
+    
+    if((message == nil) && (title == nil) && (image == nil)) return nil;
+
+    UILabel *messageLabel = nil;
+    UILabel *titleLabel = nil;
+    UIImageView *imageView = nil;
+    
+    // create the parent view
+    UIView *wrapperView = [[[UIView alloc] init] autorelease];
+    [wrapperView.layer setCornerRadius:kCornerRadius];
+    [wrapperView setBackgroundColor:[[UIColor blackColor] colorWithAlphaComponent:kOpacity]];
+    wrapperView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin;
+
+    if(image != nil) {
+        imageView = [[[UIImageView alloc] initWithImage:image] autorelease];
+        [imageView setContentMode:UIViewContentModeScaleAspectFit];
+        [imageView setFrame:CGRectMake(kHorizontalPadding, kVerticalPadding, kImageWidth, kImageHeight)];
+    }
+    
+    float imageWidth, imageHeight, imageLeft;
+    
+    // the imageView frame values will be used to size & position the other views
+    if(imageView != nil) {
+        imageWidth = imageView.bounds.size.width;
+        imageHeight = imageView.bounds.size.height;
+        imageLeft = kHorizontalPadding;
+    } else {
+        imageWidth = imageHeight = imageLeft = 0;
+    }
+    
+    if (title != nil) {
+        titleLabel = [[[UILabel alloc] init] autorelease];
+        [titleLabel setNumberOfLines:kMaxTitleLines];
+        [titleLabel setFont:[UIFont boldSystemFontOfSize:kFontSize]];
+        [titleLabel setTextAlignment:UITextAlignmentLeft];
+        [titleLabel setLineBreakMode:UILineBreakModeWordWrap];
+        [titleLabel setTextColor:[UIColor whiteColor]];
+        [titleLabel setBackgroundColor:[UIColor clearColor]];
+        [titleLabel setAlpha:1.0];
+        [titleLabel setText:title];
+        
+        // size the title label according to the length of the text
+        CGSize maxSizeTitle = CGSizeMake((self.bounds.size.width * kMaxWidth) - imageWidth, self.bounds.size.height * kMaxHeight);
+        CGSize expectedSizeTitle = [title sizeWithFont:titleLabel.font constrainedToSize:maxSizeTitle lineBreakMode:titleLabel.lineBreakMode]; 
+        [titleLabel setFrame:CGRectMake(0, 0, expectedSizeTitle.width, expectedSizeTitle.height)];
+    }
+    
+    if (message != nil) {
+        messageLabel = [[[UILabel alloc] init] autorelease];
+        [messageLabel setNumberOfLines:kMaxMessageLines];
+        [messageLabel setFont:[UIFont systemFontOfSize:kFontSize]];
+        [messageLabel setLineBreakMode:UILineBreakModeWordWrap];
+        [messageLabel setTextColor:[UIColor whiteColor]];
+        [messageLabel setTextAlignment:UITextAlignmentCenter];
+        [messageLabel setBackgroundColor:[UIColor clearColor]];
+        [messageLabel setAlpha:1.0];
+        [messageLabel setText:message];
+        
+        // size the message label according to the length of the text
+        CGSize maxSizeMessage = CGSizeMake((self.bounds.size.width * kMaxWidth) - imageWidth, self.bounds.size.height * kMaxHeight);
+        CGSize expectedSizeMessage = [message sizeWithFont:messageLabel.font constrainedToSize:maxSizeMessage lineBreakMode:messageLabel.lineBreakMode]; 
+        [messageLabel setFrame:CGRectMake(0, 0, expectedSizeMessage.width, expectedSizeMessage.height)];
+    }
+    
+    // titleLabel frame values
+    float titleWidth, titleHeight, titleTop, titleLeft;
+    
+    if(titleLabel != nil) {
+        titleWidth = titleLabel.bounds.size.width;
+        titleHeight = titleLabel.bounds.size.height;
+        titleTop = kVerticalPadding;
+        titleLeft = imageLeft + imageWidth + kHorizontalPadding;
+    } else {
+        titleWidth = titleHeight = titleTop = titleLeft = 0;
+    }
+    
+    // messageLabel frame values
+    float messageWidth, messageHeight, messageLeft, messageTop;
+
+    if(messageLabel != nil) {
+        messageWidth = messageLabel.bounds.size.width;
+        messageHeight = messageLabel.bounds.size.height;
+        messageLeft = imageLeft + imageWidth + kHorizontalPadding;
+        messageTop = titleTop + titleHeight + kVerticalPadding;
+    } else {
+        messageWidth = messageHeight = messageLeft = messageTop = 0;
+    }
+    
+    // compare the title & message widths and use the longer value to calculate the size of the wrapper width
+    // the same logic applies to the x value (left)
+    float longerWidth = (messageWidth < titleWidth) ? titleWidth : messageWidth;
+    float longerLeft = (messageLeft < titleLeft) ? titleLeft : messageLeft;
+    
+    // if the image width is larger than longerWidth, use the image width to calculate the wrapper width.
+    // the same logic applies to the wrapper height
+    float wrapperWidth = ((longerLeft + longerWidth + kHorizontalPadding) < imageWidth + (kHorizontalPadding * 2)) ? imageWidth + (kHorizontalPadding * 2) : (longerLeft + longerWidth + kHorizontalPadding);
+    float wrapperHeight = ((messageTop + messageHeight + kVerticalPadding) < imageHeight + (kVerticalPadding * 2)) ? imageHeight + (kVerticalPadding * 2) : (messageTop + messageHeight + kVerticalPadding);
+                         
+    [wrapperView setFrame:CGRectMake(0, 0, wrapperWidth, wrapperHeight)];
+    
+    if(titleLabel != nil) {
+        [titleLabel setFrame:CGRectMake(titleLeft, titleTop, titleWidth, titleHeight)];
+        [wrapperView addSubview:titleLabel];
+    }
+    
+    if(messageLabel != nil) {
+        [messageLabel setFrame:CGRectMake(messageLeft, messageTop, messageWidth, messageHeight)];
+        [wrapperView addSubview:messageLabel];
+    }
+    
+    if(imageView != nil) {
+        [wrapperView addSubview:imageView];
+    }
+    
+    return wrapperView;
+}
+
+@end
diff --git a/client/iOS/AppDelegate.h b/client/iOS/AppDelegate.h
new file mode 100644 (file)
index 0000000..7c751ed
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ App delegate
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import <UIKit/UIKit.h>
+
+@class MainTabBarController;
+
+@interface AppDelegate : NSObject <UIApplicationDelegate> {
+
+    MainTabBarController* _tabBarController;
+}
+
+@property (nonatomic, retain) IBOutlet UIWindow *window;
+@property (nonatomic, retain) IBOutlet MainTabBarController* tabBarController;
+
+@end
diff --git a/client/iOS/AppDelegate.m b/client/iOS/AppDelegate.m
new file mode 100644 (file)
index 0000000..a51410c
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ App delegate
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "AppDelegate.h"
+
+#import "AboutController.h"
+#import "HelpController.h"
+#import "BookmarkListController.h"
+#import "AppSettingsController.h"
+#import "MainTabBarController.h"
+#import "Utils.h"
+
+@implementation AppDelegate
+
+
+@synthesize window = _window, tabBarController = _tabBarController;
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
+{    
+       // Set default values for most NSUserDefaults
+       [[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Defaults" ofType:@"plist"]]];
+
+    // init global settings
+    SetSwapMouseButtonsFlag([[NSUserDefaults standardUserDefaults] boolForKey:@"ui.swap_mouse_buttons"]);
+    SetInvertScrollingFlag([[NSUserDefaults standardUserDefaults] boolForKey:@"ui.invert_scrolling"]);
+    
+    // create bookmark view and navigation controller
+    BookmarkListController* bookmarkListController = [[[BookmarkListController alloc] initWithNibName:@"BookmarkListView" bundle:nil] autorelease];
+    UINavigationController* bookmarkNavigationController = [[[UINavigationController alloc] initWithRootViewController:bookmarkListController] autorelease];   
+
+    // create app settings view and navigation controller
+    AppSettingsController* appSettingsController = [[[AppSettingsController alloc] initWithStyle:UITableViewStyleGrouped] autorelease];
+    UINavigationController* appSettingsNavigationController = [[[UINavigationController alloc] initWithRootViewController:appSettingsController] autorelease]; 
+     
+    // create help view controller
+    HelpController* helpViewController = [[[HelpController alloc] initWithNibName:nil bundle:nil] autorelease];
+
+    // create about view controller
+    AboutController* aboutViewController = [[[AboutController alloc] initWithNibName:nil bundle:nil] autorelease];
+     
+    // add tab-bar controller to the main window and display everything
+    NSArray* tabItems = [NSArray arrayWithObjects:bookmarkNavigationController, appSettingsNavigationController, helpViewController, aboutViewController, nil];
+    [_tabBarController setViewControllers:tabItems];
+    if ([_window respondsToSelector:@selector(setRootViewController:)])
+        [_window setRootViewController:_tabBarController];
+    else
+        [_window addSubview:[_tabBarController view]];
+    [_window makeKeyAndVisible];          
+
+    return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application
+{
+    /*
+     Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+     Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+     */
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application
+{
+    /*
+     Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
+     If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+     */
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application
+{
+    /*
+     Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+     */
+    // cancel disconnect timer
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application
+{
+    /*
+     Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+     */
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application
+{
+    /*
+     Called when the application is about to terminate.
+     Save data if appropriate.
+     See also applicationDidEnterBackground:.
+     */
+}
+
+- (void)dealloc
+{
+    [_window release];
+    [super dealloc];
+}
+
+@end
diff --git a/client/iOS/CMakeLists.txt b/client/iOS/CMakeLists.txt
new file mode 100644 (file)
index 0000000..0dd5b20
--- /dev/null
@@ -0,0 +1,54 @@
+# FreeRDP: A Remote Desktop Protocol Implementation
+# Android Client
+#
+# Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+# Copyright 2013 Martin Fleisz <mfleisz@thinstuff.at>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set(IOS_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+set(IOS_PACKAGE_NAME "iFreeRDP")
+
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/iFreeRDP.xcodeproj/project.pbxproj.cmake ${CMAKE_CURRENT_SOURCE_DIR}/iFreeRDP.xcodeproj/project.pbxproj @ONLY)
+
+if(IOS_BUILD_OBJC)
+       # And isn't shiped with the android ndk/sdk so
+       # we need to find it on the local machine
+       SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER, BOTH)
+       find_program(XCODEBUILD_COMMAND xcodebuild)
+       SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER, ONLY)
+
+       if(XCODEBUILD_COMMAND STREQUAL "XCODEBUILD_COMMAND-NOTFOUND")
+               message(FATAL_ERROR "xcodebuild not found but required to build ios objective-c")
+       endif()
+
+       if(IOS_BUILD_OBJC_DEBUG)
+               set(IOS_BUILD_TYPE "Debug")
+       else()
+               set(IOS_BUILD_TYPE "Release")
+       endif()
+
+       set(IOS_APP_OUTPUT_DIR "${IOS_SOURCE_DIR}/bin/${IOS_BUILD_TYPE}")
+       set(IOS_APP "${IOS_APP_OUTPUT_DIR}/${IOS_PACKAGE_NAME}.app")
+       
+       # command to create the ios package
+       add_custom_command(
+               OUTPUT "${IOS_APP}"
+               COMMAND ${XCODEBUILD_COMMAND} -project "${IOS_SOURCE_DIR}/iFreeRDP.xcodeproj" -sdk ${CMAKE_IOS_SDK_ROOT} -configuration ${IOS_BUILD_TYPE} CONFIGURATION_BUILD_DIR="${IOS_APP_OUTPUT_DIR}"
+               WORKING_DIRECTORY "${IOS_SOURCE_DIR}"
+               MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/iFreeRDP.xcodeproj/project.pbxproj
+               DEPENDS freerdp winpr
+       )
+       add_custom_target(ios-package ALL SOURCES "${IOS_APP}")
+       SET_DIRECTORY_PROPERTIES(PROPERTIES  ADDITIONAL_MAKE_CLEAN_FILES "bin;build")
+endif()
diff --git a/client/iOS/Controllers/AboutController.h b/client/iOS/Controllers/AboutController.h
new file mode 100644 (file)
index 0000000..0ace59c
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ Application info controller
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import <UIKit/UIKit.h>
+
+
+@interface AboutController : UIViewController <UIWebViewDelegate, UIAlertViewDelegate>
+{
+    NSString* last_link_clicked;
+       UIWebView* webView;
+}
+
+@end
diff --git a/client/iOS/Controllers/AboutController.m b/client/iOS/Controllers/AboutController.m
new file mode 100644 (file)
index 0000000..fe4ba31
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ Application info controller
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "AboutController.h"
+#import "Utils.h"
+
+@implementation AboutController
+
+ // The designated initializer.  Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
+- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
+    if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
+
+               // set title and tab-bar image
+               [self setTitle:NSLocalizedString(@"About", @"About Controller title")];
+        UIImage* tabBarIcon = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"tabbar_icon_about" ofType:@"png"]];
+        [self setTabBarItem:[[UITabBarItem alloc] initWithTitle:NSLocalizedString(@"About", @"Tabbar item about") image:tabBarIcon tag:0]];
+        
+        last_link_clicked = nil;
+    }
+    return self;
+}
+
+- (void)dealloc
+{
+    [super dealloc];
+    [last_link_clicked release];    
+}
+
+// Implement loadView to create a view hierarchy programmatically, without using a nib.
+- (void)loadView 
+{
+       webView = [[[UIWebView alloc] initWithFrame:CGRectZero] autorelease];
+       [webView setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];
+       [webView setAutoresizesSubviews:YES];
+       [webView setDelegate:self];     
+       [webView setDataDetectorTypes:UIDataDetectorTypeNone];  
+       [self setView:webView]; 
+}
+
+
+
+// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
+- (void)viewDidLoad 
+{
+    [super viewDidLoad];
+       
+    NSString *filename = (IsPhone() ? @"about_phone" : @"about");
+       NSString *htmlString = [[[NSString alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:filename ofType:@"html" inDirectory:@"about_page"]  encoding:NSUTF8StringEncoding error:nil] autorelease];
+           
+       [webView loadHTMLString:[NSString stringWithFormat:htmlString, 
+                             TSXAppFullVersion(), 
+                             [[UIDevice currentDevice] systemName],
+                             [[UIDevice currentDevice] systemVersion],
+                             [[UIDevice currentDevice] model]] baseURL:[NSURL fileURLWithPath:[[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"about_page"]]];
+}
+
+// Override to allow orientations other than the default portrait orientation.
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
+    return YES;
+}
+
+#pragma mark -
+#pragma mark UIWebView callbacks
+- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
+{      
+       if([[request URL] isFileURL])
+               return YES;
+       
+       if(navigationType == UIWebViewNavigationTypeLinkClicked)
+       {
+        [last_link_clicked release];
+               last_link_clicked = [[[request URL] absoluteString] retain];
+               UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"External Link", @"External Link Alert Title")
+                                                message:[NSString stringWithFormat:NSLocalizedString(@"Open [%@] in Browser?", @"Open link in browser (with link as parameter)"), last_link_clicked]
+                                                                                                          delegate:self 
+                                                                                         cancelButtonTitle:NSLocalizedString(@"OK", @"OK Button")
+                                                                                         otherButtonTitles:NSLocalizedString(@"No", @"No Button"), nil];
+               [alert show];
+               [alert release];
+               
+               return NO;
+       }
+       return YES;
+}
+
+#pragma mark UIAlertView delegate
+- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
+{
+    if (buttonIndex == 0)
+        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:last_link_clicked]];
+}
+
+@end
diff --git a/client/iOS/Controllers/AdvancedBookmarkEditorController.h b/client/iOS/Controllers/AdvancedBookmarkEditorController.h
new file mode 100644 (file)
index 0000000..1096349
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ Controller to edit advanced bookmark settings
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "EditorBaseController.h"
+
+@class ComputerBookmark;
+@class ConnectionParams;
+
+@interface AdvancedBookmarkEditorController : EditorBaseController
+{
+@private
+    ComputerBookmark* _bookmark;
+    ConnectionParams* _params;
+}
+
+// init for the given bookmark
+- (id)initWithBookmark:(ComputerBookmark*)bookmark;
+
+@end
diff --git a/client/iOS/Controllers/AdvancedBookmarkEditorController.m b/client/iOS/Controllers/AdvancedBookmarkEditorController.m
new file mode 100644 (file)
index 0000000..17b9750
--- /dev/null
@@ -0,0 +1,310 @@
+/*
+ Controller to edit advanced bookmark settings
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "AdvancedBookmarkEditorController.h"
+#import "Bookmark.h"
+#import "Utils.h"
+#import "EditorSelectionController.h"
+#import "ScreenSelectionController.h"
+#import "PerformanceEditorController.h"
+
+@interface AdvancedBookmarkEditorController ()
+
+@end
+
+#define SECTION_ADVANCED_SETTINGS 0
+#define SECTION_COUNT 1
+
+@implementation AdvancedBookmarkEditorController
+
+- (id)initWithBookmark:(ComputerBookmark*)bookmark
+{
+    if ((self = [super initWithStyle:UITableViewStyleGrouped])) 
+       {
+               // set additional settings state according to bookmark data
+               _bookmark = [bookmark retain];
+        _params = [bookmark params];                
+    }
+    return self;
+}
+
+- (void)viewDidLoad
+{
+    [super viewDidLoad];
+    [self setTitle:NSLocalizedString(@"Advanced Settings", @"Advanced Settings title")];
+}
+
+- (void)viewWillAppear:(BOOL)animated
+{
+    [super viewWillAppear:animated];
+    
+    // we need to reload the table view data here to have up-to-date data for the 
+    // advanced settings accessory items (like for resolution/color mode settings)
+    [[self tableView] reloadData];
+}
+
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
+{
+    return YES;
+}
+
+#pragma mark -
+#pragma mark Table view data source
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
+    // Return the number of sections.
+    return SECTION_COUNT;
+}
+
+
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+    // Return the number of rows in the section.
+       switch (section)
+       {
+               case SECTION_ADVANCED_SETTINGS: // advanced settings
+                       return 7;
+               default:
+                       break;
+       }
+       
+    return 0;
+}
+
+
+// set section headers
+- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
+{
+       switch(section)
+       {
+               case SECTION_ADVANCED_SETTINGS:
+                       return NSLocalizedString(@"Advanced", @"'Advanced': advanced settings header");
+       }
+       return @"unknown";
+}
+
+
+// Customize the appearance of table view cells.
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+    
+       // determine the required cell type
+       NSString* cellType = nil;
+       switch([indexPath section])
+       {
+        case SECTION_ADVANCED_SETTINGS: // advanced settings
+        {
+            switch([indexPath row]) 
+            {
+                case 0: // 3G Settings
+                    cellType = TableCellIdentifierYesNo;
+                    break;
+                case 1:        // 3G screen/color depth
+                    cellType = TableCellIdentifierSelection;
+                    break;
+                case 2:        // 3G performance settings
+                    cellType = TableCellIdentifierSubEditor;
+                    break;
+                case 3: // security mode
+                    cellType = TableCellIdentifierSelection;
+                    break;
+                case 4:        // remote program
+                case 5:        // work dir
+                    cellType = TableCellIdentifierText;
+                    break;
+                case 6:        // console mode
+                    cellType = TableCellIdentifierYesNo;
+                    break;
+                default:                                               
+                    break;
+            }
+                       break;
+        }
+       }       
+       NSAssert(cellType != nil, @"Couldn't determine cell type");     
+       
+       // get the table view cell
+       UITableViewCell *cell = [self tableViewCellFromIdentifier:cellType];
+       NSAssert(cell, @"Invalid cell");        
+    
+       // set cell values
+       switch([indexPath section]) 
+       {
+            // advanced settings
+               case SECTION_ADVANCED_SETTINGS:
+                       [self initAdvancedSettings:indexPath cell:cell];
+                       break;
+            
+               default:
+                       break;
+       }       
+    
+    return cell;
+}
+
+// updates advanced settings in the UI
+- (void)initAdvancedSettings:(NSIndexPath*)indexPath cell:(UITableViewCell*)cell
+{
+    BOOL enable_3G_settings = [_params boolForKey:@"enable_3g_settings"];
+       switch(indexPath.row) 
+       {
+               case 0:
+        {
+            EditFlagTableViewCell* flagCell = (EditFlagTableViewCell*)cell;
+            [[flagCell label] setText:NSLocalizedString(@"3G Settings", @"'3G Settings': Bookmark enable 3G settings")];
+            [[flagCell toggle] setTag:GET_TAG_FROM_PATH(indexPath)];
+            [[flagCell toggle] setOn:[_params boolForKey:@"enable_3g_settings"]];
+            [[flagCell toggle] addTarget:self action:@selector(toggleSettingValue:) forControlEvents:UIControlEventValueChanged];
+            break;
+        }
+               case 1:
+        {
+            EditSelectionTableViewCell* selCell = (EditSelectionTableViewCell*)cell;
+            [[selCell label] setText:NSLocalizedString(@"3G Screen", @"'3G Screen': Bookmark 3G Screen settings")];
+            NSString* resolution = ScreenResolutionDescription([_params intForKeyPath:@"settings_3g.screen_resolution_type"], [_params intForKeyPath:@"settings_3g.width"], [_params intForKeyPath:@"settings_3g.height"]);
+            int colorBits = [_params intForKeyPath:@"settings_3g.colors"];
+            [[selCell selection] setText:[NSString stringWithFormat:@"%@@%d", resolution, colorBits]];
+            [[selCell label] setEnabled:enable_3G_settings];
+            [[selCell selection] setEnabled:enable_3G_settings];
+            [selCell setSelectionStyle:enable_3G_settings ? UITableViewCellSelectionStyleBlue : UITableViewCellSelectionStyleNone];
+            break;
+        }            
+               case 2:
+        {
+            EditSubEditTableViewCell* editCell = (EditSubEditTableViewCell*)cell;
+            [[editCell label] setText:NSLocalizedString(@"3G Performance", @"'3G Performance': Bookmark 3G Performance Settings")];
+            [[editCell label] setEnabled:enable_3G_settings];
+            [editCell setSelectionStyle:enable_3G_settings ? UITableViewCellSelectionStyleBlue : UITableViewCellSelectionStyleNone];
+            break;
+        }                      
+               case 3:
+        {
+            EditSelectionTableViewCell* selCell = (EditSelectionTableViewCell*)cell;
+            [[selCell label] setText:NSLocalizedString(@"Security", @"'Security': Bookmark protocl security settings")];
+            [[selCell selection] setText:ProtocolSecurityDescription([_params intForKey:@"security"])];
+            break;
+        }                                    
+               case 4:
+        {
+            EditTextTableViewCell* textCell = (EditTextTableViewCell*)cell;
+            [[textCell label] setText:NSLocalizedString(@"Remote Program", @"'Remote Program': Bookmark remote program settings")];
+            [[textCell textfield] setText:[_params StringForKey:@"remote_program"]];
+            [[textCell textfield] setTag:GET_TAG_FROM_PATH(indexPath)];
+            [[textCell textfield] setPlaceholder:NSLocalizedString(@"not set", @"not set placeholder")];
+            [self adjustEditTextTableViewCell:textCell];
+            break;
+        }            
+               case 5:
+        {
+            EditTextTableViewCell* textCell = (EditTextTableViewCell*)cell;
+            [[textCell label] setText:NSLocalizedString(@"Working Directory", @"'Working Directory': Bookmark working directory settings")];
+            [[textCell textfield] setText:[_params StringForKey:@"working_dir"]];
+            [[textCell textfield] setTag:GET_TAG_FROM_PATH(indexPath)];
+            [[textCell textfield] setPlaceholder:NSLocalizedString(@"not set", @"not set placeholder")];
+            [self adjustEditTextTableViewCell:textCell];
+            break;
+        }            
+               case 6:
+        {
+            EditFlagTableViewCell* flagCell = (EditFlagTableViewCell*)cell;
+            [[flagCell label] setText:NSLocalizedString(@"Console Mode", @"'Console Mode': Bookmark console mode settings")];
+            [[flagCell toggle] setTag:GET_TAG_FROM_PATH(indexPath)];
+            [[flagCell toggle] setOn:[_params boolForKey:@"console"]];
+            [[flagCell toggle] addTarget:self action:@selector(toggleSettingValue:) forControlEvents:UIControlEventValueChanged];
+            break;
+        }
+               default:
+                       NSLog(@"Invalid row index in settings table!");
+                       break;
+       }                       
+}
+
+#pragma mark -
+#pragma mark Table view delegate
+
+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+    UIViewController* viewCtrl = nil;
+    
+    // determine view
+    switch ([indexPath row])
+    {
+        case 1:
+            if ([_params boolForKey:@"enable_3g_settings"])
+                viewCtrl = [[[ScreenSelectionController alloc] initWithConnectionParams:_params keyPath:@"settings_3g"] autorelease];
+            break;
+        case 2:
+            if ([_params boolForKey:@"enable_3g_settings"])
+                viewCtrl = [[[PerformanceEditorController alloc] initWithConnectionParams:_params keyPath:@"settings_3g"] autorelease];
+            break;                    
+        case 3:
+            viewCtrl = [[[EditorSelectionController alloc] initWithConnectionParams:_params entries:[NSArray arrayWithObject:@"security"] selections:[NSArray arrayWithObject:SelectionForSecuritySetting()]] autorelease];
+            break;                                    
+        default:
+            break;
+    }
+    
+    // display view
+    if(viewCtrl)
+        [[self navigationController] pushViewController:viewCtrl animated:YES];
+}
+
+
+#pragma mark -
+#pragma mark Text Field delegate
+
+- (BOOL)textFieldShouldReturn:(UITextField*)textField
+{
+       [textField resignFirstResponder];
+       return NO;
+}
+
+- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
+{
+       switch(textField.tag)
+       {
+        // update remote program/work dir settings
+        case GET_TAG(SECTION_ADVANCED_SETTINGS, 4):
+        {
+            [_params setValue:[textField text] forKey:@"remote_program"];
+            break;
+        }
+            
+        case GET_TAG(SECTION_ADVANCED_SETTINGS, 5):
+        {
+            [_params setValue:[textField text] forKey:@"working_dir"];
+            break;
+        }
+                       
+               default:
+                       break;
+       }
+       return YES;
+}
+
+#pragma mark - Action handlers
+
+- (void)toggleSettingValue:(id)sender
+{
+    UISwitch* valueSwitch = (UISwitch*)sender;
+    switch(valueSwitch.tag)
+    {
+        case GET_TAG(SECTION_ADVANCED_SETTINGS, 0):
+            [_params setBool:[valueSwitch isOn] forKey:@"enable_3g_settings"];
+            NSArray* indexPaths = [NSArray arrayWithObjects:[NSIndexPath indexPathForRow:1 inSection:SECTION_ADVANCED_SETTINGS], [NSIndexPath indexPathForRow:2 inSection:SECTION_ADVANCED_SETTINGS], nil];
+            [[self tableView] reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
+            break;
+            
+        case GET_TAG(SECTION_ADVANCED_SETTINGS, 6):
+            [_params setBool:[valueSwitch isOn] forKey:@"console"];
+            break;
+            
+        default:
+            break;
+    }    
+}
+
+@end
diff --git a/client/iOS/Controllers/AppSettingsController.h b/client/iOS/Controllers/AppSettingsController.h
new file mode 100644 (file)
index 0000000..d962f8d
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ Controller to specify application wide settings
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "EditorBaseController.h"
+
+@interface AppSettingsController : EditorBaseController
+
+@end
diff --git a/client/iOS/Controllers/AppSettingsController.m b/client/iOS/Controllers/AppSettingsController.m
new file mode 100644 (file)
index 0000000..5eaa758
--- /dev/null
@@ -0,0 +1,309 @@
+/*
+ Controller to specify application wide settings
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "AppSettingsController.h"
+#import "Utils.h"
+#import "Toast+UIView.h"
+
+@implementation AppSettingsController
+
+// keep this up-to-date for correct section display/hidding
+#define SECTION_UI_SETTINGS 0
+#define SECTION_CERTIFICATE_HANDLING_SETTINGS 1
+#define SECTION_NUM_SECTIONS 2
+
+#pragma mark -
+#pragma mark Initialization
+
+
+- (id)initWithStyle:(UITableViewStyle)style
+{
+    if ((self = [super initWithStyle:style])) 
+       {                   
+        UIImage* tabBarIcon = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"tabbar_icon_settings" ofType:@"png"]];
+        [self setTabBarItem:[[UITabBarItem alloc] initWithTitle:NSLocalizedString(@"Settings", @"Tabbar item settings") image:tabBarIcon tag:0]];
+    }
+    return self;
+}
+
+#pragma mark -
+#pragma mark View lifecycle
+
+- (void)viewDidLoad {
+    [super viewDidLoad];
+
+    // set title
+    [self setTitle:NSLocalizedString(@"Settings", @"App Settings title")];
+}
+
+
+- (void)viewWillDisappear:(BOOL)animated {
+    [super viewWillDisappear:animated];
+}
+
+// Override to allow orientations other than the default portrait orientation.
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
+    return YES;
+}
+
+
+- (void)dealloc {
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+    [super dealloc];
+}
+
+#pragma mark -
+#pragma mark Table view data source
+
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
+    // Return the number of sections.
+    return SECTION_NUM_SECTIONS;
+}
+
+
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+    // Return the number of rows in the section.
+       switch (section)    
+       {
+        case SECTION_UI_SETTINGS: // UI settings
+            return 5;
+        case SECTION_CERTIFICATE_HANDLING_SETTINGS: // certificate handling settings
+            return 2;
+               default:
+                       break;
+       }
+       
+    return 0;
+}
+
+
+// set section headers
+- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
+{
+       switch(section)
+       {
+        case SECTION_UI_SETTINGS:
+                       return NSLocalizedString(@"User Interface", @"UI settings section title");
+        case SECTION_CERTIFICATE_HANDLING_SETTINGS:
+                       return NSLocalizedString(@"Server Certificate Handling", @"Server Certificate Handling section title");
+        default:
+                       return nil;
+       }
+       return @"unknown";
+}
+
+// Customize the appearance of table view cells.
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+    
+       // determine the required cell type
+       NSString* cellIdentifier = nil;
+       switch([indexPath section])
+       {
+        case SECTION_UI_SETTINGS:
+        {
+            switch([indexPath row])
+            {
+                case 0:
+                case 1:
+                case 2:
+                case 3:
+                case 4:
+                    cellIdentifier = TableCellIdentifierYesNo;
+                    break;
+            }
+            break;
+        }
+        case SECTION_CERTIFICATE_HANDLING_SETTINGS:
+        {
+            switch([indexPath row])
+            {
+                case 0:
+                    cellIdentifier = TableCellIdentifierYesNo;
+                    break;
+                case 1:
+                    cellIdentifier = TableCellIdentifierSubEditor;
+                    break;
+            }
+            break;
+        }
+       }       
+       NSAssert(cellIdentifier != nil, @"Couldn't determine cell type");       
+       
+       // get the table view cell
+       UITableViewCell *cell = [self tableViewCellFromIdentifier:cellIdentifier];
+       NSAssert(cell, @"Invalid cell");        
+    
+       // set cell values
+       switch([indexPath section]) 
+       {               
+        case SECTION_UI_SETTINGS:
+            [self initUISettings:indexPath cell:cell];
+            break;
+            
+        case SECTION_CERTIFICATE_HANDLING_SETTINGS:
+            [self initCertificateHandlingSettings:indexPath cell:cell];
+            break;      
+            
+               default:
+                       break;
+       }       
+    
+    return cell;
+}
+
+#pragma mark - Initialization helpers
+
+// updates UI settings in the UI
+- (void)initUISettings:(NSIndexPath*)indexPath cell:(UITableViewCell*)cell
+{
+       switch([indexPath row]) 
+       {
+               case 0:
+        {
+            EditFlagTableViewCell* flagCell = (EditFlagTableViewCell*)cell;            
+            [[flagCell label] setText:NSLocalizedString(@"Hide Status Bar", "Show/Hide Phone Status Bar setting")];
+            [[flagCell toggle] setTag:GET_TAG_FROM_PATH(indexPath)];
+            [[flagCell toggle] setOn:[[NSUserDefaults standardUserDefaults] boolForKey:@"ui.hide_status_bar"]];
+            [[flagCell toggle] addTarget:self action:@selector(toggleSettingValue:) forControlEvents:UIControlEventValueChanged];
+                       break;            
+        }
+               case 1:
+        {
+            EditFlagTableViewCell* flagCell = (EditFlagTableViewCell*)cell;
+            [[flagCell label] setText:NSLocalizedString(@"Hide Tool Bar", "Show/Hide Tool Bar setting")];
+            [[flagCell toggle] setTag:GET_TAG_FROM_PATH(indexPath)];
+            [[flagCell toggle] setOn:[[NSUserDefaults standardUserDefaults] boolForKey:@"ui.hide_tool_bar"]];
+            [[flagCell toggle] addTarget:self action:@selector(toggleSettingValue:) forControlEvents:UIControlEventValueChanged];
+                       break;
+        }
+               case 2:
+        {
+            EditFlagTableViewCell* flagCell = (EditFlagTableViewCell*)cell;            
+            [[flagCell label] setText:NSLocalizedString(@"Swap Mouse Buttons", "Swap Mouse Button UI setting")];
+            [[flagCell toggle] setTag:GET_TAG_FROM_PATH(indexPath)];
+            [[flagCell toggle] setOn:[[NSUserDefaults standardUserDefaults] boolForKey:@"ui.swap_mouse_buttons"]];
+            [[flagCell toggle] addTarget:self action:@selector(toggleSettingValue:) forControlEvents:UIControlEventValueChanged];
+                       break;            
+        }
+               case 3:
+        {
+            EditFlagTableViewCell* flagCell = (EditFlagTableViewCell*)cell;            
+            [[flagCell label] setText:NSLocalizedString(@"Invert Scrolling", "Invert Scrolling UI setting")];
+            [[flagCell toggle] setTag:GET_TAG_FROM_PATH(indexPath)];
+            [[flagCell toggle] setOn:[[NSUserDefaults standardUserDefaults] boolForKey:@"ui.invert_scrolling"]];
+            [[flagCell toggle] addTarget:self action:@selector(toggleSettingValue:) forControlEvents:UIControlEventValueChanged];
+                       break;            
+        }
+               case 4:
+        {
+            EditFlagTableViewCell* flagCell = (EditFlagTableViewCell*)cell;            
+            [[flagCell label] setText:NSLocalizedString(@"Touch Pointer Auto Scroll", "Touch Pointer Auto Scroll UI setting")];
+            [[flagCell toggle] setTag:GET_TAG_FROM_PATH(indexPath)];
+            [[flagCell toggle] setOn:[[NSUserDefaults standardUserDefaults] boolForKey:@"ui.auto_scroll_touchpointer"]];
+            [[flagCell toggle] addTarget:self action:@selector(toggleSettingValue:) forControlEvents:UIControlEventValueChanged];
+                       break;            
+        }
+               default:
+                       NSLog(@"Invalid row index in settings table!");
+                       break;
+       }
+}
+
+// updates certificate handling settings in the UI
+- (void)initCertificateHandlingSettings:(NSIndexPath*)indexPath cell:(UITableViewCell*)cell
+{
+       switch([indexPath row]) 
+       {
+               case 0:
+        {
+            EditFlagTableViewCell* flagCell = (EditFlagTableViewCell*)cell;            
+            [[flagCell label] setText:NSLocalizedString(@"Accept all Certificates", "Accept All Certificates setting")];
+            [[flagCell toggle] setTag:GET_TAG_FROM_PATH(indexPath)];
+            [[flagCell toggle] setOn:[[NSUserDefaults standardUserDefaults] boolForKey:@"security.accept_certificates"]];
+            [[flagCell toggle] addTarget:self action:@selector(toggleSettingValue:) forControlEvents:UIControlEventValueChanged];
+                       break;            
+        }
+               case 1:
+        {
+            EditSubEditTableViewCell* subCell = (EditSubEditTableViewCell*)cell;
+            [[subCell label] setText:NSLocalizedString(@"Erase Certificate Cache", @"Erase certificate cache button")];
+            break;                        
+        }            
+               default:
+                       NSLog(@"Invalid row index in settings table!");
+                       break;
+       }
+}
+
+#pragma mark -
+#pragma mark Table view delegate
+
+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+
+    // deselect any row to fake a button-pressed like effect
+    [tableView deselectRowAtIndexPath:indexPath animated:YES];
+
+    // ensure everything is stored in our settings before we proceed
+    [[self view] endEditing:NO];
+    
+    // clear certificate cache
+    if([indexPath section] == SECTION_CERTIFICATE_HANDLING_SETTINGS && [indexPath row] == 1)
+    {
+        // delete certificates cache
+        NSError* err;
+        if ([[NSFileManager defaultManager] removeItemAtPath:[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"/.freerdp"] error:&err])
+            [[self view] makeToast:NSLocalizedString(@"Certificate Cache cleared!", @"Clear Certificate cache success message") duration:ToastDurationNormal position:@"center"];
+        else
+            [[self view] makeToast:NSLocalizedString(@"Error clearing the Certificate Cache!", @"Clear Certificate cache failed message") duration:ToastDurationNormal position:@"center"];
+    }
+}
+
+#pragma mark -
+#pragma mark Action Handlers
+
+- (void)toggleSettingValue:(id)sender
+{
+    UISwitch* valueSwitch = (UISwitch*)sender;
+    switch([valueSwitch tag])
+    {
+        case GET_TAG(SECTION_UI_SETTINGS, 0):
+            [[NSUserDefaults standardUserDefaults] setBool:[valueSwitch isOn] forKey:@"ui.hide_status_bar"];
+            break;
+
+        case GET_TAG(SECTION_UI_SETTINGS, 1):
+            [[NSUserDefaults standardUserDefaults] setBool:[valueSwitch isOn] forKey:@"ui.hide_tool_bar"];
+            break;
+
+        case GET_TAG(SECTION_UI_SETTINGS, 2):
+            [[NSUserDefaults standardUserDefaults] setBool:[valueSwitch isOn] forKey:@"ui.swap_mouse_buttons"];
+            SetSwapMouseButtonsFlag([valueSwitch isOn]);
+            break;
+
+        case GET_TAG(SECTION_UI_SETTINGS, 3):
+            [[NSUserDefaults standardUserDefaults] setBool:[valueSwitch isOn] forKey:@"ui.invert_scrolling"];
+            SetInvertScrollingFlag([valueSwitch isOn]);
+            break;
+
+        case GET_TAG(SECTION_UI_SETTINGS, 4):
+            [[NSUserDefaults standardUserDefaults] setBool:[valueSwitch isOn] forKey:@"ui.auto_scroll_touchpointer"];
+            SetInvertScrollingFlag([valueSwitch isOn]);
+            break;
+
+        case GET_TAG(SECTION_CERTIFICATE_HANDLING_SETTINGS, 0):
+            [[NSUserDefaults standardUserDefaults] setBool:[valueSwitch isOn] forKey:@"security.accept_certificates"];
+            break;
+            
+        default:
+            break;
+    }    
+}
+
+@end
+
diff --git a/client/iOS/Controllers/BookmarkEditorController.h b/client/iOS/Controllers/BookmarkEditorController.h
new file mode 100644 (file)
index 0000000..1ca68d3
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ Bookmark editor controller
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+
+#import <UIKit/UIKit.h>
+#import "EditorBaseController.h"
+
+@class ComputerBookmark;
+@class ConnectionParams;
+
+
+@protocol BookmarkEditorDelegate <NSObject>
+// bookmark editing finsihed
+- (void)commitBookmark:(ComputerBookmark*)bookmark;
+@end
+
+
+@interface BookmarkEditorController : EditorBaseController <UIAlertViewDelegate>
+{
+@private
+    ComputerBookmark* _bookmark;
+    ConnectionParams* _params;
+        
+    BOOL _display_server_settings;
+    
+    id<BookmarkEditorDelegate> delegate;
+}
+
+@property (nonatomic, assign) id<BookmarkEditorDelegate> delegate;
+
+// init for the given bookmark
+- (id)initWithBookmark:(ComputerBookmark*)bookmark;
+
+@end
diff --git a/client/iOS/Controllers/BookmarkEditorController.m b/client/iOS/Controllers/BookmarkEditorController.m
new file mode 100644 (file)
index 0000000..de80c50
--- /dev/null
@@ -0,0 +1,400 @@
+/*
+ Bookmark editor controller
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "BookmarkEditorController.h"
+#import "Bookmark.h"
+#import "Utils.h"
+#import "ScreenSelectionController.h"
+#import "PerformanceEditorController.h"
+#import "CredentialsEditorController.h"
+#import "AdvancedBookmarkEditorController.h"
+
+@implementation BookmarkEditorController
+
+@synthesize delegate;
+
+#define SECTION_SERVER 0
+#define SECTION_CREDENTIALS 1
+#define SECTION_SETTINGS 2
+#define SECTION_COUNT 3
+
+#pragma mark -
+#pragma mark Initialization    
+
+- (id)initWithBookmark:(ComputerBookmark*)bookmark
+{
+    if ((self = [super initWithStyle:UITableViewStyleGrouped])) 
+       {
+               // set additional settings state according to bookmark data
+               _bookmark = [bookmark retain];
+        _params = [bookmark params];
+
+               // if this is a TSX Connect bookmark - disable server settings
+               if([_bookmark isKindOfClass:NSClassFromString(@"TSXConnectComputerBookmark")])
+                       _display_server_settings = NO;
+               else
+                       _display_server_settings = YES;
+    }
+    return self;
+}
+
+
+#pragma mark -
+#pragma mark View lifecycle
+
+
+- (void)viewDidLoad {
+    [super viewDidLoad];
+
+    // replace back button with a custom handler that checks if the required bookmark settings were specified
+    UIBarButtonItem* saveButton = [[[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Save", @"Save Button title") style:UIBarButtonItemStyleDone target:self action:@selector(handleSave:)] autorelease];
+    UIBarButtonItem* cancelButton = [[[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Cancel", @"Cancel Button title") style:UIBarButtonItemStyleBordered target:self action:@selector(handleCancel:)] autorelease];
+    [[self navigationItem] setLeftBarButtonItem:cancelButton];    
+    [[self navigationItem] setRightBarButtonItem:saveButton];    
+}
+
+- (void)viewWillAppear:(BOOL)animated {
+    [super viewWillAppear:animated];
+
+    // we need to reload the table view data here to have up-to-date data for the 
+    // advanced settings accessory items (like for resolution/color mode settings)
+    [[self tableView] reloadData];
+}
+
+// Override to allow orientations other than the default portrait orientation.
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
+    return YES;
+}
+
+#pragma mark -
+#pragma mark Table view data source
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
+    // Return the number of sections.
+    return SECTION_COUNT;
+}
+
+
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+    // Return the number of rows in the section.
+       switch (section)
+       {
+               case SECTION_SERVER: // server settings
+                       return (_display_server_settings ? 3 : 0);
+               case SECTION_CREDENTIALS: // credentials
+                       return 1;
+               case SECTION_SETTINGS: // session settings
+                       return 3;
+               default:
+                       break;
+       }
+       
+    return 0;
+}
+
+
+// set section headers
+- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
+{
+       switch(section)
+       {
+               case SECTION_SERVER:
+                       return (_display_server_settings ? NSLocalizedString(@"Host", @"'Host': host settings header") : nil);
+               case SECTION_CREDENTIALS:
+                       return NSLocalizedString(@"Credentials", @"'Credentials': credentials settings header");
+               case SECTION_SETTINGS:
+                       return NSLocalizedString(@"Settings", @"'Session Settings': session settings header");
+       }
+       return @"unknown";
+}
+
+
+// Customize the appearance of table view cells.
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+
+       // determine the required cell type
+       NSString* cellType = nil;
+       switch([indexPath section])
+       {
+               case SECTION_SERVER:
+            cellType = TableCellIdentifierText;
+                       break;
+
+        case SECTION_CREDENTIALS:
+            cellType = TableCellIdentifierSelection;
+            break;
+            
+               case SECTION_SETTINGS: // settings
+                       {
+                               switch([indexPath row]) 
+                               {
+                                       case 0: // screen/color depth
+                                               cellType = TableCellIdentifierSelection;
+                                               break;
+                                       case 1: // performance settings
+                    case 2: // advanced settings
+                                               cellType = TableCellIdentifierSubEditor;
+                                               break;          
+                                       default:                                                
+                                               break;
+                               }
+                       }
+                       break;                  
+
+        default:
+            break;
+       }       
+       NSAssert(cellType != nil, @"Couldn't determine cell type");     
+       
+       // get the table view cell
+       UITableViewCell *cell = [self tableViewCellFromIdentifier:cellType];
+       NSAssert(cell, @"Invalid cell");        
+                               
+       // set cell values
+       switch([indexPath section]) 
+       {
+               // server settings
+               case SECTION_SERVER:
+                       [self initServerSettings:indexPath cell:cell];
+                       break;
+                       
+               // credentials
+               case SECTION_CREDENTIALS:
+                       [self initCredentialSettings:indexPath cell:cell];
+                       break;
+
+               // session settings
+               case SECTION_SETTINGS:
+                       [self initSettings:indexPath cell:cell];
+                       break;
+
+               default:
+                       break;
+       }       
+    
+    return cell;
+}
+
+// updates server settings in the UI
+- (void)initServerSettings:(NSIndexPath*)indexPath cell:(UITableViewCell*)cell
+{
+    EditTextTableViewCell* textCell = (EditTextTableViewCell*)cell;
+       [[textCell textfield] setTag:GET_TAG_FROM_PATH(indexPath)];
+       switch([indexPath row]) 
+       {
+               case 0:
+                       [[textCell label] setText:NSLocalizedString(@"Label", @"'Label': Bookmark label")];
+                       [[textCell textfield] setText:[_bookmark label]];
+            [[textCell textfield] setPlaceholder:NSLocalizedString(@"not set", @"not set placeholder")];
+                       break;
+               case 1:
+                       [[textCell label] setText:NSLocalizedString(@"Host", @"'Host': Bookmark hostname")];
+                       [[textCell textfield] setText:[_params StringForKey:@"hostname"]];
+            [[textCell textfield] setPlaceholder:NSLocalizedString(@"not set", @"not set placeholder")];
+                       break;
+               case 2:
+                       [[textCell label] setText:NSLocalizedString(@"Port", @"'Port': Bookmark port")];
+                       [[textCell textfield] setText:[NSString stringWithFormat:@"%d", [_params intForKey:@"port"]]];
+            [[textCell textfield] setKeyboardType:UIKeyboardTypeNumberPad];
+                       break;
+               default:
+                       NSLog(@"Invalid row index in settings table!");
+                       break;
+       }       
+
+    [self adjustEditTextTableViewCell:textCell];
+}
+
+// updates credentials in the UI
+- (void)initCredentialSettings:(NSIndexPath*)indexPath cell:(UITableViewCell*)cell
+{
+    EditSelectionTableViewCell* selCell = (EditSelectionTableViewCell*)cell;
+       switch(indexPath.row) 
+       {
+               case 0:
+            [[selCell label] setText:NSLocalizedString(@"Credentials", @"'Credentials': Bookmark credentials")];
+            [[selCell selection] setText:[_params StringForKey:@"username"]];
+                       break;
+               default:
+                       NSLog(@"Invalid row index in settings table!");
+                       break;
+       }
+}
+
+// updates session settings in the UI
+- (void)initSettings:(NSIndexPath*)indexPath cell:(UITableViewCell*)cell
+{      
+       switch(indexPath.row) 
+       {
+               case 0:
+        {
+            EditSelectionTableViewCell* selCell = (EditSelectionTableViewCell*)cell;
+            [[selCell label] setText:NSLocalizedString(@"Screen", @"'Screen': Bookmark Screen settings")];
+            NSString* resolution = ScreenResolutionDescription([_params intForKey:@"screen_resolution_type"], [_params intForKey:@"width"], [_params intForKey:@"height"]);
+            int colorBits = [_params intForKey:@"colors"];
+            [[selCell selection] setText:[NSString stringWithFormat:@"%@@%d", resolution, colorBits]];
+            break;
+        }            
+               case 1:
+        {
+            EditSubEditTableViewCell* editCell = (EditSubEditTableViewCell*)cell;
+            [[editCell label] setText:NSLocalizedString(@"Performance", @"'Performance': Bookmark Performance Settings")];
+            break;
+        }                      
+               case 2:
+        {
+            EditSubEditTableViewCell* editCell = (EditSubEditTableViewCell*)cell;
+            [[editCell label] setText:NSLocalizedString(@"Advanced", @"'Advanced': Bookmark Advanced Settings")];
+            break;
+        }                      
+               default:
+                       NSLog(@"Invalid row index in settings table!");
+                       break;
+       }                       
+}
+
+
+#pragma mark -
+#pragma mark Table view delegate
+
+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+    UIViewController* viewCtrl = nil;
+
+    // determine view
+    switch([indexPath section])
+    {
+        case SECTION_CREDENTIALS:
+        {
+            if ([indexPath row] == 0)
+                viewCtrl = [[[CredentialsEditorController alloc] initWithBookmark:_bookmark] autorelease];
+            break;
+        }
+            
+        case SECTION_SETTINGS:
+        {            
+            switch ([indexPath row])
+            {
+                case 0:
+                    viewCtrl = [[[ScreenSelectionController alloc] initWithConnectionParams:_params] autorelease];
+                    break;
+                case 1:
+                    viewCtrl = [[[PerformanceEditorController alloc] initWithConnectionParams:_params] autorelease];
+                    break;    
+                case 2:
+                    viewCtrl = [[[AdvancedBookmarkEditorController alloc] initWithBookmark:_bookmark] autorelease];
+                    break;
+                default:
+                    break;
+            }            
+            
+            break;
+        }            
+    }
+
+    // display view
+    if(viewCtrl)
+        [[self navigationController] pushViewController:viewCtrl animated:YES];
+}
+
+
+#pragma mark -
+#pragma mark Text Field delegate
+
+- (BOOL)textFieldShouldReturn:(UITextField*)textField
+{
+       [textField resignFirstResponder];
+       return NO;
+}
+
+- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
+{
+       switch(textField.tag)
+       {
+               // update server settings
+               case GET_TAG(SECTION_SERVER, 0):
+                       [_bookmark setLabel:[textField text]];
+                       break;
+
+               case GET_TAG(SECTION_SERVER, 1):
+                       [_params setValue:[textField text] forKey:@"hostname"];
+                       break;
+
+               case GET_TAG(SECTION_SERVER, 2):
+                       [_params setInt:[[textField text] intValue] forKey:@"port"];
+                       break;
+                           
+               default:
+                       break;
+       }
+       return YES;
+}
+
+#pragma mark - UIAlertViewDelegate methods
+
+- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+    // clicked yes?
+    if (buttonIndex == 0)
+    {
+        // cancel bookmark editing and return to previous view controller
+        [[self navigationController] popViewControllerAnimated:YES];        
+    }
+}
+
+#pragma mark -
+#pragma mark Action Handlers
+
+- (void)handleSave:(id)sender
+{
+    // resign any first responder (so that we finish editing any bookmark parameter that might be currently edited)
+    [[self view] endEditing:NO];
+    
+    // verify that bookmark is complete (only for manual bookmarks)
+    if (![_bookmark isKindOfClass:NSClassFromString(@"TSXConnectComputerBookmark")])
+    {
+        if ([[_bookmark label] length] == 0 || [[_params StringForKey:@"hostname"] length] == 0 || [_params intForKey:@"port"] == 0)        
+        {
+            UIAlertView* alertView = [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Cancel without saving?", @"Incomplete bookmark error title") message:NSLocalizedString(@"Press 'Cancel' to abort!\nPress 'Continue' to specify the required fields!", @"Incomplete bookmark error message") delegate:self cancelButtonTitle:NSLocalizedString(@"Cancel", @"Cancel Button") otherButtonTitles:NSLocalizedString(@"Continue", @"Continue Button"), nil] autorelease];
+            [alertView show];    
+            return;
+        }        
+    }        
+    
+    // commit bookmark
+    if ([[self delegate] respondsToSelector:@selector(commitBookmark:)])
+        [[self delegate] commitBookmark:_bookmark];
+    
+    // return to previous view controller
+    [[self navigationController] popViewControllerAnimated:YES];
+}
+
+- (void)handleCancel:(id)sender
+{
+    // return to previous view controller
+    [[self navigationController] popViewControllerAnimated:YES];    
+}
+
+#pragma mark -
+#pragma mark Memory management
+
+- (void)didReceiveMemoryWarning {
+    // Releases the view if it doesn't have a superview.
+    [super didReceiveMemoryWarning];
+    
+    // Relinquish ownership any cached data, images, etc that aren't in use.
+}
+
+- (void)dealloc {
+    [super dealloc];
+    [_bookmark autorelease];
+}
+
+
+@end
+
diff --git a/client/iOS/Controllers/BookmarkListController.h b/client/iOS/Controllers/BookmarkListController.h
new file mode 100644 (file)
index 0000000..a8a046e
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ bookmarks and active session view controller
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import <UIKit/UIKit.h>
+#import "Bookmark.h"
+#import "BookmarkTableCell.h"
+#import "SessionTableCell.h"
+#import "BookmarkEditorController.h"
+#import "Reachability.h"
+
+@interface BookmarkListController : UIViewController <UISearchBarDelegate, UITableViewDelegate, UITableViewDataSource, UIAlertViewDelegate, BookmarkEditorDelegate>
+{      
+       // custom bookmark and session table cells
+       BookmarkTableCell* _bmTableCell;
+    SessionTableCell* _sessTableCell;
+
+       // child views
+       UISearchBar* _searchBar;
+       UITableView* _tableView;
+   
+       // array with search results (or nil if no search active)
+       NSMutableArray* _manual_search_result;
+       NSMutableArray* _tsxconnect_search_result;   
+    NSMutableArray* _history_search_result;
+
+    // bookmark arrays
+    NSMutableArray* _manual_bookmarks;
+    NSMutableArray* _tsxconnect_bookmarks;
+    
+    // bookmark star images
+    UIImage* _star_on_img;
+    UIImage* _star_off_img;
+    
+    // array with active sessions
+    NSMutableArray* _active_sessions;
+    
+    // array with connection history entries
+    NSMutableArray* _connection_history;
+    
+    // temporary bookmark when asking if the user wants to store a bookmark for a session initiated by a quick connect
+    ComputerBookmark* _temporary_bookmark;
+    
+    // reachability notification helper for tsx connect
+    Reachability* _tsxconnect_reachability;
+}
+
+@property (nonatomic, retain) IBOutlet UISearchBar* searchBar;
+@property (nonatomic, retain) IBOutlet UITableView* tableView;
+@property (nonatomic, retain) IBOutlet BookmarkTableCell* bmTableCell;
+@property (nonatomic, retain) IBOutlet SessionTableCell* sessTableCell;
+
+
+@end
diff --git a/client/iOS/Controllers/BookmarkListController.m b/client/iOS/Controllers/BookmarkListController.m
new file mode 100644 (file)
index 0000000..27a5081
--- /dev/null
@@ -0,0 +1,839 @@
+/*
+ bookmarks and active session view controller
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "BookmarkListController.h"
+#import "Utils.h"
+#import "BookmarkEditorController.h"
+#import "RDPSessionViewController.h"
+#import "Toast+UIView.h"
+#import "Reachability.h"
+
+#define SECTION_SESSIONS    0
+#define SECTION_BOOKMARKS   1
+#define NUM_SECTIONS        2
+
+@interface BookmarkListController (Private)
+#pragma mark misc functions
+- (UIButton*)disclosureButtonWithImage:(UIImage*)image;
+- (void)performSearch:(NSString*)searchText;
+#pragma mark Persisting bookmarks
+- (void)scheduleWriteBookmarksToDataStore;
+- (void)writeBookmarksToDataStore;
+- (void)scheduleWriteManualBookmarksToDataStore;
+- (void)writeManualBookmarksToDataStore;
+- (void)readManualBookmarksFromDataStore;
+- (void)writeArray:(NSArray*)bookmarks toDataStoreURL:(NSURL*)url;
+- (NSMutableArray*)arrayFromDataStoreURL:(NSURL*)url;
+- (NSURL*)manualBookmarksDataStoreURL;
+- (NSURL*)connectionHistoryDataStoreURL;
+@end
+
+
+@implementation BookmarkListController
+
+@synthesize searchBar = _searchBar, tableView = _tableView, bmTableCell = _bmTableCell, sessTableCell = _sessTableCell;
+
+ // The designated initializer.  Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
+- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
+    if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) 
+       {   
+        // load bookmarks
+        [self readManualBookmarksFromDataStore];
+
+        // load connection history
+        [self readConnectionHistoryFromDataStore];
+        
+               // init search result array
+               _manual_search_result = nil;            
+        
+        // register for session notifications
+        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sessionDisconnected:) name:TSXSessionDidDisconnectNotification object:nil];
+        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sessionFailedToConnect:) name:TSXSessionDidFailToConnectNotification object:nil];
+                
+        // set title and tabbar controller image
+        [self setTitle:NSLocalizedString(@"Connections", @"'Connections': bookmark controller title")];
+        [self setTabBarItem:[[UITabBarItem alloc] initWithTabBarSystemItem:UITabBarSystemItemBookmarks tag:0]];
+
+        // load images
+        _star_on_img = [[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"icon_accessory_star_on" ofType:@"png"]] retain];
+        _star_off_img = [[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"icon_accessory_star_off" ofType:@"png"]] retain];
+
+        // init reachability detection
+        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityChanged:) name:kReachabilityChangedNotification object:nil];
+        
+        // init other properties
+        _active_sessions = [[NSMutableArray alloc] init];
+        _temporary_bookmark = nil;
+    }
+    return self;
+}
+
+- (void)loadView
+{
+    [super loadView];    
+}
+
+// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
+- (void)viewDidLoad {
+    [super viewDidLoad];        
+    
+    // set edit button to allow bookmark list editing
+    [[self navigationItem] setRightBarButtonItem:[self editButtonItem]];
+    
+/*
+    if (![[InAppPurchaseManager sharedInAppPurchaseManager] isProVersion])
+        [[self navigationItem] setLeftBarButtonItem:[[UIBarButtonItem alloc] initWithTitle:@"Go Pro" style:UIBarButtonItemStyleDone target:self action:@selector(goProButtonPressed:)]];
+*/
+}
+
+
+- (void)viewWillAppear:(BOOL)animated 
+{
+       [super viewWillAppear:animated];
+    
+    // in case we had a search - search again cause the bookmark searchable items could have changed
+    if ([[_searchBar text] length] > 0)
+        [self performSearch:[_searchBar text]];
+
+    // to reflect any bookmark changes - reload table
+    [_tableView reloadData];
+}
+
+- (void)viewWillDisappear:(BOOL)animated
+{
+    [super viewWillDisappear:animated];
+    
+    // clear any search
+    [_searchBar setText:@""];
+    [_searchBar resignFirstResponder];
+    [self performSearch:@""];
+}
+
+// Override to allow orientations other than the default portrait orientation.
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
+    // Return YES for supported orientations
+    return YES;
+}
+
+
+- (void)didReceiveMemoryWarning {
+    // Releases the view if it doesn't have a superview.
+    [super didReceiveMemoryWarning];
+    
+    // Release any cached data, images, etc that aren't in use.
+}
+
+- (void)viewDidUnload {
+    [super viewDidUnload];
+    // Release any retained subviews of the main view.
+    // e.g. self.myOutlet = nil;
+}
+
+
+- (void)dealloc 
+{         
+    [_tsxconnect_reachability stopNotifier];
+    [_tsxconnect_reachability release];
+
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+
+    [_temporary_bookmark release];
+    [_connection_history release];
+    [_active_sessions release];
+       [_tsxconnect_search_result release];
+       [_manual_search_result release];
+    [_manual_bookmarks release];
+    [_tsxconnect_bookmarks release];
+
+    [super dealloc];
+}
+
+
+#pragma mark -
+#pragma mark Table view data source
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
+    // Return the number of sections.
+       return NUM_SECTIONS;
+}
+
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+       
+       switch(section)
+       {
+        case SECTION_SESSIONS:
+            return 0;
+            break;
+            
+               case SECTION_BOOKMARKS:
+                       {
+                               // (+1 for Add Bookmark entry)
+                               if(_manual_search_result != nil)
+                                       return ([_manual_search_result count] + [_history_search_result count] + 1);
+                               return ([_manual_bookmarks count] + 1);
+                       }
+                       break;  
+                       
+               default:
+                       break;
+       }
+       return 0;
+}
+
+- (UITableViewCell*)cellForGenericListEntry
+{
+    static NSString *CellIdentifier = @"BookmarkListCell";
+    UITableViewCell *cell = [[self tableView] dequeueReusableCellWithIdentifier:CellIdentifier];
+    if(cell == nil)
+    {
+        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
+        [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
+        [cell setAccessoryView:[self disclosureButtonWithImage:_star_off_img]];                        
+    }
+
+    return cell;
+}
+
+- (BookmarkTableCell*)cellForBookmark
+{
+    static NSString *BookmarkCellIdentifier = @"BookmarkCell";   
+    BookmarkTableCell *cell = (BookmarkTableCell*)[[self tableView] dequeueReusableCellWithIdentifier:BookmarkCellIdentifier];
+    if(cell == nil) 
+    {
+        [[NSBundle mainBundle] loadNibNamed:@"BookmarkTableViewCell" owner:self options:nil];
+        [_bmTableCell setAccessoryView:[self disclosureButtonWithImage:_star_on_img]];                        
+        cell = _bmTableCell;
+        _bmTableCell = nil;
+    }
+    
+    return cell;
+}
+
+// Customize the appearance of table view cells.
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+
+
+    switch ([indexPath section])
+    {
+        case SECTION_SESSIONS:
+        {
+            // get custom session cell
+            static NSString *SessionCellIdentifier = @"SessionCell";
+            SessionTableCell *cell = (SessionTableCell*)[tableView dequeueReusableCellWithIdentifier:SessionCellIdentifier];
+            if(cell == nil) 
+            {
+                [[NSBundle mainBundle] loadNibNamed:@"SessionTableViewCell" owner:self options:nil];
+                cell = _sessTableCell;
+                _sessTableCell = nil;
+            }
+            
+            // set cell data
+            RDPSession* session = [_active_sessions objectAtIndex:[indexPath row]];        
+            [[cell title] setText:[session sessionName]];
+            [[cell server] setText:[[session params] StringForKey:@"hostname"]];
+            if([[[cell server] text] length] == 0)
+                [[cell server] setText:@"TSX Connect"];
+            [[cell username] setText:[[session params] StringForKey:@"username"]];
+            [[cell screenshot] setImage:[session getScreenshotWithSize:[[cell screenshot] bounds].size]];
+            [[cell disconnectButton] setTag:[indexPath row]];        
+            return cell;
+        }
+            
+        case SECTION_BOOKMARKS:
+        {
+            // special handling for first cell - quick connect/quick create Bookmark cell
+            if([indexPath row] == 0)
+            {                
+                // if a search text is entered the cell becomes a quick connect/quick create bookmark cell - otherwise it's just an add bookmark cell
+                UITableViewCell* cell = [self cellForGenericListEntry];
+                if ([[_searchBar text] length] == 0)
+                {
+                    [[cell textLabel] setText:[@"  " stringByAppendingString:NSLocalizedString(@"Add Connection", @"'Add Connection': button label")]];
+                    [((UIButton*)[cell accessoryView]) setHidden:YES];
+                }
+                else
+                {
+                    [[cell textLabel] setText:[@"  " stringByAppendingString:[_searchBar text]]];            
+                    [((UIButton*)[cell accessoryView]) setHidden:NO];
+                }
+                
+                return cell;
+            }
+            else            
+            {
+                // do we have a history cell or bookmark cell?
+                if ([self isIndexPathToHistoryItem:indexPath])
+                {
+                    UITableViewCell* cell = [self cellForGenericListEntry];
+                    [[cell textLabel] setText:[@"  " stringByAppendingString:[_history_search_result objectAtIndex:[self historyIndexFromIndexPath:indexPath]]]];
+                    [((UIButton*)[cell accessoryView]) setHidden:NO];                    
+                    return cell;
+                }
+                else
+                {
+                    // set cell properties
+                    ComputerBookmark* entry;
+                    BookmarkTableCell* cell = [self cellForBookmark];
+                    if(_manual_search_result == nil)
+                        entry = [_manual_bookmarks objectAtIndex:[self bookmarkIndexFromIndexPath:indexPath]];
+                    else
+                        entry = [[_manual_search_result objectAtIndex:[self bookmarkIndexFromIndexPath:indexPath]] valueForKey:@"bookmark"];
+                    
+                    [[cell title] setText:[entry label]];
+                    [[cell subTitle] setText:[[entry params] StringForKey:@"hostname"]];
+                    return cell;                
+                }                
+            }            
+        }
+            
+        default:
+            break;
+    }
+    
+    NSAssert(0, @"Failed to create cell");
+    return nil;        
+}
+
+
+
+// Override to support conditional editing of the table view.
+- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
+       // dont allow to edit Add Bookmark item
+    if([indexPath section] == SECTION_SESSIONS)
+        return NO;
+    if([indexPath section] == SECTION_BOOKMARKS && [indexPath row] == 0)
+               return NO;
+    return YES;
+}
+
+
+
+ // Override to support editing the table view.
+ - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
+{
+       if(editingStyle == UITableViewCellEditingStyleDelete) 
+       {
+               // Delete the row from the data source
+               switch([indexPath section])
+               {
+            case SECTION_BOOKMARKS:
+            {
+                if (_manual_search_result == nil)
+                    [_manual_bookmarks removeObjectAtIndex:[self bookmarkIndexFromIndexPath:indexPath]];
+                else
+                {
+                    // history item or bookmark?
+                    if ([self isIndexPathToHistoryItem:indexPath])
+                    {
+                        [_connection_history removeObject:[_history_search_result objectAtIndex:[self historyIndexFromIndexPath:indexPath]]];
+                        [_history_search_result removeObjectAtIndex:[self historyIndexFromIndexPath:indexPath]];
+                    }                    
+                    else
+                    {
+                        [_manual_bookmarks removeObject:[[_manual_search_result objectAtIndex:[self bookmarkIndexFromIndexPath:indexPath]] valueForKey:@"bookmark"]];
+                        [_manual_search_result removeObjectAtIndex:[self bookmarkIndexFromIndexPath:indexPath]];
+                    }                    
+                }
+                [self scheduleWriteManualBookmarksToDataStore];
+                break;
+            }                
+               }
+
+               [tableView reloadSections:[NSIndexSet indexSetWithIndex:[indexPath section]] withRowAnimation:UITableViewRowAnimationNone];
+       }   
+}
+
+
+// Override to support rearranging the table view.
+- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath 
+{
+       if([fromIndexPath compare:toIndexPath] != NSOrderedSame)
+       {
+               switch([fromIndexPath section])
+               {
+            case SECTION_BOOKMARKS:
+            {
+                int fromIdx = [self bookmarkIndexFromIndexPath:fromIndexPath];
+                int toIdx = [self bookmarkIndexFromIndexPath:toIndexPath];
+                ComputerBookmark* temp_bookmark = [[_manual_bookmarks objectAtIndex:fromIdx] retain];
+                [_manual_bookmarks removeObjectAtIndex:fromIdx];
+                if (toIdx >= [_manual_bookmarks count])
+                    [_manual_bookmarks addObject:temp_bookmark];
+                else
+                    [_manual_bookmarks insertObject:temp_bookmark atIndex:toIdx];
+                [temp_bookmark release];
+                
+                [self scheduleWriteManualBookmarksToDataStore];
+                break;
+            }
+               }
+       }
+}
+
+
+// prevent that an item is moved befoer the Add Bookmark item
+-(NSIndexPath*)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
+{
+    // don't allow to move:
+    //  - items between sections
+    //  - the quick connect/quick create bookmark cell
+    //  - any item while a search is applied
+    if([proposedDestinationIndexPath row] == 0 || ([sourceIndexPath section] != [proposedDestinationIndexPath section]) || 
+       _manual_search_result != nil || _tsxconnect_search_result != nil)
+    {
+        return sourceIndexPath;
+    }
+    else
+    {
+        return proposedDestinationIndexPath;
+    }
+}
+
+
+// Override to support conditional rearranging of the table view.
+- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
+       // dont allow to reorder Add Bookmark item
+    if([indexPath section] == SECTION_BOOKMARKS && [indexPath row] == 0)
+               return NO;
+    return YES;
+}
+
+- (NSString*)tableView:(UITableView*)tableView titleForHeaderInSection:(NSInteger)section
+{
+       if(section == SECTION_SESSIONS && [_active_sessions count] > 0)
+               return NSLocalizedString(@"My Sessions", @"'My Session': section sessions header");
+       if(section == SECTION_BOOKMARKS)
+               return NSLocalizedString(@"Manual Connections", @"'Manual Connections': section manual bookmarks header");
+       return nil;
+}
+
+- (NSString*)tableView:(UITableView*)tableView titleForFooterInSection:(NSInteger)section
+{
+       return nil;
+}
+
+- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
+{
+    if([indexPath section] == SECTION_SESSIONS)
+        return 72;
+    return [tableView rowHeight];
+}
+
+#pragma mark -
+#pragma mark Table view delegate
+
+- (void)setEditing:(BOOL)editing animated:(BOOL)animated
+{
+    [super setEditing:editing animated:animated];
+    [[self tableView] setEditing:editing animated:animated];
+}
+
+- (void)accessoryButtonTapped:(UIControl*)button withEvent:(UIEvent*)event
+{
+    // forward a tap on our custom accessory button to the real accessory button handler
+    NSIndexPath* indexPath = [[self tableView] indexPathForRowAtPoint:[[[event touchesForView:button] anyObject] locationInView:[self tableView]]];
+    if (indexPath == nil)
+        return;
+    
+    [[[self tableView] delegate] tableView:[self tableView] accessoryButtonTappedForRowWithIndexPath:indexPath];
+}
+
+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
+{    
+    if([indexPath section] == SECTION_SESSIONS)
+    {
+        // resume session
+        RDPSession* session = [_active_sessions objectAtIndex:[indexPath row]];
+        UIViewController* ctrl = [[RDPSessionViewController alloc] initWithNibName:@"RDPSessionView" bundle:nil session:session];
+        [ctrl setHidesBottomBarWhenPushed:YES];
+        [[self navigationController] pushViewController:ctrl animated:YES];
+    }
+       else
+       {
+               ComputerBookmark* bookmark = nil;
+               if([indexPath section] == SECTION_BOOKMARKS)
+               {
+            // first row has either quick connect or add bookmark item
+            if([indexPath row] == 0)
+            {
+                if ([[_searchBar text] length] == 0)
+                {                    
+                    // show add bookmark controller
+                    BookmarkEditorController* bookmarkEditorController = [[[BookmarkEditorController alloc] initWithBookmark:[[ComputerBookmark alloc] initWithBaseDefaultParameters]] autorelease];
+                    [bookmarkEditorController setTitle:NSLocalizedString(@"Add Connection", @"Add Connection title")];
+                    [bookmarkEditorController setDelegate:self];
+                    [bookmarkEditorController setHidesBottomBarWhenPushed:YES];
+                    [[self navigationController] pushViewController:bookmarkEditorController animated:YES];
+                }
+                else
+                {
+                    // create a quick connect bookmark and add an entry to the quick connect history (if not already in the history)
+                    bookmark = [self bookmarkForQuickConnectTo:[_searchBar text]];     
+                    if (![_connection_history containsObject:[_searchBar text]])
+                    {
+                        [_connection_history addObject:[_searchBar text]];
+                        [self scheduleWriteConnectionHistoryToDataStore];                        
+                    }
+                }
+            }
+            else
+            {
+                if(_manual_search_result != nil)
+                {
+                    if ([self isIndexPathToHistoryItem:indexPath])
+                    {
+                        // create a quick connect bookmark for a history item
+                        NSString* item = [_history_search_result objectAtIndex:[self historyIndexFromIndexPath:indexPath]];
+                        bookmark = [self bookmarkForQuickConnectTo:item];
+                    }
+                    else
+                        bookmark = [[_manual_search_result objectAtIndex:[self bookmarkIndexFromIndexPath:indexPath]] valueForKey:@"bookmark"];                    
+                }
+                else
+                    bookmark = [_manual_bookmarks objectAtIndex:[self bookmarkIndexFromIndexPath:indexPath]]; // -1 because of ADD BOOKMARK entry
+            }
+            
+            // set reachability status
+            WakeUpWWAN();
+            [bookmark setConntectedViaWLAN:[[Reachability reachabilityWithHostName:[[bookmark params] StringForKey:@"hostname"]] currentReachabilityStatus] == ReachableViaWiFi];            
+               }
+               
+               if(bookmark != nil)
+               {                   
+                       // create rdp session
+            RDPSession* session = [[[RDPSession alloc] initWithBookmark:bookmark] autorelease];
+            UIViewController* ctrl = [[RDPSessionViewController alloc] initWithNibName:@"RDPSessionView" bundle:nil session:session];
+            [ctrl setHidesBottomBarWhenPushed:YES];
+            [[self navigationController] pushViewController:ctrl animated:YES];
+            [_active_sessions addObject:session];
+        }
+       }
+}
+
+
+- (void)tableView:(UITableView*)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath*)indexPath
+{    
+       // get the bookmark
+    NSString* bookmark_editor_title = NSLocalizedString(@"Edit Connection", @"Edit Connection title");
+       ComputerBookmark* bookmark = nil;
+       if ([indexPath section] == SECTION_BOOKMARKS)
+       {
+        if ([indexPath row] == 0)
+        {
+            // create a new bookmark and init hostname and label
+            bookmark = [self bookmarkForQuickConnectTo:[_searchBar text]];     
+            bookmark_editor_title = NSLocalizedString(@"Add Connection", @"Add Connection title");
+        }
+        else
+        {
+            if (_manual_search_result != nil)
+            {
+                if ([self isIndexPathToHistoryItem:indexPath])
+                {
+                    // create a new bookmark and init hostname and label
+                    NSString* item = [_history_search_result objectAtIndex:[self historyIndexFromIndexPath:indexPath]];
+                    bookmark = [self bookmarkForQuickConnectTo:item];     
+                    bookmark_editor_title = NSLocalizedString(@"Add Connection", @"Add Connection title");
+                }
+                else
+                    bookmark = [[_manual_search_result objectAtIndex:[self bookmarkIndexFromIndexPath:indexPath]] valueForKey:@"bookmark"];
+            }
+            else
+                bookmark = [_manual_bookmarks objectAtIndex:[self bookmarkIndexFromIndexPath:indexPath]];      // -1 because of ADD BOOKMARK entry
+        }
+       }
+
+    // bookmark found? - start the editor
+       if (bookmark != nil)
+       {
+               BookmarkEditorController* editBookmarkController = [[[BookmarkEditorController alloc] initWithBookmark:bookmark] autorelease];
+        [editBookmarkController setHidesBottomBarWhenPushed:YES];
+        [editBookmarkController setTitle:bookmark_editor_title];
+        [editBookmarkController setDelegate:self];
+               [[self navigationController] pushViewController:editBookmarkController animated:YES];   
+       }
+}
+
+#pragma mark -
+#pragma mark Search Bar Delegates
+
+- (BOOL)searchBarShouldBeginEditing:(UISearchBar*)searchBar
+{
+       // show cancel button
+       [searchBar setShowsCancelButton:YES animated:YES];
+       return YES;
+}
+
+- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
+{
+       // clear search result
+       [_tsxconnect_search_result release];
+       _tsxconnect_search_result = nil;
+       [_manual_search_result release];
+       _manual_search_result = nil;
+       
+       // clear text and remove cancel button
+       [searchBar setText:@""];
+       [searchBar resignFirstResponder];
+}
+
+- (BOOL)searchBarShouldEndEditing:(UISearchBar*)searchBar
+{      
+       [searchBar setShowsCancelButton:NO animated:YES];
+       
+       // re-enable table selection
+       [_tableView setAllowsSelection:YES];
+       
+       return YES;
+}
+
+- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
+{
+       [_searchBar resignFirstResponder];
+}
+
+- (void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)searchText
+{
+    [self performSearch:searchText];
+       [_tableView reloadData];
+}
+
+#pragma mark - Session handling
+
+// session was added
+- (void)sessionDisconnected:(NSNotification*)notification
+{
+    // remove session from active sessions
+    RDPSession* session = (RDPSession*)[notification object];
+    [_active_sessions removeObject:session];
+
+    // if this view is currently active refresh tsxconnect entries
+    if([[self navigationController] visibleViewController] == self)
+        [_tableView reloadSections:[NSIndexSet indexSetWithIndex:SECTION_SESSIONS] withRowAnimation:UITableViewRowAnimationNone];      
+    
+    // if session's bookmark is not in the bookmark list ask the user if he wants to add it
+    // (this happens if the session is created using the quick connect feature)
+    if (![[session bookmark] isKindOfClass:NSClassFromString(@"TSXConnectComputerBookmark")] &&  
+        ![_manual_bookmarks containsObject:[session bookmark]])
+    {
+        // retain the bookmark in case we want to save it later
+        _temporary_bookmark = [[session bookmark] retain];
+        
+        // ask the user if he wants to save the bookmark
+        NSString* title = NSLocalizedString(@"Save Connection Settings?", @"Save connection settings title");
+        NSString* message = NSLocalizedString(@"Your Connection Settings have not been saved. Do you want to save them?", @"Save connection settings message");
+        UIAlertView* alert = [[UIAlertView alloc] initWithTitle:title message:message delegate:self 
+                                              cancelButtonTitle:NSLocalizedString(@"Yes", @"Yes Button") otherButtonTitles:NSLocalizedString(@"No", @"No Button"), nil];
+        [alert show];
+    }
+}
+
+- (void)sessionFailedToConnect:(NSNotification*)notification
+{
+    // remove session from active sessions
+    RDPSession* session = (RDPSession*)[notification object];
+    [_active_sessions removeObject:session];    
+    
+    // display error toast
+    [[self view] makeToast:NSLocalizedString(@"Failed to connect to session!", @"Failed to connect error message") duration:ToastDurationNormal position:@"center"];
+}
+
+#pragma mark - UIAlertView delegates 
+
+- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+    // yes clicked?
+    if (buttonIndex == 0 && _temporary_bookmark)
+    {        
+        [_manual_bookmarks addObject:_temporary_bookmark];
+        [_tableView reloadSections:[NSIndexSet indexSetWithIndex:SECTION_BOOKMARKS] withRowAnimation:UITableViewRowAnimationNone];
+    }
+    
+    [_temporary_bookmark autorelease];
+    _temporary_bookmark = nil;
+}
+
+#pragma mark - Reachability notification
+- (void)reachabilityChanged:(NSNotification*)notification
+{
+    // no matter how the network changed - we will disconnect
+    // disconnect session (if there is any)
+    if ([_active_sessions count] > 0)
+    {
+        RDPSession* session = [_active_sessions objectAtIndex:0];
+        [session disconnect];
+    }
+}
+
+#pragma mark - BookmarkEditorController delegate
+
+- (void)commitBookmark:(ComputerBookmark *)bookmark
+{
+    // if we got a manual bookmark that is not in the list yet - add it
+    if (![_manual_bookmarks containsObject:bookmark])
+        [_manual_bookmarks addObject:bookmark];
+        
+    // remove any quick connect history entry with the same hostname
+    NSString* hostname = [[bookmark params] StringForKey:@"hostname"];
+    if ([_connection_history containsObject:hostname])
+    {
+        [_connection_history removeObject:hostname];
+        [self scheduleWriteConnectionHistoryToDataStore];
+    }
+        
+    [self scheduleWriteManualBookmarksToDataStore];
+}
+
+- (IBAction)disconnectButtonPressed:(id)sender
+{
+    // disconnect session and refresh table view
+    RDPSession* session = [_active_sessions objectAtIndex:[sender tag]];
+    [session disconnect];
+}
+
+#pragma mark - Misc functions
+
+- (BOOL)hasNoBookmarks
+{
+    return ([_manual_bookmarks count] == 0 && [_tsxconnect_bookmarks count] == 0);
+}
+
+- (UIButton*)disclosureButtonWithImage:(UIImage*)image
+{
+    // we make the button a little bit bigger (image widht * 2, height + 10) so that the user doesn't accidentally connect to the bookmark ...
+    UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];  
+    [button setFrame:CGRectMake(0, 0, [image size].width * 2, [image size].height + 10)];
+    [button setImage:image forState:UIControlStateNormal];
+    [button addTarget:self action:@selector(accessoryButtonTapped:withEvent:) forControlEvents:UIControlEventTouchUpInside];    
+    [button setUserInteractionEnabled:YES];
+    return button;
+}
+
+- (void)performSearch:(NSString*)searchText
+{
+    [_manual_search_result autorelease];
+    [_tsxconnect_search_result autorelease];
+    
+       if([searchText length] > 0)
+       {
+               _manual_search_result = [FilterBookmarks(_manual_bookmarks, [searchText componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]) retain];
+               _tsxconnect_search_result = [FilterBookmarks(_tsxconnect_bookmarks, [searchText componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]) retain];        
+        _history_search_result = [FilterHistory(_connection_history, searchText) retain];
+    }
+       else
+       {
+        _history_search_result = nil;
+               _tsxconnect_search_result = nil;
+               _manual_search_result = nil;
+       }    
+}
+
+- (int)bookmarkIndexFromIndexPath:(NSIndexPath*)indexPath
+{
+    return [indexPath row] - ((_history_search_result != nil) ? [_history_search_result count] : 0) - 1;
+}
+
+- (int)historyIndexFromIndexPath:(NSIndexPath*)indexPath
+{
+    return [indexPath row] - 1;
+}
+
+- (BOOL)isIndexPathToHistoryItem:(NSIndexPath*)indexPath
+{
+    return (([indexPath row] - 1) < [_history_search_result count]);
+}
+
+- (ComputerBookmark*)bookmarkForQuickConnectTo:(NSString*)host
+{
+    ComputerBookmark* bookmark = [[[ComputerBookmark alloc] initWithBaseDefaultParameters] autorelease];
+    [bookmark setLabel:host]; 
+    [[bookmark params] setValue:host forKey:@"hostname"];                
+    return bookmark;
+}
+
+#pragma mark - Persisting bookmarks
+
+- (void)scheduleWriteBookmarksToDataStore
+{
+       [[NSOperationQueue mainQueue] addOperationWithBlock:^{
+               [self writeBookmarksToDataStore];
+       }];
+}
+
+- (void)writeBookmarksToDataStore
+{    
+    [self writeManualBookmarksToDataStore];
+}
+
+- (void)scheduleWriteManualBookmarksToDataStore
+{
+       [[NSOperationQueue mainQueue] addOperation:[[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(writeManualBookmarksToDataStore) object:nil] autorelease]];
+}
+
+- (void)writeManualBookmarksToDataStore
+{    
+    [self writeArray:_manual_bookmarks toDataStoreURL:[self manualBookmarksDataStoreURL]];
+}
+
+- (void)scheduleWriteConnectionHistoryToDataStore
+{
+       [[NSOperationQueue mainQueue] addOperation:[[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(writeConnectionHistoryToDataStore) object:nil] autorelease]];
+}
+
+- (void)writeConnectionHistoryToDataStore
+{    
+    [self writeArray:_connection_history toDataStoreURL:[self connectionHistoryDataStoreURL]];
+}
+
+- (void)writeArray:(NSArray*)bookmarks toDataStoreURL:(NSURL*)url
+{
+       NSData* archived_data = [NSKeyedArchiver archivedDataWithRootObject:bookmarks];
+       [archived_data writeToURL:url atomically:YES];    
+}
+
+- (void)readManualBookmarksFromDataStore
+{
+    [_manual_bookmarks autorelease];
+    _manual_bookmarks = [self arrayFromDataStoreURL:[self manualBookmarksDataStoreURL]];
+
+    if(_manual_bookmarks == nil)
+        _manual_bookmarks = [[NSMutableArray alloc] init];
+}
+
+- (void)readConnectionHistoryFromDataStore
+{
+    [_connection_history autorelease];
+    _connection_history = [self arrayFromDataStoreURL:[self connectionHistoryDataStoreURL]];
+    
+    if(_connection_history == nil)
+        _connection_history = [[NSMutableArray alloc] init];
+}
+
+- (NSMutableArray*)arrayFromDataStoreURL:(NSURL*)url
+{
+       NSData* archived_data = [NSData dataWithContentsOfURL:url];
+       
+       if (!archived_data)
+               return nil;
+    
+       return [[NSKeyedUnarchiver unarchiveObjectWithData:archived_data] retain];
+}
+
+- (NSURL*)manualBookmarksDataStoreURL
+{
+       return [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/%@", [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject], @"com.thinstuff.tsx-rdc-ios.bookmarks.plist"]];
+}
+
+- (NSURL*)connectionHistoryDataStoreURL
+{
+       return [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/%@", [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject], @"com.thinstuff.tsx-rdc-ios.connection_history.plist"]];
+}
+
+@end
+
diff --git a/client/iOS/Controllers/CredentialsEditorController.h b/client/iOS/Controllers/CredentialsEditorController.h
new file mode 100644 (file)
index 0000000..c555eb3
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ Controller to edit bookmark credentials
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "EditorBaseController.h"
+
+@class ComputerBookmark;
+@class ConnectionParams;
+
+@interface CredentialsEditorController : EditorBaseController
+{
+@private
+    ComputerBookmark* _bookmark;
+    ConnectionParams* _params;
+}
+
+// init for the given bookmark
+- (id)initWithBookmark:(ComputerBookmark*)bookmark;
+
+@end
diff --git a/client/iOS/Controllers/CredentialsEditorController.m b/client/iOS/Controllers/CredentialsEditorController.m
new file mode 100644 (file)
index 0000000..21e328a
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ Controller to edit bookmark credentials
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "CredentialsEditorController.h"
+#import "Bookmark.h"
+#import "Utils.h"
+
+@interface CredentialsEditorController ()
+
+@end
+
+#define SECTION_CREDENTIALS 0
+#define SECTION_COUNT 1
+
+@implementation CredentialsEditorController
+
+- (id)initWithBookmark:(ComputerBookmark*)bookmark
+{
+    if ((self = [super initWithStyle:UITableViewStyleGrouped])) 
+       {
+               // set additional settings state according to bookmark data
+               _bookmark = [bookmark retain];
+        _params = [bookmark params];        
+    }
+    return self;
+}
+
+- (void)viewDidLoad
+{
+    [super viewDidLoad];
+    [self setTitle:NSLocalizedString(@"Credentials", @"Credentials title")];
+}
+
+- (void)viewDidUnload
+{
+    [super viewDidUnload];
+    // Release any retained subviews of the main view.
+}
+
+- (void)viewWillDisappear:(BOOL)animated
+{
+    [super viewWillDisappear:animated];
+    
+    // foce any active editing to stop
+    [[self view] endEditing:NO];
+}
+
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
+{
+    return YES;
+}
+
+#pragma mark -
+#pragma mark Table view data source
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
+    // Return the number of sections.
+    return SECTION_COUNT;
+}
+
+
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+    // Return the number of rows in the section.
+       switch (section)
+       {
+               case SECTION_CREDENTIALS: // credentials
+                       return 3;
+               default:
+                       break;
+       }
+       
+    return 0;
+}
+
+
+// set section headers
+- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
+{
+       switch(section)
+       {
+               case SECTION_CREDENTIALS:
+                       return NSLocalizedString(@"Credentials", @"'Credentials': credentials settings header");
+       }
+       return @"unknown";
+}
+
+
+// Customize the appearance of table view cells.
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+    
+       // determine the required cell type
+       NSString* cellType = nil;
+       switch([indexPath section])
+       {
+               case SECTION_CREDENTIALS: // credentials
+                       if([indexPath row] == 1)
+                cellType = TableCellIdentifierSecretText; // password field
+            else
+                cellType = TableCellIdentifierText;
+                       break;
+                        
+        default:
+            break;
+       }       
+       NSAssert(cellType != nil, @"Couldn't determine cell type");     
+       
+       // get the table view cell
+       UITableViewCell *cell = [self tableViewCellFromIdentifier:cellType];
+       NSAssert(cell, @"Invalid cell");        
+    
+       // set cell values
+       switch([indexPath section]) 
+       {                       
+            // credentials
+               case SECTION_CREDENTIALS:
+                       [self initCredentialSettings:indexPath cell:cell];
+                       break;            
+            
+               default:
+                       break;
+       }       
+    
+    return cell;
+}
+
+
+// updates credentials in the UI
+- (void)initCredentialSettings:(NSIndexPath*)indexPath cell:(UITableViewCell*)cell
+{
+       switch(indexPath.row) 
+       {
+               case 0:
+        {
+            EditTextTableViewCell* textCell = (EditTextTableViewCell*)cell;
+            [[textCell textfield] setTag:GET_TAG_FROM_PATH(indexPath)];
+            [[textCell label] setText:NSLocalizedString(@"Username", @"'Username': Bookmark username")];
+                       [[textCell textfield] setText:[_params StringForKey:@"username"]];
+            [[textCell textfield] setPlaceholder:NSLocalizedString(@"not set", @"not set placeholder")];
+                       break;            
+        }
+               case 1:
+        {
+            EditSecretTextTableViewCell* textCell = (EditSecretTextTableViewCell*)cell;
+            [[textCell textfield] setTag:GET_TAG_FROM_PATH(indexPath)];            
+                       [[textCell label] setText:NSLocalizedString(@"Password", @"'Password': Bookmark password")];
+                       [[textCell textfield] setText:[_params StringForKey:@"password"]];
+            [[textCell textfield] setPlaceholder:NSLocalizedString(@"not set", @"not set placeholder")];
+                       break;
+        }
+               case 2:
+        {
+            EditTextTableViewCell* textCell = (EditTextTableViewCell*)cell;
+            [[textCell textfield] setTag:GET_TAG_FROM_PATH(indexPath)];
+                       [[textCell label] setText:NSLocalizedString(@"Domain", @"'Domain': Bookmark domain")];
+                       [[textCell textfield] setText:[_params StringForKey:@"domain"]];
+            [[textCell textfield] setPlaceholder:NSLocalizedString(@"not set", @"not set placeholder")];
+                       break;            
+        }
+               default:
+                       NSLog(@"Invalid row index in settings table!");
+                       break;
+       }    
+}
+
+#pragma mark -
+#pragma mark Text Field delegate
+
+- (BOOL)textFieldShouldReturn:(UITextField*)textField
+{
+       [textField resignFirstResponder];
+       return NO;
+}
+
+- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
+{
+       switch(textField.tag)
+       {            
+            // update credentials settings
+               case GET_TAG(SECTION_CREDENTIALS, 0):
+                       [_params setValue:[textField text] forKey:@"username"];
+                       break;
+                               
+               case GET_TAG(SECTION_CREDENTIALS, 1):
+                       [_params setValue:[textField text] forKey:@"password"];
+                       break;
+
+               case GET_TAG(SECTION_CREDENTIALS, 2):
+                       [_params setValue:[textField text] forKey:@"domain"];
+                       break;
+            
+               default:
+                       break;
+       }
+       return YES;
+}
+
+@end
diff --git a/client/iOS/Controllers/CredentialsInputController.h b/client/iOS/Controllers/CredentialsInputController.h
new file mode 100644 (file)
index 0000000..221cfc1
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ Credentials input controller
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import <UIKit/UIKit.h>
+
+@class RDPSession;
+
+@interface CredentialsInputController : UIViewController
+{
+@private
+    IBOutlet UITextField* _textfield_username;    
+    IBOutlet UITextField* _textfield_password;    
+    IBOutlet UITextField* _textfield_domain;    
+    IBOutlet UIButton* _btn_login;
+    IBOutlet UIButton* _btn_cancel;
+    IBOutlet UIScrollView* _scroll_view;
+    IBOutlet UILabel* _lbl_message;
+    
+    RDPSession* _session;
+    NSMutableDictionary* _params;
+}
+
+- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil session:(RDPSession*)session params:(NSMutableDictionary*)params;
+
+@end
diff --git a/client/iOS/Controllers/CredentialsInputController.m b/client/iOS/Controllers/CredentialsInputController.m
new file mode 100644 (file)
index 0000000..1217d2e
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ Credentials input controller
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "CredentialsInputController.h"
+#import "RDPSession.h"
+#import "Utils.h"
+
+@implementation CredentialsInputController
+
+- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil session:(RDPSession *)session params:(NSMutableDictionary *)params
+{
+    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
+    if (self) {
+        _session = session;
+        _params = params;
+        [self setModalPresentationStyle:UIModalPresentationFormSheet];
+
+        // on iphone we have the problem that the buttons are hidden by the keyboard
+        // we solve this issue by registering keyboard notification handlers and adjusting the scrollview accordingly
+        if (IsPhone())
+        {
+            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name: UIKeyboardWillShowNotification object:nil];
+            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name: UIKeyboardWillHideNotification object:nil];            
+        }
+    }
+    return self;
+}
+
+- (void)viewDidLoad
+{
+    [super viewDidLoad];
+
+    // set localized strings
+    [_lbl_message setText:NSLocalizedString(@"Please provide the missing user information in order to proceed and login.", @"Credentials input view message")];
+    [_textfield_username setPlaceholder:NSLocalizedString(@"Username", @"Credentials Input Username hint")];
+    [_textfield_password setPlaceholder:NSLocalizedString(@"Password", @"Credentials Input Password hint")];
+    [_textfield_domain setPlaceholder:NSLocalizedString(@"Domain", @"Credentials Input Domain hint")];
+    [_btn_login setTitle:NSLocalizedString(@"Login", @"Login Button") forState:UIControlStateNormal];
+    [_btn_cancel setTitle:NSLocalizedString(@"Cancel", @"Cancel Button") forState:UIControlStateNormal];
+
+    // init scrollview content size
+    [_scroll_view setContentSize:[_scroll_view frame].size];
+    
+    // set params in the view
+    [_textfield_username setText:[_params valueForKey:@"username"]];
+    [_textfield_password setText:[_params valueForKey:@"password"]];
+    [_textfield_domain setText:[_params valueForKey:@"domain"]];
+}
+
+- (void)viewDidUnload
+{
+    [super viewDidUnload];
+}
+
+- (void)viewDidDisappear:(BOOL)animated
+{
+    [super viewDidDisappear:animated];
+    // set signal
+    [[_session uiRequestCompleted] signal];    
+}
+
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
+{
+    return YES;
+}
+
+- (void)dealloc
+{
+    [super dealloc];
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+}
+
+#pragma mark -
+#pragma mark iOS Keyboard Notification Handlers
+
+- (void)keyboardWillShow:(NSNotification *)notification
+{   
+       CGRect keyboardEndFrame = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
+    CGRect keyboardFrame = [[self view] convertRect:keyboardEndFrame toView:nil];
+    
+    [UIView beginAnimations:nil context:NULL];
+    [UIView setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
+    [UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
+       CGRect frame = [_scroll_view frame];
+       frame.size.height -=  keyboardFrame.size.height;
+       [_scroll_view setFrame:frame];
+       [UIView commitAnimations];    
+}
+
+- (void)keyboardWillHide:(NSNotification *)notification
+{
+       CGRect keyboardEndFrame = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
+    CGRect keyboardFrame = [[self view] convertRect:keyboardEndFrame toView:nil];
+
+    [UIView beginAnimations:nil context:NULL];
+    [UIView setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
+    [UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
+       CGRect frame = [_scroll_view frame];
+       frame.size.height +=  keyboardFrame.size.height;
+       [_scroll_view setFrame:frame];
+    [UIView commitAnimations];
+}
+
+
+#pragma mark - Action handlers
+
+- (IBAction)loginPressed:(id)sender
+{
+    // read input back in 
+    [_params setValue:[_textfield_username text] forKey:@"username"];
+    [_params setValue:[_textfield_password text] forKey:@"password"];
+    [_params setValue:[_textfield_domain text] forKey:@"domain"];
+    [_params setValue:[NSNumber numberWithBool:YES] forKey:@"result"];
+
+    // dismiss controller
+    [self dismissModalViewControllerAnimated:YES];
+}
+
+- (IBAction)cancelPressed:(id)sender
+{
+    [_params setValue:[NSNumber numberWithBool:NO] forKey:@"result"];
+    
+    // dismiss controller
+    [self dismissModalViewControllerAnimated:YES];
+}
+
+@end
diff --git a/client/iOS/Controllers/EditorBaseController.h b/client/iOS/Controllers/EditorBaseController.h
new file mode 100644 (file)
index 0000000..0fd81bb
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ Basic interface for settings editors
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+
+#import <UIKit/UIKit.h>
+#import "EditTextTableViewCell.h"
+#import "EditFlagTableViewCell.h"
+#import "EditSelectionTableViewCell.h"
+#import "EditSubEditTableViewCell.h"
+#import "EditSecretTextTableViewCell.h"
+#import "EditButtonTableViewCell.h"
+
+extern NSString* TableCellIdentifierText;
+extern NSString* TableCellIdentifierSecretText;
+extern NSString* TableCellIdentifierYesNo;
+extern NSString* TableCellIdentifierSelection;
+extern NSString* TableCellIdentifierSubEditor;
+extern NSString* TableCellIdentifierMultiChoice;
+extern NSString* TableCellIdentifierButton;
+
+@interface EditorBaseController : UITableViewController <UITextFieldDelegate>
+{   
+@private    
+    IBOutlet EditTextTableViewCell* _textTableViewCell;
+    IBOutlet EditSecretTextTableViewCell* _secretTextTableViewCell;
+    IBOutlet EditFlagTableViewCell* _flagTableViewCell;
+    IBOutlet EditSelectionTableViewCell* _selectionTableViewCell;
+    IBOutlet EditSubEditTableViewCell* _subEditTableViewCell;
+    IBOutlet EditButtonTableViewCell* _buttonTableViewCell;
+}
+
+// returns one of the requested table view cells
+- (UITableViewCell*)tableViewCellFromIdentifier:(NSString*)identifier;
+
+// Adjust text input cells label/textfield widht according to the label's text size
+- (void)adjustEditTextTableViewCell:(EditTextTableViewCell*)cell;
+
+@end
diff --git a/client/iOS/Controllers/EditorBaseController.m b/client/iOS/Controllers/EditorBaseController.m
new file mode 100644 (file)
index 0000000..bf29e3d
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ Basic interface for settings editors
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "EditorBaseController.h"
+
+@interface EditorBaseController ()
+
+@end
+
+NSString* TableCellIdentifierText = @"cellIdText";
+NSString* TableCellIdentifierSecretText = @"cellIdSecretText";
+NSString* TableCellIdentifierYesNo = @"cellIdYesNo";
+NSString* TableCellIdentifierSelection = @"cellIdSelection";
+NSString* TableCellIdentifierSubEditor = @"cellIdSubEditor";
+NSString* TableCellIdentifierMultiChoice = @"cellIdMultiChoice";
+NSString* TableCellIdentifierButton = @"cellIdButton";
+
+@implementation EditorBaseController
+
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
+{
+    return YES;
+}
+
+#pragma mark - Create table view cells
+- (UITableViewCell*)tableViewCellFromIdentifier:(NSString*)identifier
+{
+    // try to reuse a cell
+    UITableViewCell* cell = [[self tableView] dequeueReusableCellWithIdentifier:identifier];
+    if (cell != nil)
+        return cell;
+
+    // we have to create a new cell
+    if ([identifier isEqualToString:TableCellIdentifierText])
+    {
+        [[NSBundle mainBundle] loadNibNamed:@"EditTextTableViewCell" owner:self options:nil];        
+        cell = _textTableViewCell;
+        _textTableViewCell = nil;
+    }
+    else if ([identifier isEqualToString:TableCellIdentifierSecretText])
+    {
+        [[NSBundle mainBundle] loadNibNamed:@"EditSecretTextTableViewCell" owner:self options:nil];        
+        cell = _secretTextTableViewCell; 
+        _secretTextTableViewCell = nil;        
+    }
+    else if ([identifier isEqualToString:TableCellIdentifierYesNo])
+    {
+        [[NSBundle mainBundle] loadNibNamed:@"EditFlagTableViewCell" owner:self options:nil];
+        cell = _flagTableViewCell;
+        _flagTableViewCell = nil;
+    }
+    else if ([identifier isEqualToString:TableCellIdentifierSelection])
+    {
+        [[NSBundle mainBundle] loadNibNamed:@"EditSelectionTableViewCell" owner:self options:nil];
+        cell = _selectionTableViewCell;
+        _selectionTableViewCell = nil;
+    }
+    else if ([identifier isEqualToString:TableCellIdentifierSubEditor])
+    {
+        [[NSBundle mainBundle] loadNibNamed:@"EditSubEditTableViewCell" owner:self options:nil];
+        cell = _subEditTableViewCell;
+        _subEditTableViewCell = nil;
+    }
+    else if ([identifier isEqualToString:TableCellIdentifierButton])
+    {
+        [[NSBundle mainBundle] loadNibNamed:@"EditButtonTableViewCell" owner:self options:nil];
+        cell = _buttonTableViewCell;
+        _buttonTableViewCell = nil;
+    }
+    else if ([identifier isEqualToString:TableCellIdentifierMultiChoice])
+    {
+        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:identifier] autorelease];
+    }
+    else
+    {
+        NSAssert(false, @"Unknown table cell identifier");
+    }
+        
+    return cell;
+}
+
+#pragma mark - Utility functions
+- (void)adjustEditTextTableViewCell:(EditTextTableViewCell*)cell
+{
+    UILabel* label = [cell label];
+    UITextField* textField = [cell textfield];
+    
+    // adjust label
+    CGFloat width = [[label text] sizeWithFont:[label font]].width;
+    CGRect frame = [label frame];
+    CGFloat delta = width - frame.size.width;
+    frame.size.width = width;
+    [label setFrame:frame];
+    
+    // adjust text field
+    frame = [textField frame];
+    frame.origin.x += delta;
+    frame.size.width -= delta;
+    [textField setFrame:frame];
+}
+
+@end
diff --git a/client/iOS/Controllers/EditorSelectionController.h b/client/iOS/Controllers/EditorSelectionController.h
new file mode 100644 (file)
index 0000000..81225a9
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ Generic controller to select a single item from a list of options
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "EditorBaseController.h"
+
+@class ConnectionParams;
+
+@interface EditorSelectionController : EditorBaseController
+{
+    ConnectionParams* _params;
+
+    // array with entries in connection parameters that are altered
+    NSArray* _entries;
+
+    // array with dictionaries containing label/value pairs that represent the available values for each entry
+    NSArray* _selections;    
+       
+    // current selections
+    NSMutableArray* _cur_selections;
+}
+
+- (id)initWithConnectionParams:(ConnectionParams*)params entries:(NSArray*)entries selections:(NSArray*)selections;
+
+@end
diff --git a/client/iOS/Controllers/EditorSelectionController.m b/client/iOS/Controllers/EditorSelectionController.m
new file mode 100644 (file)
index 0000000..84d5e87
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ Generic controller to select a single item from a list of options
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "EditorSelectionController.h"
+#import "ConnectionParams.h"
+#import "OrderedDictionary.h"
+
+@interface EditorSelectionController (Private)
+- (OrderedDictionary*)selectionForIndex:(int)index;
+@end
+
+@implementation EditorSelectionController
+
+- (id)initWithConnectionParams:(ConnectionParams*)params entries:(NSArray *)entries selections:(NSArray *)selections
+{
+    self = [super initWithStyle:UITableViewStyleGrouped];
+    if (self)
+    {
+        _params = [params retain];
+        _entries = [entries retain];
+        _selections = [selections retain];
+        
+        // allocate and init current selections array
+        _cur_selections = [[NSMutableArray alloc] initWithCapacity:[_entries count]];        
+        for (int i = 0; i < [entries count]; ++i)
+        {
+            NSString* entry = [entries objectAtIndex:i];            
+            if([_params hasValueForKeyPath:entry])
+            {
+                NSUInteger idx = [(OrderedDictionary*)[selections objectAtIndex:i] indexForValue:[NSNumber numberWithInt:[_params intForKeyPath:entry]]];
+                [_cur_selections addObject:[NSNumber numberWithInt:(idx != NSNotFound ? idx : 0)]];
+            }
+            else
+                [_cur_selections addObject:[NSNumber numberWithInt:0]];
+        }
+    }
+    return self;
+}
+
+- (void)didReceiveMemoryWarning
+{
+    // Releases the view if it doesn't have a superview.
+    [super didReceiveMemoryWarning];
+    
+    // Release any cached data, images, etc that aren't in use.
+    [_params autorelease];
+    [_entries autorelease];
+    [_selections autorelease];    
+    [_cur_selections autorelease];
+}
+
+#pragma mark - View lifecycle
+
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
+{
+    // Return YES for supported orientations
+    return YES;
+}
+
+#pragma mark - Table view data source
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
+{
+    // Return the number of sections.
+    return [_entries count];
+}
+
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
+{
+    // Return the number of rows in the section.
+    return [[self selectionForIndex:section] count];
+}
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
+{
+    UITableViewCell *cell = [self tableViewCellFromIdentifier:TableCellIdentifierMultiChoice];
+    
+    // get selection
+    OrderedDictionary* selection = [self selectionForIndex:[indexPath section]];
+    
+    // set cell properties
+       [[cell textLabel] setText:[selection keyAtIndex:[indexPath row]]];
+       
+       // set default checkmark
+       if([indexPath row] == [[_cur_selections objectAtIndex:[indexPath section]] intValue])
+               [cell setAccessoryType:UITableViewCellAccessoryCheckmark];
+       else
+               [cell setAccessoryType:UITableViewCellAccessoryNone];
+       
+    return cell;
+}
+
+#pragma mark - Table view delegate
+
+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
+{
+       // has selection change?
+    int cur_selection = [[_cur_selections objectAtIndex:[indexPath section]] intValue];
+       if([indexPath row] != cur_selection)
+       {
+               [tableView deselectRowAtIndexPath:indexPath animated:NO];
+               
+               NSIndexPath* oldIndexPath = [NSIndexPath indexPathForRow:cur_selection inSection:[indexPath section]];
+        
+               // clear old checkmark
+               UITableViewCell* old_sel_cell = [tableView cellForRowAtIndexPath:oldIndexPath];
+               old_sel_cell.accessoryType = UITableViewCellAccessoryNone;
+        
+               // set new checkmark
+               UITableViewCell* new_sel_cell = [tableView cellForRowAtIndexPath:indexPath];
+               new_sel_cell.accessoryType = UITableViewCellAccessoryCheckmark;
+
+        // get value from selection dictionary
+        OrderedDictionary* dict = [self selectionForIndex:[indexPath section]];
+        int sel_value = [[dict valueForKey:[dict keyAtIndex:[indexPath row]]] intValue];
+
+               // update selection index and params value
+        [_cur_selections replaceObjectAtIndex:[indexPath section] withObject:[NSNumber numberWithInt:[indexPath row]]];
+        [_params setInt:sel_value forKeyPath:[_entries objectAtIndex:[indexPath section]]];
+    }    
+}
+
+#pragma mark - Convenience functions
+
+- (OrderedDictionary*)selectionForIndex:(int)index
+{
+    return (OrderedDictionary*)[_selections objectAtIndex:index];
+}
+
+@end
diff --git a/client/iOS/Controllers/EncryptionController.h b/client/iOS/Controllers/EncryptionController.h
new file mode 100644 (file)
index 0000000..1ce197e
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ Password Encryption Controller
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Dorian Johnson
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import <Foundation/Foundation.h>
+#import "Encryptor.h"
+
+@interface EncryptionController : NSObject
+{
+       Encryptor* _shared_encryptor;
+}
+
++ (EncryptionController*)sharedEncryptionController;
+
+// Return a Encryptor suitable for encrypting or decrypting with the master password
+- (Encryptor*)decryptor;
+- (Encryptor*)encryptor;
+
+@end
diff --git a/client/iOS/Controllers/EncryptionController.m b/client/iOS/Controllers/EncryptionController.m
new file mode 100644 (file)
index 0000000..089e87a
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ Password Encryption Controller
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Dorian Johnson
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "EncryptionController.h"
+#import "SFHFKeychainUtils.h"
+
+@interface EncryptionController (Private)
+
+- (BOOL)verifyPassword:(Encryptor*)decryptor;
+- (NSData*)encryptedVerificationData;
+- (void)setEncryptedVerificationData:(Encryptor*)encryptor;
+
+- (NSString*)keychainServerName;
+- (NSString*)keychainUsername;
+- (void)setKeychainPassword:(NSString*)password;
+- (NSString*)keychainPassword;
+- (NSString*)keychainDefaultPassword;
+
+@end
+
+static EncryptionController* _shared_encryption_controller = nil;
+
+
+#pragma mark -
+
+@implementation EncryptionController
+
++ (EncryptionController*)sharedEncryptionController
+{
+       @synchronized(self)
+       {
+               if (_shared_encryption_controller == nil)
+                       _shared_encryption_controller = [[EncryptionController alloc] init];            
+       }
+       
+       return _shared_encryption_controller;   
+}
+
+#pragma mark Getting an encryptor or decryptor
+
+- (Encryptor*)encryptor
+{
+       if (_shared_encryptor)
+               return _shared_encryptor;
+       
+       NSString* saved_password = [self keychainPassword];    
+       if (saved_password == nil)
+    {
+        saved_password = [self keychainDefaultPassword];        
+        Encryptor* encryptor = [[[Encryptor alloc] initWithPassword:saved_password] autorelease];
+        [self setEncryptedVerificationData:encryptor];        
+        _shared_encryptor = [encryptor retain];
+    }
+    else
+    {
+        Encryptor* encryptor = [[[Encryptor alloc] initWithPassword:saved_password] autorelease];
+        if ([self verifyPassword:encryptor])
+            _shared_encryptor = [encryptor retain];
+    }    
+    
+    return _shared_encryptor;
+}
+
+// For the current implementation, decryptors and encryptors are equivilant.
+- (Encryptor*)decryptor { return [self encryptor]; }
+
+@end
+
+#pragma mark -
+
+@implementation EncryptionController (Private)
+
+#pragma mark -
+#pragma mark Keychain password storage
+
+- (NSString*)keychainServerName
+{
+       return [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
+}
+
+- (NSString*)keychainUsername
+{
+       return @"master.password";
+}
+
+- (void)setKeychainPassword:(NSString*)password
+{      
+    NSError* error;
+       if (password == nil)
+       {
+        [SFHFKeychainUtils deleteItemForUsername:[self keychainUsername] andServerName:[self keychainServerName] error:&error];
+               return;
+       }
+
+       [SFHFKeychainUtils storeUsername:[self keychainUsername] andPassword:password forServerName:[self keychainServerName] updateExisting:YES error:&error];
+}
+
+- (NSString*)keychainPassword
+{
+    NSError* error;
+    return [SFHFKeychainUtils getPasswordForUsername:[self keychainUsername] andServerName:[self keychainServerName] error:&error];
+}
+
+- (NSString*)keychainDefaultPassword
+{
+    return [[UIDevice currentDevice] uniqueIdentifier];
+}
+
+#pragma mark -
+#pragma mark Verification of encryption key against verification data
+
+- (BOOL)verifyPassword:(Encryptor*)decryptor 
+{
+       return [[decryptor plaintextPassword] isEqualToString:[decryptor decryptString:[self encryptedVerificationData]]];
+}
+
+- (NSData*)encryptedVerificationData
+{
+       return [[NSUserDefaults standardUserDefaults] dataForKey:@"TSXMasterPasswordVerification"];
+}
+
+- (void)setEncryptedVerificationData:(Encryptor*)encryptor
+{
+       [[NSUserDefaults standardUserDefaults] setObject:[encryptor encryptString:[encryptor plaintextPassword]] forKey:@"TSXMasterPasswordVerification"];
+}
+
+@end
diff --git a/client/iOS/Controllers/HelpController.h b/client/iOS/Controllers/HelpController.h
new file mode 100644 (file)
index 0000000..ad3cfe7
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ Application help controller
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import <UIKit/UIKit.h>
+
+@interface HelpController : UIViewController <UIWebViewDelegate>
+{
+       UIWebView* webView;    
+}
+@end
diff --git a/client/iOS/Controllers/HelpController.m b/client/iOS/Controllers/HelpController.m
new file mode 100644 (file)
index 0000000..61a05a4
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ Application help controller
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "HelpController.h"
+#import "Utils.h"
+
+@implementation HelpController
+
+- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
+{
+    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
+    if (self) {
+               // set title and tab-bar image
+               [self setTitle:NSLocalizedString(@"Help", @"Help Controller title")];
+        UIImage* tabBarIcon = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"tabbar_icon_help" ofType:@"png"]];
+        [self setTabBarItem:[[UITabBarItem alloc] initWithTitle:NSLocalizedString(@"Help", @"Tabbar item help") image:tabBarIcon tag:0]];
+    }
+    return self;
+}
+
+// Implement loadView to create a view hierarchy programmatically, without using a nib.
+- (void)loadView 
+{
+       webView = [[[UIWebView alloc] initWithFrame:CGRectZero] autorelease];
+       [webView setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];
+       [webView setAutoresizesSubviews:YES];
+       [webView setDelegate:self];     
+       [webView setDataDetectorTypes:UIDataDetectorTypeNone];  
+       [self setView:webView];
+}
+
+- (void)dealloc {
+    [super dealloc];
+}
+
+// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
+- (void)viewDidLoad 
+{
+    [super viewDidLoad];
+       
+    NSString *filename = (IsPhone() ? @"gestures_phone" : @"gestures");
+       NSString *htmlString = [[[NSString alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:filename ofType:@"html" inDirectory:@"help_page"]  encoding:NSUTF8StringEncoding error:nil] autorelease];
+       
+       [webView loadHTMLString:htmlString baseURL:[NSURL fileURLWithPath:[[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"help_page"]]];    
+}
+
+// Override to allow orientations other than the default portrait orientation.
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
+    return YES;
+}
+
+#pragma mark -
+#pragma mark UIWebView callbacks
+- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
+{      
+       if([[request URL] isFileURL])
+               return YES;
+       
+       if(navigationType == UIWebViewNavigationTypeLinkClicked)
+       {
+               NSString* lastClickedLink = [[request URL] absoluteString];
+               UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"External Link"
+                                                                                                               message:[NSString stringWithFormat:@"Open [%@] in Browser?", lastClickedLink]
+                                                                                                          delegate:self 
+                                                                                         cancelButtonTitle:@"OK" 
+                                                                                         otherButtonTitles:@"No", nil];
+               [alert show];
+               [alert release];
+               
+               return NO;
+       }
+       return YES;
+}
+
+@end
diff --git a/client/iOS/Controllers/MainTabBarController.h b/client/iOS/Controllers/MainTabBarController.h
new file mode 100644 (file)
index 0000000..796c1fa
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ main tabbar controller
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import <Foundation/Foundation.h>
+
+
+@interface MainTabBarController : UITabBarController {
+    
+}
+
+@end
diff --git a/client/iOS/Controllers/MainTabBarController.m b/client/iOS/Controllers/MainTabBarController.m
new file mode 100644 (file)
index 0000000..613f53b
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ main tabbar controller
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "MainTabBarController.h"
+
+
+@implementation MainTabBarController
+
+-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
+{
+    return YES;
+}
+
+@end
diff --git a/client/iOS/Controllers/PerformanceEditorController.h b/client/iOS/Controllers/PerformanceEditorController.h
new file mode 100644 (file)
index 0000000..4d09ee6
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ controller for performance settings selection
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "EditorBaseController.h"
+
+@class ConnectionParams;
+
+@interface PerformanceEditorController : EditorBaseController
+{
+@private
+    ConnectionParams* _params;
+    NSString* _keyPath;
+}
+
+- (id)initWithConnectionParams:(ConnectionParams*)params;
+- (id)initWithConnectionParams:(ConnectionParams*)params keyPath:(NSString*)keyPath;
+
+@end
diff --git a/client/iOS/Controllers/PerformanceEditorController.m b/client/iOS/Controllers/PerformanceEditorController.m
new file mode 100644 (file)
index 0000000..104b13c
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ controller for performance settings selection
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "PerformanceEditorController.h"
+#import "ConnectionParams.h"
+#import "Utils.h"
+
+@interface PerformanceEditorController (Private)
+-(NSString*)keyPathForKey:(NSString*)key;
+@end
+
+@implementation PerformanceEditorController
+
+- (id)initWithConnectionParams:(ConnectionParams*)params
+{
+    return [self initWithConnectionParams:params keyPath:nil];
+}
+
+- (id)initWithConnectionParams:(ConnectionParams*)params keyPath:(NSString*)keyPath;
+{
+    self = [super initWithStyle:UITableViewStyleGrouped];
+    if (self) {
+        _params = [params retain];
+        _keyPath = (keyPath != nil ? [keyPath retain] : nil);
+    }
+    return self;
+}
+
+- (void)viewDidLoad
+{
+    [super viewDidLoad];
+       // Do any additional setup after loading the view.
+}
+
+- (void)viewDidUnload
+{
+    [super viewDidUnload];
+    // Release any retained subviews of the main view.
+}
+
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
+{
+    return YES;
+}
+
+-(NSString*)keyPathForKey:(NSString*)key
+{
+    if (_keyPath)
+        return [_keyPath stringByAppendingFormat:@".%@", key];
+    return key;
+}
+
+#pragma mark -
+#pragma mark Table view data source
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
+    // Return the number of sections.
+    return 1;
+}
+
+
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+    return 7;
+}
+
+
+// set section headers
+- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
+{
+       return NSLocalizedString(@"Performance Settings", @"'Performance Settings': performance settings header");
+}
+
+// Customize the appearance of table view cells.
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+    
+    // get the table view cell
+       EditFlagTableViewCell *cell = (EditFlagTableViewCell*)[self tableViewCellFromIdentifier:TableCellIdentifierYesNo];
+       NSAssert(cell, @"Invalid cell");        
+    
+    switch ([indexPath row])
+    {
+        case 0:
+        {
+            [[cell label] setText:NSLocalizedString(@"RemoteFX", @"RemoteFX performance setting")];
+            [[cell toggle] setOn:[_params boolForKeyPath:[self keyPathForKey:@"perf_remotefx"]]];
+            break;
+        }
+
+        case 1:
+        {
+            [[cell label] setText:NSLocalizedString(@"Desktop Background", @"Desktop background performance setting")];
+            [[cell toggle] setOn:[_params boolForKeyPath:[self keyPathForKey:@"perf_show_desktop"]]];
+            break;
+        }
+
+        case 2:
+        {
+            [[cell label] setText:NSLocalizedString(@"Font Smoothing", @"Font smoothing performance setting")];
+            [[cell toggle] setOn:[_params boolForKeyPath:[self keyPathForKey:@"perf_font_smoothing"]]];
+            break;
+        }
+            
+        case 3:
+        {
+            [[cell label] setText:NSLocalizedString(@"Desktop Composition", @"Desktop composition performance setting")];
+            [[cell toggle] setOn:[_params boolForKeyPath:[self keyPathForKey:@"perf_desktop_composition"]]];
+            break;
+        }            
+            
+        case 4:
+        {
+            [[cell label] setText:NSLocalizedString(@"Window contents while dragging", @"Window Dragging performance setting")];
+            [[cell toggle] setOn:[_params boolForKeyPath:[self keyPathForKey:@"perf_window_dragging"]]];
+            break;
+        }
+            
+        case 5:
+        {
+            [[cell label] setText:NSLocalizedString(@"Menu Animation", @"Menu Animations performance setting")];
+            [[cell toggle] setOn:[_params boolForKeyPath:[self keyPathForKey:@"perf_menu_animation"]]];
+            break;
+        }
+
+        case 6:
+        {
+            [[cell label] setText:NSLocalizedString(@"Visual Styles", @"Use Themes performance setting")];
+            [[cell toggle] setOn:[_params boolForKeyPath:[self keyPathForKey:@"perf_windows_themes"]]];
+            break;
+        }
+
+        default:
+            break;
+    }
+    
+    [[cell toggle] setTag:GET_TAG_FROM_PATH(indexPath)];
+    [[cell toggle] addTarget:self action:@selector(togglePerformanceSetting:) forControlEvents:UIControlEventValueChanged];
+    return cell;
+}
+
+#pragma mark -
+#pragma mark Action Handlers
+
+- (void)togglePerformanceSetting:(id)sender
+{
+    UISwitch* valueSwitch = (UISwitch*)sender;
+    switch(valueSwitch.tag)
+    {
+        case GET_TAG(0, 0):
+            [_params setBool:[valueSwitch isOn] forKeyPath:[self keyPathForKey:@"perf_remotefx"]];
+            break;
+
+        case GET_TAG(0, 1):
+            [_params setBool:[valueSwitch isOn] forKeyPath:[self keyPathForKey:@"perf_show_desktop"]];
+            break;
+            
+        case GET_TAG(0, 2):
+            [_params setBool:[valueSwitch isOn] forKeyPath:[self keyPathForKey:@"perf_font_smoothing"]];
+            break;
+            
+        case GET_TAG(0, 3):
+            [_params setBool:[valueSwitch isOn] forKeyPath:[self keyPathForKey:@"perf_desktop_composition"]];
+            break;
+
+        case GET_TAG(0, 4):
+            [_params setBool:[valueSwitch isOn] forKeyPath:[self keyPathForKey:@"perf_window_dragging"]];
+            break;
+            
+        case GET_TAG(0, 5):
+            [_params setBool:[valueSwitch isOn] forKeyPath:[self keyPathForKey:@"perf_menu_animation"]];
+            break;
+
+        case GET_TAG(0, 6):
+            [_params setBool:[valueSwitch isOn] forKeyPath:[self keyPathForKey:@"perf_windows_themes"]];
+            break;
+
+        default:
+            break;
+    }    
+}
+
+@end
diff --git a/client/iOS/Controllers/RDPSessionViewController.h b/client/iOS/Controllers/RDPSessionViewController.h
new file mode 100644 (file)
index 0000000..52502bf
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ RDP Session View Controller
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import <UIKit/UIKit.h>
+#import "RDPSession.h"
+#import "RDPKeyboard.h"
+#import "RDPSessionView.h"
+#import "TouchPointerView.h"
+#import "AdvancedKeyboardView.h"
+
+@interface RDPSessionViewController : UIViewController <RDPSessionDelegate, TouchPointerDelegate, AdvancedKeyboardDelegate, RDPKeyboardDelegate, UIScrollViewDelegate, UITextFieldDelegate, UIAlertViewDelegate>
+{
+       // scrollview that hosts the rdp session view
+       IBOutlet UIScrollView* _session_scrollview;
+       
+       // rdp session view
+       IBOutlet RDPSessionView* _session_view;
+
+    // touch pointer view
+    IBOutlet TouchPointerView* _touchpointer_view;
+    BOOL _autoscroll_with_touchpointer;
+    BOOL _is_autoscrolling;
+
+       // rdp session toolbar
+       IBOutlet UIToolbar* _session_toolbar;
+    BOOL _session_toolbar_visible;
+       
+       // dummy text field used to display the keyboard
+       IBOutlet UITextField* _dummy_textfield;
+       
+    // connecting view and the controls within that view
+    IBOutlet UIView* _connecting_view;
+    IBOutlet UILabel* _lbl_connecting;
+    IBOutlet UIActivityIndicatorView* _connecting_indicator_view;
+    IBOutlet UIButton* _cancel_connect_button;
+    
+    // extended keyboard toolbar
+    UIToolbar* _keyboard_toolbar;
+    
+    // rdp session
+    RDPSession* _session;
+    BOOL _session_initilized;
+    
+       // flag that indicates whether the keyboard is visible or not
+       BOOL _keyboard_visible;
+    
+    // flag to switch between left/right mouse button mode
+    BOOL _toggle_mouse_button;
+    
+    // keyboard extension view
+    AdvancedKeyboardView* _advanced_keyboard_view;
+    BOOL _advanced_keyboard_visible;
+    BOOL _requesting_advanced_keyboard;
+    
+    // delayed mouse move event sending
+    NSTimer* _mouse_move_event_timer;
+    int _mouse_move_events_skipped;
+    CGPoint _prev_long_press_position;
+}
+
+- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil session:(RDPSession*)session;
+
+@end
diff --git a/client/iOS/Controllers/RDPSessionViewController.m b/client/iOS/Controllers/RDPSessionViewController.m
new file mode 100644 (file)
index 0000000..08dbe75
--- /dev/null
@@ -0,0 +1,980 @@
+/*
+ RDP Session View Controller
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import <QuartzCore/QuartzCore.h>
+#import "RDPSessionViewController.h"
+#import "RDPKeyboard.h"
+#import "Utils.h"
+#import "Toast+UIView.h"
+#import "ConnectionParams.h"
+#import "CredentialsInputController.h"
+#import "VerifyCertificateController.h"
+
+#define TOOLBAR_HEIGHT 30
+
+#define AUTOSCROLLDISTANCE 20
+#define AUTOSCROLLTIMEOUT 0.05
+
+@interface RDPSessionViewController (Private)
+-(void)showSessionToolbar:(BOOL)show;
+-(UIToolbar*)keyboardToolbar;
+-(void)initGestureRecognizers;
+- (void)suspendSession;
+- (NSDictionary*)eventDescriptorForMouseEvent:(int)event position:(CGPoint)position;
+- (void)handleMouseMoveForPosition:(CGPoint)position;
+@end
+
+
+@implementation RDPSessionViewController
+
+#pragma mark class methods
+
+- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil session:(RDPSession *)session
+{
+    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
+    if (self) 
+    {
+        _session = [session retain];
+        [_session setDelegate:self];
+        _session_initilized = NO;
+        
+        _mouse_move_events_skipped = 0;
+        _mouse_move_event_timer = nil;
+
+        _advanced_keyboard_view = nil;
+        _advanced_keyboard_visible = NO;
+        _requesting_advanced_keyboard = NO;    
+
+        _session_toolbar_visible = NO;
+        
+        _toggle_mouse_button = NO;
+        
+        _autoscroll_with_touchpointer = [[NSUserDefaults standardUserDefaults] boolForKey:@"ui.auto_scroll_touchpointer"];
+        _is_autoscrolling = NO;
+        
+        [UIView setAnimationDelegate:self];
+        [UIView setAnimationDidStopSelector:@selector(animationStopped:finished:context:)];
+    }
+    
+    return self;
+}
+
+// Implement loadView to create a view hierarchy programmatically, without using a nib.
+- (void)loadView 
+{
+       // load default view and set background color and resizing mask
+       [super loadView];
+
+    // init keyboard handling vars and register required notification handlers
+    _keyboard_visible = NO;
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name: UIKeyboardWillShowNotification object:nil];
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name: UIKeyboardDidShowNotification object:nil];
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name: UIKeyboardWillHideNotification object:nil];     
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidHide:) name: UIKeyboardDidHideNotification object:nil];
+
+    // init keyboard toolbar
+    _keyboard_toolbar = [[self keyboardToolbar] retain];
+    [_dummy_textfield setInputAccessoryView:_keyboard_toolbar];
+    
+    // init gesture recognizers
+    [self initGestureRecognizers];
+    
+    // hide session toolbar
+    [_session_toolbar setFrame:CGRectMake(0.0, -TOOLBAR_HEIGHT, [[self view] bounds].size.width, TOOLBAR_HEIGHT)];
+}
+
+
+// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
+- (void)viewDidLoad 
+{
+    [super viewDidLoad];
+}
+
+
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
+    return YES;
+}
+
+- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
+{
+    if (![_touchpointer_view isHidden])
+        [_touchpointer_view ensurePointerIsVisible];
+}
+
+- (void)didReceiveMemoryWarning {
+    // Releases the view if it doesn't have a superview.
+    [super didReceiveMemoryWarning];
+    
+    // Release any cached data, images, etc. that aren't in use.
+}
+
+- (void)viewDidUnload {
+    [super viewDidUnload];
+    // Release any retained subviews of the main view.
+    // e.g. self.myOutlet = nil;
+}
+
+- (void)viewWillAppear:(BOOL)animated 
+{
+       [super viewWillAppear:animated];
+
+    // hide navigation bar and (if enabled) the status bar
+    if ([[NSUserDefaults standardUserDefaults] boolForKey:@"ui.hide_status_bar"])
+    {
+        if(animated == YES)
+            [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
+        else
+            [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
+    }
+    [[self navigationController] setNavigationBarHidden:YES animated:animated];        
+       
+    // if sesssion is suspended - notify that we got a new bitmap context
+    if ([_session isSuspended]) 
+        [self sessionBitmapContextWillChange:_session];
+
+    // init keyboard
+    [[RDPKeyboard getSharedRDPKeyboard] initWithSession:_session delegate:self];
+}
+
+- (void)viewDidAppear:(BOOL)animated
+{
+       [super viewDidAppear:animated];
+        
+    if (!_session_initilized)
+    {
+        if ([_session isSuspended]) 
+        {
+            [_session resume];
+            [self sessionBitmapContextDidChange:_session];
+            [_session_view setNeedsDisplay];
+        }
+        else
+            [_session connect];
+        
+        _session_initilized = YES;
+    }
+}
+
+- (void)viewWillDisappear:(BOOL)animated 
+{
+    [super viewWillDisappear:animated];
+
+    // show navigation and status bar again
+       if(animated == YES)
+               [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide];
+       else
+               [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];
+       [[self navigationController] setNavigationBarHidden:NO animated:animated];
+       
+    // reset all modifier keys on rdp keyboard
+    [[RDPKeyboard getSharedRDPKeyboard] reset];
+    
+       // hide toolbar and keyboard
+    [self showSessionToolbar:NO];
+       [_dummy_textfield resignFirstResponder];
+}
+
+
+- (void)dealloc {
+    // remove any observers
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+    
+    // the session lives on longer so set the delegate to nil
+    [_session setDelegate:nil];
+
+    [_advanced_keyboard_view release];
+    [_keyboard_toolbar release];
+    [_session release];
+    [super dealloc];
+}
+
+#pragma mark -
+#pragma mark ScrollView delegate methods
+
+- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
+{      
+    return _session_view;      
+}
+
+-(void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale
+{
+    NSLog(@"New zoom scale: %f", scale);
+       [_session_view setNeedsDisplay];
+}
+
+#pragma mark -
+#pragma mark TextField delegate methods
+-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
+{
+       _keyboard_visible = YES;
+    _advanced_keyboard_visible = NO;
+       return YES;
+}
+
+-(BOOL)textFieldShouldEndEditing:(UITextField *)textField
+{
+       _keyboard_visible = NO;
+    _advanced_keyboard_visible = NO;
+       return YES;
+}
+
+- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
+{      
+       if([string length] > 0)
+       {
+               for(int i = 0 ; i < [string length] ; i++)
+               {
+                       NSString *characterTyped = [string substringWithRange:NSMakeRange(i, 1)];
+            unichar curChar = [characterTyped characterAtIndex:0];
+
+            // special handling for return/enter key
+            if(curChar == '\n')
+                [[RDPKeyboard getSharedRDPKeyboard] sendEnterKeyStroke];
+            else
+                [[RDPKeyboard getSharedRDPKeyboard] sendUnicode:curChar];
+               }
+       }
+       else
+       {
+               [[RDPKeyboard getSharedRDPKeyboard] sendBackspaceKeyStroke];
+       }               
+       
+       return NO;
+}
+
+#pragma mark -
+#pragma mark AdvancedKeyboardDelegate functions
+-(void)advancedKeyPressedVKey:(int)key
+{
+    [[RDPKeyboard getSharedRDPKeyboard] sendVirtualKeyCode:key];
+}
+
+-(void)advancedKeyPressedUnicode:(int)key
+{
+    [[RDPKeyboard getSharedRDPKeyboard] sendUnicode:key];
+}
+
+#pragma mark - RDP keyboard handler
+
+- (void)modifiersChangedForKeyboard:(RDPKeyboard *)keyboard
+{
+    UIBarButtonItem* curItem;
+    
+    // shift button (only on iPad)   
+    int objectIdx = 0;
+    if (IsPad())
+    {
+        objectIdx = 2;
+        curItem = (UIBarButtonItem*)[[_keyboard_toolbar items] objectAtIndex:objectIdx];
+        [curItem setStyle:[keyboard shiftPressed] ? UIBarButtonItemStyleDone : UIBarButtonItemStyleBordered];
+    }
+    
+    // ctrl button
+    objectIdx += 2;
+    curItem = (UIBarButtonItem*)[[_keyboard_toolbar items] objectAtIndex:objectIdx];
+    [curItem setStyle:[keyboard ctrlPressed] ? UIBarButtonItemStyleDone : UIBarButtonItemStyleBordered];
+    
+    // win button
+    objectIdx += 2;
+    curItem = (UIBarButtonItem*)[[_keyboard_toolbar items] objectAtIndex:objectIdx];
+    [curItem setStyle:[keyboard winPressed] ? UIBarButtonItemStyleDone : UIBarButtonItemStyleBordered];
+    
+    // alt button
+    objectIdx += 2;
+    curItem = (UIBarButtonItem*)[[_keyboard_toolbar items] objectAtIndex:objectIdx];
+    [curItem setStyle:[keyboard altPressed] ? UIBarButtonItemStyleDone : UIBarButtonItemStyleBordered];    
+}
+
+#pragma mark -
+#pragma mark RDPSessionDelegate functions
+
+- (void)session:(RDPSession*)session didFailToConnect:(int)reason
+{
+    // remove and release connecting view
+    [_connecting_indicator_view stopAnimating];
+    [_connecting_view removeFromSuperview];
+    [_connecting_view autorelease];          
+
+    // return to bookmark list
+    [[self navigationController] popViewControllerAnimated:YES];
+}
+
+- (void)sessionWillConnect:(RDPSession*)session
+{
+    // load connecting view
+    [[NSBundle mainBundle] loadNibNamed:@"RDPConnectingView" owner:self options:nil];
+    
+    // set strings
+    [_lbl_connecting setText:NSLocalizedString(@"Connecting", @"Connecting progress view - label")];
+    [_cancel_connect_button setTitle:NSLocalizedString(@"Cancel", @"Cancel Button") forState:UIControlStateNormal];
+    
+    // center view and give it round corners
+    [_connecting_view setCenter:[[self view] center]];
+    [[_connecting_view layer] setCornerRadius:10];
+
+    // display connecting view and start indicator
+    [[self view] addSubview:_connecting_view];
+    [_connecting_indicator_view startAnimating];
+}
+
+- (void)sessionDidConnect:(RDPSession*)session
+{
+    // remove and release connecting view
+    [_connecting_indicator_view stopAnimating];
+    [_connecting_view removeFromSuperview];
+    [_connecting_view autorelease];   
+    
+    // check if session settings changed ...
+    // The 2nd width check is to ignore changes in resolution settings due to the RDVH display bug (refer to RDPSEssion.m for more details)
+    ConnectionParams* orig_params = [session params];
+    rdpSettings* sess_params = [session getSessionParams];
+    if (([orig_params intForKey:@"width"] != sess_params->DesktopWidth && [orig_params intForKey:@"width"] != (sess_params->DesktopWidth + 1)) ||
+        [orig_params intForKey:@"height"] != sess_params->DesktopHeight || [orig_params intForKey:@"colors"] != sess_params->ColorDepth)
+    {
+        // display notification that the session params have been changed by the server
+        NSString* message = [NSString stringWithFormat:NSLocalizedString(@"The server changed the screen settings to %dx%dx%d", @"Screen settings not supported message with width, height and colors parameter"), sess_params->DesktopWidth, sess_params->DesktopHeight, sess_params->ColorDepth];
+        [[self view] makeToast:message duration:ToastDurationNormal position:@"bottom"];        
+    }
+}
+
+- (void)sessionWillDisconnect:(RDPSession*)session
+{
+
+}
+
+- (void)sessionDidDisconnect:(RDPSession*)session
+{
+    // return to bookmark list
+    [[self navigationController] popViewControllerAnimated:YES];    
+}
+
+- (void)sessionBitmapContextWillChange:(RDPSession*)session
+{
+    // calc new view frame
+    rdpSettings* sess_params = [session getSessionParams];
+    CGRect view_rect = CGRectMake(0, 0, sess_params->DesktopWidth, sess_params->DesktopHeight);
+
+    // reset  zoom level and update content size
+    [_session_scrollview setZoomScale:1.0];
+    [_session_scrollview setContentSize:view_rect.size];
+
+    // set session view size
+    [_session_view setFrame:view_rect];
+    
+    // show/hide toolbar
+    [_session setToolbarVisible:![[NSUserDefaults standardUserDefaults] boolForKey:@"ui.hide_tool_bar"]];
+    [self showSessionToolbar:[_session toolbarVisible]];
+}
+
+- (void)sessionBitmapContextDidChange:(RDPSession*)session
+{
+    // associate view with session
+    [_session_view setSession:session];    
+}
+
+- (void)session:(RDPSession*)session needsRedrawInRect:(CGRect)rect
+{
+    [_session_view setNeedsDisplayInRect:rect];    
+}
+
+- (void)session:(RDPSession *)session requestsAuthenticationWithParams:(NSMutableDictionary *)params
+{
+    CredentialsInputController* view_controller = [[[CredentialsInputController alloc] initWithNibName:@"CredentialsInputView" bundle:nil session:_session params:params] autorelease];
+    [self presentModalViewController:view_controller animated:YES];
+}
+
+- (void)session:(RDPSession *)session verifyCertificateWithParams:(NSMutableDictionary *)params
+{
+    VerifyCertificateController* view_controller = [[[VerifyCertificateController alloc] initWithNibName:@"VerifyCertificateView" bundle:nil session:_session params:params] autorelease];
+    [self presentModalViewController:view_controller animated:YES];
+}
+
+- (CGSize)sizeForFitScreenForSession:(RDPSession*)session
+{
+    if (IsPad())
+        return [self view].bounds.size;
+    else
+    {
+        // on phones make a resolution that has a 16:10 ratio with the phone's height
+        CGSize size = [self view].bounds.size;
+        CGFloat maxSize = (size.width > size.height) ? size.width : size.height;
+        return CGSizeMake(maxSize * 1.6f, maxSize);
+    }
+}
+
+- (void)showGoProScreen:(RDPSession*)session
+{
+    UIAlertView* alertView = [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Pro Version", @"Pro version dialog title") 
+                                                message:NSLocalizedString(@"Do you want to buy Thinstuff RDC Pro and enable the full RDP Experience", @"Pro version dialog message") delegate:self cancelButtonTitle:NSLocalizedString(@"No", @"No Button title") otherButtonTitles:NSLocalizedString(@"Yes", @"Yes button title"), nil] autorelease];
+    [alertView show];
+}
+
+#pragma mark - Keyboard Toolbar Handlers
+
+-(void)showAdvancedKeyboardAnimated
+{
+    // calc initial and final rect of the advanced keyboard view
+    CGRect rect = [[_keyboard_toolbar superview] bounds];    
+    rect.origin.y = [_keyboard_toolbar bounds].size.height;
+    rect.size.height -= rect.origin.y;
+    
+    // create new view (hidden) and add to host-view of keyboard toolbar
+    _advanced_keyboard_view = [[AdvancedKeyboardView alloc] initWithFrame:CGRectMake(rect.origin.x, 
+                                                                                     [[_keyboard_toolbar superview] bounds].size.height, 
+                                                                                     rect.size.width, rect.size.height) delegate:self];
+    [[_keyboard_toolbar superview] addSubview:_advanced_keyboard_view];
+    // we set autoresize to YES for the keyboard toolbar's superview so that our adv. keyboard view gets properly resized
+    [[_keyboard_toolbar superview] setAutoresizesSubviews:YES];
+    
+    // show view with animation
+    [UIView beginAnimations:nil context:NULL];
+    [_advanced_keyboard_view setFrame:rect];
+    [UIView commitAnimations]; 
+}
+
+-(IBAction)toggleKeyboardWhenOtherVisible:(id)sender
+{       
+    if(_advanced_keyboard_visible == NO)
+    {
+        [self showAdvancedKeyboardAnimated];
+    }
+    else
+    {
+        // hide existing view
+        [UIView beginAnimations:@"hide_advanced_keyboard_view" context:NULL];
+        CGRect rect = [_advanced_keyboard_view frame];
+        rect.origin.y = [[_keyboard_toolbar superview] bounds].size.height;
+        [_advanced_keyboard_view setFrame:rect];
+        [UIView commitAnimations];        
+        
+        // the view is released in the animationDidStop selector registered in init
+    }
+    
+    // toggle flag
+    _advanced_keyboard_visible = !_advanced_keyboard_visible;
+}
+
+-(IBAction)toggleWinKey:(id)sender
+{
+    [[RDPKeyboard getSharedRDPKeyboard] toggleWinKey];
+}
+
+-(IBAction)toggleShiftKey:(id)sender
+{
+    [[RDPKeyboard getSharedRDPKeyboard] toggleShiftKey];
+}
+
+-(IBAction)toggleCtrlKey:(id)sender
+{
+    [[RDPKeyboard getSharedRDPKeyboard] toggleCtrlKey];
+}
+
+-(IBAction)toggleAltKey:(id)sender
+{
+    [[RDPKeyboard getSharedRDPKeyboard] toggleAltKey];
+}
+
+-(IBAction)pressEscKey:(id)sender
+{
+    [[RDPKeyboard getSharedRDPKeyboard] sendEscapeKeyStroke];
+}
+
+#pragma mark -
+#pragma mark event handlers
+
+- (void)animationStopped:(NSString*)animationID finished:(NSNumber*)finished context:(void*)context
+{
+    if ([animationID isEqualToString:@"hide_advanced_keyboard_view"])
+    {
+        // cleanup advanced keyboard view
+        [_advanced_keyboard_view removeFromSuperview];
+        [_advanced_keyboard_view autorelease];
+        _advanced_keyboard_view = nil;        
+    }
+}
+
+- (IBAction)switchSession:(id)sender
+{
+    [self suspendSession];
+}
+
+- (IBAction)toggleKeyboard:(id)sender
+{
+       if(!_keyboard_visible)
+               [_dummy_textfield becomeFirstResponder];
+       else
+               [_dummy_textfield resignFirstResponder];
+}
+
+- (IBAction)toggleExtKeyboard:(id)sender
+{
+    // if the sys kb is shown but not the advanced kb then toggle the advanced kb
+    if(_keyboard_visible && !_advanced_keyboard_visible)
+        [self toggleKeyboardWhenOtherVisible:nil];
+    else
+    {
+        // if not visible request the advanced keyboard view
+        if(_advanced_keyboard_visible == NO)
+            _requesting_advanced_keyboard = YES;
+        [self toggleKeyboard:nil];        
+    }    
+}
+
+- (IBAction)toggleTouchPointer:(id)sender
+{
+    BOOL toggle_visibilty = ![_touchpointer_view isHidden];
+    [_touchpointer_view setHidden:toggle_visibilty];
+    if(toggle_visibilty)
+        [_session_scrollview setContentInset:UIEdgeInsetsZero];
+    else
+        [_session_scrollview setContentInset:[_touchpointer_view getEdgeInsets]];
+}
+
+- (IBAction)disconnectSession:(id)sender
+{
+    [_session disconnect];        
+}
+
+
+-(IBAction)cancelButtonPressed:(id)sender
+{
+    [_session disconnect];        
+}
+
+#pragma mark In-App purchase transaction notification handlers
+
+- (void)onTransactionSuccess:(NSNotification*)notification
+{
+    UIAlertView* alertView = [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Transaction Succeeded", @"Pro version bought dialog title") 
+                                                         message:NSLocalizedString(@"Thanks for buying Thinstuff RDC Pro. In order for the purchase to take effect please reconnect your current session.", @"Pro version bought dialog message") delegate:nil cancelButtonTitle:NSLocalizedString(@"OK", @"OK Button title") otherButtonTitles:nil] autorelease];
+    [alertView show];        
+}
+
+- (void)onTransactionFailed:(NSNotification*)notification
+{
+    UIAlertView* alertView = [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Transaction Failed", @"Pro version buy failed dialog title") 
+                                                         message:NSLocalizedString(@"The transaction did not complete successfully!", @"Pro version buy failed dialog message") delegate:nil cancelButtonTitle:NSLocalizedString(@"OK", @"OK Button title") otherButtonTitles:nil] autorelease];
+    [alertView show];            
+}
+
+#pragma mark -
+#pragma mark iOS Keyboard Notification Handlers
+
+- (void)keyboardWillShow:(NSNotification *)notification
+{   
+       CGRect keyboardEndFrame = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
+    
+    [UIView beginAnimations:nil context:NULL];
+    [UIView setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
+    [UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
+       CGRect frame = [_session_scrollview frame];
+       frame.size.height -= [[self view] convertRect:keyboardEndFrame toView:nil].size.height;
+       [_session_scrollview setFrame:frame];
+    [_touchpointer_view setFrame:frame];    
+       [UIView commitAnimations];
+
+    [_touchpointer_view ensurePointerIsVisible];
+}
+
+- (void)keyboardDidShow:(NSNotification *)notification
+{
+    if(_requesting_advanced_keyboard)
+    {
+        [self showAdvancedKeyboardAnimated];
+        _advanced_keyboard_visible = YES;
+        _requesting_advanced_keyboard = NO;
+    }            
+}
+
+- (void)keyboardWillHide:(NSNotification *)notification
+{
+       CGRect keyboardEndFrame = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
+    
+    [UIView beginAnimations:nil context:NULL];
+    [UIView setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
+    [UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
+       CGRect frame = [_session_scrollview frame];
+       frame.size.height += [[self view] convertRect:keyboardEndFrame toView:nil].size.height;
+    [_session_scrollview setFrame:frame];
+    [_touchpointer_view setFrame:frame];
+    [UIView commitAnimations];
+}
+
+- (void)keyboardDidHide:(NSNotification*)notification
+{
+    // release adanced keyboard view
+    if(_advanced_keyboard_visible == YES)
+    {
+        _advanced_keyboard_visible = NO;
+        [_advanced_keyboard_view removeFromSuperview];
+        [_advanced_keyboard_view autorelease];
+        _advanced_keyboard_view = nil;
+    }    
+}
+
+#pragma mark -
+#pragma mark Gesture handlers
+
+- (void)handleSingleTap:(UITapGestureRecognizer*)gesture
+{
+       CGPoint pos = [gesture locationInView:_session_view];
+    if (_toggle_mouse_button)
+    {
+        [_session sendInputEvent:[self eventDescriptorForMouseEvent:GetRightMouseButtonClickEvent(YES) position:pos]]; 
+        [_session sendInputEvent:[self eventDescriptorForMouseEvent:GetRightMouseButtonClickEvent(NO) position:pos]];          
+    }
+    else
+    {
+        [_session sendInputEvent:[self eventDescriptorForMouseEvent:GetLeftMouseButtonClickEvent(YES) position:pos]];  
+        [_session sendInputEvent:[self eventDescriptorForMouseEvent:GetLeftMouseButtonClickEvent(NO) position:pos]];           
+    }
+
+    _toggle_mouse_button = NO;
+}
+
+- (void)handleDoubleTap:(UITapGestureRecognizer*)gesture
+{
+       CGPoint pos = [gesture locationInView:_session_view];   
+    [_session sendInputEvent:[self eventDescriptorForMouseEvent:GetLeftMouseButtonClickEvent(YES) position:pos]];      
+    [_session sendInputEvent:[self eventDescriptorForMouseEvent:GetLeftMouseButtonClickEvent(NO) position:pos]];       
+    [_session sendInputEvent:[self eventDescriptorForMouseEvent:GetLeftMouseButtonClickEvent(YES) position:pos]];      
+    [_session sendInputEvent:[self eventDescriptorForMouseEvent:GetLeftMouseButtonClickEvent(NO) position:pos]];       
+    _toggle_mouse_button = NO;
+}
+
+- (void)handleLongPress:(UILongPressGestureRecognizer*)gesture
+{    
+       CGPoint pos = [gesture locationInView:_session_view];
+    
+       if([gesture state] == UIGestureRecognizerStateBegan) 
+        [_session sendInputEvent:[self eventDescriptorForMouseEvent:GetLeftMouseButtonClickEvent(YES) position:pos]];  
+       else if([gesture state] == UIGestureRecognizerStateChanged)
+        [self handleMouseMoveForPosition:pos];
+       else if([gesture state] == UIGestureRecognizerStateEnded)
+        [_session sendInputEvent:[self eventDescriptorForMouseEvent:GetLeftMouseButtonClickEvent(NO) position:pos]];   
+}
+
+
+- (void)handleDoubleLongPress:(UILongPressGestureRecognizer*)gesture
+{
+    // this point is mapped against the scroll view because we want to have relative movement to the screen/scrollview
+       CGPoint pos = [gesture locationInView:_session_scrollview];
+    
+       if([gesture state] == UIGestureRecognizerStateBegan) 
+        _prev_long_press_position = pos;
+       else if([gesture state] == UIGestureRecognizerStateChanged)
+    {
+        int delta = _prev_long_press_position.y - pos.y;
+        
+        if(delta > GetScrollGestureDelta())
+        {
+            [_session sendInputEvent:[self eventDescriptorForMouseEvent:GetMouseWheelEvent(YES) position:pos]];        
+            _prev_long_press_position = pos;
+        }
+        else if(delta < -GetScrollGestureDelta())
+        {            
+            [_session sendInputEvent:[self eventDescriptorForMouseEvent:GetMouseWheelEvent(NO) position:pos]]; 
+            _prev_long_press_position = pos;
+        }
+    }
+}
+
+-(void)handleSingle2FingersTap:(UITapGestureRecognizer*)gesture
+{
+    _toggle_mouse_button = !_toggle_mouse_button;
+}
+
+-(void)handleSingle3FingersTap:(UITapGestureRecognizer*)gesture
+{
+    [_session setToolbarVisible:![_session toolbarVisible]];
+    [self showSessionToolbar:[_session toolbarVisible]];
+}
+
+#pragma mark -
+#pragma mark Touch Pointer delegates
+// callback if touch pointer should be closed
+-(void)touchPointerClose
+{
+    [self toggleTouchPointer:nil];
+}
+
+// callback for a left click action
+-(void)touchPointerLeftClick:(CGPoint)pos down:(BOOL)down
+{
+    CGPoint session_view_pos = [_touchpointer_view convertPoint:pos toView:_session_view];
+    [_session sendInputEvent:[self eventDescriptorForMouseEvent:GetLeftMouseButtonClickEvent(down) position:session_view_pos]];        
+}
+
+// callback for a right click action
+-(void)touchPointerRightClick:(CGPoint)pos down:(BOOL)down
+{
+    CGPoint session_view_pos = [_touchpointer_view convertPoint:pos toView:_session_view];
+    [_session sendInputEvent:[self eventDescriptorForMouseEvent:GetRightMouseButtonClickEvent(down) position:session_view_pos]];
+}
+
+- (void)doAutoScrolling
+{
+    int scrollX = 0;
+    int scrollY = 0;
+    CGPoint curPointerPos = [_touchpointer_view getPointerPosition];
+    CGRect viewBounds = [_touchpointer_view bounds];
+    CGRect scrollBounds = [_session_view bounds];
+
+    // add content insets to scroll bounds
+    scrollBounds.size.width += [_session_scrollview contentInset].right;
+    scrollBounds.size.height += [_session_scrollview contentInset].bottom;
+    
+    // add zoom factor
+    scrollBounds.size.width *= [_session_scrollview zoomScale];
+    scrollBounds.size.height *= [_session_scrollview zoomScale];
+    
+    if (curPointerPos.x > (viewBounds.size.width - [_touchpointer_view getPointerWidth]))
+        scrollX = AUTOSCROLLDISTANCE;
+    else if (curPointerPos.x < 0)
+        scrollX = -AUTOSCROLLDISTANCE;
+
+    if (curPointerPos.y > (viewBounds.size.height - [_touchpointer_view getPointerHeight]))
+        scrollY = AUTOSCROLLDISTANCE;
+    else if (curPointerPos.y < (_session_toolbar_visible ? TOOLBAR_HEIGHT : 0))
+        scrollY = -AUTOSCROLLDISTANCE;
+
+    CGPoint newOffset = [_session_scrollview contentOffset];
+    newOffset.x += scrollX;
+    newOffset.y += scrollY;
+
+    // if offset is going off screen - stop scrolling in that direction
+    if (newOffset.x < 0)
+    {
+        scrollX = 0;
+        newOffset.x = 0;
+    }
+    else if (newOffset.x > (scrollBounds.size.width - viewBounds.size.width))
+    {
+        scrollX = 0;
+        newOffset.x = MAX(scrollBounds.size.width - viewBounds.size.width, 0);
+    }
+    if (newOffset.y < 0)
+    {
+        scrollY = 0;
+        newOffset.y = 0;
+    }
+    else if (newOffset.y > (scrollBounds.size.height - viewBounds.size.height))
+    {
+        scrollY = 0;
+        newOffset.y = MAX(scrollBounds.size.height - viewBounds.size.height, 0);
+    }
+
+    // perform scrolling
+    [_session_scrollview setContentOffset:newOffset];
+
+    // continue scrolling?
+    if (scrollX != 0 || scrollY != 0)
+        [self performSelector:@selector(doAutoScrolling) withObject:nil afterDelay:AUTOSCROLLTIMEOUT];
+    else
+        _is_autoscrolling = NO;    
+}
+
+// callback for a right click action
+-(void)touchPointerMove:(CGPoint)pos
+{
+    CGPoint session_view_pos = [_touchpointer_view convertPoint:pos toView:_session_view];
+    [self handleMouseMoveForPosition:session_view_pos];
+    
+    if (_autoscroll_with_touchpointer && !_is_autoscrolling)
+    {
+        _is_autoscrolling = YES;
+        [self performSelector:@selector(doAutoScrolling) withObject:nil afterDelay:AUTOSCROLLTIMEOUT];
+    }
+}
+
+// callback if scrolling is performed
+-(void)touchPointerScrollDown:(BOOL)down
+{   
+    [_session sendInputEvent:[self eventDescriptorForMouseEvent:GetMouseWheelEvent(down) position:CGPointZero]];
+}
+
+// callback for toggling the standard keyboard
+-(void)touchPointerToggleKeyboard
+{
+    if(_advanced_keyboard_visible)
+        [self toggleKeyboardWhenOtherVisible:nil];
+    else
+        [self toggleKeyboard:nil];
+}
+
+// callback for toggling the extended keyboard
+-(void)touchPointerToggleExtendedKeyboard
+{
+    [self toggleExtKeyboard:nil];
+}
+
+// callback for reset view
+-(void)touchPointerResetSessionView
+{
+    [_session_scrollview setZoomScale:1.0 animated:YES];
+}
+
+@end
+
+
+@implementation RDPSessionViewController (Private)
+
+#pragma mark -
+#pragma mark Helper functions
+
+-(void)showSessionToolbar:(BOOL)show
+{
+    // already shown or hidden?
+    if (_session_toolbar_visible == show)
+        return;
+    
+    if(show)
+    {
+        [UIView beginAnimations:@"showToolbar" context:nil];
+        [UIView setAnimationDuration:.4];
+        [UIView setAnimationCurve:UIViewAnimationCurveLinear];
+        [_session_toolbar setFrame:CGRectMake(0.0, 0.0, [[self view] bounds].size.width, TOOLBAR_HEIGHT)];
+        [UIView commitAnimations];             
+        _session_toolbar_visible = YES;        
+    }
+    else
+    {
+        [UIView beginAnimations:@"hideToolbar" context:nil];
+        [UIView setAnimationDuration:.4];
+        [UIView setAnimationCurve:UIViewAnimationCurveLinear];
+        [_session_toolbar setFrame:CGRectMake(0.0, -TOOLBAR_HEIGHT, [[self view] bounds].size.width, TOOLBAR_HEIGHT)];
+        [UIView commitAnimations];             
+        _session_toolbar_visible = NO;
+    }
+}
+
+-(UIToolbar*)keyboardToolbar
+{
+       UIToolbar* keyboard_toolbar = [[[UIToolbar alloc] initWithFrame:CGRectNull] autorelease];
+       [keyboard_toolbar setBarStyle:UIBarStyleBlackOpaque];
+    
+       UIBarButtonItem* esc_btn = [[[UIBarButtonItem alloc] initWithTitle:@"Esc" style:UIBarButtonItemStyleBordered target:self action:@selector(pressEscKey:)] autorelease];
+    UIImage* win_icon = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"toolbar_icon_win" ofType:@"png"]];
+       UIBarButtonItem* win_btn = [[[UIBarButtonItem alloc] initWithImage:win_icon style:UIBarButtonItemStyleBordered target:self action:@selector(toggleWinKey:)] autorelease];
+       UIBarButtonItem* ctrl_btn = [[[UIBarButtonItem alloc] initWithTitle:@"Ctrl" style:UIBarButtonItemStyleBordered target:self action:@selector(toggleCtrlKey:)] autorelease];
+       UIBarButtonItem* alt_btn = [[[UIBarButtonItem alloc] initWithTitle:@"Alt" style:UIBarButtonItemStyleBordered target:self action:@selector(toggleAltKey:)] autorelease];
+       UIBarButtonItem* ext_btn = [[[UIBarButtonItem alloc] initWithTitle:@"Ext" style:UIBarButtonItemStyleBordered target:self action:@selector(toggleKeyboardWhenOtherVisible:)] autorelease];
+       UIBarButtonItem* done_btn = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(toggleKeyboard:)] autorelease];
+       UIBarButtonItem* flex_spacer = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil] autorelease];
+    
+    // iPad gets a shift button, iphone doesn't (there's just not enough space ...)
+    NSArray* items;
+    if(IsPad())
+    {
+        UIBarButtonItem* shift_btn = [[[UIBarButtonItem alloc] initWithTitle:@"Shift" style:UIBarButtonItemStyleBordered target:self action:@selector(toggleShiftKey:)] autorelease];
+        items = [NSArray arrayWithObjects:esc_btn, flex_spacer, 
+                 shift_btn, flex_spacer, 
+                 ctrl_btn, flex_spacer, 
+                 win_btn, flex_spacer, 
+                 alt_btn, flex_spacer, 
+                 ext_btn, flex_spacer, done_btn, nil];
+    }
+    else
+    {
+        items = [NSArray arrayWithObjects:esc_btn, flex_spacer, ctrl_btn, flex_spacer, win_btn, flex_spacer, alt_btn, flex_spacer, ext_btn, flex_spacer, done_btn, nil];        
+    }
+    
+       [keyboard_toolbar setItems:items];
+    [keyboard_toolbar sizeToFit];
+    return keyboard_toolbar;
+}
+
+- (void)initGestureRecognizers
+{        
+       // single and double tap recognizer 
+    UITapGestureRecognizer* doubleTapRecognizer = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)] autorelease];
+    [doubleTapRecognizer setNumberOfTouchesRequired:1];
+       [doubleTapRecognizer setNumberOfTapsRequired:2];        
+    
+       UITapGestureRecognizer* singleTapRecognizer = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)] autorelease];
+       [singleTapRecognizer requireGestureRecognizerToFail:doubleTapRecognizer];       
+    [singleTapRecognizer setNumberOfTouchesRequired:1];
+       [singleTapRecognizer setNumberOfTapsRequired:1];
+    
+    // 2 fingers - tap recognizer 
+       UITapGestureRecognizer* single2FingersTapRecognizer = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingle2FingersTap:)] autorelease];
+    [single2FingersTapRecognizer setNumberOfTouchesRequired:2];
+       [single2FingersTapRecognizer setNumberOfTapsRequired:1];
+    
+       // long press gesture recognizer
+       UILongPressGestureRecognizer* longPressRecognizer = [[[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)] autorelease];
+       [longPressRecognizer setMinimumPressDuration:0.5];
+    
+    // double long press gesture recognizer
+       UILongPressGestureRecognizer* doubleLongPressRecognizer = [[[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleLongPress:)] autorelease];
+    [doubleLongPressRecognizer setNumberOfTouchesRequired:2];
+       [doubleLongPressRecognizer setMinimumPressDuration:0.5];
+    
+    // 3 finger, single tap gesture for showing/hiding the toolbar
+    UITapGestureRecognizer* single3FingersTapRecognizer = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingle3FingersTap:)] autorelease];
+    [single3FingersTapRecognizer setNumberOfTapsRequired:1];
+    [single3FingersTapRecognizer setNumberOfTouchesRequired:3];
+    
+    // add gestures to scroll view
+       [_session_scrollview addGestureRecognizer:singleTapRecognizer];
+       [_session_scrollview addGestureRecognizer:doubleTapRecognizer];
+       [_session_scrollview addGestureRecognizer:single2FingersTapRecognizer];
+       [_session_scrollview addGestureRecognizer:longPressRecognizer];
+       [_session_scrollview addGestureRecognizer:doubleLongPressRecognizer];
+    [_session_scrollview addGestureRecognizer:single3FingersTapRecognizer];
+}
+
+- (void)suspendSession
+{
+       // suspend session and pop navigation controller
+    [_session suspend];
+    
+    // pop current view controller
+    [[self navigationController] popViewControllerAnimated:YES];
+}
+
+- (NSDictionary*)eventDescriptorForMouseEvent:(int)event position:(CGPoint)position
+{
+    return [NSDictionary dictionaryWithObjectsAndKeys: 
+                        @"mouse", @"type",
+                        [NSNumber numberWithUnsignedShort:event], @"flags",
+                        [NSNumber numberWithUnsignedShort:lrintf(position.x)], @"coord_x",
+                        [NSNumber numberWithUnsignedShort:lrintf(position.y)], @"coord_y",
+                        nil];
+}
+
+- (void)sendDelayedMouseEventWithTimer:(NSTimer*)timer
+{
+    _mouse_move_event_timer = nil;
+    NSDictionary* event = [timer userInfo];
+    [_session sendInputEvent:event];
+    [timer autorelease];
+}
+
+- (void)handleMouseMoveForPosition:(CGPoint)position
+{
+    NSDictionary* event = [self eventDescriptorForMouseEvent:PTR_FLAGS_MOVE position:position];
+    
+    // cancel pending mouse move events
+    [_mouse_move_event_timer invalidate];
+    _mouse_move_events_skipped++;
+    
+    if (_mouse_move_events_skipped >= 5)
+    {
+        [_session sendInputEvent:event];
+        _mouse_move_events_skipped = 0;
+    }
+    else
+    {
+        [_mouse_move_event_timer autorelease];
+        _mouse_move_event_timer = [[NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(sendDelayedMouseEventWithTimer:) userInfo:event repeats:NO] retain];        
+    }    
+}
+
+@end
diff --git a/client/iOS/Controllers/ScreenSelectionController.h b/client/iOS/Controllers/ScreenSelectionController.h
new file mode 100644 (file)
index 0000000..a972a6c
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ controller for screen settings selection
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "EditorBaseController.h"
+
+@class ConnectionParams;
+@class OrderedDictionary;
+
+@interface ScreenSelectionController : EditorBaseController
+{
+@private
+    NSString* _keyPath;
+    ConnectionParams* _params;    
+    
+    // avaiable options
+    OrderedDictionary* _color_options;
+    NSArray* _resolution_modes;
+
+    // current selections
+    int _selection_color;
+    int _selection_resolution;
+}
+
+- (id)initWithConnectionParams:(ConnectionParams*)params;
+- (id)initWithConnectionParams:(ConnectionParams*)params keyPath:(NSString*)keyPath;
+
+@end
diff --git a/client/iOS/Controllers/ScreenSelectionController.m b/client/iOS/Controllers/ScreenSelectionController.m
new file mode 100644 (file)
index 0000000..e0a553f
--- /dev/null
@@ -0,0 +1,234 @@
+/*
+ controller for screen settings selection
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "ScreenSelectionController.h"
+#import "Utils.h"
+#import "OrderedDictionary.h"
+#import "ConnectionParams.h"
+
+@interface ScreenSelectionController (Private)
+-(NSString*)keyPathForKey:(NSString*)key;
+@end
+
+@implementation ScreenSelectionController
+
+- (id)initWithConnectionParams:(ConnectionParams*)params
+{
+    return [self initWithConnectionParams:params keyPath:nil];
+}
+
+- (id)initWithConnectionParams:(ConnectionParams*)params keyPath:(NSString*)keyPath
+{
+    self = [super initWithStyle:UITableViewStyleGrouped];
+    if (self)
+    {
+        _params = [params retain];
+        _keyPath = (keyPath != nil ? [keyPath retain] : nil);
+        _color_options = (OrderedDictionary*)[SelectionForColorSetting() retain];
+        _resolution_modes = [ResolutionModes() retain];
+        
+        // init current selections
+        NSUInteger idx = [_color_options indexForValue:[NSNumber numberWithInt:[_params intForKeyPath:[self keyPathForKey:@"colors"]]]];
+        _selection_color = (idx != NSNotFound) ? idx : 0;
+
+        idx = [_resolution_modes indexOfObject:ScreenResolutionDescription([_params intForKeyPath:[self keyPathForKey:@"screen_resolution_type"]],
+                                    [_params intForKeyPath:[self keyPathForKey:@"width"]],
+                                    [_params intForKeyPath:[self keyPathForKey:@"height"]])];
+        _selection_resolution = (idx != NSNotFound) ? idx : 0;
+    }
+    return self;    
+}
+
+- (void)dealloc
+{
+    [super dealloc];
+    [_params autorelease];
+    [_keyPath autorelease];
+    [_color_options autorelease];
+    [_resolution_modes autorelease];
+}
+
+-(NSString*)keyPathForKey:(NSString*)key
+{
+    if (_keyPath)
+        return [_keyPath stringByAppendingFormat:@".%@", key];
+    return key;
+}
+
+#pragma mark - View lifecycle
+
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
+{
+    // Return YES for supported orientations
+    return YES;
+}
+
+#pragma mark - Table view data source
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
+{
+    return 2;
+}
+
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
+{
+    // Return the number of rows in the section.
+    if (section == 0)
+        return [_color_options count];
+    return [_resolution_modes count] + 2; // +2 for custom width/height input fields
+}
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
+{
+    UITableViewCell *cell = nil;
+    switch ([indexPath section])
+    {
+        case 0:
+            cell = [self tableViewCellFromIdentifier:TableCellIdentifierMultiChoice];
+            [[cell textLabel] setText:[_color_options keyAtIndex:[indexPath row]]];        
+            break;
+            
+        case 1:
+            if ([indexPath row] < [_resolution_modes count])
+            {
+                cell = [self tableViewCellFromIdentifier:TableCellIdentifierMultiChoice];   
+                [[cell textLabel] setText:[_resolution_modes objectAtIndex:[indexPath row]]];        
+            }
+            else
+                cell = [self tableViewCellFromIdentifier:TableCellIdentifierText];
+            break;
+            
+        default:
+            break;
+    }
+    
+    if ([indexPath section] == 1)
+    {
+        BOOL enabled = ([_params intForKeyPath:[self keyPathForKey:@"screen_resolution_type"]] == TSXScreenOptionCustom);
+        if ([indexPath row] == [_resolution_modes count])
+        {
+            int value = [_params intForKeyPath:[self keyPathForKey:@"width"]];
+            EditTextTableViewCell* textCell = (EditTextTableViewCell*)cell;
+            [[textCell label] setText:NSLocalizedString(@"Width", @"Custom Screen Width")];
+            [[textCell textfield] setText:[NSString stringWithFormat:@"%d", value ? value : 800]];
+            [[textCell textfield] setKeyboardType:UIKeyboardTypeNumberPad];
+            [[textCell label] setEnabled:enabled];
+            [[textCell textfield] setEnabled:enabled];
+            [[textCell textfield] setTag:1];
+        }
+        else if ([indexPath row] == ([_resolution_modes count] + 1))
+        {
+            int value = [_params intForKeyPath:[self keyPathForKey:@"height"]];
+            EditTextTableViewCell* textCell = (EditTextTableViewCell*)cell;
+            [[textCell label] setText:NSLocalizedString(@"Height", @"Custom Screen Height")];
+            [[textCell textfield] setText:[NSString stringWithFormat:@"%d", value ? value : 600]];
+            [[textCell textfield] setKeyboardType:UIKeyboardTypeNumberPad];
+            [[textCell label] setEnabled:enabled];
+            [[textCell textfield] setEnabled:enabled];
+            [[textCell textfield] setTag:2];
+        }
+    }
+       
+       // set default checkmark
+       if([indexPath row] == ([indexPath section] == 0 ? _selection_color : _selection_resolution))
+               [cell setAccessoryType:UITableViewCellAccessoryCheckmark];
+       else
+               [cell setAccessoryType:UITableViewCellAccessoryNone];
+       
+    return cell;
+}
+
+#pragma mark - Table view delegate
+
+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
+{
+    // custom widht/height cells are not selectable
+    if ([indexPath section] == 1 && [indexPath row] >= [_resolution_modes count])
+        return;
+    
+       // has selection change?
+    int cur_selection = ([indexPath section] == 0 ? _selection_color : _selection_resolution);
+       if([indexPath row] != cur_selection)
+       {
+               [tableView deselectRowAtIndexPath:indexPath animated:NO];
+               
+               NSIndexPath* oldIndexPath = [NSIndexPath indexPathForRow:cur_selection inSection:[indexPath section]];
+        
+               // clear old checkmark
+               UITableViewCell* old_sel_cell = [tableView cellForRowAtIndexPath:oldIndexPath];
+               old_sel_cell.accessoryType = UITableViewCellAccessoryNone;
+        
+               // set new checkmark
+               UITableViewCell* new_sel_cell = [tableView cellForRowAtIndexPath:indexPath];
+               new_sel_cell.accessoryType = UITableViewCellAccessoryCheckmark;
+        
+        if ([indexPath section] == 0)
+        {
+            // get value from color dictionary
+            int sel_value = [[_color_options valueForKey:[_color_options keyAtIndex:[indexPath row]]] intValue];
+            
+            // update selection index and params value
+            [_params setInt:sel_value forKeyPath:[self keyPathForKey:@"colors"]];
+            _selection_color = [indexPath row];
+        }
+        else
+        {
+            // update selection index and params value
+            int width, height;
+            TSXScreenOptions mode;
+            ScanScreenResolution([_resolution_modes objectAtIndex:[indexPath row]], &width, &height, &mode);
+            [_params setInt:mode forKeyPath:[self keyPathForKey:@"screen_resolution_type"]];
+            if (mode != TSXScreenOptionCustom)
+            {
+                [_params setInt:width forKeyPath:[self keyPathForKey:@"width"]];
+                [_params setInt:height forKeyPath:[self keyPathForKey:@"height"]];                
+            }
+            _selection_resolution = [indexPath row];
+
+            // refresh width/height edit fields if custom selection changed
+            NSArray* indexPaths = [NSArray arrayWithObjects:[NSIndexPath indexPathForRow:[_resolution_modes count] inSection:1], 
+                                                            [NSIndexPath indexPathForRow:([_resolution_modes count] + 1) inSection:1], nil];
+            [[self tableView] reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
+        }
+    }    
+}
+
+#pragma mark -
+#pragma mark Text Field delegate
+
+- (BOOL)textFieldShouldReturn:(UITextField*)textField
+{
+       [textField resignFirstResponder];
+       return NO;
+}
+
+- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
+{
+   
+       switch([textField tag])
+       {            
+            // update resolution settings (and check for invalid input)
+               case 1:
+            if ([[textField text] intValue] < 640) [textField setText:@"640"];
+                       [_params setInt:[[textField text] intValue] forKeyPath:[self keyPathForKey:@"width"]];
+                       break;
+            
+               case 2:
+            if ([[textField text] intValue] < 480) [textField setText:@"480"];
+                       [_params setInt:[[textField text] intValue] forKeyPath:[self keyPathForKey:@"height"]];
+                       break;
+                        
+               default:
+                       break;
+       }
+       return YES;
+}
+
+@end
diff --git a/client/iOS/Controllers/VerifyCertificateController.h b/client/iOS/Controllers/VerifyCertificateController.h
new file mode 100644 (file)
index 0000000..d842a4d
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ Certificate verification controller
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import <UIKit/UIKit.h>
+
+@class RDPSession;
+
+@interface VerifyCertificateController : UIViewController
+{
+@private
+    IBOutlet UILabel* _label_issuer;    
+    IBOutlet UIButton* _btn_accept;
+    IBOutlet UIButton* _btn_decline;
+    IBOutlet UILabel* _label_message;
+    IBOutlet UILabel* _label_for_issuer;
+
+    RDPSession* _session;
+    NSMutableDictionary* _params;
+}
+
+- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil session:(RDPSession*)session params:(NSMutableDictionary*)params;
+
+@end
diff --git a/client/iOS/Controllers/VerifyCertificateController.m b/client/iOS/Controllers/VerifyCertificateController.m
new file mode 100644 (file)
index 0000000..6390dd9
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ Certificate verification controller
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "VerifyCertificateController.h"
+#import "RDPSession.h"
+
+@implementation VerifyCertificateController
+
+- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil session:(RDPSession *)session params:(NSMutableDictionary *)params
+{
+    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
+    if (self) {
+        _session = session;
+        _params = params;
+        [self setModalPresentationStyle:UIModalPresentationFormSheet];
+    }
+    return self;
+}
+
+- (void)viewDidLoad
+{
+    [super viewDidLoad];
+
+    NSString* message = NSLocalizedString(@"The identity of the remote computer cannot be verified. Do you want to connect anyway?", @"Verify certificate view message");
+    
+    // init strings
+    [_label_message setText:message];
+    [_label_for_issuer setText:NSLocalizedString(@"Issuer:", @"Verify certificate view issuer label")];
+    [_btn_accept setTitle:NSLocalizedString(@"Yes", @"Yes Button") forState:UIControlStateNormal];
+    [_btn_decline setTitle:NSLocalizedString(@"No", @"No Button") forState:UIControlStateNormal];
+
+    [_label_issuer setText:[_params valueForKey:@"issuer"]];
+}
+
+- (void)viewDidUnload
+{
+    [super viewDidUnload];
+    // Release any retained subviews of the main view.
+}
+
+- (void)viewDidDisappear:(BOOL)animated
+{
+    [super viewDidDisappear:animated];
+
+    // set signal
+    [[_session uiRequestCompleted] signal];    
+}
+
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
+{
+    return YES;
+}
+
+
+#pragma mark - Action handlers
+
+- (IBAction)acceptPressed:(id)sender
+{
+    [_params setValue:[NSNumber numberWithBool:YES] forKey:@"result"];
+        
+    // dismiss controller
+    [self dismissModalViewControllerAnimated:YES];
+}
+
+- (IBAction)declinePressed:(id)sender
+{
+    [_params setValue:[NSNumber numberWithBool:NO] forKey:@"result"];
+    
+    // dismiss controller
+    [self dismissModalViewControllerAnimated:YES];
+}
+
+@end
diff --git a/client/iOS/Defaults.plist b/client/iOS/Defaults.plist
new file mode 100644 (file)
index 0000000..88e2113
--- /dev/null
@@ -0,0 +1,72 @@
+<?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>TSXDefaultComputerBookmarkSettings</key>
+       <dict>
+               <key>hostname</key>
+               <string></string>
+               <key>port</key>
+               <integer>3389</integer>
+               <key>screen_resolution_type</key>
+               <integer>0</integer>
+               <key>width</key>
+               <integer>1024</integer>
+               <key>height</key>
+               <integer>768</integer>
+               <key>colors</key>
+               <integer>16</integer>
+               <key>perf_font_smoothing</key>
+               <false/>
+               <key>perf_menu_animation</key>
+               <false/>
+               <key>perf_show_desktop</key>
+               <false/>
+               <key>perf_window_dragging</key>
+               <false/>
+               <key>perf_windows_themes</key>
+               <false/>
+               <key>perf_remotefx</key>
+               <false/>
+               <key>perf_desktop_composition</key>
+               <false/>
+               <key>enable_3g_settings</key>
+               <false/>
+               <key>settings_3g</key>
+               <dict>
+                       <key>screen_resolution_type</key>
+                       <integer>0</integer>
+                       <key>width</key>
+                       <integer>800</integer>
+                       <key>height</key>
+                       <integer>600</integer>
+                       <key>colors</key>
+                       <integer>16</integer>
+                       <key>perf_remotefx</key>
+                       <false/>
+                       <key>perf_desktop_composition</key>
+                       <false/>
+                       <key>perf_windows_themes</key>
+                       <false/>
+                       <key>perf_window_dragging</key>
+                       <false/>
+                       <key>perf_show_desktop</key>
+                       <false/>
+                       <key>perf_menu_animation</key>
+                       <false/>
+                       <key>perf_font_smoothing</key>
+                       <false/>
+               </dict>
+               <key>security</key>
+               <integer>0</integer>
+               <key>remote_program</key>
+               <string></string>
+               <key>working_dir</key>
+               <string></string>
+               <key>console</key>
+               <false/>
+       </dict>
+       <key>ui.auto_scroll_touchpointer</key>
+       <true/>
+</dict>
+</plist>
diff --git a/client/iOS/FreeRDP/ios_freerdp.h b/client/iOS/FreeRDP/ios_freerdp.h
new file mode 100644 (file)
index 0000000..47820d7
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ RDP run-loop
+ Copyright 2013 Thinstuff Technologies GmbH, Authors: Martin Fleisz, Dorian Johnson
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import <freerdp/freerdp.h>
+#import <freerdp/channels/channels.h>
+#import "TSXTypes.h"
+
+@class RDPSession, RDPSessionView;
+
+// FreeRDP extended structs
+typedef struct mf_info mfInfo;
+
+
+typedef struct mf_context
+{
+       rdpContext _p;
+       
+       mfInfo* mfi;
+       rdpSettings* settings;
+} mfContext;
+
+
+struct mf_info
+{
+       // RDP
+       freerdp* instance;
+       mfContext* context;
+       rdpContext* _context;
+       
+       // UI
+       RDPSession* session;
+       
+       // Graphics
+       CGContextRef bitmap_context;
+       
+       // Events
+       int event_pipe_producer, event_pipe_consumer;
+
+       // Tracking connection state
+       volatile TSXConnectionState connection_state;
+       volatile BOOL unwanted; // set when controlling Session no longer wants the connection to continue
+};
+
+
+#define MFI_FROM_INSTANCE(inst) (((mfContext*)((inst)->context))->mfi)
+
+
+enum MF_EXIT_CODE
+{
+       MF_EXIT_SUCCESS = 0,
+
+       MF_EXIT_CONN_FAILED = 128,
+       MF_EXIT_CONN_CANCELED = 129,
+    MF_EXIT_LOGON_TIMEOUT = 130,
+       
+       MF_EXIT_UNKNOWN = 255
+};
+
+void ios_init_freerdp();
+void ios_uninit_freerdp();
+freerdp* ios_freerdp_new();
+int ios_run_freerdp(freerdp* instance);
+void ios_freerdp_free(freerdp* instance);
+
+
+
+
diff --git a/client/iOS/FreeRDP/ios_freerdp.m b/client/iOS/FreeRDP/ios_freerdp.m
new file mode 100644 (file)
index 0000000..55738be
--- /dev/null
@@ -0,0 +1,289 @@
+/*
+ RDP run-loop
+ Copyright 2013 Thinstuff Technologies GmbH, Authors: Martin Fleisz, Dorian Johnson
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import <freerdp/utils/event.h>
+#import <freerdp/gdi/gdi.h>
+#import <freerdp/utils/file.h>
+
+#import "ios_freerdp.h"
+#import "ios_freerdp_ui.h"
+#import "ios_freerdp_events.h"
+
+#import "RDPSession.h"
+#import "Utils.h"
+
+
+#pragma mark Connection helpers
+
+static BOOL
+ios_pre_connect(freerdp * instance)
+{      
+       rdpSettings* settings = instance->settings;     
+
+       settings->AutoLogonEnabled = settings->Password && (strlen(settings->Password) > 0);
+       
+       // Verify screen width/height are sane
+       if ((settings->DesktopWidth < 64) || (settings->DesktopHeight < 64) || (settings->DesktopWidth > 4096) || (settings->DesktopHeight > 4096))
+       {
+               NSLog(@"%s: invalid dimensions %d %d", __func__, settings->DesktopWidth, settings->DesktopHeight);
+               return FALSE;
+       }
+       
+       BOOL bitmap_cache = settings->BitmapCacheEnabled;
+       
+       settings->OrderSupport[NEG_DSTBLT_INDEX] = TRUE;
+       settings->OrderSupport[NEG_PATBLT_INDEX] = TRUE;
+       settings->OrderSupport[NEG_SCRBLT_INDEX] = TRUE;
+       settings->OrderSupport[NEG_OPAQUE_RECT_INDEX] = TRUE;
+       settings->OrderSupport[NEG_DRAWNINEGRID_INDEX] = FALSE;
+       settings->OrderSupport[NEG_MULTIDSTBLT_INDEX] = FALSE;
+       settings->OrderSupport[NEG_MULTIPATBLT_INDEX] = FALSE;
+       settings->OrderSupport[NEG_MULTISCRBLT_INDEX] = FALSE;
+       settings->OrderSupport[NEG_MULTIOPAQUERECT_INDEX] = TRUE;
+       settings->OrderSupport[NEG_MULTI_DRAWNINEGRID_INDEX] = FALSE;
+       settings->OrderSupport[NEG_LINETO_INDEX] = TRUE;
+       settings->OrderSupport[NEG_POLYLINE_INDEX] = TRUE;
+       settings->OrderSupport[NEG_MEMBLT_INDEX] = bitmap_cache;
+       settings->OrderSupport[NEG_MEM3BLT_INDEX] = TRUE;
+       settings->OrderSupport[NEG_MEMBLT_V2_INDEX] = bitmap_cache;
+       settings->OrderSupport[NEG_MEM3BLT_V2_INDEX] = FALSE;
+       settings->OrderSupport[NEG_SAVEBITMAP_INDEX] = FALSE;
+       settings->OrderSupport[NEG_GLYPH_INDEX_INDEX] = TRUE;
+       settings->OrderSupport[NEG_FAST_INDEX_INDEX] = TRUE;
+       settings->OrderSupport[NEG_FAST_GLYPH_INDEX] = TRUE;
+       settings->OrderSupport[NEG_POLYGON_SC_INDEX] = FALSE;
+       settings->OrderSupport[NEG_POLYGON_CB_INDEX] = FALSE;
+       settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = FALSE;
+       settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE;
+       
+    settings->FrameAcknowledge = 10;
+
+//     freerdp_channels_pre_connect(instance->context->channels, instance);
+
+       return TRUE;
+}
+
+static BOOL ios_post_connect(freerdp* instance)
+{
+       mfInfo* mfi = MFI_FROM_INSTANCE(instance);
+
+    instance->context->cache = cache_new(instance->settings);
+    
+       // Graphics callbacks
+       ios_allocate_display_buffer(mfi);
+       instance->update->BeginPaint = ios_ui_begin_paint;
+       instance->update->EndPaint = ios_ui_end_paint;
+       instance->update->DesktopResize = ios_ui_resize_window;
+               
+       // Channel allocation
+//     freerdp_channels_post_connect(instance->context->channels, instance);
+
+       [mfi->session performSelectorOnMainThread:@selector(sessionDidConnect) withObject:nil waitUntilDone:YES];
+       return TRUE;
+}
+
+#pragma mark -
+#pragma mark Running the connection
+
+int
+ios_run_freerdp(freerdp * instance)
+{
+       mfContext* context = (mfContext*)instance->context;
+       mfInfo* mfi = context->mfi;
+//     rdpChannels* channels = instance->context->channels;
+               
+       mfi->connection_state = TSXConnectionConnecting;
+       
+       if (!freerdp_connect(instance))
+       {
+               NSLog(@"%s: inst->rdp_connect failed", __func__);
+               return mfi->unwanted ? MF_EXIT_CONN_CANCELED : MF_EXIT_CONN_FAILED;
+       }
+       
+       if (mfi->unwanted)
+               return MF_EXIT_CONN_CANCELED;
+
+       mfi->connection_state = TSXConnectionConnected;
+                       
+       // Connection main loop
+       NSAutoreleasePool* pool;
+       int i;
+       int fds;
+       int max_fds;
+       int rcount;
+       int wcount;
+       void* rfds[32];
+       void* wfds[32];
+       fd_set rfds_set;
+       fd_set wfds_set;
+       
+       memset(rfds, 0, sizeof(rfds));
+       memset(wfds, 0, sizeof(wfds));
+
+       while (1)
+       {
+               rcount = wcount = 0;
+               
+               pool = [[NSAutoreleasePool alloc] init];
+
+               if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
+               {
+                       NSLog(@"%s: inst->rdp_get_fds failed", __func__);
+                       break;
+               }
+
+/*             if (freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount) != TRUE)
+               {
+                       NSLog(@"%s: freerdp_chanman_get_fds failed", __func__);
+                       break;
+               }
+*/
+               if (ios_events_get_fds(mfi, rfds, &rcount, wfds, &wcount) != TRUE)
+               {
+                       NSLog(@"%s: ios_events_get_fds", __func__);
+                       break;
+               }
+               
+               max_fds = 0;
+               FD_ZERO(&rfds_set);
+               FD_ZERO(&wfds_set);
+               
+               for (i = 0; i < rcount; i++)
+               {
+                       fds = (int)(long)(rfds[i]);
+                       
+                       if (fds > max_fds)
+                               max_fds = fds;
+                       
+                       FD_SET(fds, &rfds_set);
+               }
+               
+               if (max_fds == 0)
+                       break;
+               
+               if (select(max_fds + 1, &rfds_set, &wfds_set, NULL, NULL) == -1)
+               {
+                       /* these are not really errors */
+                       if (!((errno == EAGAIN) ||
+                                 (errno == EWOULDBLOCK) ||
+                                 (errno == EINPROGRESS) ||
+                                 (errno == EINTR))) /* signal occurred */
+                       {
+                               NSLog(@"%s: max_sck is zero.", __func__);
+                               break;
+                       }
+               }
+               
+               // Check the libfreerdp fds
+               if (freerdp_check_fds(instance) != true)
+               {
+                       NSLog(@"%s: inst->rdp_check_fds failed.", __func__);
+                       break;
+               }
+               
+               // Check input event fds
+               if (ios_events_check_fds(mfi, &rfds_set) != TRUE)
+               {
+                       // This event will fail when the app asks for a disconnect.
+                       //NSLog(@"%s: ios_events_check_fds failed: terminating connection.", __func__);
+                       break;
+               }
+               
+               // Check channel fds
+/*             if (freerdp_channels_check_fds(channels, instance) != TRUE)
+               {
+                       NSLog(@"%s: freerdp_chanman_check_fds failed", __func__);
+                       break;
+               }
+*/
+               [pool release]; pool = nil;
+       }       
+       
+       mfi->connection_state = TSXConnectionDisconnected;
+       
+       // Cleanup
+//     freerdp_channels_close(channels, instance);
+//     freerdp_channels_free(channels);
+       freerdp_disconnect(instance);
+       gdi_free(instance);
+    cache_free(instance->context->cache);
+       
+       [pool release]; pool = nil;
+       return MF_EXIT_SUCCESS;
+}
+
+#pragma mark -
+#pragma mark Context callbacks
+
+void ios_context_new(freerdp* instance, rdpContext* context)
+{
+       mfInfo* mfi = (mfInfo*)calloc(1, sizeof(mfInfo));
+       ((mfContext*) context)->mfi = mfi;
+//     context->channels = freerdp_channels_new();
+       ios_events_create_pipe(mfi);
+       
+       mfi->_context = context;
+       mfi->context = (mfContext*)context;
+       mfi->context->settings = instance->settings;
+       mfi->instance = instance;
+}
+
+void ios_context_free(freerdp* instance, rdpContext* context)
+{
+       mfInfo* mfi = ((mfContext*) context)->mfi;
+       ios_events_free_pipe(mfi);
+       free(mfi);
+}
+
+#pragma mark -
+#pragma mark Initialization and cleanup
+
+freerdp* ios_freerdp_new()
+{
+       freerdp* inst = freerdp_new();
+       
+       inst->PreConnect = ios_pre_connect;
+       inst->PostConnect = ios_post_connect;
+       inst->Authenticate = ios_ui_authenticate;
+       inst->VerifyCertificate = ios_ui_check_certificate;
+    inst->VerifyChangedCertificate = ios_ui_check_changed_certificate;
+
+       inst->context_size = sizeof(mfContext);
+       inst->ContextNew = ios_context_new;
+       inst->ContextFree = ios_context_free;
+       freerdp_context_new(inst);
+
+    // determine new home path
+    NSString* home_path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
+    free(inst->settings->HomePath);
+    free(inst->settings->ConfigPath);
+    inst->settings->HomePath = strdup([home_path UTF8String]);
+    inst->settings->ConfigPath = NULL;
+    freerdp_detect_paths(inst->settings);
+
+       return inst;
+}
+
+void ios_freerdp_free(freerdp* instance)
+{
+       freerdp_context_free(instance);
+       freerdp_free(instance);
+}
+
+void ios_init_freerdp()
+{
+       signal(SIGPIPE, SIG_IGN);
+//     freerdp_channels_global_init();
+}
+
+void ios_uninit_freerdp()
+{
+//     freerdp_channels_global_uninit();
+}
+
diff --git a/client/iOS/FreeRDP/ios_freerdp_events.h b/client/iOS/FreeRDP/ios_freerdp_events.h
new file mode 100755 (executable)
index 0000000..d2f9e79
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ RDP event queuing 
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Dorian Johnson
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef IOS_RDP_EVENT_H
+#define IOS_RDP_EVENT_H
+
+#import "ios_freerdp.h"
+
+// For UI: use to send events
+BOOL ios_events_send(mfInfo* mfi, NSDictionary * event_description);
+
+// For connection runloop: use to poll for queued input events
+BOOL ios_events_get_fds(mfInfo* mfi, void ** read_fds, int * read_count, void ** write_fds, int * write_count);
+BOOL ios_events_check_fds(mfInfo* mfi, fd_set* rfds);
+BOOL ios_events_create_pipe(mfInfo* mfi);
+void ios_events_free_pipe(mfInfo* mfi);
+
+#endif /* IOS_RDP_EVENT_H */
diff --git a/client/iOS/FreeRDP/ios_freerdp_events.m b/client/iOS/FreeRDP/ios_freerdp_events.m
new file mode 100755 (executable)
index 0000000..be16485
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ RDP event queuing 
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Dorian Johnson
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "ios_freerdp_events.h"
+
+#pragma mark -
+#pragma mark Sending compacted input events (from main thread)
+
+// While this function may be called from any thread that has an autorelease pool allocated, it is not threadsafe: caller is responsible for synchronization
+BOOL ios_events_send(mfInfo* mfi, NSDictionary * event_description)
+{              
+       NSData * encoded_description = [NSKeyedArchiver archivedDataWithRootObject:event_description];
+       
+       if ([encoded_description length] > 32000 || (mfi->event_pipe_producer == -1) )
+               return FALSE;
+       
+       uint32_t archived_data_len = (uint32_t)[encoded_description length];
+       
+       //NSLog(@"writing %d bytes to input event pipe", archived_data_len);
+       
+       if (write(mfi->event_pipe_producer, &archived_data_len, 4) == -1)
+       {
+               NSLog(@"%s: Failed to write length descriptor to pipe.", __func__);
+               return FALSE;
+       }
+       
+       if (write(mfi->event_pipe_producer, [encoded_description bytes], archived_data_len) == -1)
+       {
+               NSLog(@"%s: Failed to write %d bytes into the event queue (event type: %@).", __func__, (int)[encoded_description length], [event_description objectForKey:@"type"]);
+               return FALSE;
+       }
+       
+       return TRUE;    
+}
+
+
+#pragma mark -
+#pragma mark Processing compacted input events (from connection thread runloop)
+
+static BOOL ios_events_handle_event(mfInfo* mfi, NSDictionary * event_description)
+{
+       NSString * event_type = [event_description objectForKey:@"type"];
+       BOOL should_continue = TRUE;
+       freerdp* instance = mfi->instance;
+       
+       if ([event_type isEqualToString:@"mouse"])
+       {        
+               instance->input->MouseEvent(instance->input, 
+                                    [[event_description objectForKey:@"flags"] unsignedShortValue],
+                                    [[event_description objectForKey:@"coord_x"] unsignedShortValue],
+                                    [[event_description objectForKey:@"coord_y"] unsignedShortValue]);
+       }
+       else if ([event_type isEqualToString:@"keyboard"])
+       {
+               if ([[event_description objectForKey:@"subtype"] isEqualToString:@"scancode"])
+                       instance->input->KeyboardEvent(instance->input, 
+                                           [[event_description objectForKey:@"flags"] unsignedShortValue],
+                                           [[event_description objectForKey:@"scancode"] unsignedShortValue]);
+               else if ([[event_description objectForKey:@"subtype"] isEqualToString:@"unicode"])
+                       instance->input->UnicodeKeyboardEvent(instance->input,
+                                                  [[event_description objectForKey:@"flags"] unsignedShortValue],
+                                                  [[event_description objectForKey:@"unicode_char"] unsignedShortValue]);
+               else
+                       NSLog(@"%s: doesn't know how to send keyboard input with subtype %@", __func__, [event_description objectForKey:@"subtype"]);
+       }
+       else if ([event_type isEqualToString:@"disconnect"])
+               should_continue = FALSE;
+       else
+               NSLog(@"%s: unrecognized event type: %@", __func__, event_type);
+       
+       return should_continue;
+}
+
+BOOL ios_events_check_fds(mfInfo* mfi, fd_set* rfds)
+{      
+       if ( (mfi->event_pipe_consumer == -1) || !FD_ISSET(mfi->event_pipe_consumer, rfds))
+               return TRUE;
+       
+       uint32_t archived_data_length = 0;
+       ssize_t bytes_read;
+       
+       // First, read the length of the blob
+       bytes_read = read(mfi->event_pipe_consumer, &archived_data_length, 4);
+       
+       if (bytes_read == -1 || archived_data_length < 1 || archived_data_length > 32000)
+       {
+               NSLog(@"%s: just read length descriptor. bytes_read=%ld, archived_data_length=%u", __func__, bytes_read, archived_data_length);
+               return FALSE;
+       }
+       
+       //NSLog(@"reading %d bytes from input event pipe", archived_data_length);
+       
+       NSMutableData * archived_object_data = [[NSMutableData alloc] initWithLength:archived_data_length];
+       bytes_read = read(mfi->event_pipe_consumer, [archived_object_data mutableBytes], archived_data_length);
+       
+       if (bytes_read != archived_data_length)
+       {
+               NSLog(@"%s: attempted to read data; read %ld bytes but wanted %d bytes.", __func__, bytes_read, archived_data_length);
+               [archived_object_data release];
+               return FALSE;
+       }
+       
+       id unarchived_object_data = [NSKeyedUnarchiver unarchiveObjectWithData:archived_object_data];
+       [archived_object_data release];
+       
+       return ios_events_handle_event(mfi, unarchived_object_data);
+}
+
+BOOL ios_events_get_fds(mfInfo* mfi, void ** read_fds, int * read_count, void ** write_fds, int * write_count)
+{
+       read_fds[*read_count] = (void *)(long)(mfi->event_pipe_consumer);
+       (*read_count)++;
+       return TRUE;
+}
+
+// Sets up the event pipe
+BOOL ios_events_create_pipe(mfInfo* mfi)
+{
+       int pipe_fds[2];
+       
+       if (pipe(pipe_fds) == -1)
+       {
+               NSLog(@"%s: pipe failed.", __func__);
+               return FALSE;
+       }
+       
+       mfi->event_pipe_consumer = pipe_fds[0];
+       mfi->event_pipe_producer = pipe_fds[1];
+       return TRUE;
+}
+
+void ios_events_free_pipe(mfInfo* mfi)
+{
+       int consumer_fd = mfi->event_pipe_consumer, producer_fd = mfi->event_pipe_producer;
+       
+       mfi->event_pipe_consumer = mfi->event_pipe_producer = -1;
+       close(producer_fd);
+       close(consumer_fd);     
+}
diff --git a/client/iOS/FreeRDP/ios_freerdp_ui.h b/client/iOS/FreeRDP/ios_freerdp_ui.h
new file mode 100644 (file)
index 0000000..a87a568
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ RDP ui callbacks
+ Copyright 2013 Thinstuff Technologies GmbH, Authors: Martin Fleisz, Dorian Johnson
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "ios_freerdp.h"
+
+void ios_ui_begin_paint(rdpContext * context);
+void ios_ui_end_paint(rdpContext * context);
+void ios_ui_resize_window(rdpContext * context);
+
+BOOL ios_ui_authenticate(freerdp * instance, char** username, char** password, char** domain);
+BOOL ios_ui_check_certificate(freerdp * instance, char * subject, char * issuer, char * fingerprint);
+BOOL ios_ui_check_changed_certificate(freerdp * instance, char * subject, char * issuer, char * new_fingerprint, char * old_fingerprint);
+
+void ios_allocate_display_buffer(mfInfo* mfi);
+void ios_resize_display_buffer(mfInfo* mfi);
diff --git a/client/iOS/FreeRDP/ios_freerdp_ui.m b/client/iOS/FreeRDP/ios_freerdp_ui.m
new file mode 100644 (file)
index 0000000..436fa50
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ RDP ui callbacks
+ Copyright 2013 Thinstuff Technologies GmbH, Authors: Martin Fleisz, Dorian Johnson
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import <Foundation/Foundation.h>
+
+#import <freerdp/gdi/gdi.h>
+#import "ios_freerdp_ui.h"
+
+#import "RDPSession.h"
+
+#pragma mark -
+#pragma mark Certificate authentication
+
+BOOL ios_ui_authenticate(freerdp * instance, char** username, char** password, char** domain)
+{
+       mfInfo* mfi = MFI_FROM_INSTANCE(instance);
+
+       NSMutableDictionary* params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+               (*username) ? [NSString stringWithUTF8String:*username] : @"", @"username",
+               (*password) ? [NSString stringWithUTF8String:*password] : @"", @"password",
+               (*domain) ? [NSString stringWithUTF8String:*domain] : @"", @"domain",
+               [NSString stringWithUTF8String:instance->settings->ServerHostname], @"hostname", // used for the auth prompt message; not changed
+               nil];
+
+    // request auth UI
+    [mfi->session performSelectorOnMainThread:@selector(sessionRequestsAuthenticationWithParams:) withObject:params waitUntilDone:YES];
+    
+    // wait for UI request to be completed
+    [[mfi->session uiRequestCompleted] lock];
+    [[mfi->session uiRequestCompleted] wait];
+    [[mfi->session uiRequestCompleted] unlock];
+    
+       if (![[params valueForKey:@"result"] boolValue])
+       {
+               mfi->unwanted = YES;
+               return FALSE;
+       }
+          
+       // Free old values
+       free(*username);
+       free(*password);
+       free(*domain);
+       
+       // set values back
+       *username = strdup([[params objectForKey:@"username"] UTF8String]);
+       *password = strdup([[params objectForKey:@"password"] UTF8String]);
+       *domain = strdup([[params objectForKey:@"domain"] UTF8String]);
+       
+       return TRUE;
+}
+
+BOOL ios_ui_check_certificate(freerdp * instance, char * subject, char * issuer, char * fingerprint)
+{
+    // check whether we accept all certificates
+    if ([[NSUserDefaults standardUserDefaults] boolForKey:@"security.accept_certificates"] == YES)
+        return TRUE;
+    
+       mfInfo* mfi = MFI_FROM_INSTANCE(instance);
+       NSMutableDictionary* params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+                                        (subject) ? [NSString stringWithUTF8String:subject] : @"", @"subject",
+                                        (issuer) ? [NSString stringWithUTF8String:issuer] : @"", @"issuer",
+                                        (fingerprint) ? [NSString stringWithUTF8String:subject] : @"", @"fingerprint",
+                                        nil];
+       
+    // request certificate verification UI
+    [mfi->session performSelectorOnMainThread:@selector(sessionVerifyCertificateWithParams:) withObject:params waitUntilDone:YES];
+    
+    // wait for UI request to be completed
+    [[mfi->session uiRequestCompleted] lock];
+    [[mfi->session uiRequestCompleted] wait];
+    [[mfi->session uiRequestCompleted] unlock];
+    
+       if (![[params valueForKey:@"result"] boolValue])
+       {
+               mfi->unwanted = YES;
+               return FALSE;
+       }
+       
+       return TRUE;
+}
+
+BOOL ios_ui_check_changed_certificate(freerdp * instance, char * subject, char * issuer, char * new_fingerprint, char * old_fingerprint)
+{
+       return ios_ui_check_certificate(instance, subject, issuer, new_fingerprint);    
+}
+
+
+#pragma mark -
+#pragma mark Graphics updates
+
+void ios_ui_begin_paint(rdpContext * context)
+{
+       rdpGdi *gdi = context->gdi;
+       gdi->primary->hdc->hwnd->invalid->null = 1;
+}
+
+void ios_ui_end_paint(rdpContext * context)
+{
+    mfInfo* mfi = MFI_FROM_INSTANCE(context->instance);
+       rdpGdi *gdi = context->gdi;
+       CGRect dirty_rect = CGRectMake(gdi->primary->hdc->hwnd->invalid->x, gdi->primary->hdc->hwnd->invalid->y, gdi->primary->hdc->hwnd->invalid->w, gdi->primary->hdc->hwnd->invalid->h);
+       
+       [mfi->session performSelectorOnMainThread:@selector(setNeedsDisplayInRectAsValue:) withObject:[NSValue valueWithCGRect:dirty_rect] waitUntilDone:NO];
+}
+
+
+void ios_ui_resize_window(rdpContext * context)
+{
+       ios_resize_display_buffer(MFI_FROM_INSTANCE(context->instance));
+}
+
+
+#pragma mark -
+#pragma mark Exported
+
+static void ios_create_bitmap_context(mfInfo* mfi)
+{      
+       [mfi->session performSelectorOnMainThread:@selector(sessionBitmapContextWillChange) withObject:nil waitUntilDone:YES];
+           
+    rdpGdi* gdi = mfi->instance->context->gdi;
+    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+       if(gdi->dstBpp == 16)
+               mfi->bitmap_context = CGBitmapContextCreate(gdi->primary_buffer, gdi->width, gdi->height, 5, gdi->width * 2, colorSpace, kCGBitmapByteOrder16Little | kCGImageAlphaNoneSkipFirst);
+       else
+               mfi->bitmap_context = CGBitmapContextCreate(gdi->primary_buffer, gdi->width, gdi->height, 8, gdi->width * 4, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst);
+    CGColorSpaceRelease(colorSpace);
+    
+       [mfi->session performSelectorOnMainThread:@selector(sessionBitmapContextDidChange) withObject:nil waitUntilDone:YES];
+}
+
+void ios_allocate_display_buffer(mfInfo* mfi)
+{
+       gdi_init(mfi->instance, CLRCONV_RGB555 | ((mfi->instance->settings->ColorDepth > 16) ? CLRBUF_32BPP : CLRBUF_16BPP), NULL);
+       ios_create_bitmap_context(mfi);
+}
+
+void ios_resize_display_buffer(mfInfo* mfi)
+{
+       // Release the old context in a thread-safe manner
+       CGContextRef old_context = mfi->bitmap_context;
+       mfi->bitmap_context = NULL;
+       CGContextRelease(old_context);
+       
+       // Create the new context
+    gdi_resize(mfi->instance->context->gdi, mfi->instance->settings->DesktopWidth, mfi->instance->settings->DesktopHeight);
+       ios_create_bitmap_context(mfi);
+}
+
diff --git a/client/iOS/Misc/Reachability.h b/client/iOS/Misc/Reachability.h
new file mode 100755 (executable)
index 0000000..fa5f9b6
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ File: Reachability.h
+ Abstract: Basic demonstration of how to use the SystemConfiguration Reachablity APIs.
+ Version: 2.2
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms.  If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under
+ Apple's copyrights in this original Apple software (the "Apple Software"), to
+ use, reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions
+ of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may be used
+ to endorse or promote products derived from the Apple Software without specific
+ prior written permission from Apple.  Except as expressly stated in this notice,
+ no other rights or licenses, express or implied, are granted by Apple herein,
+ including but not limited to any patent rights that may be infringed by your
+ derivative works or by other works in which the Apple Software may be
+ incorporated.
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR
+ DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF
+ CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+ APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Copyright (C) 2010 Apple Inc. All Rights Reserved.
+*/
+
+
+#import <Foundation/Foundation.h>
+#import <SystemConfiguration/SystemConfiguration.h>
+#import <netinet/in.h>
+
+typedef enum {
+       NotReachable = 0,
+       ReachableViaWiFi = 1,
+       ReachableViaWWAN = 2
+} NetworkStatus;
+#define kReachabilityChangedNotification @"kNetworkReachabilityChangedNotification"
+
+@interface Reachability: NSObject
+{
+       BOOL localWiFiRef;
+       SCNetworkReachabilityRef reachabilityRef;
+}
+
+//reachabilityWithHostName- Use to check the reachability of a particular host name. 
++ (Reachability*) reachabilityWithHostName: (NSString*) hostName;
+
+//reachabilityWithAddress- Use to check the reachability of a particular IP address. 
++ (Reachability*) reachabilityWithAddress: (const struct sockaddr_in*) hostAddress;
+
+//reachabilityForInternetConnection- checks whether the default route is available.  
+//  Should be used by applications that do not connect to a particular host
++ (Reachability*) reachabilityForInternetConnection;
+
+//reachabilityForLocalWiFi- checks whether a local wifi connection is available.
++ (Reachability*) reachabilityForLocalWiFi;
+
+//Start listening for reachability notifications on the current run loop
+- (BOOL) startNotifier;
+- (void) stopNotifier;
+
+- (NetworkStatus) currentReachabilityStatus;
+//WWAN may be available, but not active until a connection has been established.
+//WiFi may require a connection for VPN on Demand.
+- (BOOL) connectionRequired;
+@end
+
+
diff --git a/client/iOS/Misc/Reachability.m b/client/iOS/Misc/Reachability.m
new file mode 100755 (executable)
index 0000000..5ecdcf4
--- /dev/null
@@ -0,0 +1,273 @@
+/*
+ File: Reachability.m
+ Abstract: Basic demonstration of how to use the SystemConfiguration Reachablity APIs.
+ Version: 2.2
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms.  If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under
+ Apple's copyrights in this original Apple software (the "Apple Software"), to
+ use, reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions
+ of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may be used
+ to endorse or promote products derived from the Apple Software without specific
+ prior written permission from Apple.  Except as expressly stated in this notice,
+ no other rights or licenses, express or implied, are granted by Apple herein,
+ including but not limited to any patent rights that may be infringed by your
+ derivative works or by other works in which the Apple Software may be
+ incorporated.
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR
+ DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF
+ CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+ APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Copyright (C) 2010 Apple Inc. All Rights Reserved.
+*/
+
+#import <sys/socket.h>
+#import <netinet/in.h>
+#import <netinet6/in6.h>
+#import <arpa/inet.h>
+#import <ifaddrs.h>
+#import <netdb.h>
+
+#import <CoreFoundation/CoreFoundation.h>
+
+#import "Reachability.h"
+
+#define kShouldPrintReachabilityFlags 1
+
+static void PrintReachabilityFlags(SCNetworkReachabilityFlags    flags, const char* comment)
+{
+#if kShouldPrintReachabilityFlags
+       
+    NSLog(@"Reachability Flag Status: %c%c %c%c%c%c%c%c%c %s\n",
+                       (flags & kSCNetworkReachabilityFlagsIsWWAN)                               ? 'W' : '-',
+                       (flags & kSCNetworkReachabilityFlagsReachable)            ? 'R' : '-',
+                       
+                       (flags & kSCNetworkReachabilityFlagsTransientConnection)  ? 't' : '-',
+                       (flags & kSCNetworkReachabilityFlagsConnectionRequired)   ? 'c' : '-',
+                       (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic)  ? 'C' : '-',
+                       (flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-',
+                       (flags & kSCNetworkReachabilityFlagsConnectionOnDemand)   ? 'D' : '-',
+                       (flags & kSCNetworkReachabilityFlagsIsLocalAddress)       ? 'l' : '-',
+                       (flags & kSCNetworkReachabilityFlagsIsDirect)             ? 'd' : '-',
+                       comment
+                       );
+#endif
+}
+
+
+@implementation Reachability
+static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info)
+{
+       #pragma unused (target, flags)
+       NSCAssert(info != NULL, @"info was NULL in ReachabilityCallback");
+       NSCAssert([(NSObject*) info isKindOfClass: [Reachability class]], @"info was wrong class in ReachabilityCallback");
+
+       //We're on the main RunLoop, so an NSAutoreleasePool is not necessary, but is added defensively
+       // in case someon uses the Reachablity object in a different thread.
+       NSAutoreleasePool* myPool = [[NSAutoreleasePool alloc] init];
+       
+       Reachability* noteObject = (Reachability*) info;
+       // Post a notification to notify the client that the network reachability changed.
+       [[NSNotificationCenter defaultCenter] postNotificationName: kReachabilityChangedNotification object: noteObject];
+       
+       [myPool release];
+}
+
+- (BOOL) startNotifier
+{
+       BOOL retVal = NO;
+       SCNetworkReachabilityContext    context = {0, self, NULL, NULL, NULL};
+       if(SCNetworkReachabilitySetCallback(reachabilityRef, ReachabilityCallback, &context))
+       {
+               if(SCNetworkReachabilityScheduleWithRunLoop(reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode))
+               {
+                       retVal = YES;
+               }
+       }
+       return retVal;
+}
+
+- (void) stopNotifier
+{
+       if(reachabilityRef!= NULL)
+       {
+               SCNetworkReachabilityUnscheduleFromRunLoop(reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
+       }
+}
+
+- (void) dealloc
+{
+       [self stopNotifier];
+       if(reachabilityRef!= NULL)
+       {
+               CFRelease(reachabilityRef);
+       }
+       [super dealloc];
+}
+
++ (Reachability*) reachabilityWithHostName: (NSString*) hostName;
+{
+       Reachability* retVal = NULL;
+       SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, [hostName UTF8String]);
+       if(reachability!= NULL)
+       {
+               retVal= [[[self alloc] init] autorelease];
+               if(retVal!= NULL)
+               {
+                       retVal->reachabilityRef = reachability;
+                       retVal->localWiFiRef = NO;
+               }
+       }
+       return retVal;
+}
+
++ (Reachability*) reachabilityWithAddress: (const struct sockaddr_in*) hostAddress;
+{
+       SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)hostAddress);
+       Reachability* retVal = NULL;
+       if(reachability!= NULL)
+       {
+               retVal= [[[self alloc] init] autorelease];
+               if(retVal!= NULL)
+               {
+                       retVal->reachabilityRef = reachability;
+                       retVal->localWiFiRef = NO;
+               }
+       }
+       return retVal;
+}
+
++ (Reachability*) reachabilityForInternetConnection;
+{
+       struct sockaddr_in zeroAddress;
+       bzero(&zeroAddress, sizeof(zeroAddress));
+       zeroAddress.sin_len = sizeof(zeroAddress);
+       zeroAddress.sin_family = AF_INET;
+       return [self reachabilityWithAddress: &zeroAddress];
+}
+
++ (Reachability*) reachabilityForLocalWiFi;
+{
+       struct sockaddr_in localWifiAddress;
+       bzero(&localWifiAddress, sizeof(localWifiAddress));
+       localWifiAddress.sin_len = sizeof(localWifiAddress);
+       localWifiAddress.sin_family = AF_INET;
+       // IN_LINKLOCALNETNUM is defined in <netinet/in.h> as 169.254.0.0
+       localWifiAddress.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM);
+       Reachability* retVal = [self reachabilityWithAddress: &localWifiAddress];
+       if(retVal!= NULL)
+       {
+               retVal->localWiFiRef = YES;
+       }
+       return retVal;
+}
+
+#pragma mark Network Flag Handling
+
+- (NetworkStatus) localWiFiStatusForFlags: (SCNetworkReachabilityFlags) flags
+{
+       PrintReachabilityFlags(flags, "localWiFiStatusForFlags");
+
+       BOOL retVal = NotReachable;
+       if((flags & kSCNetworkReachabilityFlagsReachable) && (flags & kSCNetworkReachabilityFlagsIsDirect))
+       {
+               retVal = ReachableViaWiFi;      
+       }
+       return retVal;
+}
+
+- (NetworkStatus) networkStatusForFlags: (SCNetworkReachabilityFlags) flags
+{
+       PrintReachabilityFlags(flags, "networkStatusForFlags");
+       if ((flags & kSCNetworkReachabilityFlagsReachable) == 0)
+       {
+               // if target host is not reachable
+               return NotReachable;
+       }
+
+       BOOL retVal = NotReachable;
+       
+       if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0)
+       {
+               // if target host is reachable and no connection is required
+               //  then we'll assume (for now) that your on Wi-Fi
+               retVal = ReachableViaWiFi;
+       }
+       
+       
+       if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) ||
+               (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0))
+       {
+                       // ... and the connection is on-demand (or on-traffic) if the
+                       //     calling application is using the CFSocketStream or higher APIs
+
+                       if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0)
+                       {
+                               // ... and no [user] intervention is needed
+                               retVal = ReachableViaWiFi;
+                       }
+               }
+       
+       if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN)
+       {
+               // ... but WWAN connections are OK if the calling application
+               //     is using the CFNetwork (CFSocketStream?) APIs.
+               retVal = ReachableViaWWAN;
+       }
+       return retVal;
+}
+
+- (BOOL) connectionRequired;
+{
+       NSAssert(reachabilityRef != NULL, @"connectionRequired called with NULL reachabilityRef");
+       SCNetworkReachabilityFlags flags;
+       if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
+       {
+               return (flags & kSCNetworkReachabilityFlagsConnectionRequired);
+       }
+       return NO;
+}
+
+- (NetworkStatus) currentReachabilityStatus
+{
+       NSAssert(reachabilityRef != NULL, @"currentNetworkStatus called with NULL reachabilityRef");
+       NetworkStatus retVal = NotReachable;
+       SCNetworkReachabilityFlags flags;
+       if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
+       {
+               if(localWiFiRef)
+               {
+                       retVal = [self localWiFiStatusForFlags: flags];
+               }
+               else
+               {
+                       retVal = [self networkStatusForFlags: flags];
+               }
+       }
+       return retVal;
+}
+@end
diff --git a/client/iOS/Misc/SFHFKeychainUtils.h b/client/iOS/Misc/SFHFKeychainUtils.h
new file mode 100755 (executable)
index 0000000..45bd642
--- /dev/null
@@ -0,0 +1,41 @@
+//
+//  SFHFKeychainUtils.h
+//
+//  Created by Buzz Andersen on 10/20/08.
+//  Based partly on code by Jonathan Wight, Jon Crosby, and Mike Malone.
+//  Copyright 2008 Sci-Fi Hi-Fi. All rights reserved.
+//
+//  Permission is hereby granted, free of charge, to any person
+//  obtaining a copy of this software and associated documentation
+//  files (the "Software"), to deal in the Software without
+//  restriction, including without limitation the rights to use,
+//  copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the
+//  Software is furnished to do so, subject to the following
+//  conditions:
+//
+//  The above copyright notice and this permission notice shall be
+//  included in all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+//  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+//  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+//  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+//  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+//  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+//  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+//  OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#import <UIKit/UIKit.h>
+
+
+@interface SFHFKeychainUtils : NSObject {
+  
+}
+
++ (NSString *) getPasswordForUsername: (NSString *) username andServerName: (NSString *) serverName error: (NSError **) error;
++ (BOOL) storeUsername: (NSString *) username andPassword: (NSString *) password forServerName: (NSString *) serverName updateExisting: (BOOL) updateExisting error: (NSError **) error;
++ (BOOL) deleteItemForUsername: (NSString *) username andServerName: (NSString *) serverName error: (NSError **) error;
+
+@end
\ No newline at end of file
diff --git a/client/iOS/Misc/SFHFKeychainUtils.m b/client/iOS/Misc/SFHFKeychainUtils.m
new file mode 100755 (executable)
index 0000000..dba1e47
--- /dev/null
@@ -0,0 +1,434 @@
+//
+//  SFHFKeychainUtils.m
+//
+//  Created by Buzz Andersen on 10/20/08.
+//  Based partly on code by Jonathan Wight, Jon Crosby, and Mike Malone.
+//  Copyright 2008 Sci-Fi Hi-Fi. All rights reserved.
+//
+//  Permission is hereby granted, free of charge, to any person
+//  obtaining a copy of this software and associated documentation
+//  files (the "Software"), to deal in the Software without
+//  restriction, including without limitation the rights to use,
+//  copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the
+//  Software is furnished to do so, subject to the following
+//  conditions:
+//
+//  The above copyright notice and this permission notice shall be
+//  included in all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+//  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+//  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+//  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+//  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+//  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+//  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+//  OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#import "SFHFKeychainUtils.h"
+#import <Security/Security.h>
+
+static NSString *SFHFKeychainUtilsErrorDomain = @"SFHFKeychainUtilsErrorDomain";
+
+#if __IPHONE_OS_VERSION_MIN_REQUIRED < 30000 && TARGET_IPHONE_SIMULATOR
+@interface SFHFKeychainUtils (PrivateMethods)
++ (SecKeychainItemRef) getKeychainItemReferenceForUsername: (NSString *) username andServerName: (NSString *) serverName error: (NSError **) error;
+@end
+#endif
+
+@implementation SFHFKeychainUtils
+
+#if __IPHONE_OS_VERSION_MIN_REQUIRED < 30000 && TARGET_IPHONE_SIMULATOR
+
++ (NSString *) getPasswordForUsername: (NSString *) username andServerName: (NSString *) serverName error: (NSError **) error {
+       if (!username || !serviceName) {
+               *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: -2000 userInfo: nil];
+               return nil;
+       }
+       
+       SecKeychainItemRef item = [SFHFKeychainUtils getKeychainItemReferenceForUsername: username andServerName: serverName error: error];
+       
+       if (*error || !item) {
+               return nil;
+       }
+       
+       // from Advanced Mac OS X Programming, ch. 16
+  UInt32 length;
+  char *password;
+  SecKeychainAttribute attributes[8];
+  SecKeychainAttributeList list;
+       
+  attributes[0].tag = kSecAccountItemAttr;
+  attributes[1].tag = kSecDescriptionItemAttr;
+  attributes[2].tag = kSecLabelItemAttr;
+  attributes[3].tag = kSecModDateItemAttr;
+  
+  list.count = 4;
+  list.attr = attributes;
+  
+  OSStatus status = SecKeychainItemCopyContent(item, NULL, &list, &length, (void **)&password);
+       
+       if (status != noErr) {
+               *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: status userInfo: nil];
+               return nil;
+  }
+  
+       NSString *passwordString = nil;
+       
+       if (password != NULL) {
+               char passwordBuffer[1024];
+               
+               if (length > 1023) {
+                       length = 1023;
+               }
+               strncpy(passwordBuffer, password, length);
+               
+               passwordBuffer[length] = '\0';
+               passwordString = [NSString stringWithCString:passwordBuffer];
+       }
+       
+       SecKeychainItemFreeContent(&list, password);
+  
+  CFRelease(item);
+  
+  return passwordString;
+}
+
++ (void) storeUsername: (NSString *) username andPassword: (NSString *) password forServerName: (NSString *) serverName updateExisting: (BOOL) updateExisting error: (NSError **) error {      
+       if (!username || !password || !serverName) {
+               *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: -2000 userInfo: nil];
+               return;
+       }
+       
+       OSStatus status = noErr;
+       
+       SecKeychainItemRef item = [SFHFKeychainUtils getKeychainItemReferenceForUsername: username andServerName: serverName error: error];
+       
+       if (*error && [*error code] != noErr) {
+               return;
+       }
+       
+       *error = nil;
+       
+       if (item) {
+               status = SecKeychainItemModifyAttributesAndData(item,
+                                                    NULL,
+                                                    strlen([password UTF8String]),
+                                                    [password UTF8String]);
+               
+               CFRelease(item);
+       }
+       else {
+               status = SecKeychainAddGenericPassword(NULL,                                     
+                                           strlen([serverName UTF8String]), 
+                                           [serverName UTF8String],
+                                           strlen([username UTF8String]),                        
+                                           [username UTF8String],
+                                           strlen([password UTF8String]),
+                                           [password UTF8String],
+                                           NULL);               
+       }
+       
+       if (status != noErr) {
+               *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: status userInfo: nil];
+       }
+}
+
++ (void) deleteItemForUsername: (NSString *) username andServerName: (NSString *) serverName error: (NSError **) error {
+       if (!username || !serverName) {
+               *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: 2000 userInfo: nil];
+               return;
+       }
+       
+       *error = nil;
+       
+       SecKeychainItemRef item = [SFHFKeychainUtils getKeychainItemReferenceForUsername: username andServerName: serverName error: error];
+       
+       if (*error && [*error code] != noErr) {
+               return;
+       }
+       
+       OSStatus status;
+       
+       if (item) {
+               status = SecKeychainItemDelete(item);
+               
+               CFRelease(item);
+       }
+       
+       if (status != noErr) {
+               *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: status userInfo: nil];
+       }
+}
+
++ (SecKeychainItemRef) getKeychainItemReferenceForUsername: (NSString *) username andServerName: (NSString *) serverName error: (NSError **) error {
+       if (!username || !serverName) {
+               *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: -2000 userInfo: nil];
+               return nil;
+       }
+       
+       *error = nil;
+  
+       SecKeychainItemRef item;
+       
+       OSStatus status = SecKeychainFindGenericPassword(NULL,
+                                                   strlen([serverName UTF8String]),
+                                                   [serverName UTF8String],
+                                                   strlen([username UTF8String]),
+                                                   [username UTF8String],
+                                                   NULL,
+                                                   NULL,
+                                                   &item);
+       
+       if (status != noErr) {
+               if (status != errSecItemNotFound) {
+                       *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: status userInfo: nil];
+               }
+               
+               return nil;             
+       }
+       
+       return item;
+}
+
+#else
+
++ (NSString *) getPasswordForUsername: (NSString *) username andServerName: (NSString *) serverName error: (NSError **) error {
+       if (!username || !serverName) {
+               if (error != nil) {
+                       *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: -2000 userInfo: nil];
+               }
+               return nil;
+       }
+       
+       if (error != nil) {
+               *error = nil;
+       }
+  
+       // Set up a query dictionary with the base query attributes: item type (generic), username, and service
+       
+       NSArray *keys = [[[NSArray alloc] initWithObjects: (NSString *) kSecClass, kSecAttrAccount, kSecAttrService, nil] autorelease];
+       NSArray *objects = [[[NSArray alloc] initWithObjects: (NSString *) kSecClassGenericPassword, username, serverName, nil] autorelease];
+       
+       NSMutableDictionary *query = [[[NSMutableDictionary alloc] initWithObjects: objects forKeys: keys] autorelease];
+       
+       // First do a query for attributes, in case we already have a Keychain item with no password data set.
+       // One likely way such an incorrect item could have come about is due to the previous (incorrect)
+       // version of this code (which set the password as a generic attribute instead of password data).
+       
+       NSDictionary *attributeResult = NULL;
+       NSMutableDictionary *attributeQuery = [query mutableCopy];
+       [attributeQuery setObject: (id) kCFBooleanTrue forKey:(id) kSecReturnAttributes];
+       OSStatus status = SecItemCopyMatching((CFDictionaryRef) attributeQuery, (CFTypeRef *) &attributeResult);
+       
+       [attributeResult release];
+       [attributeQuery release];
+       
+       if (status != noErr) {
+               // No existing item found--simply return nil for the password
+               if (error != nil && status != errSecItemNotFound) {
+                       //Only return an error if a real exception happened--not simply for "not found."
+                       *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: status userInfo: nil];
+               }
+               
+               return nil;
+       }
+       
+       // We have an existing item, now query for the password data associated with it.
+       
+       NSData *resultData = nil;
+       NSMutableDictionary *passwordQuery = [query mutableCopy];
+       [passwordQuery setObject: (id) kCFBooleanTrue forKey: (id) kSecReturnData];
+  
+       status = SecItemCopyMatching((CFDictionaryRef) passwordQuery, (CFTypeRef *) &resultData);
+       
+       [resultData autorelease];
+       [passwordQuery release];
+       
+       if (status != noErr) {
+               if (status == errSecItemNotFound) {
+                       // We found attributes for the item previously, but no password now, so return a special error.
+                       // Users of this API will probably want to detect this error and prompt the user to
+                       // re-enter their credentials.  When you attempt to store the re-entered credentials
+                       // using storeUsername:andPassword:forServiceName:updateExisting:error
+                       // the old, incorrect entry will be deleted and a new one with a properly encrypted
+                       // password will be added.
+                       if (error != nil) {
+                               *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: -1999 userInfo: nil];
+                       }
+               }
+               else {
+                       // Something else went wrong. Simply return the normal Keychain API error code.
+                       if (error != nil) {
+                               *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: status userInfo: nil];
+                       }
+               }
+               
+               return nil;
+       }
+  
+       NSString *password = nil;       
+  
+       if (resultData) {
+               password = [[NSString alloc] initWithData: resultData encoding: NSUTF8StringEncoding];
+       }
+       else {
+               // There is an existing item, but we weren't able to get password data for it for some reason,
+               // Possibly as a result of an item being incorrectly entered by the previous code.
+               // Set the -1999 error so the code above us can prompt the user again.
+               if (error != nil) {
+                       *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: -1999 userInfo: nil];
+               }
+       }
+  
+       return [password autorelease];
+}
+
++ (BOOL) storeUsername: (NSString *) username andPassword: (NSString *) password forServerName: (NSString *) serverName updateExisting: (BOOL) updateExisting error: (NSError **) error 
+{              
+       if (!username || !password || !serverName) 
+  {
+               if (error != nil) 
+    {
+                       *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: -2000 userInfo: nil];
+               }
+               return NO;
+       }
+       
+       // See if we already have a password entered for these credentials.
+       NSError *getError = nil;
+       NSString *existingPassword = [SFHFKeychainUtils getPasswordForUsername: username andServerName: serverName error:&getError];
+  
+       if ([getError code] == -1999) 
+  {
+               // There is an existing entry without a password properly stored (possibly as a result of the previous incorrect version of this code.
+               // Delete the existing item before moving on entering a correct one.
+    
+               getError = nil;
+               
+               [self deleteItemForUsername: username andServerName: serverName error: &getError];
+    
+               if ([getError code] != noErr) 
+    {
+                       if (error != nil) 
+      {
+                               *error = getError;
+                       }
+                       return NO;
+               }
+       }
+       else if ([getError code] != noErr) 
+  {
+               if (error != nil) 
+    {
+                       *error = getError;
+               }
+               return NO;
+       }
+       
+       if (error != nil) 
+  {
+               *error = nil;
+       }
+       
+       OSStatus status = noErr;
+  
+       if (existingPassword) 
+  {
+               // We have an existing, properly entered item with a password.
+               // Update the existing item.
+               
+               if (![existingPassword isEqualToString:password] && updateExisting) 
+    {
+                       //Only update if we're allowed to update existing.  If not, simply do nothing.
+                       
+                       NSArray *keys = [[[NSArray alloc] initWithObjects: (NSString *) kSecClass, 
+                        kSecAttrService, 
+                        kSecAttrLabel, 
+                        kSecAttrAccount, 
+                        nil] autorelease];
+                       
+                       NSArray *objects = [[[NSArray alloc] initWithObjects: (NSString *) kSecClassGenericPassword, 
+                           serverName,
+                           serverName,
+                           username,
+                           nil] autorelease];
+                       
+                       NSDictionary *query = [[[NSDictionary alloc] initWithObjects: objects forKeys: keys] autorelease];                      
+                       
+                       status = SecItemUpdate((CFDictionaryRef) query, (CFDictionaryRef) [NSDictionary dictionaryWithObject: [password dataUsingEncoding: NSUTF8StringEncoding] forKey: (NSString *) kSecValueData]);
+               }
+       }
+       else 
+  {
+               // No existing entry (or an existing, improperly entered, and therefore now
+               // deleted, entry).  Create a new entry.
+               
+               NSArray *keys = [[[NSArray alloc] initWithObjects: (NSString *) kSecClass, 
+                      kSecAttrService, 
+                      kSecAttrLabel, 
+                      kSecAttrAccount, 
+                      kSecValueData, 
+                      nil] autorelease];
+               
+               NSArray *objects = [[[NSArray alloc] initWithObjects: (NSString *) kSecClassGenericPassword, 
+                         serverName,
+                         serverName,
+                         username,
+                         [password dataUsingEncoding: NSUTF8StringEncoding],
+                         nil] autorelease];
+               
+               NSDictionary *query = [[[NSDictionary alloc] initWithObjects: objects forKeys: keys] autorelease];                      
+    
+               status = SecItemAdd((CFDictionaryRef) query, NULL);
+       }
+       
+       if (error != nil && status != noErr) 
+  {
+               // Something went wrong with adding the new item. Return the Keychain error code.
+               *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: status userInfo: nil];
+    
+    return NO;
+       }
+  
+  return YES;
+}
+
++ (BOOL) deleteItemForUsername: (NSString *) username andServerName: (NSString *) serverName error: (NSError **) error 
+{
+       if (!username || !serverName) 
+  {
+               if (error != nil) 
+    {
+                       *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: -2000 userInfo: nil];
+               }
+               return NO;
+       }
+       
+       if (error != nil) 
+  {
+               *error = nil;
+       }
+  
+       NSArray *keys = [[[NSArray alloc] initWithObjects: (NSString *) kSecClass, kSecAttrAccount, kSecAttrService, kSecReturnAttributes, nil] autorelease];
+       NSArray *objects = [[[NSArray alloc] initWithObjects: (NSString *) kSecClassGenericPassword, username, serverName, kCFBooleanTrue, nil] autorelease];
+       
+       NSDictionary *query = [[[NSDictionary alloc] initWithObjects: objects forKeys: keys] autorelease];
+       
+       OSStatus status = SecItemDelete((CFDictionaryRef) query);
+       
+       if (error != nil && status != noErr) 
+  {
+               *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: status userInfo: nil];            
+    
+    return NO;
+       }
+  
+  return YES;
+}
+
+#endif
+
+@end
\ No newline at end of file
diff --git a/client/iOS/Misc/TSXTypes.h b/client/iOS/Misc/TSXTypes.h
new file mode 100644 (file)
index 0000000..c5d8ecd
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ Basic type defines for TSX RDC
+ Copyright 2013 Thinstuff Technologies GmbH, Authors: Martin Fleisz, Dorian Johnson
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef TSXRemoteDesktop_TSXTypes_h
+#define TSXRemoteDesktop_TSXTypes_h
+
+#pragma mark Internal state
+
+// Represents the underlying state of a TWSession RDP connection.
+typedef enum _TSXConnectionState
+{
+       TSXConnectionClosed = 0,       // Session either hasn't begun connecting, or its connection has finished disconnecting.
+    TSXConnectionConnecting = 1,   // Session is in the process of establishing an RDP connection. A TCP or SSL connection might be established, but the RDP initialization sequence isn't finished.
+       TSXConnectionConnected = 2,    // Session has a full RDP connection established; though if the windows computer doesn't support NLA, a login screen might be shown in the session.
+       TSXConnectionDisconnected = 3  // Session is disconnected at the RDP layer. TSX RDC might still be disposing of resources, however.
+} TSXConnectionState;
+
+#pragma mark Session settings
+
+// Represents the type of screen resolution the user has selected. Most are dynamic sizes, meaning that the actual session dimensions are calculated when connecting.
+typedef enum _TSXScreenOptions
+{
+       TSXScreenOptionFixed = 0,      // A static resolution, like 1024x768
+       TSXScreenOptionFitScreen = 1,   // Upon connection, fit the session to the entire screen size
+       TSXScreenOptionCustom = 2,      // Like fixed just specified by the user
+} TSXScreenOptions;
+
+typedef enum _TSXAudioPlaybackOptions
+{
+       TSXAudioPlaybackLocal  = 0,
+       TSXAudioPlaybackServer = 1,
+       TSXAudioPlaybackSilent = 2
+} TSXAudioPlaybackOptions;
+
+typedef enum _TSXProtocolSecurityOptions
+{
+       TSXProtocolSecurityAutomatic  = 0,
+       TSXProtocolSecurityRDP  = 1,
+       TSXProtocolSecurityTLS = 2,
+       TSXProtocolSecurityNLA = 3
+} TSXProtocolSecurityOptions;
+
+#endif
diff --git a/client/iOS/Misc/Utils.h b/client/iOS/Misc/Utils.h
new file mode 100644 (file)
index 0000000..a252f6d
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ Utility functions
+ Copyright 2013 Thinstuff Technologies GmbH, Authors: Martin Fleisz, Dorian Johnson
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import <Foundation/Foundation.h>
+#import "TSXTypes.h"
+
+// helper macro to encode a table path into a tag value (used to identify controls in their delegate handlers)
+#define GET_TAG(section, row) ((((int)section) << 16) | ((int)(row)))
+#define GET_TAG_FROM_PATH(path) ((((int)path.section) << 16) | ((int)(path.row)))
+
+
+BOOL ScanHostNameAndPort(NSString* address, NSString** host, unsigned short* port);
+
+#pragma mark -
+#pragma mark Screen Resolutions
+
+NSString* ScreenResolutionDescription(TSXScreenOptions type, int width, int height);
+BOOL ScanScreenResolution(NSString* description, int* width, int* height, TSXScreenOptions* type);
+
+NSDictionary* SelectionForColorSetting();
+NSArray* ResolutionModes();
+
+#pragma mark Security Protocol
+
+NSString* ProtocolSecurityDescription(TSXProtocolSecurityOptions type);
+BOOL ScanProtocolSecurity(NSString* description, TSXProtocolSecurityOptions* type);
+NSDictionary* SelectionForSecuritySetting();
+
+#pragma mark Bookmarks
+@class BookmarkBase;
+NSMutableArray* FilterBookmarks(NSArray* bookmarks, NSArray* filter_words);
+NSMutableArray* FilterHistory(NSArray* history, NSString* filterStr);
+
+#pragma mark iPad/iPhone detection
+
+BOOL IsPad();
+BOOL IsPhone();
+
+#pragma mark Version Info
+NSString* TSXAppFullVersion();
+
+#pragma mark Touch/Mouse handling
+
+// set mouse buttons swapped flag
+void SetSwapMouseButtonsFlag(BOOL swapped);
+
+// set invert scrolling flag
+void SetInvertScrollingFlag(BOOL invert);
+
+// return event value for left mouse button 
+int GetLeftMouseButtonClickEvent(BOOL down);
+
+// return event value for right mouse button 
+int GetRightMouseButtonClickEvent(BOOL down);
+
+// return event value for mouse move event
+int GetMouseMoveEvent();
+
+// return mouse wheel event
+int GetMouseWheelEvent(BOOL down);
+
+// scrolling gesture detection delta
+CGFloat GetScrollGestureDelta();
+
+#pragma mark Connectivity tools
+// activates the iphone's WWAN interface in case it is offline
+void WakeUpWWAN();
+
+#pragma mark System Info functions
+NSString* TSXGetPlatform();
+BOOL TSXDeviceHasJailBreak();
+NSString* TSXGetPrimaryMACAddress(NSString *sep);
+
diff --git a/client/iOS/Misc/Utils.m b/client/iOS/Misc/Utils.m
new file mode 100644 (file)
index 0000000..e627ad3
--- /dev/null
@@ -0,0 +1,371 @@
+/*
+ Utility functions
+ Copyright 2013 Thinstuff Technologies GmbH, Authors: Martin Fleisz, Dorian Johnson
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "Utils.h"
+#import "OrderedDictionary.h"
+#import "TSXAdditions.h"
+
+#import <freerdp/input.h>
+#import "config.h"
+
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <sys/socket.h>
+#include <ifaddrs.h>
+#include <net/if_dl.h>
+
+BOOL ScanHostNameAndPort(NSString* address, NSString** host, unsigned short* port)
+{
+       *host = @""; *port = 0;
+       
+       if (![address length])
+               return NO;
+       
+       NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:@"rdp://%@", address]];
+       
+       if (!url || ![[url host] length])
+               return NO;
+       
+       *host = [url host];
+       *port = [[url port] unsignedShortValue];
+       return YES;
+}
+
+#pragma mark -
+#pragma mark Working with Screen Resolutions
+
+NSString* LocalizedFitScreen()
+{
+    return NSLocalizedString(@"Automatic", @"Screen resolution selector: Automatic resolution (Full Screen on iPad, reasonable size on iPhone)");    
+}
+
+NSString* LocalizedCustom()
+{
+    return NSLocalizedString(@"Custom", @"Screen resolution selector: Custom");    
+}
+
+BOOL ScanScreenResolution(NSString* description, int* width, int* height, TSXScreenOptions* type)
+{
+       *height = 0; *width = 0; *type = TSXScreenOptionFixed;
+       
+       if ([description isEqualToString:LocalizedFitScreen()])
+       {
+               *type = TSXScreenOptionFitScreen;
+               return YES;
+       }
+       else if ([description isEqualToString:LocalizedCustom()])
+       {
+               *type = TSXScreenOptionCustom;
+               return YES;
+       }
+    
+       NSArray* resolution_components = [description componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"x*×"]];
+       
+       if ([resolution_components count] != 2)
+               return NO;
+       
+       *width = [[resolution_components objectAtIndex:0] intValue];
+       *height = [[resolution_components objectAtIndex:1] intValue];   
+       return YES;
+}
+
+NSString* ScreenResolutionDescription(TSXScreenOptions type, int width, int height)
+{
+       if (type == TSXScreenOptionFitScreen)
+               return LocalizedFitScreen();
+       else if (type == TSXScreenOptionCustom)
+               return LocalizedCustom();
+    
+       return [NSString stringWithFormat:@"%dx%d", width, height];
+}
+
+
+NSDictionary* SelectionForColorSetting()
+{
+    OrderedDictionary* dict = [OrderedDictionary dictionaryWithCapacity:3];
+    [dict setValue:[NSNumber numberWithInt:16] forKey:NSLocalizedString(@"High Color (16 Bit)", @"16 bit color selection")];
+    [dict setValue:[NSNumber numberWithInt:24] forKey:NSLocalizedString(@"True Color (24 Bit)", @"24 bit color selection")];
+    [dict setValue:[NSNumber numberWithInt:32] forKey:NSLocalizedString(@"Highest Quality (32 Bit)", @"32 bit color selection")];
+    return dict;
+}
+
+NSArray* ResolutionModes()
+{
+    NSArray* array = [NSArray arrayWithObjects:ScreenResolutionDescription(TSXScreenOptionFitScreen, 0, 0),
+                                               ScreenResolutionDescription(TSXScreenOptionFixed, 640, 480),                      
+                                               ScreenResolutionDescription(TSXScreenOptionFixed, 800, 600),
+                                               ScreenResolutionDescription(TSXScreenOptionFixed, 1024, 768),
+                                               ScreenResolutionDescription(TSXScreenOptionFixed, 1280, 1024),
+                                               ScreenResolutionDescription(TSXScreenOptionFixed, 1440, 900),
+                                               ScreenResolutionDescription(TSXScreenOptionFixed, 1440, 1050),
+                                               ScreenResolutionDescription(TSXScreenOptionFixed, 1600, 1200),
+                                               ScreenResolutionDescription(TSXScreenOptionFixed, 1920, 1080),
+                                               ScreenResolutionDescription(TSXScreenOptionFixed, 1920, 1200),
+                                               ScreenResolutionDescription(TSXScreenOptionCustom, 0, 0), nil];
+    return array;    
+}
+
+#pragma mark Working with Security Protocols
+
+NSString* LocalizedAutomaticSecurity()
+{
+    return NSLocalizedString(@"Automatic", @"Automatic protocl security selection");    
+}
+
+NSString* ProtocolSecurityDescription(TSXProtocolSecurityOptions type)
+{
+       if (type == TSXProtocolSecurityNLA)
+               return @"NLA";
+       else if (type == TSXProtocolSecurityTLS)
+               return @"TLS";
+       else if (type == TSXProtocolSecurityRDP)
+               return @"RDP";
+    
+       return LocalizedAutomaticSecurity();
+}
+
+BOOL ScanProtocolSecurity(NSString* description, TSXProtocolSecurityOptions* type)
+{
+       *type = TSXProtocolSecurityRDP;
+       
+       if ([description isEqualToString:@"NLA"])
+       {
+               *type = TSXProtocolSecurityNLA;
+               return YES;
+       }
+       else if ([description isEqualToString:@"TLS"])
+       {
+               *type = TSXProtocolSecurityTLS;
+               return YES;
+       }
+       else if ([description isEqualToString:@"RDP"])
+       {
+               *type = TSXProtocolSecurityRDP;
+               return YES;
+       }
+       else if ([description isEqualToString:LocalizedAutomaticSecurity()])
+       {
+               *type = TSXProtocolSecurityAutomatic;
+               return YES;
+       }
+    
+       return NO;
+}
+
+NSDictionary* SelectionForSecuritySetting()
+{
+    OrderedDictionary* dict = [OrderedDictionary dictionaryWithCapacity:4];
+    [dict setValue:[NSNumber numberWithInt:TSXProtocolSecurityAutomatic] forKey:ProtocolSecurityDescription(TSXProtocolSecurityAutomatic)];
+    [dict setValue:[NSNumber numberWithInt:TSXProtocolSecurityRDP] forKey:ProtocolSecurityDescription(TSXProtocolSecurityRDP)];
+    [dict setValue:[NSNumber numberWithInt:TSXProtocolSecurityTLS] forKey:ProtocolSecurityDescription(TSXProtocolSecurityTLS)];
+    [dict setValue:[NSNumber numberWithInt:TSXProtocolSecurityNLA] forKey:ProtocolSecurityDescription(TSXProtocolSecurityNLA)];
+    return dict;
+}
+
+
+#pragma mark -
+#pragma mark Bookmarks
+
+#import "Bookmark.h"
+
+NSMutableArray* FilterBookmarks(NSArray* bookmarks, NSArray* filter_words)
+{
+       NSMutableArray* matching_items = [NSMutableArray array];
+    NSArray* searched_keys = [NSArray arrayWithObjects:@"label", @"params.hostname", @"params.username", @"params.domain", nil];
+    
+    for (ComputerBookmark* cur_bookmark in bookmarks)
+    {
+        double match_score = 0.0; 
+        for (int i = 0; i < [searched_keys count]; i++)
+        {
+            NSString* val = [cur_bookmark valueForKeyPath:[searched_keys objectAtIndex:i]];
+            
+            if (![val isKindOfClass:[NSString class]] || ![val length])
+                continue;
+            
+            for (NSString* word in filter_words)
+                if ([val rangeOfString:word options:(NSCaseInsensitiveSearch | NSWidthInsensitiveSearch)].location != NSNotFound)
+                    match_score += (1.0 / [filter_words count]) * pow(2, [searched_keys count] - i);
+        }
+        
+        if (match_score > 0.001)
+            [matching_items addObject:[NSDictionary dictionaryWithObjectsAndKeys:
+                                       cur_bookmark, @"bookmark",
+                                       [NSNumber numberWithFloat:match_score], @"score",
+                                       nil]];
+    }
+       
+       [matching_items sortUsingComparator:^NSComparisonResult(NSDictionary* obj1, NSDictionary* obj2) {
+               return [[obj2 objectForKey:@"score"] compare:[obj1 objectForKey:@"score"]];
+       }];
+    
+       return matching_items;
+}
+
+NSMutableArray* FilterHistory(NSArray* history, NSString* filterStr)
+{
+    NSMutableArray* result = [NSMutableArray array];
+    for (NSString* item in history)
+    {
+        if ([item rangeOfString:filterStr].location != NSNotFound)
+            [result addObject:item];
+    }
+    
+    return result;
+}
+
+#pragma mark Version Info
+NSString* TSXAppFullVersion()
+{
+       NSDictionary* info_dict = [[NSBundle mainBundle] infoDictionary];
+       return [NSString stringWithFormat:@"%@.%@ (%@)", [info_dict objectForKey:@"CFBundleShortVersionString"], [info_dict objectForKey:@"CFBundleVersion"], [NSString stringWithUTF8String:GIT_REVISION]];
+}
+
+#pragma mark iPad/iPhone detection
+
+BOOL IsPad()
+{
+#ifdef UI_USER_INTERFACE_IDIOM
+    return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
+#else
+    return NO;
+#endif
+}
+
+BOOL IsPhone()
+{
+#ifdef UI_USER_INTERFACE_IDIOM
+    return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone);
+#else
+    return NO;
+#endif    
+}
+
+// set mouse buttons swapped flag
+static BOOL g_swap_mouse_buttons = NO;
+void SetSwapMouseButtonsFlag(BOOL swapped)
+{
+    g_swap_mouse_buttons = swapped;    
+}
+
+// set invert scrolling flag
+static BOOL g_invert_scrolling = NO;
+void SetInvertScrollingFlag(BOOL invert)
+{
+    g_invert_scrolling = invert;
+}
+
+// return event value for left mouse button 
+int GetLeftMouseButtonClickEvent(BOOL down)
+{
+    if (g_swap_mouse_buttons)
+        return (PTR_FLAGS_BUTTON2 | (down ? PTR_FLAGS_DOWN : 0));
+    else
+        return (PTR_FLAGS_BUTTON1 | (down ? PTR_FLAGS_DOWN : 0));
+}
+
+// return event value for right mouse button 
+int GetRightMouseButtonClickEvent(BOOL down)
+{
+    if (g_swap_mouse_buttons)
+        return (PTR_FLAGS_BUTTON1 | (down ? PTR_FLAGS_DOWN : 0));
+    else
+        return (PTR_FLAGS_BUTTON2 | (down ? PTR_FLAGS_DOWN : 0));
+}
+
+// get mouse move event
+int GetMouseMoveEvent()
+{
+    return (PTR_FLAGS_MOVE);    
+}
+
+// return mouse wheel event
+int GetMouseWheelEvent(BOOL down)
+{
+    if (g_invert_scrolling)
+        down = !down;
+    
+    if(down)
+        return (PTR_FLAGS_WHEEL | PTR_FLAGS_WHEEL_NEGATIVE | (0x0088));
+    else
+        return (PTR_FLAGS_WHEEL | (0x0078));    
+}
+
+// scrolling gesture detection delta
+CGFloat GetScrollGestureDelta()
+{
+    return 10.0f;
+}
+
+// this hack activates the iphone's WWAN interface in case it is offline
+void WakeUpWWAN()
+{
+    NSURL * url = [[[NSURL alloc] initWithString:@"http://www.nonexistingdummyurl.com"] autorelease];
+    //NSData * data =
+    [NSData dataWithContentsOfURL:url]; // we don't need data but assigning one causes a "data not used" compiler warning
+}
+
+
+#pragma mark System Info functions
+
+NSString* TSXGetPrimaryMACAddress(NSString *sep)
+{
+    NSString* macaddress = @"";
+
+    struct ifaddrs *addrs;
+
+    if (getifaddrs(&addrs) < 0)
+    {
+        NSLog(@"getPrimaryMACAddress: getifaddrs failed.");
+        return macaddress;
+    }
+
+    for (struct ifaddrs *cursor = addrs; cursor!=NULL; cursor = cursor->ifa_next) 
+    {
+        if(strcmp(cursor->ifa_name, "en0"))
+            continue;
+        if( (cursor->ifa_addr->sa_family == AF_LINK) 
+           && (((struct sockaddr_dl *) cursor->ifa_addr)->sdl_type == 0x6 /*IFT_ETHER*/))  
+        {
+            struct sockaddr_dl *dlAddr = (struct sockaddr_dl *) cursor->ifa_addr;
+            if(dlAddr->sdl_alen != 6)
+                continue;
+            unsigned char* base = (unsigned char *) &dlAddr->sdl_data[dlAddr->sdl_nlen];
+            macaddress = [NSString hexStringFromData:base ofSize:6 withSeparator:sep afterNthChar:1];
+            break;
+        }
+    }
+
+    freeifaddrs(addrs);
+
+    return macaddress;
+}
+
+BOOL TSXDeviceHasJailBreak()
+{
+    if ([[NSFileManager defaultManager] fileExistsAtPath:@"/Applications/Cydia.app/"])
+        return YES;
+
+    if ([[NSFileManager defaultManager] fileExistsAtPath:@"/etc/apt/"])
+        return YES;
+
+    return NO; 
+}
+
+NSString* TSXGetPlatform()
+{
+    size_t size;
+    sysctlbyname("hw.machine", NULL, &size, NULL, 0);
+    char *machine = malloc(size);
+    sysctlbyname("hw.machine", machine, &size, NULL, 0);
+    NSString *platform = [NSString stringWithCString:machine encoding:NSASCIIStringEncoding];
+    free(machine);
+    return platform;
+}
+
diff --git a/client/iOS/Models/Bookmark.h b/client/iOS/Models/Bookmark.h
new file mode 100644 (file)
index 0000000..bcaaca0
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ Bookmark model abstraction
+ Copyright 2013 Thinstuff Technologies GmbH, Authors: Dorian Johnson
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+
+#import <Foundation/Foundation.h>
+#import "ConnectionParams.h"
+
+@interface ComputerBookmark : NSObject <NSCoding> {
+@protected
+       ComputerBookmark* _parent;
+       NSString* _uuid, * _label;
+       UIImage* _image;
+    ConnectionParams* _connection_params;
+    BOOL _connected_via_wlan;
+}
+
+@property (nonatomic,assign)   ComputerBookmark* parent;
+@property (nonatomic,readonly) NSString* uuid;
+@property (nonatomic,copy)     NSString* label;
+@property (nonatomic,retain)   UIImage* image;
+@property (readonly, nonatomic) ConnectionParams* params;
+@property (nonatomic, assign) BOOL conntectedViaWLAN;
+
+// Creates a copy of this object, with a new UUID
+- (id)copy;
+
+// Whether user can delete, move, or rename this entry
+- (BOOL)isDeletable;
+- (BOOL)isMovable;
+- (BOOL)isRenamable;
+- (BOOL)hasImmutableHost;
+
+- (id)initWithConnectionParameters:(ConnectionParams*)params;
+- (id)initWithBaseDefaultParameters;
+
+// A copy of @params, with _bookmark_uuid set.
+- (ConnectionParams*)copyMarkedParams;
+
+@end
+
diff --git a/client/iOS/Models/Bookmark.m b/client/iOS/Models/Bookmark.m
new file mode 100644 (file)
index 0000000..2ce7903
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ Bookmark model abstraction
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Dorian Johnson
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+
+#import "Bookmark.h"
+#import "TSXAdditions.h"
+#import "Utils.h"
+
+#import "GlobalDefaults.h"
+
+@interface ComputerBookmark (Private)
+- (void)willChangeValueForKeyPath:(NSString *)keyPath;
+- (void)didChangeValueForKeyPath:(NSString *)keyPath;
+@end
+
+@implementation ComputerBookmark
+
+@synthesize parent=_parent, uuid=_uuid, label=_label, image=_image;
+@synthesize params=_connection_params, conntectedViaWLAN = _connected_via_wlan;
+
+
+- (id)init
+{
+    if (!(self = [super init]))
+               return nil;
+       
+       _uuid = [[NSString stringWithUUID] retain];
+       _label = @"";
+    _connected_via_wlan = NO;
+    return self;
+}
+
+// Designated initializer.
+- (id)initWithConnectionParameters:(ConnectionParams*)params
+{
+       if (!(self = [super init]))
+               return nil;
+       
+       _connection_params = [params copy];
+    _connected_via_wlan = NO;
+       return self;
+}
+
+
+- (id)initWithCoder:(NSCoder *)decoder
+{
+       if (!(self = [self init]))
+               return nil;
+       
+       if (![decoder allowsKeyedCoding])
+               [NSException raise:NSInvalidArgumentException format:@"coder must support keyed archiving"];
+               
+       if ([decoder containsValueForKey:@"uuid"])
+       {
+               [_uuid release];
+               _uuid = [[decoder decodeObjectForKey:@"uuid"] retain]; 
+       }
+       
+       if ([decoder containsValueForKey:@"label"])
+               [self setLabel:[decoder decodeObjectForKey:@"label"]];
+    
+       if ([decoder containsValueForKey:@"connectionParams"])
+       {
+               [_connection_params release];
+               _connection_params = [[decoder decodeObjectForKey:@"connectionParams"] retain];
+       }
+       
+       return self;
+}
+
+- (id)initWithBaseDefaultParameters
+{
+       return [self initWithConnectionParameters:[[[ConnectionParams alloc] initWithBaseDefaultParameters] autorelease]];
+}
+
+- (id)copy
+{
+    ComputerBookmark* copy = [[[self class] alloc] init];
+       [copy setLabel:[self label]];
+       copy->_connection_params = [_connection_params copy];
+       return copy;
+}
+
+- (void)encodeWithCoder:(NSCoder *)coder
+{
+       if (![coder allowsKeyedCoding])
+               [NSException raise:NSInvalidArgumentException format:@"coder must support keyed archiving"];
+       
+       [coder encodeObject:_uuid forKey:@"uuid"];
+       [coder encodeObject:_label forKey:@"label"];
+       [coder encodeObject:_connection_params forKey:@"connectionParams"];
+}
+
+- (void)dealloc
+{      
+       _parent = nil;
+       [_label release]; _label = nil;
+       [_uuid release]; _uuid = nil;
+       [_connection_params release]; _connection_params = nil;
+       [super dealloc];
+}
+
+- (UIImage*)image
+{
+    return nil;
+}
+
+- (BOOL)isEqual:(id)object
+{
+       return [object respondsToSelector:@selector(uuid)] && [[object uuid] isEqual:_uuid];
+}
+
+- (NSString*)description
+{
+       return ([self label] != nil) ? [self label] : _uuid;
+}
+
+- (BOOL)validateValue:(id *)val forKey:(NSString *)key error:(NSError **)error
+{
+       NSString* string_value = *val;
+       
+       if ([key isEqualToString:@"label"])
+       {
+               if (![[string_value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length])
+               {
+                       if (error)
+                               *error = [NSError errorWithDomain:@"" code:NSKeyValueValidationError userInfo:
+                          [NSDictionary dictionaryWithObjectsAndKeys:
+                           NSLocalizedString(@"Connection labels cannot be blank", @"Bookmark data validation: label blank title."), NSLocalizedDescriptionKey, 
+                           NSLocalizedString(@"Please enter the short description of this Connection that will appear in the Connection list.", @"Bookmark data validation: label blank message."), NSLocalizedRecoverySuggestionErrorKey, 
+                           nil]];
+                       return NO;
+               }
+       }
+    
+       return YES;
+}
+
+- (BOOL)validateValue:(id *)val forKeyPath:(NSString *)keyPath error:(NSError **)error
+{
+       // Could be used to validate params.hostname, params.password, params.port, etc.
+       return [super validateValue:val forKeyPath:keyPath error:error];
+}
+
+- (BOOL)isDeletable { return YES; }
+- (BOOL)isMovable   { return YES; }
+- (BOOL)isRenamable { return YES; }
+- (BOOL)hasImmutableHost { return NO; }
+
+
+#pragma mark Custom KVC
+
+- (void)setValue:(id)value forKeyPath:(NSString *)keyPath
+{
+       if ([keyPath isEqualToString:@"params.resolution"])
+       {
+               int width, height;
+               TSXScreenOptions type;
+               if (ScanScreenResolution(value, &width, &height, &type))
+               {
+                       [_connection_params willChangeValueForKey:@"resolution"];
+                       [[self params] setInt:type forKey:@"screen_resolution_type"];
+                       
+                       if (type == TSXScreenOptionFixed)
+                       {
+                               [[self params] setInt:width forKey:@"width"];
+                               [[self params] setInt:height forKey:@"height"];
+                       }
+                       [_connection_params didChangeValueForKey:@"resolution"];
+               }
+               else
+                       [NSException raise:NSInvalidArgumentException format:@"%s got invalid screen resolution '%@'", __func__, value];
+       }
+       else
+       {
+               [self willChangeValueForKeyPath:keyPath];
+               [super setValue:value forKeyPath:keyPath];      
+               [self didChangeValueForKeyPath:keyPath];
+       }
+}
+
+- (id)valueForKeyPath:(NSString *)keyPath
+{
+       if ([keyPath isEqualToString:@"params.resolution"])
+               return ScreenResolutionDescription([[self params] intForKey:@"screen_resolution_type"], [[self params] intForKey:@"width"], [[self params] intForKey:@"height"]);
+       
+       return [super valueForKeyPath:keyPath];
+}
+
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
+{      
+       if ([[change objectForKey:NSKeyValueChangeNotificationIsPriorKey] boolValue])
+               [self willChangeValueForKeyPath:keyPath];
+       else
+               [self didChangeValueForKeyPath:keyPath];        
+}
+
+- (NSDictionary*)targetForChangeNotificationForKeyPath:(NSString*)keyPath
+{
+       NSString* changed_key = keyPath;
+       NSObject* changed_object = self;
+       
+       if ([keyPath rangeOfString:@"params."].location == 0)
+       {
+               changed_key = [keyPath substringFromIndex:[@"params." length]];
+               changed_object = _connection_params;
+       }
+       
+       return [NSDictionary dictionaryWithObjectsAndKeys:changed_key, @"key", changed_object, @"object", nil];
+}
+
+- (void)willChangeValueForKeyPath:(NSString *)keyPath
+{
+       NSDictionary* target = [self targetForChangeNotificationForKeyPath:keyPath];    
+       [[target objectForKey:@"object"] willChangeValueForKey:[target objectForKey:@"key"]];
+}
+
+- (void)didChangeValueForKeyPath:(NSString *)keyPath
+{
+       NSDictionary* target = [self targetForChangeNotificationForKeyPath:keyPath];    
+       [[target objectForKey:@"object"] didChangeValueForKey:[target objectForKey:@"key"]];
+}
+
+- (ConnectionParams*)copyMarkedParams
+{
+       ConnectionParams* param_copy = [[self params] copy];
+       [param_copy setValue:[self uuid] forKey:@"_bookmark_uuid"];
+       return param_copy;
+}
+
+
+#pragma mark No children
+- (NSUInteger)numberOfChildren { return 0; }
+- (NSUInteger)numberOfDescendants { return 1; }
+- (BookmarkBase *)childAtIndex:(NSUInteger)index { return nil; }
+- (NSUInteger)indexOfChild:(BookmarkBase *)child { return 0; }
+- (void)removeChild:(BookmarkBase *)child { }
+- (void)addChild:(BookmarkBase *)child { }
+- (void)addChild:(BookmarkBase *)child afterExistingChild:(BookmarkBase *)existingChild { }
+- (void)addChild:(BookmarkBase *)child atIndex:(NSInteger)index { }
+- (BOOL)hasDescendant:(BookmarkBase *)needle { return NO; }
+- (BOOL)canContainChildren { return NO; }
+@end
+
diff --git a/client/iOS/Models/ConnectionParams.h b/client/iOS/Models/ConnectionParams.h
new file mode 100644 (file)
index 0000000..72136b9
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ Connection Parameters abstraction
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Dorian Johnson
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+
+#import <Foundation/Foundation.h>
+
+@interface ConnectionParams : NSObject
+{
+@private
+    NSMutableDictionary* _connection_params;
+}
+
+// Designated initializer.
+- (id)initWithDictionary:(NSDictionary*)dict;
+- (id)initWithBaseDefaultParameters;
+
+// Getting/setting values
+- (NSArray*)allKeys;
+- (void)setValue:(id)value forKey:(NSString *)key;
+- (id)valueForKey:(NSString*)key;
+- (BOOL)hasValueForKey:(NSString*)key;
+- (void)setInt:(int)integer forKey:(NSString*)key;
+- (int)intForKey:(NSString*)key;
+- (void)setBool:(BOOL)v forKey:(NSString*)key;
+- (BOOL)boolForKey:(NSString*)key;
+- (const char*)UTF8StringForKey:(NSString*)key;
+- (NSString*)StringForKey:(NSString*)key;
+
+- (BOOL)hasValueForKeyPath:(NSString*)key;
+- (void)setInt:(int)integer forKeyPath:(NSString*)key;
+- (int)intForKeyPath:(NSString*)key;
+- (void)setBool:(BOOL)v forKeyPath:(NSString*)key;
+- (BOOL)boolForKeyPath:(NSString*)key;
+- (const char*)UTF8StringForKeyPath:(NSString*)key;
+- (NSString*)StringForKeyPath:(NSString*)key;
+
+
+- (int)intForKey:(NSString*)key with3GEnabled:(BOOL)enabled;
+- (BOOL)boolForKey:(NSString*)key with3GEnabled:(BOOL)enabled;
+
+@end
diff --git a/client/iOS/Models/ConnectionParams.m b/client/iOS/Models/ConnectionParams.m
new file mode 100644 (file)
index 0000000..030216a
--- /dev/null
@@ -0,0 +1,247 @@
+/*
+ Connection Parameters abstraction
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Dorian Johnson
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+
+#import "ConnectionParams.h"
+#import "GlobalDefaults.h"
+#import "EncryptionController.h"
+#import "Utils.h"
+#import "TSXAdditions.h"
+
+@interface ConnectionParams (Private)
+- (id)initWithConnectionParams:(ConnectionParams*)params;
+@end
+
+@implementation ConnectionParams
+
+// Designated initializer.
+- (id)initWithDictionary:(NSDictionary*)dict
+{
+       if (!(self = [super init]))
+               return nil;
+       
+       _connection_params = [dict mutableDeepCopy];
+       
+       if ([[_connection_params objectForKey:@"password"] isKindOfClass:[NSData class]])
+       {
+               NSString* plaintext_password = [[[EncryptionController sharedEncryptionController] decryptor] decryptString:[_connection_params objectForKey:@"password"]];
+        
+               [self setValue:plaintext_password forKey:@"password"];
+       }
+       
+       return self;
+}
+
+- (id)initWithBaseDefaultParameters
+{
+       return [self initWithDictionary:[[NSUserDefaults standardUserDefaults] dictionaryForKey:@"TSXDefaultComputerBookmarkSettings"]];
+}
+
+- (id)init
+{
+       return [self initWithDictionary:[NSDictionary dictionary]];
+}
+
+- (id)initWithConnectionParams:(ConnectionParams*)params
+{
+       return [self initWithDictionary:params->_connection_params];
+}
+- (void)dealloc
+{
+       [_connection_params release]; _connection_params = nil; 
+       [super dealloc];
+}
+
+- (id)copyWithZone:(NSZone *)zone
+{
+       return [[ConnectionParams alloc] initWithDictionary:_connection_params];
+}
+
+- (NSString*)description
+{
+       return [NSString stringWithFormat:@"ConnectionParams: %@", [_connection_params description]];
+}
+
+#pragma mark -
+#pragma mark NSCoder
+
+- (id)initWithCoder:(NSCoder *)decoder
+{
+       if ([decoder containsValueForKey:@"connectionParams"])
+               return [self initWithDictionary:[decoder decodeObjectForKey:@"connectionParams"]];
+       
+       return [self init];
+}
+
+- (void)encodeWithCoder:(NSCoder *)coder
+{      
+       NSSet* unserializable_keys = [NSSet setWithObjects:@"view", nil];
+       NSMutableDictionary* serializable_params = [[NSMutableDictionary alloc] initWithCapacity:[_connection_params count]];
+       
+       for (NSString* k in _connection_params)
+               if ( ([k characterAtIndex:0] != '_') && ![unserializable_keys containsObject:k])
+                       [serializable_params setObject:[_connection_params objectForKey:k] forKey:k];
+       
+       if ([serializable_params objectForKey:@"password"] != nil)
+       {
+               NSData* encrypted_password = [[[EncryptionController sharedEncryptionController] encryptor] encryptString:[serializable_params objectForKey:@"password"]];
+               
+               if (encrypted_password)
+                       [serializable_params setObject:encrypted_password forKey:@"password"];
+               else
+                       [serializable_params removeObjectForKey:@"password"]; 
+       }
+       
+       [coder encodeObject:serializable_params forKey:@"connectionParams"];
+       [serializable_params release];
+}
+
+
+#pragma mark -
+#pragma mark NSKeyValueCoding
+
+- (void)setValue:(id)value forKey:(NSString *)key
+{
+       [self willChangeValueForKey:key];
+       
+       if (value == nil)
+               [self setNilValueForKey:key];
+       else
+               [_connection_params setValue:value forKey:key];
+       
+       [self didChangeValueForKey:key];
+}
+
+- (void)setValue:(id)value forKeyPath:(NSString *)key
+{
+       [self willChangeValueForKey:key];
+       
+       if (value == nil)
+               [self setNilValueForKey:key];
+       else
+               [_connection_params setValue:value forKeyPath:key];
+       
+       [self didChangeValueForKey:key];
+}
+
+- (void)setNilValueForKey:(NSString *)key
+{
+       [_connection_params removeObjectForKey:key];
+}
+
+- (id)valueForKey:(NSString*)key
+{
+       return [_connection_params valueForKey:key];
+}
+
+- (NSArray*)allKeys
+{
+       return [_connection_params allKeys];
+}
+
+#pragma mark -
+#pragma mark KV convenience
+
+- (BOOL)hasValueForKey:(NSString*)key
+{
+       return [_connection_params objectForKey:key] != nil;
+}
+
+- (void)setInt:(int)integer forKey:(NSString*)key
+{
+       [self setValue:[NSNumber numberWithInteger:integer] forKey:key];
+}
+- (int)intForKey:(NSString*)key
+{
+       return [[self valueForKey:key] intValue];
+}
+
+
+- (void)setBool:(BOOL)v forKey:(NSString*)key
+{
+       [self setValue:[NSNumber numberWithBool:v] forKey:key];
+}
+- (BOOL)boolForKey:(NSString*)key
+{
+       return [[_connection_params objectForKey:key] boolValue];
+}
+
+
+- (const char*)UTF8StringForKey:(NSString*)key
+{
+       id val = [self valueForKey:key];
+       const char* str;
+       
+       if ([val respondsToSelector:@selector(UTF8String)] && (str = [val UTF8String]))
+               return str;
+       
+       return "";
+}
+
+- (NSString*)StringForKey:(NSString*)key
+{
+       return [self valueForKey:key];
+}
+
+- (BOOL)hasValueForKeyPath:(NSString*)key
+{
+    return [_connection_params valueForKeyPath:key] != nil;    
+}
+
+- (void)setInt:(int)integer forKeyPath:(NSString*)key
+{
+       [self setValue:[NSNumber numberWithInteger:integer] forKeyPath:key];
+}
+- (int)intForKeyPath:(NSString*)key
+{
+       return [[self valueForKeyPath:key] intValue];
+}
+
+- (void)setBool:(BOOL)v forKeyPath:(NSString*)key
+{
+       [self setValue:[NSNumber numberWithBool:v] forKeyPath:key];
+}
+
+- (BOOL)boolForKeyPath:(NSString*)key
+{
+       return [[self valueForKeyPath:key] boolValue];
+}
+
+- (const char*)UTF8StringForKeyPath:(NSString*)key
+{
+       id val = [self valueForKeyPath:key];
+       const char* str;
+       
+       if ([val respondsToSelector:@selector(UTF8String)] && (str = [val UTF8String]))
+               return str;
+       
+       return "";
+}
+
+- (NSString*)StringForKeyPath:(NSString*)key
+{
+       return [self valueForKeyPath:key];
+}
+
+- (int)intForKey:(NSString*)key with3GEnabled:(BOOL)enabled
+{
+    if (enabled && [self boolForKey:@"enable_3g_settings"])
+        return [self intForKeyPath:[NSString stringWithFormat:@"settings_3g.%@", key]];
+    return [self intForKeyPath:key];
+}
+
+- (BOOL)boolForKey:(NSString*)key with3GEnabled:(BOOL)enabled
+{
+    if (enabled && [self boolForKey:@"enable_3g_settings"])
+        return [self boolForKeyPath:[NSString stringWithFormat:@"settings_3g.%@", key]];
+    return [self boolForKeyPath:key];    
+}
+
+@end
+
diff --git a/client/iOS/Models/Encryptor.h b/client/iOS/Models/Encryptor.h
new file mode 100644 (file)
index 0000000..75d36db
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ Password Encryptor
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Dorian Johnson
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+/* Encrypts data using AES 128 with a 256 bit key derived using PBKDF2-HMAC-SHA1  */
+
+#import <Foundation/Foundation.h>
+
+// Encryption block cipher config
+#define TSXEncryptorBlockCipherAlgo kCCAlgorithmAES128
+#define TSXEncryptorBlockCipherKeySize kCCKeySizeAES256
+#define TSXEncryptorBlockCipherOptions kCCOptionPKCS7Padding
+#define TSXEncryptorBlockCipherBlockSize 16
+
+// Key generation: If any of these are changed, existing password stores will no longer work
+#define TSXEncryptorPBKDF2Rounds 100
+#define TSXEncryptorPBKDF2Salt "9D¶3L}S¿lA[e€3C«"
+#define TSXEncryptorPBKDF2SaltLen TSXEncryptorBlockCipherOptions
+#define TSXEncryptorPBKDF2KeySize TSXEncryptorBlockCipherKeySize
+
+
+@interface Encryptor : NSObject {
+@private
+       NSData* _encryption_key;
+       NSString* _plaintext_password;
+}
+
+@property(readonly) NSString* plaintextPassword;
+
+- (id)initWithPassword:(NSString*)plaintext_password;
+
+- (NSData*)encryptData:(NSData*)plaintext_data;
+- (NSData*)decryptData:(NSData*)encrypted_data;
+- (NSData*)encryptString:(NSString*)plaintext_string;
+- (NSString*)decryptString:(NSData*)encrypted_string;
+
+@end
diff --git a/client/iOS/Models/Encryptor.m b/client/iOS/Models/Encryptor.m
new file mode 100644 (file)
index 0000000..eae578e
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ Password Encryptor
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Dorian Johnson
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+/* We try to use CommonCrypto as much as possible. PBKDF2 was added to CommonCrypto in iOS 5, so use OpenSSL only as a fallback to do PBKDF2 on pre iOS 5 systems. */
+
+#import "Encryptor.h"
+#import <CommonCrypto/CommonKeyDerivation.h> 
+#import <CommonCrypto/CommonCryptor.h> 
+#import <CommonCrypto/CommonDigest.h> 
+#import <openssl/evp.h> // For PBKDF2 on < 5.0
+#include <fcntl.h>
+
+#pragma mark -
+
+@interface Encryptor (Private)
+- (NSData*)randomInitializationVector;
+@end
+
+@implementation Encryptor
+@synthesize plaintextPassword=_plaintext_password;
+
+- (id)initWithPassword:(NSString*)plaintext_password
+{
+       if (plaintext_password == nil)
+               return nil; 
+    
+       if ( !(self = [super init]) )
+               return nil;
+       
+       _plaintext_password = [plaintext_password retain];
+       const char* plaintext_password_data = [plaintext_password length] ? [plaintext_password UTF8String] : " ";
+       
+       if (!plaintext_password_data || !strlen(plaintext_password_data))
+               [NSException raise:NSInternalInconsistencyException format:@"%s: plaintext password data is zero length!", __func__];
+       
+       
+       uint8_t* derived_key = calloc(1, TSXEncryptorPBKDF2KeySize);
+    
+       if (CCKeyDerivationPBKDF != NULL)
+       {
+        int rounds = CCCalibratePBKDF(kCCPBKDF2, strlen(plaintext_password_data), TSXEncryptorPBKDF2SaltLen, kCCPRFHmacAlgSHA1, TSXEncryptorPBKDF2KeySize, 100);
+               int ret = CCKeyDerivationPBKDF(kCCPBKDF2, plaintext_password_data, strlen(plaintext_password_data)-1, (const uint8_t*)TSXEncryptorPBKDF2Salt, TSXEncryptorPBKDF2SaltLen, kCCPRFHmacAlgSHA1, rounds, derived_key, TSXEncryptorPBKDF2KeySize);
+               //NSLog(@"CCKeyDerivationPBKDF ret = %d; key: %@", ret, [NSData dataWithBytesNoCopy:derived_key length:TWEncryptorPBKDF2KeySize freeWhenDone:NO]);
+               
+               if (ret)
+               {
+                       NSLog(@"%s: CCKeyDerivationPBKDF ret == %d, indicating some sort of failure.", __func__, ret);
+                       [self autorelease];
+                       return nil;
+               }
+       }
+       else
+       {
+               // iOS 4.x or earlier -- use OpenSSL
+               unsigned long ret = PKCS5_PBKDF2_HMAC_SHA1(plaintext_password_data, (int)strlen(plaintext_password_data)-1, (const unsigned char*)TSXEncryptorPBKDF2Salt, TSXEncryptorPBKDF2SaltLen, TSXEncryptorPBKDF2Rounds, TSXEncryptorPBKDF2KeySize, derived_key);
+               //NSLog(@"PKCS5_PBKDF2_HMAC_SHA1 ret = %lu; key: %@", ret, [NSData dataWithBytesNoCopy:derived_key length:TWEncryptorPBKDF2KeySize freeWhenDone:NO]);
+               
+               if (ret != 1)
+               {
+                       NSLog(@"%s: PKCS5_PBKDF2_HMAC_SHA1 ret == %lu, indicating some sort of failure.", __func__, ret);
+                       [self release];
+                       return nil;
+               }
+       }       
+    
+    
+       _encryption_key = [[NSData alloc] initWithBytesNoCopy:derived_key length:TSXEncryptorPBKDF2KeySize freeWhenDone:YES];
+       return self;
+}
+
+
+#pragma mark -
+#pragma mark Encrypting/Decrypting data
+
+- (NSData*)encryptData:(NSData*)plaintext_data
+{
+       if (![plaintext_data length])
+               return nil;
+    
+       NSData* iv = [self randomInitializationVector];
+       NSMutableData* encrypted_data = [NSMutableData dataWithLength:[iv length] + [plaintext_data length] + TSXEncryptorBlockCipherBlockSize];
+       [encrypted_data replaceBytesInRange:NSMakeRange(0, [iv length]) withBytes:[iv bytes]];
+       
+       size_t data_out_moved = 0;
+       int ret = CCCrypt(kCCEncrypt, TSXEncryptorBlockCipherAlgo, TSXEncryptorBlockCipherOptions, [_encryption_key bytes], TSXEncryptorBlockCipherKeySize, [iv bytes], [plaintext_data bytes], [plaintext_data length], [encrypted_data mutableBytes]+[iv length], [encrypted_data length]-[iv length], &data_out_moved);
+    
+       switch (ret)
+       {
+               case kCCSuccess:
+                       [encrypted_data setLength:[iv length] + data_out_moved];
+                       return encrypted_data;
+            
+               default:
+                       NSLog(@"%s: uncaught error, ret CCCryptorStatus = %d (plaintext len = %lu; buffer size = %lu)", __func__, ret, (unsigned long)[plaintext_data length], (unsigned long)([encrypted_data length]-[iv length]));
+                       return nil;
+       }
+       
+       return nil;
+}
+
+- (NSData*)decryptData:(NSData*)encrypted_data
+{
+       if ([encrypted_data length] <= TSXEncryptorBlockCipherBlockSize)
+               return nil;
+       
+       NSMutableData* plaintext_data = [NSMutableData dataWithLength:[encrypted_data length] + TSXEncryptorBlockCipherBlockSize];
+       size_t data_out_moved = 0;
+       
+       int ret = CCCrypt(kCCDecrypt, TSXEncryptorBlockCipherAlgo, TSXEncryptorBlockCipherOptions, [_encryption_key bytes], TSXEncryptorBlockCipherKeySize, [encrypted_data bytes], [encrypted_data bytes] + TSXEncryptorBlockCipherBlockSize, [encrypted_data length] - TSXEncryptorBlockCipherBlockSize, [plaintext_data mutableBytes], [plaintext_data length], &data_out_moved);
+    
+       switch (ret)
+       {
+               case kCCSuccess:
+                       [plaintext_data setLength:data_out_moved];
+                       return plaintext_data;
+                       
+               case kCCBufferTooSmall: // Our output buffer is big enough to decrypt valid data. This return code indicates malformed data.
+               case kCCAlignmentError: // Shouldn't get this, since we're using padding.
+               case kCCDecodeError:    // Wrong key.
+                       return nil;
+                       
+               default:
+                       NSLog(@"%s: uncaught error, ret CCCryptorStatus = %d (encrypted data len = %lu; buffer size = %lu; dom = %lu)", __func__, ret, (unsigned long)[encrypted_data length], (unsigned long)[plaintext_data length], data_out_moved);
+                       return nil;
+       }
+    
+       return nil;
+}
+
+
+- (NSData*)encryptString:(NSString*)plaintext_string
+{
+       return [self encryptData:[plaintext_string dataUsingEncoding:NSUTF8StringEncoding]];
+}
+
+- (NSString*)decryptString:(NSData*)encrypted_string
+{
+       return [[[NSString alloc] initWithData:[self decryptData:encrypted_string] encoding:NSUTF8StringEncoding] autorelease];
+}
+
+- (NSData*)randomInitializationVector
+{
+       NSMutableData* iv = [NSMutableData dataWithLength:TSXEncryptorBlockCipherBlockSize];
+       int fd;
+       
+       if ( (fd = open("/dev/urandom", O_RDONLY)) < 0)
+               return nil;
+    
+       NSInteger bytes_needed = [iv length];
+       char* p = [iv mutableBytes];
+       
+       while (bytes_needed)
+       {
+               long bytes_read = read(fd, p, bytes_needed);
+               
+               if (bytes_read < 0)
+                       continue;
+        
+               p += bytes_read;
+               bytes_needed -= bytes_read;
+       }
+    
+       close(fd);
+       return iv;
+}
+
+@end
diff --git a/client/iOS/Models/GlobalDefaults.h b/client/iOS/Models/GlobalDefaults.h
new file mode 100644 (file)
index 0000000..ecbee2c
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ Global default bookmark settings
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Dorian Johnson
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+
+#import <Foundation/Foundation.h>
+
+@class ConnectionParams, ComputerBookmark;
+
+@interface GlobalDefaults : NSObject{
+@private
+       ComputerBookmark* _default_bookmark;
+}
+
++ (GlobalDefaults*)sharedGlobalDefaults;
+
+// The same object is always returned from this method.
+@property (readonly,nonatomic) ComputerBookmark* bookmark;
+
+- (ConnectionParams*)newParams;
+- (ComputerBookmark*)newBookmark;
+
+@end
diff --git a/client/iOS/Models/GlobalDefaults.m b/client/iOS/Models/GlobalDefaults.m
new file mode 100644 (file)
index 0000000..1a0619a
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ Global default bookmark settings
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Dorian Johnson
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "GlobalDefaults.h"
+#import "Bookmark.h"
+#import "ConnectionParams.h"
+
+@implementation GlobalDefaults
+
++ (GlobalDefaults*)sharedGlobalDefaults
+{
+       static GlobalDefaults* _shared_global_defaults = nil;
+       
+       if (_shared_global_defaults == nil)
+       {
+               @synchronized(self)
+               {
+                       if (_shared_global_defaults == nil)
+                               _shared_global_defaults = [[GlobalDefaults alloc] init];                
+               }
+       }
+       
+       return _shared_global_defaults; 
+}
+
+- (id)init
+{
+       if (!(self = [super init]))
+               return nil;
+       
+       ComputerBookmark* bookmark = nil;
+       NSData* bookmark_data = [[NSUserDefaults standardUserDefaults] objectForKey:@"TSXSharedGlobalDefaultBookmark"];
+       
+       if (bookmark_data && [bookmark_data length])
+               bookmark = [NSKeyedUnarchiver unarchiveObjectWithData:bookmark_data];
+       
+       if (!bookmark)
+               bookmark = [[[ComputerBookmark alloc] initWithBaseDefaultParameters] autorelease];
+       
+       _default_bookmark = [bookmark retain];
+       return self;
+}
+
+- (void)dealloc
+{
+       [_default_bookmark release];
+       [super dealloc];
+}
+
+#pragma mark -
+
+@synthesize bookmark=_default_bookmark;
+
+- (ComputerBookmark*)newBookmark
+{
+       return [[ComputerBookmark alloc] initWithConnectionParameters:[[self newParams] autorelease]];
+}
+
+- (ConnectionParams*)newParams
+{
+       ConnectionParams* param_copy = [[[self bookmark] params] copy];
+       return param_copy;
+}
+
+@end
diff --git a/client/iOS/Models/RDPKeyboard.h b/client/iOS/Models/RDPKeyboard.h
new file mode 100644 (file)
index 0000000..3ce2b82
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ RDP Keyboard helper 
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import <Foundation/Foundation.h>
+#import "RDPSession.h"
+
+@class RDPKeyboard;
+
+
+@protocol RDPKeyboardDelegate <NSObject>
+@optional
+- (void)modifiersChangedForKeyboard:(RDPKeyboard*)keyboard;
+@end
+
+
+@interface RDPKeyboard : NSObject {
+
+    RDPSession* _session;
+    
+       int _virtual_key_map[256];
+    int _unicode_map[256];
+    NSDictionary* _special_keys;
+
+    NSObject<RDPKeyboardDelegate>* _delegate;
+    
+       BOOL _ctrl_pressed;
+    BOOL _alt_pressed;
+    BOOL _shift_pressed;
+    BOOL _win_pressed;
+}
+
+@property (assign) id <RDPKeyboardDelegate> delegate;
+@property (readonly) BOOL ctrlPressed;
+@property (readonly) BOOL altPressed;
+@property (readonly) BOOL shiftPressed;
+@property (readonly) BOOL winPressed;
+
+// returns a keyboard instance
++ (RDPKeyboard*)getSharedRDPKeyboard;
+
+// init the keyboard and assign the given rdp session and delegate
+- (void)initWithSession:(RDPSession*)session delegate:(NSObject<RDPKeyboardDelegate>*)delegate;
+
+// called to reset any pending key states (i.e. pressed modifier keys)
+- (void)reset;
+
+// sends the given unicode character to the server
+- (void)sendUnicode:(int)character;
+
+// send a key stroke event using the given virtual key code
+- (void)sendVirtualKeyCode:(int)keyCode;
+
+// toggle ctrl key, returns true if pressed, otherwise false
+- (void)toggleCtrlKey;
+
+// toggle alt key, returns true if pressed, otherwise false
+- (void)toggleAltKey;
+
+// toggle shift key, returns true if pressed, otherwise false
+- (void)toggleShiftKey;
+
+// toggle windows key, returns true if pressed, otherwise false
+- (void)toggleWinKey;
+
+// send key strokes
+- (void)sendEnterKeyStroke;
+- (void)sendEscapeKeyStroke;
+- (void)sendBackspaceKeyStroke;
+
+@end
diff --git a/client/iOS/Models/RDPKeyboard.m b/client/iOS/Models/RDPKeyboard.m
new file mode 100644 (file)
index 0000000..89c62ed
--- /dev/null
@@ -0,0 +1,306 @@
+/*
+ RDP Keyboard helper 
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "RDPKeyboard.h"
+#include <freerdp/locale/keyboard.h>
+
+@interface RDPKeyboard (Private)
+- (void)sendVirtualKey:(int)vKey up:(BOOL)up;
+- (void)handleSpecialKey:(int)character;
+- (void)handleAlphaNumChar:(int)character;
+- (void)notifyDelegateModifiersChanged;
+@end
+
+@implementation RDPKeyboard
+
+@synthesize delegate = _delegate, ctrlPressed = _ctrl_pressed, altPressed = _alt_pressed, shiftPressed = _shift_pressed, winPressed = _win_pressed;
+
+- (id)init
+{
+       if((self = [super init]) != nil)
+       {
+        [self initWithSession:nil delegate:nil];
+        
+               memset(_virtual_key_map, 0, sizeof(_virtual_key_map));
+        memset(_unicode_map, 0, sizeof(_unicode_map));
+               
+               // init vkey map - used for alpha-num characters
+               _virtual_key_map['0'] = VK_KEY_0;
+               _virtual_key_map['1'] = VK_KEY_1;
+               _virtual_key_map['2'] = VK_KEY_2;
+               _virtual_key_map['3'] = VK_KEY_3;
+               _virtual_key_map['4'] = VK_KEY_4;
+               _virtual_key_map['5'] = VK_KEY_5;
+               _virtual_key_map['6'] = VK_KEY_6;
+               _virtual_key_map['7'] = VK_KEY_7;
+               _virtual_key_map['8'] = VK_KEY_8;
+               _virtual_key_map['9'] = VK_KEY_9;
+               
+               _virtual_key_map['a'] = VK_KEY_A;
+               _virtual_key_map['b'] = VK_KEY_B;
+               _virtual_key_map['c'] = VK_KEY_C;
+               _virtual_key_map['d'] = VK_KEY_D;
+               _virtual_key_map['e'] = VK_KEY_E;
+               _virtual_key_map['f'] = VK_KEY_F;
+               _virtual_key_map['g'] = VK_KEY_G;
+               _virtual_key_map['h'] = VK_KEY_H;
+               _virtual_key_map['i'] = VK_KEY_I;
+               _virtual_key_map['j'] = VK_KEY_J;
+               _virtual_key_map['k'] = VK_KEY_K;
+               _virtual_key_map['l'] = VK_KEY_L;
+               _virtual_key_map['m'] = VK_KEY_M;
+               _virtual_key_map['n'] = VK_KEY_N;
+               _virtual_key_map['o'] = VK_KEY_O;
+               _virtual_key_map['p'] = VK_KEY_P;
+               _virtual_key_map['q'] = VK_KEY_Q;
+               _virtual_key_map['r'] = VK_KEY_R;
+               _virtual_key_map['s'] = VK_KEY_S;
+               _virtual_key_map['t'] = VK_KEY_T;
+               _virtual_key_map['u'] = VK_KEY_U;
+               _virtual_key_map['v'] = VK_KEY_V;
+               _virtual_key_map['w'] = VK_KEY_W;
+               _virtual_key_map['x'] = VK_KEY_X;
+               _virtual_key_map['y'] = VK_KEY_Y;
+               _virtual_key_map['z'] = VK_KEY_Z;
+        
+        // init scancode map - used for special characters
+        _unicode_map['-'] = 45;
+        _unicode_map['/'] = 47;
+        _unicode_map[':'] = 58;
+        _unicode_map[';'] = 59;
+        _unicode_map['('] = 40;
+        _unicode_map[')'] = 41;
+        _unicode_map['&'] = 38;
+        _unicode_map['@'] = 64;        
+        _unicode_map['.'] = 46;
+        _unicode_map[','] = 44;
+        _unicode_map['?'] = 63;
+        _unicode_map['!'] = 33;
+        _unicode_map['\''] = 39;
+        _unicode_map['\"'] = 34;
+               
+        _unicode_map['['] = 91;
+        _unicode_map[']'] = 93;        
+        _unicode_map['{'] = 123;
+        _unicode_map['}'] = 125;
+        _unicode_map['#'] = 35;
+        _unicode_map['%'] = 37;
+        _unicode_map['^'] = 94;
+        _unicode_map['*'] = 42;
+        _unicode_map['+'] = 43;
+        _unicode_map['='] = 61;
+
+        _unicode_map['_'] = 95;
+        _unicode_map['\\'] = 92;
+        _unicode_map['|'] = 124;
+        _unicode_map['~'] = 126;
+        _unicode_map['<'] = 60;
+        _unicode_map['>'] = 62;
+        _unicode_map['$'] = 36;
+    }
+       return self;
+}
+
+- (void)dealloc
+{
+       [super dealloc];
+}
+
+#pragma mark -
+#pragma mark class methods
+
+// return a keyboard instance
++ (RDPKeyboard*)getSharedRDPKeyboard
+{
+       static RDPKeyboard* _shared_keyboard = nil;
+       
+       if (_shared_keyboard == nil)
+       {
+               @synchronized(self)
+               {
+                       if (_shared_keyboard == nil)
+                               _shared_keyboard = [[RDPKeyboard alloc] init];          
+               }
+       }
+       
+       return _shared_keyboard;        
+}
+
+// reset the keyboard instance and assign the given rdp instance
+- (void)initWithSession:(RDPSession *)session delegate:(NSObject<RDPKeyboardDelegate> *)delegate
+{
+    _alt_pressed = NO;
+    _ctrl_pressed = NO;
+    _shift_pressed = NO;
+    _win_pressed = NO;
+    
+    _session = session;
+    _delegate = delegate;
+}
+
+- (void)reset
+{
+    // reset pressed ctrl, alt, shift or win key
+    if(_shift_pressed)
+        [self toggleShiftKey];
+    if(_alt_pressed)
+        [self toggleAltKey];
+    if(_ctrl_pressed)
+        [self toggleCtrlKey];
+    if(_win_pressed)
+        [self toggleWinKey];        
+}
+
+// handles button pressed input event from the iOS keyboard
+// performs all conversions etc.
+- (void)sendUnicode:(int)character
+{   
+    if(isalnum(character))
+        [self handleAlphaNumChar:character];
+    else
+        [self handleSpecialKey:character];
+
+    [self reset];
+}
+
+// send a backspace key press
+- (void)sendVirtualKeyCode:(int)keyCode
+{
+    [self sendVirtualKey:keyCode up:NO];    
+    [self sendVirtualKey:keyCode up:YES];        
+}
+
+#pragma mark modifier key handling
+// toggle ctrl key, returns true if pressed, otherwise false
+- (void)toggleCtrlKey
+{    
+    [self sendVirtualKey:VK_LCONTROL up:_ctrl_pressed];
+    _ctrl_pressed = !_ctrl_pressed;
+    [self notifyDelegateModifiersChanged];    
+}
+
+// toggle alt key, returns true if pressed, otherwise false
+- (void)toggleAltKey
+{
+    [self sendVirtualKey:VK_LMENU up:_alt_pressed];
+    _alt_pressed = !_alt_pressed;
+    [self notifyDelegateModifiersChanged];
+}
+
+// toggle shift key, returns true if pressed, otherwise false
+- (void)toggleShiftKey
+{
+    [self sendVirtualKey:VK_LSHIFT up:_shift_pressed];
+    _shift_pressed = !_shift_pressed;
+    [self notifyDelegateModifiersChanged];
+}
+
+// toggle windows key, returns true if pressed, otherwise false
+- (void)toggleWinKey
+{
+    [self sendVirtualKey:VK_LWIN up:_win_pressed];
+    _win_pressed = !_win_pressed;
+    [self notifyDelegateModifiersChanged];
+}
+
+#pragma mark Sending special key strokes
+
+- (void)sendEnterKeyStroke
+{
+    [self sendVirtualKeyCode:VK_RETURN];
+}
+
+- (void)sendEscapeKeyStroke
+{
+    [self sendVirtualKeyCode:VK_ESCAPE];
+}
+
+- (void)sendBackspaceKeyStroke
+{
+    [self sendVirtualKeyCode:VK_BACK];
+}
+
+@end
+
+#pragma mark -
+@implementation RDPKeyboard (Private)
+
+- (void)handleAlphaNumChar:(int)character
+{
+    // if we recive an uppercase letter - make it lower and send an shift down event to server
+    BOOL shift_was_sent = NO;
+    if(isupper(character) && _shift_pressed == NO)
+    {
+        character = tolower(character);
+        [self sendVirtualKey:VK_SHIFT up:NO];
+        shift_was_sent = YES;
+    }
+    
+    // convert the character to a VK
+    int vk = _virtual_key_map[character];
+    if(vk != 0)
+    {
+        // send key pressed
+        [self sendVirtualKey:vk up:NO];    
+        [self sendVirtualKey:vk up:YES];        
+    }
+    
+    // send the missing shift up if we had a shift down
+    if(shift_was_sent)
+        [self sendVirtualKey:VK_SHIFT up:YES];
+}
+
+- (void)handleSpecialKey:(int)character
+{
+    NSDictionary* eventDescriptor = nil;
+    if(character < 256)
+    {
+        // convert the character to a unicode character
+        int code = _unicode_map[character];
+        if(code != 0)
+            eventDescriptor = [NSDictionary dictionaryWithObjectsAndKeys:      
+                               @"keyboard", @"type",
+                               @"unicode", @"subtype",
+                               [NSNumber numberWithUnsignedShort:0], @"flags",
+                               [NSNumber numberWithUnsignedShort:code], @"unicode_char",
+                               nil];
+    }
+
+    if (eventDescriptor == nil)
+        eventDescriptor = [NSDictionary dictionaryWithObjectsAndKeys:  
+                           @"keyboard", @"type",
+                           @"unicode", @"subtype",
+                           [NSNumber numberWithUnsignedShort:0], @"flags",
+                           [NSNumber numberWithUnsignedShort:character], @"unicode_char",
+                           nil];        
+
+    [_session sendInputEvent:eventDescriptor];        
+}
+
+// sends the vk code to the session
+- (void)sendVirtualKey:(int)vKey up:(BOOL)up
+{
+    RDP_SCANCODE scancode = freerdp_keyboard_get_rdp_scancode_from_virtual_key_code(vKey);
+    int flags = (up ? KBD_FLAGS_RELEASE : KBD_FLAGS_DOWN);
+    flags |= (RDP_SCANCODE_EXTENDED(scancode) ? KBD_FLAGS_EXTENDED : 0);
+    [_session sendInputEvent:[NSDictionary dictionaryWithObjectsAndKeys:       
+                                @"keyboard", @"type",
+                                @"scancode", @"subtype",
+                                [NSNumber numberWithUnsignedShort:flags], @"flags",
+                                [NSNumber numberWithUnsignedShort:RDP_SCANCODE_CODE(scancode)], @"scancode",
+                                nil]];        
+}
+
+- (void)notifyDelegateModifiersChanged
+{
+    if ([[self delegate] respondsToSelector:@selector(modifiersChangedForKeyboard:)])
+        [[self delegate] modifiersChangedForKeyboard:self];
+}
+
+@end
diff --git a/client/iOS/Models/RDPSession.h b/client/iOS/Models/RDPSession.h
new file mode 100644 (file)
index 0000000..c266cc9
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ RDP Session object 
+ Copyright 2013 Thinstuff Technologies GmbH, Authors: Martin Fleisz, Dorian Johnson
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import <Foundation/Foundation.h>
+
+#include <freerdp/freerdp.h>
+
+// forward declaration
+@class RDPSession;
+@class ComputerBookmark;
+@class ConnectionParams;
+
+// notification handler for session disconnect
+extern NSString* TSXSessionDidDisconnectNotification;
+extern NSString* TSXSessionDidFailToConnectNotification;
+
+// protocol for session notifications
+@protocol RDPSessionDelegate <NSObject>
+@optional
+- (void)session:(RDPSession*)session didFailToConnect:(int)reason;
+- (void)sessionWillConnect:(RDPSession*)session;
+- (void)sessionDidConnect:(RDPSession*)session;
+- (void)sessionWillDisconnect:(RDPSession*)session;
+- (void)sessionDidDisconnect:(RDPSession*)session;
+- (void)sessionBitmapContextWillChange:(RDPSession*)session;
+- (void)sessionBitmapContextDidChange:(RDPSession*)session;
+- (void)session:(RDPSession*)session needsRedrawInRect:(CGRect)rect;
+- (CGSize)sizeForFitScreenForSession:(RDPSession*)session;
+- (void)showGoProScreen:(RDPSession*)session;
+
+- (void)session:(RDPSession*)session requestsAuthenticationWithParams:(NSMutableDictionary*)params;
+- (void)session:(RDPSession*)session verifyCertificateWithParams:(NSMutableDictionary*)params;
+
+@end
+
+// rdp session
+@interface RDPSession : NSObject 
+{
+@private
+       freerdp* _freerdp;
+
+    ComputerBookmark* _bookmark;
+    
+       ConnectionParams* _params;
+       
+       NSObject<RDPSessionDelegate>* _delegate;
+    
+    NSCondition* _ui_request_completed;
+    
+    NSString* _name;
+    
+    // flag if the session is suspended
+    BOOL _suspended;
+    
+       // flag that specifies whether the RDP toolbar is visible
+       BOOL _toolbar_visible;  
+}
+
+@property (readonly) ConnectionParams* params;
+@property (readonly) ComputerBookmark* bookmark;
+@property (assign) id <RDPSessionDelegate> delegate;
+@property (assign) BOOL toolbarVisible;
+@property (readonly) CGContextRef bitmapContext;
+@property (readonly) NSCondition* uiRequestCompleted;
+
+
+// initialize a new session with the given bookmark
+- (id)initWithBookmark:(ComputerBookmark*)bookmark;
+
+#pragma mark - session control functions
+
+// connect the session
+-(void)connect;
+
+// disconnect session
+-(void)disconnect;
+
+// suspends the session
+-(void)suspend;
+
+// resumes a previously suspended session
+-(void)resume;
+
+// returns YES if the session is started
+-(BOOL)isSuspended;
+
+// send input event to the server
+-(void)sendInputEvent:(NSDictionary*)event;
+
+// session needs a refresh of its view
+- (void)setNeedsDisplayInRectAsValue:(NSValue*)rect_value;
+
+// get a small session screenshot
+- (UIImage*)getScreenshotWithSize:(CGSize)size;
+
+// returns the session's current paramters
+- (rdpSettings*)getSessionParams;
+
+// returns the session's name (usually the label of the bookmark the session was created with)
+- (NSString*)sessionName;
+
+@end
diff --git a/client/iOS/Models/RDPSession.m b/client/iOS/Models/RDPSession.m
new file mode 100644 (file)
index 0000000..75e9c5e
--- /dev/null
@@ -0,0 +1,430 @@
+/*
+ RDP Session object 
+ Copyright 2013 Thinstuff Technologies GmbH, Authors: Martin Fleisz, Dorian Johnson
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "ios_freerdp.h"
+#import "ios_freerdp_ui.h"
+#import "ios_freerdp_events.h"
+
+#import "RDPSession.h"
+#import "TSXTypes.h"
+#import "Bookmark.h"
+#import "ConnectionParams.h"
+
+NSString* TSXSessionDidDisconnectNotification = @"TSXSessionDidDisconnect";
+NSString* TSXSessionDidFailToConnectNotification = @"TSXSessionDidFailToConnect";
+
+@interface RDPSession (Private)
+- (void)runSession;
+- (void)runSessionFinished:(NSNumber*)result;
+- (mfInfo*)mfi;
+
+// The connection thread calls these on the main thread.
+- (void)sessionWillConnect;
+- (void)sessionDidConnect;
+- (void)sessionDidDisconnect;
+- (void)sessionDidFailToConnect:(int)reason;
+- (void)sessionBitmapContextWillChange;
+- (void)sessionBitmapContextDidChange;
+@end
+
+@implementation RDPSession
+
+@synthesize delegate=_delegate, params=_params, toolbarVisible = _toolbar_visible, uiRequestCompleted = _ui_request_completed, bookmark = _bookmark;
+
++ (void)initialize
+{
+    ios_init_freerdp();
+}
+
+// Designated initializer.
+- (id)initWithBookmark:(ComputerBookmark *)bookmark
+{
+       if (!(self = [super init]))
+               return nil;
+       
+       if (!bookmark)
+               [NSException raise:NSInvalidArgumentException format:@"%s: params may not be nil.", __func__];
+       
+    _bookmark = [bookmark retain];
+       _params = [[bookmark params] copy];
+    _name = [[bookmark label] retain];
+    _delegate = nil;   
+    _toolbar_visible = YES;
+       _freerdp = ios_freerdp_new();
+    rdpSettings* settings = _freerdp->settings;        
+    _ui_request_completed = [[NSCondition alloc] init];
+    
+    BOOL connected_via_3g = ![bookmark conntectedViaWLAN];
+    
+       // Screen Size is set on connect (we need a valid delegate in case the user choose an automatic screen size)
+    
+       // Other simple numeric settings
+       if ([_params hasValueForKey:@"colors"])
+               settings->ColorDepth = [_params intForKey:@"colors" with3GEnabled:connected_via_3g];
+       
+       if ([_params hasValueForKey:@"port"])
+               settings->ServerPort = [_params intForKey:@"port"];
+       
+       if ([_params boolForKey:@"console"])
+               settings->ConsoleSession = 1;
+
+       // connection info      
+    settings->ServerHostname = strdup([_params UTF8StringForKey:@"hostname"]);
+       
+       // String settings
+       if ([[_params StringForKey:@"username"] length])
+               settings->Username = strdup([_params UTF8StringForKey:@"username"]);
+    
+       if ([[_params StringForKey:@"password"] length])
+               settings->Password = strdup([_params UTF8StringForKey:@"password"]);
+       
+       if ([[_params StringForKey:@"domain"] length])
+               settings->Domain = strdup([_params UTF8StringForKey:@"domain"]);
+    
+       settings->ShellWorkingDirectory = strdup([_params UTF8StringForKey:@"working_directory"]);
+       settings->AlternateShell = strdup([_params UTF8StringForKey:@"remote_program"]);
+       
+       
+       // RemoteFX
+       if ([_params boolForKey:@"perf_remotefx" with3GEnabled:connected_via_3g])
+       {
+               settings->RemoteFxCodec = TRUE;
+               settings->FastPathOutput = TRUE;
+               settings->ColorDepth = 32;
+               settings->LargePointerFlag = TRUE;
+        settings->FrameMarkerCommandEnabled = TRUE;
+       }
+    
+       // Performance flags
+    settings->DisableWallpaper = ![_params boolForKey:@"perf_show_desktop" with3GEnabled:connected_via_3g];
+    settings->DisableFullWindowDrag = ![_params boolForKey:@"perf_window_dragging" with3GEnabled:connected_via_3g];
+    settings->DisableMenuAnims = ![_params boolForKey:@"perf_menu_animation" with3GEnabled:connected_via_3g];
+    settings->DisableThemes = ![_params boolForKey:@"perf_windows_themes" with3GEnabled:connected_via_3g];
+    settings->AllowFontSmoothing = [_params boolForKey:@"perf_font_smoothing" with3GEnabled:connected_via_3g];
+    settings->AllowDesktopComposition = [_params boolForKey:@"perf_desktop_composition" with3GEnabled:connected_via_3g];
+    
+       settings->PerformanceFlags = PERF_FLAG_NONE;
+       if (settings->DisableWallpaper)
+        settings->PerformanceFlags |= PERF_DISABLE_WALLPAPER;        
+       if (settings->DisableFullWindowDrag)
+        settings->PerformanceFlags |= PERF_DISABLE_FULLWINDOWDRAG;
+       if (settings->DisableMenuAnims)
+               settings->PerformanceFlags |= PERF_DISABLE_MENUANIMATIONS;
+       if (settings->DisableThemes)
+        settings->PerformanceFlags |= PERF_DISABLE_THEMING;
+       if (settings->AllowFontSmoothing)
+               settings->PerformanceFlags |= PERF_ENABLE_FONT_SMOOTHING;
+    if (settings->AllowDesktopComposition)
+        settings->PerformanceFlags |= PERF_ENABLE_DESKTOP_COMPOSITION;
+               
+       if ([_params hasValueForKey:@"width"])
+               settings->DesktopWidth = [_params intForKey:@"width"];
+       if ([_params hasValueForKey:@"height"])
+               settings->DesktopHeight = [_params intForKey:@"height"];
+       
+    // security
+    switch ([_params intForKey:@"security"]) 
+    {
+        case TSXProtocolSecurityNLA:
+            settings->RdpSecurity = FALSE;
+            settings->TlsSecurity = FALSE;
+            settings->NlaSecurity = TRUE;
+            settings->ExtSecurity = FALSE;
+            break;
+
+        case TSXProtocolSecurityTLS:
+            settings->RdpSecurity = FALSE;
+            settings->TlsSecurity = TRUE;
+            settings->NlaSecurity = FALSE;
+            settings->ExtSecurity = FALSE;
+            break;
+            
+        case TSXProtocolSecurityRDP:
+            settings->RdpSecurity = TRUE;
+            settings->TlsSecurity = FALSE;
+            settings->NlaSecurity = FALSE;
+            settings->ExtSecurity = FALSE;
+            settings->DisableEncryption = TRUE;
+            settings->EncryptionMethods = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS;
+            settings->EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE;
+            break;
+
+        default:
+            break;
+    }
+    
+       // Remote keyboard layout
+       settings->KeyboardLayout = 0x409;
+    
+       // Audio settings
+    settings->AudioPlayback = FALSE;
+    settings->AudioCapture = FALSE;
+       
+       [self mfi]->session = self;
+       return self;
+}
+
+- (void)dealloc
+{
+       [self setDelegate:nil];
+    [_bookmark release];
+    [_name release];
+       [_params release];
+    [_ui_request_completed release];
+    
+       ios_freerdp_free(_freerdp);
+       
+       [super dealloc];
+}
+
+- (CGContextRef)bitmapContext
+{
+       return [self mfi]->bitmap_context;
+}
+
+#pragma mark -
+#pragma mark Connecting and disconnecting
+
+- (void)connect
+{    
+       // Set Screen Size to automatic if widht or height are still 0
+    rdpSettings* settings = _freerdp->settings;        
+       if (settings->DesktopWidth == 0 || settings->DesktopHeight == 0)
+       {
+        CGSize size = CGSizeZero;        
+        if ([[self delegate] respondsToSelector:@selector(sizeForFitScreenForSession:)])
+            size = [[self delegate] sizeForFitScreenForSession:self];
+        
+        if (!CGSizeEqualToSize(CGSizeZero, size))
+        {
+            [_params setInt:size.width forKey:@"width"];
+            [_params setInt:size.height forKey:@"height"];
+            settings->DesktopWidth = size.width;
+            settings->DesktopHeight = size.height;
+        }
+       }
+    
+    // TODO: This is a hack to ensure connections to RDVH with 16bpp don't have an odd screen resolution width
+    //       Otherwise this could result in screen corruption ..
+    if (settings->ColorDepth <= 16)
+        settings->DesktopWidth &= (~1);
+    
+       [self performSelectorInBackground:@selector(runSession) withObject:nil];
+}
+
+- (void)disconnect
+{
+       mfInfo* mfi = [self mfi];
+       
+    ios_events_send(mfi, [NSDictionary dictionaryWithObject:@"disconnect" forKey:@"type"]);
+
+       if (mfi->connection_state == TSXConnectionConnecting)
+       {
+               mfi->unwanted = YES;
+               [self sessionDidDisconnect];
+               return;
+       }       
+}
+
+- (TSXConnectionState)connectionState
+{
+       return [self mfi]->connection_state;
+}
+
+// suspends the session
+-(void)suspend
+{
+    if(!_suspended)
+    {
+        _suspended = YES;
+//        instance->update->SuppressOutput(instance->context, 0, NULL);
+    }
+}
+
+// resumes a previously suspended session
+-(void)resume
+{
+    if(_suspended)
+    {
+/*        RECTANGLE_16 rec;
+        rec.left = 0;
+        rec.top = 0;
+        rec.right = instance->settings->width;
+        rec.bottom = instance->settings->height;
+*/        
+        _suspended = NO;
+//        instance->update->SuppressOutput(instance->context, 1, &rec);
+//        [delegate sessionScreenSettingsChanged:self];        
+    }
+}
+
+// returns YES if the session is started
+-(BOOL)isSuspended
+{
+    return _suspended;
+}
+
+#pragma mark -
+#pragma mark Input events
+
+- (void)sendInputEvent:(NSDictionary*)eventDescriptor
+{
+       if ([self mfi]->connection_state == TSXConnectionConnected)
+               ios_events_send([self mfi], eventDescriptor);
+}
+
+#pragma mark -
+#pragma mark Server events (main thread)
+
+- (void)setNeedsDisplayInRectAsValue:(NSValue*)rect_value
+{
+       if ([[self delegate] respondsToSelector:@selector(session:needsRedrawInRect:)])
+               [[self delegate] session:self needsRedrawInRect:[rect_value CGRectValue]];
+} 
+
+
+#pragma mark -
+#pragma mark interface functions
+
+- (UIImage*)getScreenshotWithSize:(CGSize)size
+{
+    NSAssert([self mfi]->bitmap_context != nil, @"Screenshot requested while having no valid RDP drawing context");
+    
+       CGImageRef cgImage = CGBitmapContextCreateImage([self mfi]->bitmap_context);
+       UIGraphicsBeginImageContext(size);
+       
+    CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0, size.height);
+       CGContextScaleCTM(UIGraphicsGetCurrentContext(), 1.0, -1.0);
+       CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, size.width, size.height), cgImage);
+       
+    UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
+
+       UIGraphicsEndImageContext();
+       CGImageRelease(cgImage);        
+       
+       return viewImage;    
+}
+
+- (rdpSettings*)getSessionParams
+{
+    return _freerdp->settings;
+}
+
+- (NSString*)sessionName
+{
+    return _name;
+}
+
+@end 
+
+#pragma mark -
+@implementation RDPSession (Private)
+
+- (mfInfo*)mfi
+{
+       return MFI_FROM_INSTANCE(_freerdp);
+}
+
+// Blocks until rdp session finishes.
+- (void)runSession
+{
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];        
+
+    // Run the session
+    [self performSelectorOnMainThread:@selector(sessionWillConnect) withObject:nil waitUntilDone:YES];
+    int result_code = ios_run_freerdp(_freerdp);
+    [self mfi]->connection_state = TSXConnectionDisconnected;
+    [self performSelectorOnMainThread:@selector(runSessionFinished:) withObject:[NSNumber numberWithInt:result_code] waitUntilDone:YES];
+
+    [pool release];
+}
+
+// Main thread.
+- (void)runSessionFinished:(NSNumber*)result
+{
+       int result_code = [result intValue];
+       
+       switch (result_code)
+       {
+               case MF_EXIT_CONN_CANCELED:
+                       [self sessionDidDisconnect];
+                       break;
+               case MF_EXIT_LOGON_TIMEOUT:
+               case MF_EXIT_CONN_FAILED:
+                       [self sessionDidFailToConnect:result_code];
+                       break;
+               case MF_EXIT_SUCCESS:
+               default:
+                       [self sessionDidDisconnect];    
+            break;
+       }                        
+}
+
+#pragma mark -
+#pragma mark Session management (main thread)
+
+- (void)sessionWillConnect
+{      
+       if ([[self delegate] respondsToSelector:@selector(sessionWillConnect:)])
+               [[self delegate] sessionWillConnect:self];
+}
+
+- (void)sessionDidConnect
+{
+       if ([[self delegate] respondsToSelector:@selector(sessionDidConnect:)]) 
+               [[self delegate] sessionDidConnect:self];       
+}
+
+- (void)sessionDidFailToConnect:(int)reason
+{      
+    [[NSNotificationCenter defaultCenter] postNotificationName:TSXSessionDidFailToConnectNotification object:self];
+
+       if ([[self delegate] respondsToSelector:@selector(session:didFailToConnect:)])
+               [[self delegate] session:self didFailToConnect:reason];
+}
+
+- (void)sessionDidDisconnect
+{      
+    [[NSNotificationCenter defaultCenter] postNotificationName:TSXSessionDidDisconnectNotification object:self];
+       
+    if ([[self delegate] respondsToSelector:@selector(sessionDidDisconnect:)]) 
+               [[self delegate] sessionDidDisconnect:self];
+}
+
+- (void)sessionBitmapContextWillChange
+{
+       if ([[self delegate] respondsToSelector:@selector(sessionBitmapContextWillChange:)])    
+               [[self delegate] sessionBitmapContextWillChange:self];
+}
+
+- (void)sessionBitmapContextDidChange
+{
+       if ([[self delegate] respondsToSelector:@selector(sessionBitmapContextDidChange:)])
+               [[self delegate] sessionBitmapContextDidChange:self];
+}
+
+- (void)showGoProScreen
+{
+       if ([[self delegate] respondsToSelector:@selector(showGoProScreen:)])
+               [[self delegate] showGoProScreen:self];    
+}
+
+- (void)sessionRequestsAuthenticationWithParams:(NSMutableDictionary*)params
+{
+       if ([[self delegate] respondsToSelector:@selector(session:requestsAuthenticationWithParams:)])
+               [[self delegate] session:self requestsAuthenticationWithParams:params];    
+}
+
+- (void)sessionVerifyCertificateWithParams:(NSMutableDictionary*)params
+{
+       if ([[self delegate] respondsToSelector:@selector(session:verifyCertificateWithParams:)])
+               [[self delegate] session:self verifyCertificateWithParams:params];    
+}
+
+@end
diff --git a/client/iOS/Resources/BookmarkListView.xib b/client/iOS/Resources/BookmarkListView.xib
new file mode 100644 (file)
index 0000000..94fb683
--- /dev/null
@@ -0,0 +1,365 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
+       <data>
+               <int key="IBDocument.SystemTarget">1296</int>
+               <string key="IBDocument.SystemVersion">11D50b</string>
+               <string key="IBDocument.InterfaceBuilderVersion">2182</string>
+               <string key="IBDocument.AppKitVersion">1138.32</string>
+               <string key="IBDocument.HIToolboxVersion">568.00</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                       <string key="NS.object.0">1179</string>
+               </object>
+               <array key="IBDocument.IntegratedClassDependencies">
+                       <string>IBUITableView</string>
+                       <string>IBUIView</string>
+                       <string>IBUISearchBar</string>
+                       <string>IBProxyObject</string>
+               </array>
+               <array key="IBDocument.PluginDependencies">
+                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+               </array>
+               <object class="NSMutableDictionary" key="IBDocument.Metadata">
+                       <string key="NS.key.0">PluginDependencyRecalculationVersion</string>
+                       <integer value="1" key="NS.object.0"/>
+               </object>
+               <array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+                       <object class="IBProxyObject" id="372490531">
+                               <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                       </object>
+                       <object class="IBProxyObject" id="975951072">
+                               <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                       </object>
+                       <object class="IBUIView" id="191373211">
+                               <reference key="NSNextResponder"/>
+                               <int key="NSvFlags">274</int>
+                               <array class="NSMutableArray" key="NSSubviews">
+                                       <object class="IBUITableView" id="589060229">
+                                               <reference key="NSNextResponder" ref="191373211"/>
+                                               <int key="NSvFlags">274</int>
+                                               <string key="NSFrame">{{0, 44}, {320, 416}}</string>
+                                               <reference key="NSSuperview" ref="191373211"/>
+                                               <reference key="NSWindow"/>
+                                               <reference key="NSNextKeyView" ref="72664573"/>
+                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                               <object class="NSColor" key="IBUIBackgroundColor">
+                                                       <int key="NSColorSpace">10</int>
+                                                       <object class="NSImage" key="NSImage">
+                                                               <int key="NSImageFlags">549453824</int>
+                                                               <string key="NSSize">{512, 1}</string>
+                                                               <array class="NSMutableArray" key="NSReps">
+                                                                       <array>
+                                                                               <integer value="0"/>
+                                                                               <object class="NSBitmapImageRep">
+                                                                                       <object class="NSData" key="NSTIFFRepresentation">
+                                                                                               <bytes key="NS.bytes">TU0AKgAACAjFzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/
+y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/
+xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/
+xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/
+xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/
+xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/
+xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/
+y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/
+y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/
+xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/
+xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/
+xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/
+xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/
+xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/
+y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/
+y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/
+xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/
+xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/
+xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/
+xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/
+xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/
+y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/
+y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/
+xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/
+xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/
+xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/
+xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/
+xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/
+y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/
+y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/
+xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/
+xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/
+xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/
+xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/
+xczS/8vS2P/L0tj/xczU/wANAQAAAwAAAAECAAAAAQEAAwAAAAEAAQAAAQIAAwAAAAQAAAiqAQMAAwAA
+AAEAAQAAAQYAAwAAAAEAAgAAAREABAAAAAEAAAAIARIAAwAAAAEAAQAAARUAAwAAAAEABAAAARYAAwAA
+AAEAAQAAARcABAAAAAEAAAgAARwAAwAAAAEAAQAAAVIAAwAAAAEAAQAAAVMAAwAAAAQAAAiyAAAAAAAI
+AAgACAAIAAEAAQABAAE</bytes>
+                                                                                       </object>
+                                                                               </object>
+                                                                       </array>
+                                                               </array>
+                                                               <object class="NSColor" key="NSColor">
+                                                                       <int key="NSColorSpace">3</int>
+                                                                       <bytes key="NSWhite">MCAwAA</bytes>
+                                                               </object>
+                                                       </object>
+                                                       <string key="IBUIColorCocoaTouchKeyPath">groupTableViewBackgroundColor</string>
+                                               </object>
+                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                               <bool key="IBUIAlwaysBounceVertical">YES</bool>
+                                               <int key="IBUIStyle">1</int>
+                                               <int key="IBUISeparatorStyle">2</int>
+                                               <int key="IBUISectionIndexMinimumDisplayRowCount">0</int>
+                                               <bool key="IBUIShowsSelectionImmediatelyOnTouchBegin">YES</bool>
+                                               <float key="IBUIRowHeight">44</float>
+                                               <float key="IBUISectionHeaderHeight">10</float>
+                                               <float key="IBUISectionFooterHeight">10</float>
+                                       </object>
+                                       <object class="IBUISearchBar" id="72664573">
+                                               <reference key="NSNextResponder" ref="191373211"/>
+                                               <int key="NSvFlags">290</int>
+                                               <string key="NSFrameSize">{320, 44}</string>
+                                               <reference key="NSSuperview" ref="191373211"/>
+                                               <reference key="NSWindow"/>
+                                               <reference key="NSNextKeyView"/>
+                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                               <int key="IBUIContentMode">3</int>
+                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                               <object class="IBUITextInputTraits" key="IBTextInputTraits">
+                                                       <int key="IBUIAutocorrectionType">1</int>
+                                                       <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                               </object>
+                                       </object>
+                               </array>
+                               <string key="NSFrame">{{0, 20}, {320, 460}}</string>
+                               <reference key="NSSuperview"/>
+                               <reference key="NSWindow"/>
+                               <reference key="NSNextKeyView" ref="589060229"/>
+                               <object class="NSColor" key="IBUIBackgroundColor">
+                                       <int key="NSColorSpace">3</int>
+                                       <bytes key="NSWhite">MQA</bytes>
+                                       <object class="NSColorSpace" key="NSCustomColorSpace">
+                                               <int key="NSID">2</int>
+                                       </object>
+                               </object>
+                               <object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                       </object>
+               </array>
+               <object class="IBObjectContainer" key="IBDocument.Objects">
+                       <array class="NSMutableArray" key="connectionRecords">
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">tableView</string>
+                                               <reference key="source" ref="372490531"/>
+                                               <reference key="destination" ref="589060229"/>
+                                       </object>
+                                       <int key="connectionID">6</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">view</string>
+                                               <reference key="source" ref="372490531"/>
+                                               <reference key="destination" ref="191373211"/>
+                                       </object>
+                                       <int key="connectionID">7</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">searchBar</string>
+                                               <reference key="source" ref="372490531"/>
+                                               <reference key="destination" ref="72664573"/>
+                                       </object>
+                                       <int key="connectionID">5</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">delegate</string>
+                                               <reference key="source" ref="589060229"/>
+                                               <reference key="destination" ref="372490531"/>
+                                       </object>
+                                       <int key="connectionID">8</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">dataSource</string>
+                                               <reference key="source" ref="589060229"/>
+                                               <reference key="destination" ref="372490531"/>
+                                       </object>
+                                       <int key="connectionID">9</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">delegate</string>
+                                               <reference key="source" ref="72664573"/>
+                                               <reference key="destination" ref="372490531"/>
+                                       </object>
+                                       <int key="connectionID">10</int>
+                               </object>
+                       </array>
+                       <object class="IBMutableOrderedSet" key="objectRecords">
+                               <array key="orderedObjects">
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">0</int>
+                                               <array key="object" id="0"/>
+                                               <reference key="children" ref="1000"/>
+                                               <nil key="parent"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">1</int>
+                                               <reference key="object" ref="191373211"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="589060229"/>
+                                                       <reference ref="72664573"/>
+                                               </array>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-1</int>
+                                               <reference key="object" ref="372490531"/>
+                                               <reference key="parent" ref="0"/>
+                                               <string key="objectName">File's Owner</string>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-2</int>
+                                               <reference key="object" ref="975951072"/>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">3</int>
+                                               <reference key="object" ref="589060229"/>
+                                               <array class="NSMutableArray" key="children"/>
+                                               <reference key="parent" ref="191373211"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">4</int>
+                                               <reference key="object" ref="72664573"/>
+                                               <reference key="parent" ref="191373211"/>
+                                       </object>
+                               </array>
+                       </object>
+                       <dictionary class="NSMutableDictionary" key="flattenedProperties">
+                               <string key="-1.CustomClassName">BookmarkListController</string>
+                               <string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="-2.CustomClassName">UIResponder</string>
+                               <string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="3.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="4.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                       </dictionary>
+                       <dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
+                       <nil key="activeLocalization"/>
+                       <dictionary class="NSMutableDictionary" key="localizations"/>
+                       <nil key="sourceID"/>
+                       <int key="maxID">10</int>
+               </object>
+               <object class="IBClassDescriber" key="IBDocument.Classes">
+                       <array class="NSMutableArray" key="referencedPartialClassDescriptions">
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">BookmarkListController</string>
+                                       <string key="superclassName">UIViewController</string>
+                                       <dictionary class="NSMutableDictionary" key="outlets">
+                                               <string key="bmTableCell">BookmarkTableCell</string>
+                                               <string key="searchBar">UISearchBar</string>
+                                               <string key="sessTableCell">SessionsTableCell</string>
+                                               <string key="tableView">UITableView</string>
+                                       </dictionary>
+                                       <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <object class="IBToOneOutletInfo" key="bmTableCell">
+                                                       <string key="name">bmTableCell</string>
+                                                       <string key="candidateClassName">BookmarkTableCell</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="searchBar">
+                                                       <string key="name">searchBar</string>
+                                                       <string key="candidateClassName">UISearchBar</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="sessTableCell">
+                                                       <string key="name">sessTableCell</string>
+                                                       <string key="candidateClassName">SessionsTableCell</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="tableView">
+                                                       <string key="name">tableView</string>
+                                                       <string key="candidateClassName">UITableView</string>
+                                               </object>
+                                       </dictionary>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/BookmarkListController.h</string>
+                                       </object>
+                               </object>
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">BookmarkTableCell</string>
+                                       <string key="superclassName">UITableViewCell</string>
+                                       <dictionary class="NSMutableDictionary" key="outlets">
+                                               <string key="_connection_state_icon">UIImageView</string>
+                                               <string key="_sub_title">UILabel</string>
+                                               <string key="_title">UILabel</string>
+                                       </dictionary>
+                                       <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <object class="IBToOneOutletInfo" key="_connection_state_icon">
+                                                       <string key="name">_connection_state_icon</string>
+                                                       <string key="candidateClassName">UIImageView</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_sub_title">
+                                                       <string key="name">_sub_title</string>
+                                                       <string key="candidateClassName">UILabel</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_title">
+                                                       <string key="name">_title</string>
+                                                       <string key="candidateClassName">UILabel</string>
+                                               </object>
+                                       </dictionary>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/BookmarkTableCell.h</string>
+                                       </object>
+                               </object>
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">SessionsTableCell</string>
+                                       <string key="superclassName">UITableViewCell</string>
+                                       <dictionary class="NSMutableDictionary" key="outlets">
+                                               <string key="_disconnect_button">UIButton</string>
+                                               <string key="_screenshot">UIImageView</string>
+                                               <string key="_server">UILabel</string>
+                                               <string key="_title">UILabel</string>
+                                               <string key="_username">UILabel</string>
+                                       </dictionary>
+                                       <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <object class="IBToOneOutletInfo" key="_disconnect_button">
+                                                       <string key="name">_disconnect_button</string>
+                                                       <string key="candidateClassName">UIButton</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_screenshot">
+                                                       <string key="name">_screenshot</string>
+                                                       <string key="candidateClassName">UIImageView</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_server">
+                                                       <string key="name">_server</string>
+                                                       <string key="candidateClassName">UILabel</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_title">
+                                                       <string key="name">_title</string>
+                                                       <string key="candidateClassName">UILabel</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_username">
+                                                       <string key="name">_username</string>
+                                                       <string key="candidateClassName">UILabel</string>
+                                               </object>
+                                       </dictionary>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/SessionsTableCell.h</string>
+                                       </object>
+                               </object>
+                       </array>
+               </object>
+               <int key="IBDocument.localizationMode">0</int>
+               <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+                       <real value="1296" key="NS.object.0"/>
+               </object>
+               <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+               <int key="IBDocument.defaultPropertyAccessControl">3</int>
+               <string key="IBCocoaTouchPluginVersion">1179</string>
+       </data>
+</archive>
diff --git a/client/iOS/Resources/BookmarkTableViewCell.xib b/client/iOS/Resources/BookmarkTableViewCell.xib
new file mode 100644 (file)
index 0000000..1d86f08
--- /dev/null
@@ -0,0 +1,428 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="7.10">
+       <data>
+               <int key="IBDocument.SystemTarget">1296</int>
+               <string key="IBDocument.SystemVersion">11D50b</string>
+               <string key="IBDocument.InterfaceBuilderVersion">2182</string>
+               <string key="IBDocument.AppKitVersion">1138.32</string>
+               <string key="IBDocument.HIToolboxVersion">568.00</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                       <string key="NS.object.0">1179</string>
+               </object>
+               <object class="NSArray" key="IBDocument.IntegratedClassDependencies">
+                       <bool key="EncodedWithXMLCoder">YES</bool>
+                       <string>IBProxyObject</string>
+                       <string>IBUILabel</string>
+                       <string>IBUITableViewCell</string>
+               </object>
+               <object class="NSArray" key="IBDocument.PluginDependencies">
+                       <bool key="EncodedWithXMLCoder">YES</bool>
+                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+               </object>
+               <object class="NSMutableDictionary" key="IBDocument.Metadata">
+                       <string key="NS.key.0">PluginDependencyRecalculationVersion</string>
+                       <integer value="1" key="NS.object.0"/>
+               </object>
+               <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+                       <bool key="EncodedWithXMLCoder">YES</bool>
+                       <object class="IBProxyObject" id="372490531">
+                               <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+                               <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+                       </object>
+                       <object class="IBProxyObject" id="975951072">
+                               <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+                               <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+                       </object>
+                       <object class="IBUITableViewCell" id="581303870">
+                               <reference key="NSNextResponder"/>
+                               <int key="NSvFlags">292</int>
+                               <object class="NSMutableArray" key="NSSubviews">
+                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                       <object class="IBUIView" id="806623018">
+                                               <reference key="NSNextResponder" ref="581303870"/>
+                                               <int key="NSvFlags">256</int>
+                                               <object class="NSMutableArray" key="NSSubviews">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <object class="IBUILabel" id="915789886">
+                                                               <reference key="NSNextResponder" ref="806623018"/>
+                                                               <int key="NSvFlags">290</int>
+                                                               <string key="NSFrame">{{20, 2}, {267, 21}}</string>
+                                                               <reference key="NSSuperview" ref="806623018"/>
+                                                               <reference key="NSWindow"/>
+                                                               <reference key="NSNextKeyView" ref="74446343"/>
+                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                               <bool key="IBUIOpaque">NO</bool>
+                                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                                               <int key="IBUIContentMode">7</int>
+                                                               <bool key="IBUIUserInteractionEnabled">NO</bool>
+                                                               <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+                                                               <string key="IBUIText">Label</string>
+                                                               <object class="NSColor" key="IBUITextColor" id="782525937">
+                                                                       <int key="NSColorSpace">1</int>
+                                                                       <bytes key="NSRGB">MCAwIDAAA</bytes>
+                                                               </object>
+                                                               <object class="NSColor" key="IBUIHighlightedColor" id="549211185">
+                                                                       <int key="NSColorSpace">3</int>
+                                                                       <bytes key="NSWhite">MQA</bytes>
+                                                               </object>
+                                                               <int key="IBUIBaselineAdjustment">0</int>
+                                                               <float key="IBUIMinimumFontSize">10</float>
+                                                               <object class="IBUIFontDescription" key="IBUIFontDescription">
+                                                                       <int key="type">2</int>
+                                                                       <double key="pointSize">18</double>
+                                                               </object>
+                                                               <object class="NSFont" key="IBUIFont">
+                                                                       <string key="NSName">Helvetica-Bold</string>
+                                                                       <double key="NSSize">18</double>
+                                                                       <int key="NSfFlags">16</int>
+                                                               </object>
+                                                       </object>
+                                                       <object class="IBUILabel" id="74446343">
+                                                               <reference key="NSNextResponder" ref="806623018"/>
+                                                               <int key="NSvFlags">290</int>
+                                                               <string key="NSFrame">{{20, 20}, {267, 21}}</string>
+                                                               <reference key="NSSuperview" ref="806623018"/>
+                                                               <reference key="NSWindow"/>
+                                                               <reference key="NSNextKeyView"/>
+                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                               <bool key="IBUIOpaque">NO</bool>
+                                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                                               <int key="IBUIContentMode">7</int>
+                                                               <bool key="IBUIUserInteractionEnabled">NO</bool>
+                                                               <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+                                                               <string key="IBUIText">Label</string>
+                                                               <reference key="IBUITextColor" ref="782525937"/>
+                                                               <reference key="IBUIHighlightedColor" ref="549211185"/>
+                                                               <int key="IBUIBaselineAdjustment">0</int>
+                                                               <float key="IBUIMinimumFontSize">10</float>
+                                                               <object class="IBUIFontDescription" key="IBUIFontDescription">
+                                                                       <int key="type">1</int>
+                                                                       <double key="pointSize">14</double>
+                                                               </object>
+                                                               <object class="NSFont" key="IBUIFont">
+                                                                       <string key="NSName">Helvetica</string>
+                                                                       <double key="NSSize">14</double>
+                                                                       <int key="NSfFlags">16</int>
+                                                               </object>
+                                                       </object>
+                                               </object>
+                                               <string key="NSFrameSize">{287, 43}</string>
+                                               <reference key="NSSuperview" ref="581303870"/>
+                                               <reference key="NSWindow"/>
+                                               <reference key="NSNextKeyView" ref="915789886"/>
+                                               <string key="NSReuseIdentifierKey">_NS:11</string>
+                                               <object class="NSColor" key="IBUIBackgroundColor">
+                                                       <int key="NSColorSpace">3</int>
+                                                       <bytes key="NSWhite">MCAwAA</bytes>
+                                               </object>
+                                               <bool key="IBUIOpaque">NO</bool>
+                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                               <int key="IBUIContentMode">4</int>
+                                               <bool key="IBUIMultipleTouchEnabled">YES</bool>
+                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                       </object>
+                               </object>
+                               <string key="NSFrameSize">{320, 44}</string>
+                               <reference key="NSSuperview"/>
+                               <reference key="NSWindow"/>
+                               <reference key="NSNextKeyView" ref="806623018"/>
+                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                               <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+                               <int key="IBUIAccessoryType">2</int>
+                               <reference key="IBUIContentView" ref="806623018"/>
+                       </object>
+               </object>
+               <object class="IBObjectContainer" key="IBDocument.Objects">
+                       <object class="NSMutableArray" key="connectionRecords">
+                               <bool key="EncodedWithXMLCoder">YES</bool>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">bmTableCell</string>
+                                               <reference key="source" ref="372490531"/>
+                                               <reference key="destination" ref="581303870"/>
+                                       </object>
+                                       <int key="connectionID">23</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_sub_title</string>
+                                               <reference key="source" ref="581303870"/>
+                                               <reference key="destination" ref="74446343"/>
+                                       </object>
+                                       <int key="connectionID">21</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_title</string>
+                                               <reference key="source" ref="581303870"/>
+                                               <reference key="destination" ref="915789886"/>
+                                       </object>
+                                       <int key="connectionID">22</int>
+                               </object>
+                       </object>
+                       <object class="IBMutableOrderedSet" key="objectRecords">
+                               <object class="NSArray" key="orderedObjects">
+                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">0</int>
+                                               <object class="NSArray" key="object" id="0">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                               </object>
+                                               <reference key="children" ref="1000"/>
+                                               <nil key="parent"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-1</int>
+                                               <reference key="object" ref="372490531"/>
+                                               <reference key="parent" ref="0"/>
+                                               <string key="objectName">File's Owner</string>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-2</int>
+                                               <reference key="object" ref="975951072"/>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">18</int>
+                                               <reference key="object" ref="581303870"/>
+                                               <object class="NSMutableArray" key="children">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <reference ref="915789886"/>
+                                                       <reference ref="74446343"/>
+                                               </object>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">19</int>
+                                               <reference key="object" ref="915789886"/>
+                                               <reference key="parent" ref="581303870"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">20</int>
+                                               <reference key="object" ref="74446343"/>
+                                               <reference key="parent" ref="581303870"/>
+                                       </object>
+                               </object>
+                       </object>
+                       <object class="NSMutableDictionary" key="flattenedProperties">
+                               <bool key="EncodedWithXMLCoder">YES</bool>
+                               <object class="NSArray" key="dict.sortedKeys">
+                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                       <string>-1.CustomClassName</string>
+                                       <string>-1.IBPluginDependency</string>
+                                       <string>-2.CustomClassName</string>
+                                       <string>-2.IBPluginDependency</string>
+                                       <string>18.CustomClassName</string>
+                                       <string>18.IBPluginDependency</string>
+                                       <string>19.IBPluginDependency</string>
+                                       <string>20.IBPluginDependency</string>
+                               </object>
+                               <object class="NSArray" key="dict.values">
+                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                       <string>BookmarkListController</string>
+                                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                                       <string>UIResponder</string>
+                                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                                       <string>BookmarkTableCell</string>
+                                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               </object>
+                       </object>
+                       <object class="NSMutableDictionary" key="unlocalizedProperties">
+                               <bool key="EncodedWithXMLCoder">YES</bool>
+                               <reference key="dict.sortedKeys" ref="0"/>
+                               <reference key="dict.values" ref="0"/>
+                       </object>
+                       <nil key="activeLocalization"/>
+                       <object class="NSMutableDictionary" key="localizations">
+                               <bool key="EncodedWithXMLCoder">YES</bool>
+                               <reference key="dict.sortedKeys" ref="0"/>
+                               <reference key="dict.values" ref="0"/>
+                       </object>
+                       <nil key="sourceID"/>
+                       <int key="maxID">23</int>
+               </object>
+               <object class="IBClassDescriber" key="IBDocument.Classes">
+                       <object class="NSMutableArray" key="referencedPartialClassDescriptions">
+                               <bool key="EncodedWithXMLCoder">YES</bool>
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">BookmarkListController</string>
+                                       <string key="superclassName">UIViewController</string>
+                                       <object class="NSMutableDictionary" key="outlets">
+                                               <bool key="EncodedWithXMLCoder">YES</bool>
+                                               <object class="NSArray" key="dict.sortedKeys">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <string>bmTableCell</string>
+                                                       <string>searchBar</string>
+                                                       <string>sessTableCell</string>
+                                                       <string>tableView</string>
+                                               </object>
+                                               <object class="NSArray" key="dict.values">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <string>BookmarkTableCell</string>
+                                                       <string>UISearchBar</string>
+                                                       <string>SessionTableCell</string>
+                                                       <string>UITableView</string>
+                                               </object>
+                                       </object>
+                                       <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <bool key="EncodedWithXMLCoder">YES</bool>
+                                               <object class="NSArray" key="dict.sortedKeys">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <string>bmTableCell</string>
+                                                       <string>searchBar</string>
+                                                       <string>sessTableCell</string>
+                                                       <string>tableView</string>
+                                               </object>
+                                               <object class="NSArray" key="dict.values">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">bmTableCell</string>
+                                                               <string key="candidateClassName">BookmarkTableCell</string>
+                                                       </object>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">searchBar</string>
+                                                               <string key="candidateClassName">UISearchBar</string>
+                                                       </object>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">sessTableCell</string>
+                                                               <string key="candidateClassName">SessionTableCell</string>
+                                                       </object>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">tableView</string>
+                                                               <string key="candidateClassName">UITableView</string>
+                                                       </object>
+                                               </object>
+                                       </object>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/BookmarkListController.h</string>
+                                       </object>
+                               </object>
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">BookmarkTableCell</string>
+                                       <string key="superclassName">UITableViewCell</string>
+                                       <object class="NSMutableDictionary" key="outlets">
+                                               <bool key="EncodedWithXMLCoder">YES</bool>
+                                               <object class="NSArray" key="dict.sortedKeys">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <string>_connection_state_icon</string>
+                                                       <string>_sub_title</string>
+                                                       <string>_title</string>
+                                               </object>
+                                               <object class="NSArray" key="dict.values">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <string>UIImageView</string>
+                                                       <string>UILabel</string>
+                                                       <string>UILabel</string>
+                                               </object>
+                                       </object>
+                                       <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <bool key="EncodedWithXMLCoder">YES</bool>
+                                               <object class="NSArray" key="dict.sortedKeys">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <string>_connection_state_icon</string>
+                                                       <string>_sub_title</string>
+                                                       <string>_title</string>
+                                               </object>
+                                               <object class="NSArray" key="dict.values">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">_connection_state_icon</string>
+                                                               <string key="candidateClassName">UIImageView</string>
+                                                       </object>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">_sub_title</string>
+                                                               <string key="candidateClassName">UILabel</string>
+                                                       </object>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">_title</string>
+                                                               <string key="candidateClassName">UILabel</string>
+                                                       </object>
+                                               </object>
+                                       </object>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/BookmarkTableCell.h</string>
+                                       </object>
+                               </object>
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">SessionTableCell</string>
+                                       <string key="superclassName">UITableViewCell</string>
+                                       <object class="NSMutableDictionary" key="outlets">
+                                               <bool key="EncodedWithXMLCoder">YES</bool>
+                                               <object class="NSArray" key="dict.sortedKeys">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <string>_disconnect_button</string>
+                                                       <string>_screenshot</string>
+                                                       <string>_server</string>
+                                                       <string>_title</string>
+                                                       <string>_username</string>
+                                               </object>
+                                               <object class="NSArray" key="dict.values">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <string>UIButton</string>
+                                                       <string>UIImageView</string>
+                                                       <string>UILabel</string>
+                                                       <string>UILabel</string>
+                                                       <string>UILabel</string>
+                                               </object>
+                                       </object>
+                                       <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <bool key="EncodedWithXMLCoder">YES</bool>
+                                               <object class="NSArray" key="dict.sortedKeys">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <string>_disconnect_button</string>
+                                                       <string>_screenshot</string>
+                                                       <string>_server</string>
+                                                       <string>_title</string>
+                                                       <string>_username</string>
+                                               </object>
+                                               <object class="NSArray" key="dict.values">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">_disconnect_button</string>
+                                                               <string key="candidateClassName">UIButton</string>
+                                                       </object>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">_screenshot</string>
+                                                               <string key="candidateClassName">UIImageView</string>
+                                                       </object>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">_server</string>
+                                                               <string key="candidateClassName">UILabel</string>
+                                                       </object>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">_title</string>
+                                                               <string key="candidateClassName">UILabel</string>
+                                                       </object>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">_username</string>
+                                                               <string key="candidateClassName">UILabel</string>
+                                                       </object>
+                                               </object>
+                                       </object>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/SessionTableCell.h</string>
+                                       </object>
+                               </object>
+                       </object>
+               </object>
+               <int key="IBDocument.localizationMode">0</int>
+               <string key="IBDocument.TargetRuntimeIdentifier">IBIPadFramework</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+                       <real value="1296" key="NS.object.0"/>
+               </object>
+               <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
+                       <integer value="3100" key="NS.object.0"/>
+               </object>
+               <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+               <int key="IBDocument.defaultPropertyAccessControl">3</int>
+               <string key="IBCocoaTouchPluginVersion">1179</string>
+       </data>
+</archive>
diff --git a/client/iOS/Resources/CredentialsInputView.xib b/client/iOS/Resources/CredentialsInputView.xib
new file mode 100644 (file)
index 0000000..fab4ab9
--- /dev/null
@@ -0,0 +1,481 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.10">
+       <data>
+               <int key="IBDocument.SystemTarget">1296</int>
+               <string key="IBDocument.SystemVersion">11D50b</string>
+               <string key="IBDocument.InterfaceBuilderVersion">2182</string>
+               <string key="IBDocument.AppKitVersion">1138.32</string>
+               <string key="IBDocument.HIToolboxVersion">568.00</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                       <string key="NS.object.0">1179</string>
+               </object>
+               <object class="NSArray" key="IBDocument.IntegratedClassDependencies">
+                       <bool key="EncodedWithXMLCoder">YES</bool>
+                       <string>IBUITextField</string>
+                       <string>IBUILabel</string>
+                       <string>IBUIButton</string>
+                       <string>IBUIView</string>
+                       <string>IBUIScrollView</string>
+                       <string>IBProxyObject</string>
+               </object>
+               <object class="NSArray" key="IBDocument.PluginDependencies">
+                       <bool key="EncodedWithXMLCoder">YES</bool>
+                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+               </object>
+               <object class="NSMutableDictionary" key="IBDocument.Metadata">
+                       <string key="NS.key.0">PluginDependencyRecalculationVersion</string>
+                       <integer value="1" key="NS.object.0"/>
+               </object>
+               <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+                       <bool key="EncodedWithXMLCoder">YES</bool>
+                       <object class="IBProxyObject" id="372490531">
+                               <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                       </object>
+                       <object class="IBProxyObject" id="975951072">
+                               <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                       </object>
+                       <object class="IBUIView" id="234977634">
+                               <reference key="NSNextResponder"/>
+                               <int key="NSvFlags">274</int>
+                               <object class="NSMutableArray" key="NSSubviews">
+                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                       <object class="IBUIScrollView" id="76355032">
+                                               <reference key="NSNextResponder" ref="234977634"/>
+                                               <int key="NSvFlags">279</int>
+                                               <object class="NSMutableArray" key="NSSubviews">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <object class="IBUITextField" id="502350293">
+                                                               <reference key="NSNextResponder" ref="76355032"/>
+                                                               <int key="NSvFlags">290</int>
+                                                               <string key="NSFrame">{{15, 112}, {210, 31}}</string>
+                                                               <reference key="NSSuperview" ref="76355032"/>
+                                                               <reference key="NSNextKeyView" ref="407758879"/>
+                                                               <bool key="IBUIOpaque">NO</bool>
+                                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                                               <int key="IBUIContentVerticalAlignment">0</int>
+                                                               <string key="IBUIText"/>
+                                                               <int key="IBUIBorderStyle">3</int>
+                                                               <string key="IBUIPlaceholder">Username</string>
+                                                               <object class="NSColor" key="IBUITextColor">
+                                                                       <int key="NSColorSpace">3</int>
+                                                                       <bytes key="NSWhite">MAA</bytes>
+                                                                       <object class="NSColorSpace" key="NSCustomColorSpace" id="1055564775">
+                                                                               <int key="NSID">2</int>
+                                                                       </object>
+                                                               </object>
+                                                               <bool key="IBUIAdjustsFontSizeToFit">YES</bool>
+                                                               <float key="IBUIMinimumFontSize">17</float>
+                                                               <object class="IBUITextInputTraits" key="IBUITextInputTraits">
+                                                                       <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                                               </object>
+                                                               <int key="IBUIClearButtonMode">3</int>
+                                                               <object class="IBUIFontDescription" key="IBUIFontDescription" id="72634085">
+                                                                       <int key="type">1</int>
+                                                                       <double key="pointSize">12</double>
+                                                               </object>
+                                                               <object class="NSFont" key="IBUIFont" id="168483421">
+                                                                       <string key="NSName">Helvetica</string>
+                                                                       <double key="NSSize">12</double>
+                                                                       <int key="NSfFlags">16</int>
+                                                               </object>
+                                                       </object>
+                                                       <object class="IBUITextField" id="407758879">
+                                                               <reference key="NSNextResponder" ref="76355032"/>
+                                                               <int key="NSvFlags">290</int>
+                                                               <string key="NSFrame">{{15, 161}, {210, 31}}</string>
+                                                               <reference key="NSSuperview" ref="76355032"/>
+                                                               <reference key="NSNextKeyView" ref="316210701"/>
+                                                               <bool key="IBUIOpaque">NO</bool>
+                                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                                               <int key="IBUIContentVerticalAlignment">0</int>
+                                                               <string key="IBUIText"/>
+                                                               <int key="IBUIBorderStyle">3</int>
+                                                               <string key="IBUIPlaceholder">Password</string>
+                                                               <object class="NSColor" key="IBUITextColor">
+                                                                       <int key="NSColorSpace">3</int>
+                                                                       <bytes key="NSWhite">MAA</bytes>
+                                                                       <reference key="NSCustomColorSpace" ref="1055564775"/>
+                                                               </object>
+                                                               <bool key="IBUIAdjustsFontSizeToFit">YES</bool>
+                                                               <float key="IBUIMinimumFontSize">17</float>
+                                                               <object class="IBUITextInputTraits" key="IBUITextInputTraits">
+                                                                       <bool key="IBUISecureTextEntry">YES</bool>
+                                                                       <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                                               </object>
+                                                               <int key="IBUIClearButtonMode">3</int>
+                                                               <reference key="IBUIFontDescription" ref="72634085"/>
+                                                               <reference key="IBUIFont" ref="168483421"/>
+                                                       </object>
+                                                       <object class="IBUITextField" id="316210701">
+                                                               <reference key="NSNextResponder" ref="76355032"/>
+                                                               <int key="NSvFlags">290</int>
+                                                               <string key="NSFrame">{{15, 210}, {210, 31}}</string>
+                                                               <reference key="NSSuperview" ref="76355032"/>
+                                                               <reference key="NSNextKeyView" ref="266626143"/>
+                                                               <bool key="IBUIOpaque">NO</bool>
+                                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                                               <int key="IBUIContentVerticalAlignment">0</int>
+                                                               <string key="IBUIText"/>
+                                                               <int key="IBUIBorderStyle">3</int>
+                                                               <string key="IBUIPlaceholder">Domain</string>
+                                                               <object class="NSColor" key="IBUITextColor">
+                                                                       <int key="NSColorSpace">3</int>
+                                                                       <bytes key="NSWhite">MAA</bytes>
+                                                                       <reference key="NSCustomColorSpace" ref="1055564775"/>
+                                                               </object>
+                                                               <bool key="IBUIAdjustsFontSizeToFit">YES</bool>
+                                                               <float key="IBUIMinimumFontSize">17</float>
+                                                               <object class="IBUITextInputTraits" key="IBUITextInputTraits">
+                                                                       <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                                               </object>
+                                                               <int key="IBUIClearButtonMode">3</int>
+                                                               <reference key="IBUIFontDescription" ref="72634085"/>
+                                                               <reference key="IBUIFont" ref="168483421"/>
+                                                       </object>
+                                                       <object class="IBUIButton" id="67582393">
+                                                               <reference key="NSNextResponder" ref="76355032"/>
+                                                               <int key="NSvFlags">291</int>
+                                                               <string key="NSFrame">{{130, 263}, {95, 37}}</string>
+                                                               <reference key="NSSuperview" ref="76355032"/>
+                                                               <bool key="IBUIOpaque">NO</bool>
+                                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                                               <int key="IBUIContentHorizontalAlignment">0</int>
+                                                               <int key="IBUIContentVerticalAlignment">0</int>
+                                                               <int key="IBUIButtonType">1</int>
+                                                               <string key="IBUINormalTitle">Cancel</string>
+                                                               <object class="NSColor" key="IBUIHighlightedTitleColor" id="484131582">
+                                                                       <int key="NSColorSpace">3</int>
+                                                                       <bytes key="NSWhite">MQA</bytes>
+                                                               </object>
+                                                               <object class="NSColor" key="IBUINormalTitleColor">
+                                                                       <int key="NSColorSpace">1</int>
+                                                                       <bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
+                                                               </object>
+                                                               <object class="NSColor" key="IBUINormalTitleShadowColor" id="210891822">
+                                                                       <int key="NSColorSpace">3</int>
+                                                                       <bytes key="NSWhite">MC41AA</bytes>
+                                                               </object>
+                                                               <object class="IBUIFontDescription" key="IBUIFontDescription" id="223796057">
+                                                                       <string key="name">Helvetica-Bold</string>
+                                                                       <string key="family">Helvetica</string>
+                                                                       <int key="traits">2</int>
+                                                                       <double key="pointSize">15</double>
+                                                               </object>
+                                                               <object class="NSFont" key="IBUIFont" id="1043513320">
+                                                                       <string key="NSName">Helvetica-Bold</string>
+                                                                       <double key="NSSize">15</double>
+                                                                       <int key="NSfFlags">16</int>
+                                                               </object>
+                                                       </object>
+                                                       <object class="IBUIButton" id="266626143">
+                                                               <reference key="NSNextResponder" ref="76355032"/>
+                                                               <int key="NSvFlags">294</int>
+                                                               <string key="NSFrame">{{15, 263}, {95, 37}}</string>
+                                                               <reference key="NSSuperview" ref="76355032"/>
+                                                               <reference key="NSNextKeyView" ref="67582393"/>
+                                                               <bool key="IBUIOpaque">NO</bool>
+                                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                                               <int key="IBUIContentHorizontalAlignment">0</int>
+                                                               <int key="IBUIContentVerticalAlignment">0</int>
+                                                               <int key="IBUIButtonType">1</int>
+                                                               <string key="IBUINormalTitle">Login</string>
+                                                               <reference key="IBUIHighlightedTitleColor" ref="484131582"/>
+                                                               <object class="NSColor" key="IBUINormalTitleColor">
+                                                                       <int key="NSColorSpace">1</int>
+                                                                       <bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
+                                                               </object>
+                                                               <reference key="IBUINormalTitleShadowColor" ref="210891822"/>
+                                                               <reference key="IBUIFontDescription" ref="223796057"/>
+                                                               <reference key="IBUIFont" ref="1043513320"/>
+                                                       </object>
+                                                       <object class="IBUILabel" id="876100682">
+                                                               <reference key="NSNextResponder" ref="76355032"/>
+                                                               <int key="NSvFlags">290</int>
+                                                               <string key="NSFrame">{{15, 20}, {210, 71}}</string>
+                                                               <reference key="NSSuperview" ref="76355032"/>
+                                                               <reference key="NSNextKeyView" ref="502350293"/>
+                                                               <bool key="IBUIOpaque">NO</bool>
+                                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                                               <int key="IBUIContentMode">7</int>
+                                                               <bool key="IBUIUserInteractionEnabled">NO</bool>
+                                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                                               <string key="IBUIText">Please provide the missing user information in order to proceed and login.</string>
+                                                               <object class="NSColor" key="IBUITextColor">
+                                                                       <int key="NSColorSpace">1</int>
+                                                                       <bytes key="NSRGB">MCAwIDAAA</bytes>
+                                                               </object>
+                                                               <nil key="IBUIHighlightedColor"/>
+                                                               <int key="IBUIBaselineAdjustment">1</int>
+                                                               <float key="IBUIMinimumFontSize">10</float>
+                                                               <int key="IBUINumberOfLines">3</int>
+                                                               <int key="IBUILineBreakMode">0</int>
+                                                               <object class="IBUIFontDescription" key="IBUIFontDescription">
+                                                                       <int key="type">1</int>
+                                                                       <double key="pointSize">17</double>
+                                                               </object>
+                                                               <object class="NSFont" key="IBUIFont">
+                                                                       <string key="NSName">Helvetica</string>
+                                                                       <double key="NSSize">17</double>
+                                                                       <int key="NSfFlags">16</int>
+                                                               </object>
+                                                       </object>
+                                               </object>
+                                               <string key="NSFrameSize">{240, 320}</string>
+                                               <reference key="NSSuperview" ref="234977634"/>
+                                               <reference key="NSNextKeyView" ref="876100682"/>
+                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                               <bool key="IBUIMultipleTouchEnabled">YES</bool>
+                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                       </object>
+                               </object>
+                               <string key="NSFrameSize">{240, 320}</string>
+                               <reference key="NSSuperview"/>
+                               <reference key="NSNextKeyView" ref="76355032"/>
+                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                               <object class="NSColor" key="IBUIBackgroundColor">
+                                       <int key="NSColorSpace">3</int>
+                                       <bytes key="NSWhite">MQA</bytes>
+                                       <reference key="NSCustomColorSpace" ref="1055564775"/>
+                               </object>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                       </object>
+               </object>
+               <object class="IBObjectContainer" key="IBDocument.Objects">
+                       <object class="NSMutableArray" key="connectionRecords">
+                               <bool key="EncodedWithXMLCoder">YES</bool>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">view</string>
+                                               <reference key="source" ref="372490531"/>
+                                               <reference key="destination" ref="234977634"/>
+                                       </object>
+                                       <int key="connectionID">41</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_scroll_view</string>
+                                               <reference key="source" ref="372490531"/>
+                                               <reference key="destination" ref="76355032"/>
+                                       </object>
+                                       <int key="connectionID">42</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_textfield_username</string>
+                                               <reference key="source" ref="372490531"/>
+                                               <reference key="destination" ref="502350293"/>
+                                       </object>
+                                       <int key="connectionID">34</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_textfield_password</string>
+                                               <reference key="source" ref="372490531"/>
+                                               <reference key="destination" ref="407758879"/>
+                                       </object>
+                                       <int key="connectionID">33</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_textfield_domain</string>
+                                               <reference key="source" ref="372490531"/>
+                                               <reference key="destination" ref="316210701"/>
+                                       </object>
+                                       <int key="connectionID">32</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_btn_cancel</string>
+                                               <reference key="source" ref="372490531"/>
+                                               <reference key="destination" ref="67582393"/>
+                                       </object>
+                                       <int key="connectionID">30</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_btn_login</string>
+                                               <reference key="source" ref="372490531"/>
+                                               <reference key="destination" ref="266626143"/>
+                                       </object>
+                                       <int key="connectionID">31</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_lbl_message</string>
+                                               <reference key="source" ref="372490531"/>
+                                               <reference key="destination" ref="876100682"/>
+                                       </object>
+                                       <int key="connectionID">43</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchEventConnection" key="connection">
+                                               <string key="label">cancelPressed:</string>
+                                               <reference key="source" ref="67582393"/>
+                                               <reference key="destination" ref="372490531"/>
+                                               <int key="IBEventType">7</int>
+                                       </object>
+                                       <int key="connectionID">36</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchEventConnection" key="connection">
+                                               <string key="label">loginPressed:</string>
+                                               <reference key="source" ref="266626143"/>
+                                               <reference key="destination" ref="372490531"/>
+                                               <int key="IBEventType">7</int>
+                                       </object>
+                                       <int key="connectionID">37</int>
+                               </object>
+                       </object>
+                       <object class="IBMutableOrderedSet" key="objectRecords">
+                               <object class="NSArray" key="orderedObjects">
+                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">0</int>
+                                               <object class="NSArray" key="object" id="0">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                               </object>
+                                               <reference key="children" ref="1000"/>
+                                               <nil key="parent"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-1</int>
+                                               <reference key="object" ref="372490531"/>
+                                               <reference key="parent" ref="0"/>
+                                               <string key="objectName">File's Owner</string>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-2</int>
+                                               <reference key="object" ref="975951072"/>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">40</int>
+                                               <reference key="object" ref="234977634"/>
+                                               <object class="NSMutableArray" key="children">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <reference ref="76355032"/>
+                                               </object>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">38</int>
+                                               <reference key="object" ref="76355032"/>
+                                               <object class="NSMutableArray" key="children">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <reference ref="876100682"/>
+                                                       <reference ref="266626143"/>
+                                                       <reference ref="67582393"/>
+                                                       <reference ref="502350293"/>
+                                                       <reference ref="316210701"/>
+                                                       <reference ref="407758879"/>
+                                               </object>
+                                               <reference key="parent" ref="234977634"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">3</int>
+                                               <reference key="object" ref="502350293"/>
+                                               <reference key="parent" ref="76355032"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">5</int>
+                                               <reference key="object" ref="407758879"/>
+                                               <reference key="parent" ref="76355032"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">7</int>
+                                               <reference key="object" ref="316210701"/>
+                                               <reference key="parent" ref="76355032"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">10</int>
+                                               <reference key="object" ref="67582393"/>
+                                               <reference key="parent" ref="76355032"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">20</int>
+                                               <reference key="object" ref="266626143"/>
+                                               <reference key="parent" ref="76355032"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">11</int>
+                                               <reference key="object" ref="876100682"/>
+                                               <reference key="parent" ref="76355032"/>
+                                       </object>
+                               </object>
+                       </object>
+                       <object class="NSMutableDictionary" key="flattenedProperties">
+                               <bool key="EncodedWithXMLCoder">YES</bool>
+                               <object class="NSArray" key="dict.sortedKeys">
+                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                       <string>-1.CustomClassName</string>
+                                       <string>-1.IBPluginDependency</string>
+                                       <string>-2.CustomClassName</string>
+                                       <string>-2.IBAttributePlaceholdersKey</string>
+                                       <string>-2.IBPluginDependency</string>
+                                       <string>10.IBPluginDependency</string>
+                                       <string>11.IBPluginDependency</string>
+                                       <string>20.IBPluginDependency</string>
+                                       <string>3.IBPluginDependency</string>
+                                       <string>38.IBPluginDependency</string>
+                                       <string>40.IBPluginDependency</string>
+                                       <string>5.IBPluginDependency</string>
+                                       <string>7.IBPluginDependency</string>
+                               </object>
+                               <object class="NSArray" key="dict.values">
+                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                       <string>CredentialsInputController</string>
+                                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                                       <string>UIResponder</string>
+                                       <object class="NSMutableDictionary">
+                                               <bool key="EncodedWithXMLCoder">YES</bool>
+                                               <reference key="dict.sortedKeys" ref="0"/>
+                                               <reference key="dict.values" ref="0"/>
+                                       </object>
+                                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               </object>
+                       </object>
+                       <object class="NSMutableDictionary" key="unlocalizedProperties">
+                               <bool key="EncodedWithXMLCoder">YES</bool>
+                               <reference key="dict.sortedKeys" ref="0"/>
+                               <reference key="dict.values" ref="0"/>
+                       </object>
+                       <nil key="activeLocalization"/>
+                       <object class="NSMutableDictionary" key="localizations">
+                               <bool key="EncodedWithXMLCoder">YES</bool>
+                               <reference key="dict.sortedKeys" ref="0"/>
+                               <reference key="dict.values" ref="0"/>
+                       </object>
+                       <nil key="sourceID"/>
+                       <int key="maxID">43</int>
+               </object>
+               <object class="IBClassDescriber" key="IBDocument.Classes"/>
+               <int key="IBDocument.localizationMode">0</int>
+               <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+                       <real value="1296" key="NS.object.0"/>
+               </object>
+               <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
+                       <integer value="3100" key="NS.object.0"/>
+               </object>
+               <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+               <int key="IBDocument.defaultPropertyAccessControl">3</int>
+               <string key="IBCocoaTouchPluginVersion">1179</string>
+       </data>
+</archive>
diff --git a/client/iOS/Resources/Default-568h@2x.png b/client/iOS/Resources/Default-568h@2x.png
new file mode 100755 (executable)
index 0000000..bc2676b
Binary files /dev/null and b/client/iOS/Resources/Default-568h@2x.png differ
diff --git a/client/iOS/Resources/Default-Landscape@2x~ipad.png b/client/iOS/Resources/Default-Landscape@2x~ipad.png
new file mode 100755 (executable)
index 0000000..fe643b1
Binary files /dev/null and b/client/iOS/Resources/Default-Landscape@2x~ipad.png differ
diff --git a/client/iOS/Resources/Default-Landscape~ipad.png b/client/iOS/Resources/Default-Landscape~ipad.png
new file mode 100755 (executable)
index 0000000..fe4be74
Binary files /dev/null and b/client/iOS/Resources/Default-Landscape~ipad.png differ
diff --git a/client/iOS/Resources/Default-Portrait@2x~ipad.png b/client/iOS/Resources/Default-Portrait@2x~ipad.png
new file mode 100755 (executable)
index 0000000..db4a788
Binary files /dev/null and b/client/iOS/Resources/Default-Portrait@2x~ipad.png differ
diff --git a/client/iOS/Resources/Default-Portrait~ipad.png b/client/iOS/Resources/Default-Portrait~ipad.png
new file mode 100755 (executable)
index 0000000..94b50ec
Binary files /dev/null and b/client/iOS/Resources/Default-Portrait~ipad.png differ
diff --git a/client/iOS/Resources/Default.png b/client/iOS/Resources/Default.png
new file mode 100755 (executable)
index 0000000..86fe483
Binary files /dev/null and b/client/iOS/Resources/Default.png differ
diff --git a/client/iOS/Resources/Default@2x.png b/client/iOS/Resources/Default@2x.png
new file mode 100755 (executable)
index 0000000..ba63bf0
Binary files /dev/null and b/client/iOS/Resources/Default@2x.png differ
diff --git a/client/iOS/Resources/EditButtonTableViewCell.xib b/client/iOS/Resources/EditButtonTableViewCell.xib
new file mode 100644 (file)
index 0000000..0091ff0
--- /dev/null
@@ -0,0 +1,408 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
+       <data>
+               <int key="IBDocument.SystemTarget">1296</int>
+               <string key="IBDocument.SystemVersion">11D50b</string>
+               <string key="IBDocument.InterfaceBuilderVersion">2182</string>
+               <string key="IBDocument.AppKitVersion">1138.32</string>
+               <string key="IBDocument.HIToolboxVersion">568.00</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                       <string key="NS.object.0">1179</string>
+               </object>
+               <array key="IBDocument.IntegratedClassDependencies">
+                       <string>IBUITableViewCell</string>
+                       <string>IBUIButton</string>
+                       <string>IBUILabel</string>
+                       <string>IBProxyObject</string>
+               </array>
+               <array key="IBDocument.PluginDependencies">
+                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+               </array>
+               <object class="NSMutableDictionary" key="IBDocument.Metadata">
+                       <string key="NS.key.0">PluginDependencyRecalculationVersion</string>
+                       <integer value="1" key="NS.object.0"/>
+               </object>
+               <array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+                       <object class="IBProxyObject" id="841351856">
+                               <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                       </object>
+                       <object class="IBProxyObject" id="371349661">
+                               <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                       </object>
+                       <object class="IBUITableViewCell" id="899919877">
+                               <reference key="NSNextResponder"/>
+                               <int key="NSvFlags">292</int>
+                               <array class="NSMutableArray" key="NSSubviews">
+                                       <object class="IBUIView" id="209421689">
+                                               <reference key="NSNextResponder" ref="899919877"/>
+                                               <int key="NSvFlags">256</int>
+                                               <array class="NSMutableArray" key="NSSubviews">
+                                                       <object class="IBUILabel" id="1032585218">
+                                                               <reference key="NSNextResponder" ref="209421689"/>
+                                                               <int key="NSvFlags">298</int>
+                                                               <string key="NSFrame">{{12, 10}, {218, 25}}</string>
+                                                               <reference key="NSSuperview" ref="209421689"/>
+                                                               <reference key="NSWindow"/>
+                                                               <reference key="NSNextKeyView" ref="866724112"/>
+                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                               <bool key="IBUIOpaque">NO</bool>
+                                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                                               <int key="IBUIContentMode">7</int>
+                                                               <bool key="IBUIUserInteractionEnabled">NO</bool>
+                                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                                               <string key="IBUIText">Label</string>
+                                                               <object class="NSColor" key="IBUITextColor">
+                                                                       <int key="NSColorSpace">1</int>
+                                                                       <bytes key="NSRGB">MCAwIDAAA</bytes>
+                                                               </object>
+                                                               <object class="NSColor" key="IBUIHighlightedColor" id="729087361">
+                                                                       <int key="NSColorSpace">3</int>
+                                                                       <bytes key="NSWhite">MQA</bytes>
+                                                               </object>
+                                                               <int key="IBUIBaselineAdjustment">0</int>
+                                                               <float key="IBUIMinimumFontSize">10</float>
+                                                               <object class="IBUIFontDescription" key="IBUIFontDescription">
+                                                                       <int key="type">2</int>
+                                                                       <double key="pointSize">17</double>
+                                                               </object>
+                                                               <object class="NSFont" key="IBUIFont">
+                                                                       <string key="NSName">Helvetica-Bold</string>
+                                                                       <double key="NSSize">17</double>
+                                                                       <int key="NSfFlags">16</int>
+                                                               </object>
+                                                               <bool key="IBUIAdjustsFontSizeToFit">NO</bool>
+                                                       </object>
+                                                       <object class="IBUIButton" id="866724112">
+                                                               <reference key="NSNextResponder" ref="209421689"/>
+                                                               <int key="NSvFlags">297</int>
+                                                               <string key="NSFrame">{{252, 6}, {58, 31}}</string>
+                                                               <reference key="NSSuperview" ref="209421689"/>
+                                                               <reference key="NSWindow"/>
+                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                               <bool key="IBUIOpaque">NO</bool>
+                                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                                               <int key="IBUIContentHorizontalAlignment">0</int>
+                                                               <int key="IBUIContentVerticalAlignment">0</int>
+                                                               <int key="IBUIButtonType">1</int>
+                                                               <reference key="IBUIHighlightedTitleColor" ref="729087361"/>
+                                                               <object class="NSColor" key="IBUINormalTitleColor">
+                                                                       <int key="NSColorSpace">1</int>
+                                                                       <bytes key="NSRGB">MC4xOTYwNzg0MzE0IDAuMzA5ODAzOTIxNiAwLjUyMTU2ODYyNzUAA</bytes>
+                                                               </object>
+                                                               <object class="NSColor" key="IBUINormalTitleShadowColor">
+                                                                       <int key="NSColorSpace">3</int>
+                                                                       <bytes key="NSWhite">MC41AA</bytes>
+                                                               </object>
+                                                               <object class="IBUIFontDescription" key="IBUIFontDescription">
+                                                                       <int key="type">1</int>
+                                                                       <double key="pointSize">15</double>
+                                                               </object>
+                                                               <object class="NSFont" key="IBUIFont">
+                                                                       <string key="NSName">Helvetica</string>
+                                                                       <double key="NSSize">15</double>
+                                                                       <int key="NSfFlags">16</int>
+                                                               </object>
+                                                       </object>
+                                               </array>
+                                               <string key="NSFrameSize">{320, 43}</string>
+                                               <reference key="NSSuperview" ref="899919877"/>
+                                               <reference key="NSWindow"/>
+                                               <reference key="NSNextKeyView" ref="1032585218"/>
+                                               <string key="NSReuseIdentifierKey">_NS:11</string>
+                                               <object class="NSColor" key="IBUIBackgroundColor">
+                                                       <int key="NSColorSpace">3</int>
+                                                       <bytes key="NSWhite">MCAwAA</bytes>
+                                               </object>
+                                               <bool key="IBUIOpaque">NO</bool>
+                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                               <int key="IBUIContentMode">4</int>
+                                               <bool key="IBUIMultipleTouchEnabled">YES</bool>
+                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                       </object>
+                               </array>
+                               <string key="NSFrameSize">{320, 44}</string>
+                               <reference key="NSSuperview"/>
+                               <reference key="NSWindow"/>
+                               <reference key="NSNextKeyView" ref="209421689"/>
+                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                               <reference key="IBUIContentView" ref="209421689"/>
+                       </object>
+               </array>
+               <object class="IBObjectContainer" key="IBDocument.Objects">
+                       <array class="NSMutableArray" key="connectionRecords">
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_buttonTableViewCell</string>
+                                               <reference key="source" ref="841351856"/>
+                                               <reference key="destination" ref="899919877"/>
+                                       </object>
+                                       <int key="connectionID">7</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_button</string>
+                                               <reference key="source" ref="899919877"/>
+                                               <reference key="destination" ref="866724112"/>
+                                       </object>
+                                       <int key="connectionID">5</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_label</string>
+                                               <reference key="source" ref="899919877"/>
+                                               <reference key="destination" ref="1032585218"/>
+                                       </object>
+                                       <int key="connectionID">6</int>
+                               </object>
+                       </array>
+                       <object class="IBMutableOrderedSet" key="objectRecords">
+                               <array key="orderedObjects">
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">0</int>
+                                               <array key="object" id="0"/>
+                                               <reference key="children" ref="1000"/>
+                                               <nil key="parent"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-1</int>
+                                               <reference key="object" ref="841351856"/>
+                                               <reference key="parent" ref="0"/>
+                                               <string key="objectName">File's Owner</string>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-2</int>
+                                               <reference key="object" ref="371349661"/>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">2</int>
+                                               <reference key="object" ref="899919877"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="1032585218"/>
+                                                       <reference ref="866724112"/>
+                                               </array>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">3</int>
+                                               <reference key="object" ref="1032585218"/>
+                                               <reference key="parent" ref="899919877"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">4</int>
+                                               <reference key="object" ref="866724112"/>
+                                               <reference key="parent" ref="899919877"/>
+                                       </object>
+                               </array>
+                       </object>
+                       <dictionary class="NSMutableDictionary" key="flattenedProperties">
+                               <string key="-1.CustomClassName">EditorBaseController</string>
+                               <string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="-2.CustomClassName">UIResponder</string>
+                               <string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="2.CustomClassName">EditButtonTableViewCell</string>
+                               <string key="2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="3.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="4.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                       </dictionary>
+                       <dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
+                       <nil key="activeLocalization"/>
+                       <dictionary class="NSMutableDictionary" key="localizations"/>
+                       <nil key="sourceID"/>
+                       <int key="maxID">7</int>
+               </object>
+               <object class="IBClassDescriber" key="IBDocument.Classes">
+                       <array class="NSMutableArray" key="referencedPartialClassDescriptions">
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">EditButtonTableViewCell</string>
+                                       <string key="superclassName">UITableViewCell</string>
+                                       <dictionary class="NSMutableDictionary" key="outlets">
+                                               <string key="_button">UIButton</string>
+                                               <string key="_label">UILabel</string>
+                                       </dictionary>
+                                       <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <object class="IBToOneOutletInfo" key="_button">
+                                                       <string key="name">_button</string>
+                                                       <string key="candidateClassName">UIButton</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_label">
+                                                       <string key="name">_label</string>
+                                                       <string key="candidateClassName">UILabel</string>
+                                               </object>
+                                       </dictionary>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/EditButtonTableViewCell.h</string>
+                                       </object>
+                               </object>
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">EditFlagTableViewCell</string>
+                                       <string key="superclassName">UITableViewCell</string>
+                                       <dictionary class="NSMutableDictionary" key="outlets">
+                                               <string key="_label">UILabel</string>
+                                               <string key="_toggle">UISwitch</string>
+                                       </dictionary>
+                                       <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <object class="IBToOneOutletInfo" key="_label">
+                                                       <string key="name">_label</string>
+                                                       <string key="candidateClassName">UILabel</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_toggle">
+                                                       <string key="name">_toggle</string>
+                                                       <string key="candidateClassName">UISwitch</string>
+                                               </object>
+                                       </dictionary>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/EditFlagTableViewCell.h</string>
+                                       </object>
+                               </object>
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">EditSecretTextTableViewCell</string>
+                                       <string key="superclassName">UITableViewCell</string>
+                                       <dictionary class="NSMutableDictionary" key="outlets">
+                                               <string key="_label">UILabel</string>
+                                               <string key="_textfield">UITextField</string>
+                                               <string key="_unhide_button">UIButton</string>
+                                       </dictionary>
+                                       <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <object class="IBToOneOutletInfo" key="_label">
+                                                       <string key="name">_label</string>
+                                                       <string key="candidateClassName">UILabel</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_textfield">
+                                                       <string key="name">_textfield</string>
+                                                       <string key="candidateClassName">UITextField</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_unhide_button">
+                                                       <string key="name">_unhide_button</string>
+                                                       <string key="candidateClassName">UIButton</string>
+                                               </object>
+                                       </dictionary>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/EditSecretTextTableViewCell.h</string>
+                                       </object>
+                               </object>
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">EditSelectionTableViewCell</string>
+                                       <string key="superclassName">UITableViewCell</string>
+                                       <dictionary class="NSMutableDictionary" key="outlets">
+                                               <string key="_label">UILabel</string>
+                                               <string key="_selection">UILabel</string>
+                                       </dictionary>
+                                       <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <object class="IBToOneOutletInfo" key="_label">
+                                                       <string key="name">_label</string>
+                                                       <string key="candidateClassName">UILabel</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_selection">
+                                                       <string key="name">_selection</string>
+                                                       <string key="candidateClassName">UILabel</string>
+                                               </object>
+                                       </dictionary>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/EditSelectionTableViewCell.h</string>
+                                       </object>
+                               </object>
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">EditSubEditTableViewCell</string>
+                                       <string key="superclassName">UITableViewCell</string>
+                                       <object class="NSMutableDictionary" key="outlets">
+                                               <string key="NS.key.0">_label</string>
+                                               <string key="NS.object.0">UILabel</string>
+                                       </object>
+                                       <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <string key="NS.key.0">_label</string>
+                                               <object class="IBToOneOutletInfo" key="NS.object.0">
+                                                       <string key="name">_label</string>
+                                                       <string key="candidateClassName">UILabel</string>
+                                               </object>
+                                       </object>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/EditSubEditTableViewCell.h</string>
+                                       </object>
+                               </object>
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">EditTextTableViewCell</string>
+                                       <string key="superclassName">UITableViewCell</string>
+                                       <dictionary class="NSMutableDictionary" key="outlets">
+                                               <string key="_label">UILabel</string>
+                                               <string key="_textfield">UITextField</string>
+                                       </dictionary>
+                                       <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <object class="IBToOneOutletInfo" key="_label">
+                                                       <string key="name">_label</string>
+                                                       <string key="candidateClassName">UILabel</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_textfield">
+                                                       <string key="name">_textfield</string>
+                                                       <string key="candidateClassName">UITextField</string>
+                                               </object>
+                                       </dictionary>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/EditTextTableViewCell.h</string>
+                                       </object>
+                               </object>
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">EditorBaseController</string>
+                                       <string key="superclassName">UITableViewController</string>
+                                       <dictionary class="NSMutableDictionary" key="outlets">
+                                               <string key="_buttonTableViewCell">EditButtonTableViewCell</string>
+                                               <string key="_flagTableViewCell">EditFlagTableViewCell</string>
+                                               <string key="_secretTextTableViewCell">EditSecretTextTableViewCell</string>
+                                               <string key="_selectionTableViewCell">EditSelectionTableViewCell</string>
+                                               <string key="_subEditTableViewCell">EditSubEditTableViewCell</string>
+                                               <string key="_textTableViewCell">EditTextTableViewCell</string>
+                                       </dictionary>
+                                       <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <object class="IBToOneOutletInfo" key="_buttonTableViewCell">
+                                                       <string key="name">_buttonTableViewCell</string>
+                                                       <string key="candidateClassName">EditButtonTableViewCell</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_flagTableViewCell">
+                                                       <string key="name">_flagTableViewCell</string>
+                                                       <string key="candidateClassName">EditFlagTableViewCell</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_secretTextTableViewCell">
+                                                       <string key="name">_secretTextTableViewCell</string>
+                                                       <string key="candidateClassName">EditSecretTextTableViewCell</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_selectionTableViewCell">
+                                                       <string key="name">_selectionTableViewCell</string>
+                                                       <string key="candidateClassName">EditSelectionTableViewCell</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_subEditTableViewCell">
+                                                       <string key="name">_subEditTableViewCell</string>
+                                                       <string key="candidateClassName">EditSubEditTableViewCell</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_textTableViewCell">
+                                                       <string key="name">_textTableViewCell</string>
+                                                       <string key="candidateClassName">EditTextTableViewCell</string>
+                                               </object>
+                                       </dictionary>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/EditorBaseController.h</string>
+                                       </object>
+                               </object>
+                       </array>
+               </object>
+               <int key="IBDocument.localizationMode">0</int>
+               <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+                       <real value="1296" key="NS.object.0"/>
+               </object>
+               <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+               <int key="IBDocument.defaultPropertyAccessControl">3</int>
+               <string key="IBCocoaTouchPluginVersion">1179</string>
+       </data>
+</archive>
diff --git a/client/iOS/Resources/EditFlagTableViewCell.xib b/client/iOS/Resources/EditFlagTableViewCell.xib
new file mode 100644 (file)
index 0000000..a657eef
--- /dev/null
@@ -0,0 +1,208 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
+       <data>
+               <int key="IBDocument.SystemTarget">1296</int>
+               <string key="IBDocument.SystemVersion">11D50b</string>
+               <string key="IBDocument.InterfaceBuilderVersion">2182</string>
+               <string key="IBDocument.AppKitVersion">1138.32</string>
+               <string key="IBDocument.HIToolboxVersion">568.00</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                       <string key="NS.object.0">1179</string>
+               </object>
+               <array key="IBDocument.IntegratedClassDependencies">
+                       <string>IBUITableViewCell</string>
+                       <string>IBUISwitch</string>
+                       <string>IBUILabel</string>
+                       <string>IBProxyObject</string>
+               </array>
+               <array key="IBDocument.PluginDependencies">
+                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+               </array>
+               <object class="NSMutableDictionary" key="IBDocument.Metadata">
+                       <string key="NS.key.0">PluginDependencyRecalculationVersion</string>
+                       <integer value="1" key="NS.object.0"/>
+               </object>
+               <array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+                       <object class="IBProxyObject" id="841351856">
+                               <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                       </object>
+                       <object class="IBProxyObject" id="371349661">
+                               <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                       </object>
+                       <object class="IBUITableViewCell" id="310994250">
+                               <reference key="NSNextResponder"/>
+                               <int key="NSvFlags">292</int>
+                               <array class="NSMutableArray" key="NSSubviews">
+                                       <object class="IBUIView" id="672481111">
+                                               <reference key="NSNextResponder" ref="310994250"/>
+                                               <int key="NSvFlags">256</int>
+                                               <array class="NSMutableArray" key="NSSubviews">
+                                                       <object class="IBUILabel" id="165861018">
+                                                               <reference key="NSNextResponder" ref="672481111"/>
+                                                               <int key="NSvFlags">298</int>
+                                                               <string key="NSFrame">{{10, 10}, {214, 25}}</string>
+                                                               <reference key="NSSuperview" ref="672481111"/>
+                                                               <reference key="NSNextKeyView" ref="801003579"/>
+                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                               <bool key="IBUIOpaque">NO</bool>
+                                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                                               <int key="IBUIContentMode">7</int>
+                                                               <bool key="IBUIUserInteractionEnabled">NO</bool>
+                                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                                               <string key="IBUIText">Label</string>
+                                                               <object class="NSColor" key="IBUITextColor">
+                                                                       <int key="NSColorSpace">1</int>
+                                                                       <bytes key="NSRGB">MCAwIDAAA</bytes>
+                                                               </object>
+                                                               <object class="NSColor" key="IBUIHighlightedColor">
+                                                                       <int key="NSColorSpace">3</int>
+                                                                       <bytes key="NSWhite">MQA</bytes>
+                                                               </object>
+                                                               <int key="IBUIBaselineAdjustment">0</int>
+                                                               <float key="IBUIMinimumFontSize">10</float>
+                                                               <object class="IBUIFontDescription" key="IBUIFontDescription">
+                                                                       <int key="type">2</int>
+                                                                       <double key="pointSize">17</double>
+                                                               </object>
+                                                               <object class="NSFont" key="IBUIFont">
+                                                                       <string key="NSName">Helvetica-Bold</string>
+                                                                       <double key="NSSize">17</double>
+                                                                       <int key="NSfFlags">16</int>
+                                                               </object>
+                                                               <bool key="IBUIAdjustsFontSizeToFit">NO</bool>
+                                                       </object>
+                                                       <object class="IBUISwitch" id="801003579">
+                                                               <reference key="NSNextResponder" ref="672481111"/>
+                                                               <int key="NSvFlags">297</int>
+                                                               <string key="NSFrame">{{217, 8}, {94, 27}}</string>
+                                                               <reference key="NSSuperview" ref="672481111"/>
+                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                               <bool key="IBUIOpaque">NO</bool>
+                                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                                               <int key="IBUIContentHorizontalAlignment">0</int>
+                                                               <int key="IBUIContentVerticalAlignment">0</int>
+                                                               <bool key="IBUIOn">YES</bool>
+                                                       </object>
+                                               </array>
+                                               <string key="NSFrameSize">{320, 43}</string>
+                                               <reference key="NSSuperview" ref="310994250"/>
+                                               <reference key="NSNextKeyView" ref="165861018"/>
+                                               <string key="NSReuseIdentifierKey">_NS:11</string>
+                                               <object class="NSColor" key="IBUIBackgroundColor">
+                                                       <int key="NSColorSpace">3</int>
+                                                       <bytes key="NSWhite">MCAwAA</bytes>
+                                               </object>
+                                               <bool key="IBUIOpaque">NO</bool>
+                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                               <int key="IBUIContentMode">4</int>
+                                               <bool key="IBUIMultipleTouchEnabled">YES</bool>
+                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                       </object>
+                               </array>
+                               <string key="NSFrameSize">{320, 44}</string>
+                               <reference key="NSSuperview"/>
+                               <reference key="NSNextKeyView" ref="672481111"/>
+                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                               <int key="IBUISelectionStyle">0</int>
+                               <reference key="IBUIContentView" ref="672481111"/>
+                       </object>
+               </array>
+               <object class="IBObjectContainer" key="IBDocument.Objects">
+                       <array class="NSMutableArray" key="connectionRecords">
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_flagTableViewCell</string>
+                                               <reference key="source" ref="841351856"/>
+                                               <reference key="destination" ref="310994250"/>
+                                       </object>
+                                       <int key="connectionID">7</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_label</string>
+                                               <reference key="source" ref="310994250"/>
+                                               <reference key="destination" ref="165861018"/>
+                                       </object>
+                                       <int key="connectionID">5</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_toggle</string>
+                                               <reference key="source" ref="310994250"/>
+                                               <reference key="destination" ref="801003579"/>
+                                       </object>
+                                       <int key="connectionID">6</int>
+                               </object>
+                       </array>
+                       <object class="IBMutableOrderedSet" key="objectRecords">
+                               <array key="orderedObjects">
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">0</int>
+                                               <array key="object" id="0"/>
+                                               <reference key="children" ref="1000"/>
+                                               <nil key="parent"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-1</int>
+                                               <reference key="object" ref="841351856"/>
+                                               <reference key="parent" ref="0"/>
+                                               <string key="objectName">File's Owner</string>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-2</int>
+                                               <reference key="object" ref="371349661"/>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">2</int>
+                                               <reference key="object" ref="310994250"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="801003579"/>
+                                                       <reference ref="165861018"/>
+                                               </array>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">3</int>
+                                               <reference key="object" ref="165861018"/>
+                                               <reference key="parent" ref="310994250"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">4</int>
+                                               <reference key="object" ref="801003579"/>
+                                               <reference key="parent" ref="310994250"/>
+                                       </object>
+                               </array>
+                       </object>
+                       <dictionary class="NSMutableDictionary" key="flattenedProperties">
+                               <string key="-1.CustomClassName">EditorBaseController</string>
+                               <string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="-2.CustomClassName">UIResponder</string>
+                               <string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="2.CustomClassName">EditFlagTableViewCell</string>
+                               <string key="2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="3.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="4.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                       </dictionary>
+                       <dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
+                       <nil key="activeLocalization"/>
+                       <dictionary class="NSMutableDictionary" key="localizations"/>
+                       <nil key="sourceID"/>
+                       <int key="maxID">7</int>
+               </object>
+               <object class="IBClassDescriber" key="IBDocument.Classes"/>
+               <int key="IBDocument.localizationMode">0</int>
+               <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+                       <real value="1296" key="NS.object.0"/>
+               </object>
+               <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+               <int key="IBDocument.defaultPropertyAccessControl">3</int>
+               <string key="IBCocoaTouchPluginVersion">1179</string>
+       </data>
+</archive>
diff --git a/client/iOS/Resources/EditSecretTextTableViewCell.xib b/client/iOS/Resources/EditSecretTextTableViewCell.xib
new file mode 100644 (file)
index 0000000..4aac30f
--- /dev/null
@@ -0,0 +1,288 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
+       <data>
+               <int key="IBDocument.SystemTarget">1296</int>
+               <string key="IBDocument.SystemVersion">11D50b</string>
+               <string key="IBDocument.InterfaceBuilderVersion">2182</string>
+               <string key="IBDocument.AppKitVersion">1138.32</string>
+               <string key="IBDocument.HIToolboxVersion">568.00</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                       <string key="NS.object.0">1179</string>
+               </object>
+               <array key="IBDocument.IntegratedClassDependencies">
+                       <string>IBUITableViewCell</string>
+                       <string>IBUIButton</string>
+                       <string>IBUILabel</string>
+                       <string>IBUITextField</string>
+                       <string>IBProxyObject</string>
+               </array>
+               <array key="IBDocument.PluginDependencies">
+                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+               </array>
+               <object class="NSMutableDictionary" key="IBDocument.Metadata">
+                       <string key="NS.key.0">PluginDependencyRecalculationVersion</string>
+                       <integer value="1" key="NS.object.0"/>
+               </object>
+               <array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+                       <object class="IBProxyObject" id="841351856">
+                               <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                       </object>
+                       <object class="IBProxyObject" id="371349661">
+                               <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                       </object>
+                       <object class="IBUITableViewCell" id="955840644">
+                               <reference key="NSNextResponder"/>
+                               <int key="NSvFlags">292</int>
+                               <array class="NSMutableArray" key="NSSubviews">
+                                       <object class="IBUIView" id="667249610">
+                                               <reference key="NSNextResponder" ref="955840644"/>
+                                               <int key="NSvFlags">256</int>
+                                               <array class="NSMutableArray" key="NSSubviews">
+                                                       <object class="IBUILabel" id="788635611">
+                                                               <reference key="NSNextResponder" ref="667249610"/>
+                                                               <int key="NSvFlags">300</int>
+                                                               <string key="NSFrame">{{10, 10}, {100, 25}}</string>
+                                                               <reference key="NSSuperview" ref="667249610"/>
+                                                               <reference key="NSNextKeyView" ref="739180901"/>
+                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                               <bool key="IBUIOpaque">NO</bool>
+                                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                                               <int key="IBUIContentMode">7</int>
+                                                               <bool key="IBUIUserInteractionEnabled">NO</bool>
+                                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                                               <string key="IBUIText">Label</string>
+                                                               <object class="NSColor" key="IBUITextColor">
+                                                                       <int key="NSColorSpace">1</int>
+                                                                       <bytes key="NSRGB">MCAwIDAAA</bytes>
+                                                               </object>
+                                                               <object class="NSColor" key="IBUIHighlightedColor" id="507782670">
+                                                                       <int key="NSColorSpace">3</int>
+                                                                       <bytes key="NSWhite">MQA</bytes>
+                                                               </object>
+                                                               <int key="IBUIBaselineAdjustment">0</int>
+                                                               <float key="IBUIMinimumFontSize">10</float>
+                                                               <object class="IBUIFontDescription" key="IBUIFontDescription">
+                                                                       <int key="type">2</int>
+                                                                       <double key="pointSize">17</double>
+                                                               </object>
+                                                               <object class="NSFont" key="IBUIFont">
+                                                                       <string key="NSName">Helvetica-Bold</string>
+                                                                       <double key="NSSize">17</double>
+                                                                       <int key="NSfFlags">16</int>
+                                                               </object>
+                                                               <bool key="IBUIAdjustsFontSizeToFit">NO</bool>
+                                                       </object>
+                                                       <object class="IBUITextField" id="739180901">
+                                                               <reference key="NSNextResponder" ref="667249610"/>
+                                                               <int key="NSvFlags">298</int>
+                                                               <string key="NSFrame">{{120, 10}, {150, 25}}</string>
+                                                               <reference key="NSSuperview" ref="667249610"/>
+                                                               <reference key="NSNextKeyView" ref="932654538"/>
+                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                               <bool key="IBUIOpaque">NO</bool>
+                                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                                               <int key="IBUIContentVerticalAlignment">0</int>
+                                                               <string key="IBUIText">Test</string>
+                                                               <object class="NSColor" key="IBUITextColor">
+                                                                       <int key="NSColorSpace">3</int>
+                                                                       <bytes key="NSWhite">MAA</bytes>
+                                                                       <object class="NSColorSpace" key="NSCustomColorSpace">
+                                                                               <int key="NSID">2</int>
+                                                                       </object>
+                                                               </object>
+                                                               <bool key="IBUIAdjustsFontSizeToFit">YES</bool>
+                                                               <float key="IBUIMinimumFontSize">17</float>
+                                                               <object class="IBUITextInputTraits" key="IBUITextInputTraits">
+                                                                       <int key="IBUIAutocorrectionType">1</int>
+                                                                       <bool key="IBUISecureTextEntry">YES</bool>
+                                                                       <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                                               </object>
+                                                               <int key="IBUIClearButtonMode">3</int>
+                                                               <object class="IBUIFontDescription" key="IBUIFontDescription">
+                                                                       <int key="type">1</int>
+                                                                       <double key="pointSize">17</double>
+                                                               </object>
+                                                               <object class="NSFont" key="IBUIFont">
+                                                                       <string key="NSName">Helvetica</string>
+                                                                       <double key="NSSize">17</double>
+                                                                       <int key="NSfFlags">16</int>
+                                                               </object>
+                                                       </object>
+                                                       <object class="IBUIButton" id="932654538">
+                                                               <reference key="NSNextResponder" ref="667249610"/>
+                                                               <int key="NSvFlags">297</int>
+                                                               <string key="NSFrame">{{270, 10}, {50, 25}}</string>
+                                                               <reference key="NSSuperview" ref="667249610"/>
+                                                               <reference key="NSNextKeyView"/>
+                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                               <bool key="IBUIOpaque">NO</bool>
+                                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                                               <int key="IBUIContentHorizontalAlignment">0</int>
+                                                               <int key="IBUIContentVerticalAlignment">0</int>
+                                                               <string key="IBUINormalTitle">Unhide</string>
+                                                               <reference key="IBUIHighlightedTitleColor" ref="507782670"/>
+                                                               <object class="NSColor" key="IBUINormalTitleColor">
+                                                                       <int key="NSColorSpace">1</int>
+                                                                       <bytes key="NSRGB">MC4xOTYwNzg0MzE0IDAuMzA5ODAzOTIxNiAwLjUyMTU2ODYyNzUAA</bytes>
+                                                               </object>
+                                                               <object class="NSColor" key="IBUINormalTitleShadowColor">
+                                                                       <int key="NSColorSpace">3</int>
+                                                                       <bytes key="NSWhite">MC41AA</bytes>
+                                                               </object>
+                                                               <object class="IBUIFontDescription" key="IBUIFontDescription">
+                                                                       <int key="type">1</int>
+                                                                       <double key="pointSize">15</double>
+                                                               </object>
+                                                               <object class="NSFont" key="IBUIFont">
+                                                                       <string key="NSName">Helvetica</string>
+                                                                       <double key="NSSize">15</double>
+                                                                       <int key="NSfFlags">16</int>
+                                                               </object>
+                                                       </object>
+                                               </array>
+                                               <string key="NSFrameSize">{320, 43}</string>
+                                               <reference key="NSSuperview" ref="955840644"/>
+                                               <reference key="NSNextKeyView" ref="788635611"/>
+                                               <string key="NSReuseIdentifierKey">_NS:11</string>
+                                               <object class="NSColor" key="IBUIBackgroundColor">
+                                                       <int key="NSColorSpace">3</int>
+                                                       <bytes key="NSWhite">MCAwAA</bytes>
+                                               </object>
+                                               <bool key="IBUIOpaque">NO</bool>
+                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                               <int key="IBUIContentMode">4</int>
+                                               <bool key="IBUIMultipleTouchEnabled">YES</bool>
+                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                       </object>
+                               </array>
+                               <string key="NSFrameSize">{320, 44}</string>
+                               <reference key="NSSuperview"/>
+                               <reference key="NSNextKeyView" ref="667249610"/>
+                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                               <int key="IBUISelectionStyle">0</int>
+                               <reference key="IBUIContentView" ref="667249610"/>
+                       </object>
+               </array>
+               <object class="IBObjectContainer" key="IBDocument.Objects">
+                       <array class="NSMutableArray" key="connectionRecords">
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_secretTextTableViewCell</string>
+                                               <reference key="source" ref="841351856"/>
+                                               <reference key="destination" ref="955840644"/>
+                                       </object>
+                                       <int key="connectionID">9</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_label</string>
+                                               <reference key="source" ref="955840644"/>
+                                               <reference key="destination" ref="788635611"/>
+                                       </object>
+                                       <int key="connectionID">6</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_textfield</string>
+                                               <reference key="source" ref="955840644"/>
+                                               <reference key="destination" ref="739180901"/>
+                                       </object>
+                                       <int key="connectionID">7</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_unhide_button</string>
+                                               <reference key="source" ref="955840644"/>
+                                               <reference key="destination" ref="932654538"/>
+                                       </object>
+                                       <int key="connectionID">11</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">delegate</string>
+                                               <reference key="source" ref="739180901"/>
+                                               <reference key="destination" ref="841351856"/>
+                                       </object>
+                                       <int key="connectionID">12</int>
+                               </object>
+                       </array>
+                       <object class="IBMutableOrderedSet" key="objectRecords">
+                               <array key="orderedObjects">
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">0</int>
+                                               <array key="object" id="0"/>
+                                               <reference key="children" ref="1000"/>
+                                               <nil key="parent"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-1</int>
+                                               <reference key="object" ref="841351856"/>
+                                               <reference key="parent" ref="0"/>
+                                               <string key="objectName">File's Owner</string>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-2</int>
+                                               <reference key="object" ref="371349661"/>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">2</int>
+                                               <reference key="object" ref="955840644"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="739180901"/>
+                                                       <reference ref="788635611"/>
+                                                       <reference ref="932654538"/>
+                                               </array>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">3</int>
+                                               <reference key="object" ref="739180901"/>
+                                               <reference key="parent" ref="955840644"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">4</int>
+                                               <reference key="object" ref="788635611"/>
+                                               <reference key="parent" ref="955840644"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">10</int>
+                                               <reference key="object" ref="932654538"/>
+                                               <reference key="parent" ref="955840644"/>
+                                       </object>
+                               </array>
+                       </object>
+                       <dictionary class="NSMutableDictionary" key="flattenedProperties">
+                               <string key="-1.CustomClassName">EditorBaseController</string>
+                               <string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="-2.CustomClassName">UIResponder</string>
+                               <string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="10.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="2.CustomClassName">EditSecretTextTableViewCell</string>
+                               <string key="2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="3.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="4.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                       </dictionary>
+                       <dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
+                       <nil key="activeLocalization"/>
+                       <dictionary class="NSMutableDictionary" key="localizations"/>
+                       <nil key="sourceID"/>
+                       <int key="maxID">12</int>
+               </object>
+               <object class="IBClassDescriber" key="IBDocument.Classes"/>
+               <int key="IBDocument.localizationMode">0</int>
+               <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+                       <real value="1296" key="NS.object.0"/>
+               </object>
+               <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+               <int key="IBDocument.defaultPropertyAccessControl">3</int>
+               <string key="IBCocoaTouchPluginVersion">1179</string>
+       </data>
+</archive>
diff --git a/client/iOS/Resources/EditSelectionTableViewCell.xib b/client/iOS/Resources/EditSelectionTableViewCell.xib
new file mode 100644 (file)
index 0000000..6861e5b
--- /dev/null
@@ -0,0 +1,347 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
+       <data>
+               <int key="IBDocument.SystemTarget">1296</int>
+               <string key="IBDocument.SystemVersion">11D50b</string>
+               <string key="IBDocument.InterfaceBuilderVersion">2182</string>
+               <string key="IBDocument.AppKitVersion">1138.32</string>
+               <string key="IBDocument.HIToolboxVersion">568.00</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                       <string key="NS.object.0">1179</string>
+               </object>
+               <array key="IBDocument.IntegratedClassDependencies">
+                       <string>IBProxyObject</string>
+                       <string>IBUILabel</string>
+                       <string>IBUITableViewCell</string>
+               </array>
+               <array key="IBDocument.PluginDependencies">
+                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+               </array>
+               <object class="NSMutableDictionary" key="IBDocument.Metadata">
+                       <string key="NS.key.0">PluginDependencyRecalculationVersion</string>
+                       <integer value="1" key="NS.object.0"/>
+               </object>
+               <array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+                       <object class="IBProxyObject" id="841351856">
+                               <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                       </object>
+                       <object class="IBProxyObject" id="371349661">
+                               <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                       </object>
+                       <object class="IBUITableViewCell" id="1049047257">
+                               <reference key="NSNextResponder"/>
+                               <int key="NSvFlags">292</int>
+                               <array class="NSMutableArray" key="NSSubviews">
+                                       <object class="IBUIView" id="37971195">
+                                               <reference key="NSNextResponder" ref="1049047257"/>
+                                               <int key="NSvFlags">256</int>
+                                               <array class="NSMutableArray" key="NSSubviews">
+                                                       <object class="IBUILabel" id="225091127">
+                                                               <reference key="NSNextResponder" ref="37971195"/>
+                                                               <int key="NSvFlags">302</int>
+                                                               <string key="NSFrame">{{10, 10}, {140, 25}}</string>
+                                                               <reference key="NSSuperview" ref="37971195"/>
+                                                               <reference key="NSWindow"/>
+                                                               <reference key="NSNextKeyView" ref="53086288"/>
+                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                               <bool key="IBUIOpaque">NO</bool>
+                                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                                               <int key="IBUIContentMode">7</int>
+                                                               <bool key="IBUIUserInteractionEnabled">NO</bool>
+                                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                                               <string key="IBUIText">Label</string>
+                                                               <object class="NSColor" key="IBUITextColor" id="487482859">
+                                                                       <int key="NSColorSpace">1</int>
+                                                                       <bytes key="NSRGB">MCAwIDAAA</bytes>
+                                                               </object>
+                                                               <object class="NSColor" key="IBUIHighlightedColor" id="538435083">
+                                                                       <int key="NSColorSpace">3</int>
+                                                                       <bytes key="NSWhite">MQA</bytes>
+                                                               </object>
+                                                               <int key="IBUIBaselineAdjustment">0</int>
+                                                               <float key="IBUIMinimumFontSize">10</float>
+                                                               <object class="IBUIFontDescription" key="IBUIFontDescription">
+                                                                       <int key="type">2</int>
+                                                                       <double key="pointSize">17</double>
+                                                               </object>
+                                                               <object class="NSFont" key="IBUIFont">
+                                                                       <string key="NSName">Helvetica-Bold</string>
+                                                                       <double key="NSSize">17</double>
+                                                                       <int key="NSfFlags">16</int>
+                                                               </object>
+                                                               <bool key="IBUIAdjustsFontSizeToFit">NO</bool>
+                                                       </object>
+                                                       <object class="IBUILabel" id="53086288">
+                                                               <reference key="NSNextResponder" ref="37971195"/>
+                                                               <int key="NSvFlags">299</int>
+                                                               <string key="NSFrame">{{160, 10}, {120, 25}}</string>
+                                                               <reference key="NSSuperview" ref="37971195"/>
+                                                               <reference key="NSWindow"/>
+                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                               <bool key="IBUIOpaque">NO</bool>
+                                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                                               <int key="IBUIContentMode">7</int>
+                                                               <bool key="IBUIUserInteractionEnabled">NO</bool>
+                                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                                               <string key="IBUIText">Selection</string>
+                                                               <reference key="IBUITextColor" ref="487482859"/>
+                                                               <reference key="IBUIHighlightedColor" ref="538435083"/>
+                                                               <int key="IBUIBaselineAdjustment">0</int>
+                                                               <float key="IBUIMinimumFontSize">10</float>
+                                                               <int key="IBUITextAlignment">2</int>
+                                                               <object class="IBUIFontDescription" key="IBUIFontDescription">
+                                                                       <int key="type">1</int>
+                                                                       <double key="pointSize">17</double>
+                                                               </object>
+                                                               <object class="NSFont" key="IBUIFont">
+                                                                       <string key="NSName">Helvetica</string>
+                                                                       <double key="NSSize">17</double>
+                                                                       <int key="NSfFlags">16</int>
+                                                               </object>
+                                                               <bool key="IBUIAdjustsFontSizeToFit">NO</bool>
+                                                       </object>
+                                               </array>
+                                               <string key="NSFrameSize">{300, 43}</string>
+                                               <reference key="NSSuperview" ref="1049047257"/>
+                                               <reference key="NSWindow"/>
+                                               <reference key="NSNextKeyView" ref="225091127"/>
+                                               <string key="NSReuseIdentifierKey">_NS:11</string>
+                                               <object class="NSColor" key="IBUIBackgroundColor">
+                                                       <int key="NSColorSpace">3</int>
+                                                       <bytes key="NSWhite">MCAwAA</bytes>
+                                               </object>
+                                               <bool key="IBUIOpaque">NO</bool>
+                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                               <int key="IBUIContentMode">4</int>
+                                               <bool key="IBUIMultipleTouchEnabled">YES</bool>
+                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                       </object>
+                               </array>
+                               <string key="NSFrameSize">{320, 44}</string>
+                               <reference key="NSSuperview"/>
+                               <reference key="NSWindow"/>
+                               <reference key="NSNextKeyView" ref="37971195"/>
+                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                               <int key="IBUIAccessoryType">1</int>
+                               <reference key="IBUIContentView" ref="37971195"/>
+                       </object>
+               </array>
+               <object class="IBObjectContainer" key="IBDocument.Objects">
+                       <array class="NSMutableArray" key="connectionRecords">
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_selectionTableViewCell</string>
+                                               <reference key="source" ref="841351856"/>
+                                               <reference key="destination" ref="1049047257"/>
+                                       </object>
+                                       <int key="connectionID">9</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_label</string>
+                                               <reference key="source" ref="1049047257"/>
+                                               <reference key="destination" ref="225091127"/>
+                                       </object>
+                                       <int key="connectionID">7</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_selection</string>
+                                               <reference key="source" ref="1049047257"/>
+                                               <reference key="destination" ref="53086288"/>
+                                       </object>
+                                       <int key="connectionID">8</int>
+                               </object>
+                       </array>
+                       <object class="IBMutableOrderedSet" key="objectRecords">
+                               <array key="orderedObjects">
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">0</int>
+                                               <array key="object" id="0"/>
+                                               <reference key="children" ref="1000"/>
+                                               <nil key="parent"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-1</int>
+                                               <reference key="object" ref="841351856"/>
+                                               <reference key="parent" ref="0"/>
+                                               <string key="objectName">File's Owner</string>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-2</int>
+                                               <reference key="object" ref="371349661"/>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">2</int>
+                                               <reference key="object" ref="1049047257"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="225091127"/>
+                                                       <reference ref="53086288"/>
+                                               </array>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">5</int>
+                                               <reference key="object" ref="225091127"/>
+                                               <reference key="parent" ref="1049047257"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">6</int>
+                                               <reference key="object" ref="53086288"/>
+                                               <reference key="parent" ref="1049047257"/>
+                                       </object>
+                               </array>
+                       </object>
+                       <dictionary class="NSMutableDictionary" key="flattenedProperties">
+                               <string key="-1.CustomClassName">EditorBaseController</string>
+                               <string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="-2.CustomClassName">UIResponder</string>
+                               <string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="2.CustomClassName">EditSelectionTableViewCell</string>
+                               <string key="2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="5.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="6.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                       </dictionary>
+                       <dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
+                       <nil key="activeLocalization"/>
+                       <dictionary class="NSMutableDictionary" key="localizations"/>
+                       <nil key="sourceID"/>
+                       <int key="maxID">9</int>
+               </object>
+               <object class="IBClassDescriber" key="IBDocument.Classes">
+                       <array class="NSMutableArray" key="referencedPartialClassDescriptions">
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">EditFlagTableViewCell</string>
+                                       <string key="superclassName">UITableViewCell</string>
+                                       <dictionary class="NSMutableDictionary" key="outlets">
+                                               <string key="_label">UILabel</string>
+                                               <string key="_toggle">UISwitch</string>
+                                       </dictionary>
+                                       <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <object class="IBToOneOutletInfo" key="_label">
+                                                       <string key="name">_label</string>
+                                                       <string key="candidateClassName">UILabel</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_toggle">
+                                                       <string key="name">_toggle</string>
+                                                       <string key="candidateClassName">UISwitch</string>
+                                               </object>
+                                       </dictionary>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/EditFlagTableViewCell.h</string>
+                                       </object>
+                               </object>
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">EditSelectionTableViewCell</string>
+                                       <string key="superclassName">UITableViewCell</string>
+                                       <dictionary class="NSMutableDictionary" key="outlets">
+                                               <string key="_label">UILabel</string>
+                                               <string key="_selection">UILabel</string>
+                                       </dictionary>
+                                       <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <object class="IBToOneOutletInfo" key="_label">
+                                                       <string key="name">_label</string>
+                                                       <string key="candidateClassName">UILabel</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_selection">
+                                                       <string key="name">_selection</string>
+                                                       <string key="candidateClassName">UILabel</string>
+                                               </object>
+                                       </dictionary>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/EditSelectionTableViewCell.h</string>
+                                       </object>
+                               </object>
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">EditSubEditTableViewCell</string>
+                                       <string key="superclassName">UITableViewCell</string>
+                                       <object class="NSMutableDictionary" key="outlets">
+                                               <string key="NS.key.0">_label</string>
+                                               <string key="NS.object.0">UILabel</string>
+                                       </object>
+                                       <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <string key="NS.key.0">_label</string>
+                                               <object class="IBToOneOutletInfo" key="NS.object.0">
+                                                       <string key="name">_label</string>
+                                                       <string key="candidateClassName">UILabel</string>
+                                               </object>
+                                       </object>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/EditSubEditTableViewCell.h</string>
+                                       </object>
+                               </object>
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">EditTextTableViewCell</string>
+                                       <string key="superclassName">UITableViewCell</string>
+                                       <dictionary class="NSMutableDictionary" key="outlets">
+                                               <string key="_label">UILabel</string>
+                                               <string key="_textfield">UITextField</string>
+                                       </dictionary>
+                                       <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <object class="IBToOneOutletInfo" key="_label">
+                                                       <string key="name">_label</string>
+                                                       <string key="candidateClassName">UILabel</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_textfield">
+                                                       <string key="name">_textfield</string>
+                                                       <string key="candidateClassName">UITextField</string>
+                                               </object>
+                                       </dictionary>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/EditTextTableViewCell.h</string>
+                                       </object>
+                               </object>
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">EditorBaseController</string>
+                                       <string key="superclassName">UITableViewController</string>
+                                       <dictionary class="NSMutableDictionary" key="outlets">
+                                               <string key="_flagTableViewCell">EditFlagTableViewCell</string>
+                                               <string key="_selectionTableViewCell">EditSelectionTableViewCell</string>
+                                               <string key="_subEditTableViewCell">EditSubEditTableViewCell</string>
+                                               <string key="_textTableViewCell">EditTextTableViewCell</string>
+                                       </dictionary>
+                                       <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <object class="IBToOneOutletInfo" key="_flagTableViewCell">
+                                                       <string key="name">_flagTableViewCell</string>
+                                                       <string key="candidateClassName">EditFlagTableViewCell</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_selectionTableViewCell">
+                                                       <string key="name">_selectionTableViewCell</string>
+                                                       <string key="candidateClassName">EditSelectionTableViewCell</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_subEditTableViewCell">
+                                                       <string key="name">_subEditTableViewCell</string>
+                                                       <string key="candidateClassName">EditSubEditTableViewCell</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_textTableViewCell">
+                                                       <string key="name">_textTableViewCell</string>
+                                                       <string key="candidateClassName">EditTextTableViewCell</string>
+                                               </object>
+                                       </dictionary>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/EditorBaseController.h</string>
+                                       </object>
+                               </object>
+                       </array>
+               </object>
+               <int key="IBDocument.localizationMode">0</int>
+               <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+                       <real value="1296" key="NS.object.0"/>
+               </object>
+               <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+               <int key="IBDocument.defaultPropertyAccessControl">3</int>
+               <string key="IBCocoaTouchPluginVersion">1179</string>
+       </data>
+</archive>
diff --git a/client/iOS/Resources/EditSubEditTableViewCell.xib b/client/iOS/Resources/EditSubEditTableViewCell.xib
new file mode 100644 (file)
index 0000000..967bc16
--- /dev/null
@@ -0,0 +1,179 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
+       <data>
+               <int key="IBDocument.SystemTarget">1296</int>
+               <string key="IBDocument.SystemVersion">11D50b</string>
+               <string key="IBDocument.InterfaceBuilderVersion">2182</string>
+               <string key="IBDocument.AppKitVersion">1138.32</string>
+               <string key="IBDocument.HIToolboxVersion">568.00</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                       <string key="NS.object.0">1179</string>
+               </object>
+               <array key="IBDocument.IntegratedClassDependencies">
+                       <string>IBProxyObject</string>
+                       <string>IBUILabel</string>
+                       <string>IBUITableViewCell</string>
+               </array>
+               <array key="IBDocument.PluginDependencies">
+                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+               </array>
+               <object class="NSMutableDictionary" key="IBDocument.Metadata">
+                       <string key="NS.key.0">PluginDependencyRecalculationVersion</string>
+                       <integer value="1" key="NS.object.0"/>
+               </object>
+               <array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+                       <object class="IBProxyObject" id="841351856">
+                               <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                       </object>
+                       <object class="IBProxyObject" id="371349661">
+                               <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                       </object>
+                       <object class="IBUITableViewCell" id="330133912">
+                               <reference key="NSNextResponder"/>
+                               <int key="NSvFlags">292</int>
+                               <array class="NSMutableArray" key="NSSubviews">
+                                       <object class="IBUIView" id="747305151">
+                                               <reference key="NSNextResponder" ref="330133912"/>
+                                               <int key="NSvFlags">256</int>
+                                               <array class="NSMutableArray" key="NSSubviews">
+                                                       <object class="IBUILabel" id="800335451">
+                                                               <reference key="NSNextResponder" ref="747305151"/>
+                                                               <int key="NSvFlags">298</int>
+                                                               <string key="NSFrame">{{10, 10}, {270, 25}}</string>
+                                                               <reference key="NSSuperview" ref="747305151"/>
+                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                               <bool key="IBUIOpaque">NO</bool>
+                                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                                               <int key="IBUIContentMode">7</int>
+                                                               <bool key="IBUIUserInteractionEnabled">NO</bool>
+                                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                                               <string key="IBUIText">Label</string>
+                                                               <object class="NSColor" key="IBUITextColor">
+                                                                       <int key="NSColorSpace">1</int>
+                                                                       <bytes key="NSRGB">MCAwIDAAA</bytes>
+                                                               </object>
+                                                               <object class="NSColor" key="IBUIHighlightedColor">
+                                                                       <int key="NSColorSpace">3</int>
+                                                                       <bytes key="NSWhite">MQA</bytes>
+                                                               </object>
+                                                               <int key="IBUIBaselineAdjustment">0</int>
+                                                               <float key="IBUIMinimumFontSize">10</float>
+                                                               <object class="IBUIFontDescription" key="IBUIFontDescription">
+                                                                       <int key="type">2</int>
+                                                                       <double key="pointSize">17</double>
+                                                               </object>
+                                                               <object class="NSFont" key="IBUIFont">
+                                                                       <string key="NSName">Helvetica-Bold</string>
+                                                                       <double key="NSSize">17</double>
+                                                                       <int key="NSfFlags">16</int>
+                                                               </object>
+                                                               <bool key="IBUIAdjustsFontSizeToFit">NO</bool>
+                                                       </object>
+                                               </array>
+                                               <string key="NSFrameSize">{300, 43}</string>
+                                               <reference key="NSSuperview" ref="330133912"/>
+                                               <reference key="NSNextKeyView" ref="800335451"/>
+                                               <string key="NSReuseIdentifierKey">_NS:11</string>
+                                               <object class="NSColor" key="IBUIBackgroundColor">
+                                                       <int key="NSColorSpace">3</int>
+                                                       <bytes key="NSWhite">MCAwAA</bytes>
+                                               </object>
+                                               <bool key="IBUIOpaque">NO</bool>
+                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                               <int key="IBUIContentMode">4</int>
+                                               <bool key="IBUIMultipleTouchEnabled">YES</bool>
+                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                       </object>
+                               </array>
+                               <string key="NSFrameSize">{320, 44}</string>
+                               <reference key="NSSuperview"/>
+                               <reference key="NSNextKeyView" ref="747305151"/>
+                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                               <int key="IBUIAccessoryType">1</int>
+                               <reference key="IBUIContentView" ref="747305151"/>
+                       </object>
+               </array>
+               <object class="IBObjectContainer" key="IBDocument.Objects">
+                       <array class="NSMutableArray" key="connectionRecords">
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_subEditTableViewCell</string>
+                                               <reference key="source" ref="841351856"/>
+                                               <reference key="destination" ref="330133912"/>
+                                       </object>
+                                       <int key="connectionID">5</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_label</string>
+                                               <reference key="source" ref="330133912"/>
+                                               <reference key="destination" ref="800335451"/>
+                                       </object>
+                                       <int key="connectionID">4</int>
+                               </object>
+                       </array>
+                       <object class="IBMutableOrderedSet" key="objectRecords">
+                               <array key="orderedObjects">
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">0</int>
+                                               <array key="object" id="0"/>
+                                               <reference key="children" ref="1000"/>
+                                               <nil key="parent"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-1</int>
+                                               <reference key="object" ref="841351856"/>
+                                               <reference key="parent" ref="0"/>
+                                               <string key="objectName">File's Owner</string>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-2</int>
+                                               <reference key="object" ref="371349661"/>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">2</int>
+                                               <reference key="object" ref="330133912"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="800335451"/>
+                                               </array>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">3</int>
+                                               <reference key="object" ref="800335451"/>
+                                               <reference key="parent" ref="330133912"/>
+                                       </object>
+                               </array>
+                       </object>
+                       <dictionary class="NSMutableDictionary" key="flattenedProperties">
+                               <string key="-1.CustomClassName">EditorBaseController</string>
+                               <string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="-2.CustomClassName">UIResponder</string>
+                               <string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="2.CustomClassName">EditSubEditTableViewCell</string>
+                               <string key="2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="3.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                       </dictionary>
+                       <dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
+                       <nil key="activeLocalization"/>
+                       <dictionary class="NSMutableDictionary" key="localizations"/>
+                       <nil key="sourceID"/>
+                       <int key="maxID">5</int>
+               </object>
+               <object class="IBClassDescriber" key="IBDocument.Classes"/>
+               <int key="IBDocument.localizationMode">0</int>
+               <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+                       <real value="1296" key="NS.object.0"/>
+               </object>
+               <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+               <int key="IBDocument.defaultPropertyAccessControl">3</int>
+               <string key="IBCocoaTouchPluginVersion">1179</string>
+       </data>
+</archive>
diff --git a/client/iOS/Resources/EditTextTableViewCell.xib b/client/iOS/Resources/EditTextTableViewCell.xib
new file mode 100644 (file)
index 0000000..c10c612
--- /dev/null
@@ -0,0 +1,364 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
+       <data>
+               <int key="IBDocument.SystemTarget">1296</int>
+               <string key="IBDocument.SystemVersion">11D50b</string>
+               <string key="IBDocument.InterfaceBuilderVersion">2182</string>
+               <string key="IBDocument.AppKitVersion">1138.32</string>
+               <string key="IBDocument.HIToolboxVersion">568.00</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                       <string key="NS.object.0">1179</string>
+               </object>
+               <array key="IBDocument.IntegratedClassDependencies">
+                       <string>IBUITableViewCell</string>
+                       <string>IBUILabel</string>
+                       <string>IBUITextField</string>
+                       <string>IBProxyObject</string>
+               </array>
+               <array key="IBDocument.PluginDependencies">
+                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+               </array>
+               <object class="NSMutableDictionary" key="IBDocument.Metadata">
+                       <string key="NS.key.0">PluginDependencyRecalculationVersion</string>
+                       <integer value="1" key="NS.object.0"/>
+               </object>
+               <array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+                       <object class="IBProxyObject" id="841351856">
+                               <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                       </object>
+                       <object class="IBProxyObject" id="371349661">
+                               <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                       </object>
+                       <object class="IBUITableViewCell" id="873867585">
+                               <reference key="NSNextResponder"/>
+                               <int key="NSvFlags">292</int>
+                               <array class="NSMutableArray" key="NSSubviews">
+                                       <object class="IBUIView" id="571279607">
+                                               <reference key="NSNextResponder" ref="873867585"/>
+                                               <int key="NSvFlags">256</int>
+                                               <array class="NSMutableArray" key="NSSubviews">
+                                                       <object class="IBUILabel" id="837238439">
+                                                               <reference key="NSNextResponder" ref="571279607"/>
+                                                               <int key="NSvFlags">300</int>
+                                                               <string key="NSFrame">{{10, 10}, {100, 25}}</string>
+                                                               <reference key="NSSuperview" ref="571279607"/>
+                                                               <reference key="NSWindow"/>
+                                                               <reference key="NSNextKeyView" ref="915318991"/>
+                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                               <bool key="IBUIOpaque">NO</bool>
+                                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                                               <int key="IBUIContentMode">7</int>
+                                                               <bool key="IBUIUserInteractionEnabled">NO</bool>
+                                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                                               <string key="IBUIText">Label</string>
+                                                               <object class="NSColor" key="IBUITextColor">
+                                                                       <int key="NSColorSpace">1</int>
+                                                                       <bytes key="NSRGB">MCAwIDAAA</bytes>
+                                                               </object>
+                                                               <object class="NSColor" key="IBUIHighlightedColor">
+                                                                       <int key="NSColorSpace">3</int>
+                                                                       <bytes key="NSWhite">MQA</bytes>
+                                                               </object>
+                                                               <int key="IBUIBaselineAdjustment">0</int>
+                                                               <float key="IBUIMinimumFontSize">10</float>
+                                                               <object class="IBUIFontDescription" key="IBUIFontDescription">
+                                                                       <int key="type">2</int>
+                                                                       <double key="pointSize">17</double>
+                                                               </object>
+                                                               <object class="NSFont" key="IBUIFont">
+                                                                       <string key="NSName">Helvetica-Bold</string>
+                                                                       <double key="NSSize">17</double>
+                                                                       <int key="NSfFlags">16</int>
+                                                               </object>
+                                                               <bool key="IBUIAdjustsFontSizeToFit">NO</bool>
+                                                       </object>
+                                                       <object class="IBUITextField" id="915318991">
+                                                               <reference key="NSNextResponder" ref="571279607"/>
+                                                               <int key="NSvFlags">298</int>
+                                                               <string key="NSFrame">{{120, 10}, {200, 25}}</string>
+                                                               <reference key="NSSuperview" ref="571279607"/>
+                                                               <reference key="NSWindow"/>
+                                                               <reference key="NSNextKeyView"/>
+                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                               <bool key="IBUIOpaque">NO</bool>
+                                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                                               <int key="IBUIContentVerticalAlignment">0</int>
+                                                               <string key="IBUIText">Test</string>
+                                                               <object class="NSColor" key="IBUITextColor">
+                                                                       <int key="NSColorSpace">3</int>
+                                                                       <bytes key="NSWhite">MAA</bytes>
+                                                                       <object class="NSColorSpace" key="NSCustomColorSpace">
+                                                                               <int key="NSID">2</int>
+                                                                       </object>
+                                                               </object>
+                                                               <bool key="IBUIAdjustsFontSizeToFit">YES</bool>
+                                                               <float key="IBUIMinimumFontSize">17</float>
+                                                               <object class="IBUITextInputTraits" key="IBUITextInputTraits">
+                                                                       <int key="IBUIAutocorrectionType">1</int>
+                                                                       <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                                               </object>
+                                                               <int key="IBUIClearButtonMode">3</int>
+                                                               <object class="IBUIFontDescription" key="IBUIFontDescription">
+                                                                       <int key="type">1</int>
+                                                                       <double key="pointSize">17</double>
+                                                               </object>
+                                                               <object class="NSFont" key="IBUIFont">
+                                                                       <string key="NSName">Helvetica</string>
+                                                                       <double key="NSSize">17</double>
+                                                                       <int key="NSfFlags">16</int>
+                                                               </object>
+                                                       </object>
+                                               </array>
+                                               <string key="NSFrameSize">{320, 43}</string>
+                                               <reference key="NSSuperview" ref="873867585"/>
+                                               <reference key="NSWindow"/>
+                                               <reference key="NSNextKeyView" ref="837238439"/>
+                                               <string key="NSReuseIdentifierKey">_NS:11</string>
+                                               <object class="NSColor" key="IBUIBackgroundColor">
+                                                       <int key="NSColorSpace">3</int>
+                                                       <bytes key="NSWhite">MCAwAA</bytes>
+                                               </object>
+                                               <bool key="IBUIOpaque">NO</bool>
+                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                               <int key="IBUIContentMode">4</int>
+                                               <bool key="IBUIMultipleTouchEnabled">YES</bool>
+                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                       </object>
+                               </array>
+                               <string key="NSFrameSize">{320, 44}</string>
+                               <reference key="NSSuperview"/>
+                               <reference key="NSWindow"/>
+                               <reference key="NSNextKeyView" ref="571279607"/>
+                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                               <int key="IBUISelectionStyle">0</int>
+                               <reference key="IBUIContentView" ref="571279607"/>
+                       </object>
+               </array>
+               <object class="IBObjectContainer" key="IBDocument.Objects">
+                       <array class="NSMutableArray" key="connectionRecords">
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_textTableViewCell</string>
+                                               <reference key="source" ref="841351856"/>
+                                               <reference key="destination" ref="873867585"/>
+                                       </object>
+                                       <int key="connectionID">7</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_label</string>
+                                               <reference key="source" ref="873867585"/>
+                                               <reference key="destination" ref="837238439"/>
+                                       </object>
+                                       <int key="connectionID">5</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_textfield</string>
+                                               <reference key="source" ref="873867585"/>
+                                               <reference key="destination" ref="915318991"/>
+                                       </object>
+                                       <int key="connectionID">6</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">delegate</string>
+                                               <reference key="source" ref="915318991"/>
+                                               <reference key="destination" ref="841351856"/>
+                                       </object>
+                                       <int key="connectionID">8</int>
+                               </object>
+                       </array>
+                       <object class="IBMutableOrderedSet" key="objectRecords">
+                               <array key="orderedObjects">
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">0</int>
+                                               <array key="object" id="0"/>
+                                               <reference key="children" ref="1000"/>
+                                               <nil key="parent"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-1</int>
+                                               <reference key="object" ref="841351856"/>
+                                               <reference key="parent" ref="0"/>
+                                               <string key="objectName">File's Owner</string>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-2</int>
+                                               <reference key="object" ref="371349661"/>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">2</int>
+                                               <reference key="object" ref="873867585"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="837238439"/>
+                                                       <reference ref="915318991"/>
+                                               </array>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">3</int>
+                                               <reference key="object" ref="837238439"/>
+                                               <reference key="parent" ref="873867585"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">4</int>
+                                               <reference key="object" ref="915318991"/>
+                                               <reference key="parent" ref="873867585"/>
+                                       </object>
+                               </array>
+                       </object>
+                       <dictionary class="NSMutableDictionary" key="flattenedProperties">
+                               <string key="-1.CustomClassName">EditorBaseController</string>
+                               <string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="-2.CustomClassName">UIResponder</string>
+                               <string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="2.CustomClassName">EditTextTableViewCell</string>
+                               <string key="2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="3.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="4.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                       </dictionary>
+                       <dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
+                       <nil key="activeLocalization"/>
+                       <dictionary class="NSMutableDictionary" key="localizations"/>
+                       <nil key="sourceID"/>
+                       <int key="maxID">8</int>
+               </object>
+               <object class="IBClassDescriber" key="IBDocument.Classes">
+                       <array class="NSMutableArray" key="referencedPartialClassDescriptions">
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">EditFlagTableViewCell</string>
+                                       <string key="superclassName">UITableViewCell</string>
+                                       <dictionary class="NSMutableDictionary" key="outlets">
+                                               <string key="_label">UILabel</string>
+                                               <string key="_toggle">UISwitch</string>
+                                       </dictionary>
+                                       <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <object class="IBToOneOutletInfo" key="_label">
+                                                       <string key="name">_label</string>
+                                                       <string key="candidateClassName">UILabel</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_toggle">
+                                                       <string key="name">_toggle</string>
+                                                       <string key="candidateClassName">UISwitch</string>
+                                               </object>
+                                       </dictionary>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/EditFlagTableViewCell.h</string>
+                                       </object>
+                               </object>
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">EditSelectionTableViewCell</string>
+                                       <string key="superclassName">UITableViewCell</string>
+                                       <dictionary class="NSMutableDictionary" key="outlets">
+                                               <string key="_label">UILabel</string>
+                                               <string key="_selection">UILabel</string>
+                                       </dictionary>
+                                       <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <object class="IBToOneOutletInfo" key="_label">
+                                                       <string key="name">_label</string>
+                                                       <string key="candidateClassName">UILabel</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_selection">
+                                                       <string key="name">_selection</string>
+                                                       <string key="candidateClassName">UILabel</string>
+                                               </object>
+                                       </dictionary>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/EditSelectionTableViewCell.h</string>
+                                       </object>
+                               </object>
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">EditSubEditTableViewCell</string>
+                                       <string key="superclassName">UITableViewCell</string>
+                                       <object class="NSMutableDictionary" key="outlets">
+                                               <string key="NS.key.0">_label</string>
+                                               <string key="NS.object.0">UILabel</string>
+                                       </object>
+                                       <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <string key="NS.key.0">_label</string>
+                                               <object class="IBToOneOutletInfo" key="NS.object.0">
+                                                       <string key="name">_label</string>
+                                                       <string key="candidateClassName">UILabel</string>
+                                               </object>
+                                       </object>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/EditSubEditTableViewCell.h</string>
+                                       </object>
+                               </object>
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">EditTextTableViewCell</string>
+                                       <string key="superclassName">UITableViewCell</string>
+                                       <dictionary class="NSMutableDictionary" key="outlets">
+                                               <string key="_label">UILabel</string>
+                                               <string key="_textfield">UITextField</string>
+                                       </dictionary>
+                                       <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <object class="IBToOneOutletInfo" key="_label">
+                                                       <string key="name">_label</string>
+                                                       <string key="candidateClassName">UILabel</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_textfield">
+                                                       <string key="name">_textfield</string>
+                                                       <string key="candidateClassName">UITextField</string>
+                                               </object>
+                                       </dictionary>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/EditTextTableViewCell.h</string>
+                                       </object>
+                               </object>
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">EditorBaseController</string>
+                                       <string key="superclassName">UITableViewController</string>
+                                       <dictionary class="NSMutableDictionary" key="outlets">
+                                               <string key="_flagTableViewCell">EditFlagTableViewCell</string>
+                                               <string key="_selectionTableViewCell">EditSelectionTableViewCell</string>
+                                               <string key="_subEditTableViewCell">EditSubEditTableViewCell</string>
+                                               <string key="_textTableViewCell">EditTextTableViewCell</string>
+                                       </dictionary>
+                                       <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <object class="IBToOneOutletInfo" key="_flagTableViewCell">
+                                                       <string key="name">_flagTableViewCell</string>
+                                                       <string key="candidateClassName">EditFlagTableViewCell</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_selectionTableViewCell">
+                                                       <string key="name">_selectionTableViewCell</string>
+                                                       <string key="candidateClassName">EditSelectionTableViewCell</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_subEditTableViewCell">
+                                                       <string key="name">_subEditTableViewCell</string>
+                                                       <string key="candidateClassName">EditSubEditTableViewCell</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_textTableViewCell">
+                                                       <string key="name">_textTableViewCell</string>
+                                                       <string key="candidateClassName">EditTextTableViewCell</string>
+                                               </object>
+                                       </dictionary>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/EditorBaseController.h</string>
+                                       </object>
+                               </object>
+                       </array>
+               </object>
+               <int key="IBDocument.localizationMode">0</int>
+               <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+                       <real value="1296" key="NS.object.0"/>
+               </object>
+               <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+               <int key="IBDocument.defaultPropertyAccessControl">3</int>
+               <string key="IBCocoaTouchPluginVersion">1179</string>
+       </data>
+</archive>
diff --git a/client/iOS/Resources/Icon-72.png b/client/iOS/Resources/Icon-72.png
new file mode 100755 (executable)
index 0000000..94951e1
Binary files /dev/null and b/client/iOS/Resources/Icon-72.png differ
diff --git a/client/iOS/Resources/Icon-72@2x.png b/client/iOS/Resources/Icon-72@2x.png
new file mode 100755 (executable)
index 0000000..e0278b8
Binary files /dev/null and b/client/iOS/Resources/Icon-72@2x.png differ
diff --git a/client/iOS/Resources/Icon.png b/client/iOS/Resources/Icon.png
new file mode 100755 (executable)
index 0000000..0d09cdd
Binary files /dev/null and b/client/iOS/Resources/Icon.png differ
diff --git a/client/iOS/Resources/Icon@2x.png b/client/iOS/Resources/Icon@2x.png
new file mode 100755 (executable)
index 0000000..9b7fae2
Binary files /dev/null and b/client/iOS/Resources/Icon@2x.png differ
diff --git a/client/iOS/Resources/MainWindow.xib b/client/iOS/Resources/MainWindow.xib
new file mode 100644 (file)
index 0000000..25b6add
--- /dev/null
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
+       <data>
+               <int key="IBDocument.SystemTarget">1296</int>
+               <string key="IBDocument.SystemVersion">11D50b</string>
+               <string key="IBDocument.InterfaceBuilderVersion">2182</string>
+               <string key="IBDocument.AppKitVersion">1138.32</string>
+               <string key="IBDocument.HIToolboxVersion">568.00</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                       <string key="NS.object.0">1179</string>
+               </object>
+               <array key="IBDocument.IntegratedClassDependencies">
+                       <string>IBUIWindow</string>
+                       <string>IBUITabBarController</string>
+                       <string>IBUITabBar</string>
+                       <string>IBUICustomObject</string>
+                       <string>IBProxyObject</string>
+               </array>
+               <array key="IBDocument.PluginDependencies">
+                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+               </array>
+               <object class="NSMutableDictionary" key="IBDocument.Metadata">
+                       <string key="NS.key.0">PluginDependencyRecalculationVersion</string>
+                       <integer value="1" key="NS.object.0"/>
+               </object>
+               <array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+                       <object class="IBProxyObject" id="841351856">
+                               <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                       </object>
+                       <object class="IBProxyObject" id="590933970">
+                               <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                       </object>
+                       <object class="IBUICustomObject" id="271699545">
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                       </object>
+                       <object class="IBUIWindow" id="380026005">
+                               <reference key="NSNextResponder"/>
+                               <int key="NSvFlags">1316</int>
+                               <object class="NSPSMatrix" key="NSFrameMatrix"/>
+                               <string key="NSFrameSize">{320, 480}</string>
+                               <reference key="NSSuperview"/>
+                               <object class="NSColor" key="IBUIBackgroundColor">
+                                       <int key="NSColorSpace">1</int>
+                                       <bytes key="NSRGB">MSAxIDEAA</bytes>
+                               </object>
+                               <bool key="IBUIOpaque">NO</bool>
+                               <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+                               <object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                               <bool key="IBUIResizesToFullScreen">YES</bool>
+                       </object>
+                       <object class="IBUITabBarController" id="803392999">
+                               <object class="IBUISimulatedTabBarMetrics" key="IBUISimulatedBottomBarMetrics"/>
+                               <object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
+                               <object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
+                                       <int key="IBUIInterfaceOrientation">1</int>
+                                       <int key="interfaceOrientation">1</int>
+                               </object>
+                               <bool key="IBUIDefinesPresentationContext">YES</bool>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                               <bool key="IBUIHorizontal">NO</bool>
+                               <array class="NSMutableArray" key="IBUIViewControllers"/>
+                               <object class="IBUITabBar" key="IBUITabBar" id="690969762">
+                                       <reference key="NSNextResponder"/>
+                                       <int key="NSvFlags">266</int>
+                                       <string key="NSFrame">{{0, 431}, {320, 49}}</string>
+                                       <reference key="NSSuperview"/>
+                                       <string key="NSReuseIdentifierKey">_NS:29</string>
+                                       <object class="NSColor" key="IBUIBackgroundColor">
+                                               <int key="NSColorSpace">3</int>
+                                               <bytes key="NSWhite">MCAwAA</bytes>
+                                       </object>
+                                       <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                               </object>
+                       </object>
+               </array>
+               <object class="IBObjectContainer" key="IBDocument.Objects">
+                       <array class="NSMutableArray" key="connectionRecords">
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">delegate</string>
+                                               <reference key="source" ref="841351856"/>
+                                               <reference key="destination" ref="271699545"/>
+                                       </object>
+                                       <int key="connectionID">12</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">window</string>
+                                               <reference key="source" ref="271699545"/>
+                                               <reference key="destination" ref="380026005"/>
+                                       </object>
+                                       <int key="connectionID">13</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">tabBarController</string>
+                                               <reference key="source" ref="271699545"/>
+                                               <reference key="destination" ref="803392999"/>
+                                       </object>
+                                       <int key="connectionID">14</int>
+                               </object>
+                       </array>
+                       <object class="IBMutableOrderedSet" key="objectRecords">
+                               <array key="orderedObjects">
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">0</int>
+                                               <array key="object" id="0"/>
+                                               <reference key="children" ref="1000"/>
+                                               <nil key="parent"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">2</int>
+                                               <reference key="object" ref="380026005"/>
+                                               <array class="NSMutableArray" key="children"/>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-1</int>
+                                               <reference key="object" ref="841351856"/>
+                                               <reference key="parent" ref="0"/>
+                                               <string key="objectName">File's Owner</string>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-2</int>
+                                               <reference key="object" ref="590933970"/>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">4</int>
+                                               <reference key="object" ref="803392999"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="690969762"/>
+                                               </array>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">5</int>
+                                               <reference key="object" ref="690969762"/>
+                                               <reference key="parent" ref="803392999"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">11</int>
+                                               <reference key="object" ref="271699545"/>
+                                               <reference key="parent" ref="0"/>
+                                               <string key="objectName">AppDelegate</string>
+                                       </object>
+                               </array>
+                       </object>
+                       <dictionary class="NSMutableDictionary" key="flattenedProperties">
+                               <string key="-1.CustomClassName">UIApplication</string>
+                               <string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="-2.CustomClassName">UIResponder</string>
+                               <string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="11.CustomClassName">AppDelegate</string>
+                               <string key="11.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <dictionary class="NSMutableDictionary" key="2.IBAttributePlaceholdersKey"/>
+                               <string key="2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="4.CustomClassName">MainTabBarController</string>
+                               <string key="4.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="5.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                       </dictionary>
+                       <dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
+                       <nil key="activeLocalization"/>
+                       <dictionary class="NSMutableDictionary" key="localizations"/>
+                       <nil key="sourceID"/>
+                       <int key="maxID">21</int>
+               </object>
+               <object class="IBClassDescriber" key="IBDocument.Classes"/>
+               <int key="IBDocument.localizationMode">0</int>
+               <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+                       <real value="1296" key="NS.object.0"/>
+               </object>
+               <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+               <int key="IBDocument.defaultPropertyAccessControl">3</int>
+               <string key="IBCocoaTouchPluginVersion">1179</string>
+       </data>
+</archive>
diff --git a/client/iOS/Resources/RDPConnectingView.xib b/client/iOS/Resources/RDPConnectingView.xib
new file mode 100644 (file)
index 0000000..cc0aec0
--- /dev/null
@@ -0,0 +1,342 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
+       <data>
+               <int key="IBDocument.SystemTarget">1296</int>
+               <string key="IBDocument.SystemVersion">11D50b</string>
+               <string key="IBDocument.InterfaceBuilderVersion">2182</string>
+               <string key="IBDocument.AppKitVersion">1138.32</string>
+               <string key="IBDocument.HIToolboxVersion">568.00</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                       <string key="NS.object.0">1179</string>
+               </object>
+               <array key="IBDocument.IntegratedClassDependencies">
+                       <string>IBUIButton</string>
+                       <string>IBUIActivityIndicatorView</string>
+                       <string>IBUIView</string>
+                       <string>IBUILabel</string>
+                       <string>IBProxyObject</string>
+               </array>
+               <array key="IBDocument.PluginDependencies">
+                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+               </array>
+               <object class="NSMutableDictionary" key="IBDocument.Metadata">
+                       <string key="NS.key.0">PluginDependencyRecalculationVersion</string>
+                       <integer value="1" key="NS.object.0"/>
+               </object>
+               <array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+                       <object class="IBProxyObject" id="372490531">
+                               <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                       </object>
+                       <object class="IBProxyObject" id="975951072">
+                               <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                       </object>
+                       <object class="IBUIView" id="191373211">
+                               <reference key="NSNextResponder"/>
+                               <int key="NSvFlags">301</int>
+                               <array class="NSMutableArray" key="NSSubviews">
+                                       <object class="IBUIButton" id="971255490">
+                                               <reference key="NSNextResponder" ref="191373211"/>
+                                               <int key="NSvFlags">292</int>
+                                               <string key="NSFrame">{{45, 143}, {109, 37}}</string>
+                                               <reference key="NSSuperview" ref="191373211"/>
+                                               <reference key="NSWindow"/>
+                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                               <bool key="IBUIOpaque">NO</bool>
+                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                               <int key="IBUIContentHorizontalAlignment">0</int>
+                                               <int key="IBUIContentVerticalAlignment">0</int>
+                                               <int key="IBUIButtonType">1</int>
+                                               <string key="IBUINormalTitle">Cancel</string>
+                                               <object class="NSColor" key="IBUIHighlightedTitleColor" id="107901828">
+                                                       <int key="NSColorSpace">3</int>
+                                                       <bytes key="NSWhite">MQA</bytes>
+                                               </object>
+                                               <reference key="IBUINormalTitleColor" ref="107901828"/>
+                                               <object class="NSColor" key="IBUINormalTitleShadowColor">
+                                                       <int key="NSColorSpace">3</int>
+                                                       <bytes key="NSWhite">MC41AA</bytes>
+                                               </object>
+                                               <object class="NSCustomResource" key="IBUINormalBackgroundImage">
+                                                       <string key="NSClassName">NSImage</string>
+                                                       <string key="NSResourceName">cancel_button_background.png</string>
+                                               </object>
+                                               <object class="IBUIFontDescription" key="IBUIFontDescription">
+                                                       <int key="type">2</int>
+                                                       <double key="pointSize">15</double>
+                                               </object>
+                                               <object class="NSFont" key="IBUIFont">
+                                                       <string key="NSName">Helvetica-Bold</string>
+                                                       <double key="NSSize">15</double>
+                                                       <int key="NSfFlags">16</int>
+                                               </object>
+                                       </object>
+                                       <object class="IBUIActivityIndicatorView" id="236881211">
+                                               <reference key="NSNextResponder" ref="191373211"/>
+                                               <int key="NSvFlags">301</int>
+                                               <string key="NSFrame">{{82, 81}, {37, 37}}</string>
+                                               <reference key="NSSuperview" ref="191373211"/>
+                                               <reference key="NSWindow"/>
+                                               <reference key="NSNextKeyView" ref="971255490"/>
+                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                               <bool key="IBUIOpaque">NO</bool>
+                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                               <bool key="IBUIHidesWhenStopped">NO</bool>
+                                               <int key="IBUIStyle">0</int>
+                                       </object>
+                                       <object class="IBUILabel" id="933286658">
+                                               <reference key="NSNextResponder" ref="191373211"/>
+                                               <int key="NSvFlags">292</int>
+                                               <string key="NSFrame">{{18, 20}, {165, 25}}</string>
+                                               <reference key="NSSuperview" ref="191373211"/>
+                                               <reference key="NSWindow"/>
+                                               <reference key="NSNextKeyView" ref="236881211"/>
+                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                               <bool key="IBUIOpaque">NO</bool>
+                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                               <int key="IBUIContentMode">7</int>
+                                               <bool key="IBUIUserInteractionEnabled">NO</bool>
+                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                               <string key="IBUIText">Connecting</string>
+                                               <reference key="IBUITextColor" ref="107901828"/>
+                                               <nil key="IBUIHighlightedColor"/>
+                                               <int key="IBUIBaselineAdjustment">0</int>
+                                               <float key="IBUIMinimumFontSize">10</float>
+                                               <int key="IBUITextAlignment">1</int>
+                                               <object class="IBUIFontDescription" key="IBUIFontDescription">
+                                                       <int key="type">2</int>
+                                                       <double key="pointSize">17</double>
+                                               </object>
+                                               <object class="NSFont" key="IBUIFont">
+                                                       <string key="NSName">Helvetica-Bold</string>
+                                                       <double key="NSSize">17</double>
+                                                       <int key="NSfFlags">16</int>
+                                               </object>
+                                       </object>
+                               </array>
+                               <string key="NSFrameSize">{200, 200}</string>
+                               <reference key="NSSuperview"/>
+                               <reference key="NSWindow"/>
+                               <reference key="NSNextKeyView" ref="933286658"/>
+                               <object class="NSColor" key="IBUIBackgroundColor">
+                                       <int key="NSColorSpace">3</int>
+                                       <bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes>
+                               </object>
+                               <object class="IBUISimulatedSizeMetrics" key="IBUISimulatedDestinationMetrics">
+                                       <string key="IBUISimulatedSizeMetricsClass">IBUISimulatedFreeformSizeMetricsSentinel</string>
+                                       <string key="IBUIDisplayName">Freeform</string>
+                               </object>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                       </object>
+               </array>
+               <object class="IBObjectContainer" key="IBDocument.Objects">
+                       <array class="NSMutableArray" key="connectionRecords">
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_connecting_view</string>
+                                               <reference key="source" ref="372490531"/>
+                                               <reference key="destination" ref="191373211"/>
+                                       </object>
+                                       <int key="connectionID">6</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_cancel_connect_button</string>
+                                               <reference key="source" ref="372490531"/>
+                                               <reference key="destination" ref="971255490"/>
+                                       </object>
+                                       <int key="connectionID">7</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_connecting_indicator_view</string>
+                                               <reference key="source" ref="372490531"/>
+                                               <reference key="destination" ref="236881211"/>
+                                       </object>
+                                       <int key="connectionID">8</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_lbl_connecting</string>
+                                               <reference key="source" ref="372490531"/>
+                                               <reference key="destination" ref="933286658"/>
+                                       </object>
+                                       <int key="connectionID">10</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchEventConnection" key="connection">
+                                               <string key="label">cancelButtonPressed:</string>
+                                               <reference key="source" ref="971255490"/>
+                                               <reference key="destination" ref="372490531"/>
+                                               <int key="IBEventType">7</int>
+                                       </object>
+                                       <int key="connectionID">9</int>
+                               </object>
+                       </array>
+                       <object class="IBMutableOrderedSet" key="objectRecords">
+                               <array key="orderedObjects">
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">0</int>
+                                               <array key="object" id="0"/>
+                                               <reference key="children" ref="1000"/>
+                                               <nil key="parent"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">1</int>
+                                               <reference key="object" ref="191373211"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="971255490"/>
+                                                       <reference ref="236881211"/>
+                                                       <reference ref="933286658"/>
+                                               </array>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-1</int>
+                                               <reference key="object" ref="372490531"/>
+                                               <reference key="parent" ref="0"/>
+                                               <string key="objectName">File's Owner</string>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-2</int>
+                                               <reference key="object" ref="975951072"/>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">3</int>
+                                               <reference key="object" ref="971255490"/>
+                                               <reference key="parent" ref="191373211"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">4</int>
+                                               <reference key="object" ref="236881211"/>
+                                               <reference key="parent" ref="191373211"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">5</int>
+                                               <reference key="object" ref="933286658"/>
+                                               <reference key="parent" ref="191373211"/>
+                                       </object>
+                               </array>
+                       </object>
+                       <dictionary class="NSMutableDictionary" key="flattenedProperties">
+                               <string key="-1.CustomClassName">RDPSessionViewController</string>
+                               <string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="-2.CustomClassName">UIResponder</string>
+                               <string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="3.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="4.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="5.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                       </dictionary>
+                       <dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
+                       <nil key="activeLocalization"/>
+                       <dictionary class="NSMutableDictionary" key="localizations"/>
+                       <nil key="sourceID"/>
+                       <int key="maxID">10</int>
+               </object>
+               <object class="IBClassDescriber" key="IBDocument.Classes">
+                       <array class="NSMutableArray" key="referencedPartialClassDescriptions">
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">RDPSessionView</string>
+                                       <string key="superclassName">UIView</string>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/RDPSessionView.h</string>
+                                       </object>
+                               </object>
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">RDPSessionViewController</string>
+                                       <string key="superclassName">UIViewController</string>
+                                       <dictionary class="NSMutableDictionary" key="outlets">
+                                               <string key="_cancel_connect_button">UIButton</string>
+                                               <string key="_connecting_indicator_view">UIActivityIndicatorView</string>
+                                               <string key="_connecting_view">UIView</string>
+                                               <string key="_dummy_textfield">UITextField</string>
+                                               <string key="_lbl_connecting">UILabel</string>
+                                               <string key="_session_scrollview">UIScrollView</string>
+                                               <string key="_session_toolbar">UIToolbar</string>
+                                               <string key="_session_view">RDPSessionView</string>
+                                               <string key="_touchpointer_view">TouchPointerView</string>
+                                       </dictionary>
+                                       <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <object class="IBToOneOutletInfo" key="_cancel_connect_button">
+                                                       <string key="name">_cancel_connect_button</string>
+                                                       <string key="candidateClassName">UIButton</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_connecting_indicator_view">
+                                                       <string key="name">_connecting_indicator_view</string>
+                                                       <string key="candidateClassName">UIActivityIndicatorView</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_connecting_view">
+                                                       <string key="name">_connecting_view</string>
+                                                       <string key="candidateClassName">UIView</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_dummy_textfield">
+                                                       <string key="name">_dummy_textfield</string>
+                                                       <string key="candidateClassName">UITextField</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_lbl_connecting">
+                                                       <string key="name">_lbl_connecting</string>
+                                                       <string key="candidateClassName">UILabel</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_session_scrollview">
+                                                       <string key="name">_session_scrollview</string>
+                                                       <string key="candidateClassName">UIScrollView</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_session_toolbar">
+                                                       <string key="name">_session_toolbar</string>
+                                                       <string key="candidateClassName">UIToolbar</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_session_view">
+                                                       <string key="name">_session_view</string>
+                                                       <string key="candidateClassName">RDPSessionView</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_touchpointer_view">
+                                                       <string key="name">_touchpointer_view</string>
+                                                       <string key="candidateClassName">TouchPointerView</string>
+                                               </object>
+                                       </dictionary>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/RDPSessionViewController.h</string>
+                                       </object>
+                               </object>
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">TouchPointerView</string>
+                                       <string key="superclassName">UIView</string>
+                                       <object class="NSMutableDictionary" key="outlets">
+                                               <string key="NS.key.0">delegate</string>
+                                               <string key="NS.object.0">NSObject</string>
+                                       </object>
+                                       <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <string key="NS.key.0">delegate</string>
+                                               <object class="IBToOneOutletInfo" key="NS.object.0">
+                                                       <string key="name">delegate</string>
+                                                       <string key="candidateClassName">NSObject</string>
+                                               </object>
+                                       </object>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/TouchPointerView.h</string>
+                                       </object>
+                               </object>
+                       </array>
+               </object>
+               <int key="IBDocument.localizationMode">0</int>
+               <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+                       <real value="1296" key="NS.object.0"/>
+               </object>
+               <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+               <int key="IBDocument.defaultPropertyAccessControl">3</int>
+               <object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
+                       <string key="NS.key.0">cancel_button_background.png</string>
+                       <string key="NS.object.0">{63, 33}</string>
+               </object>
+               <string key="IBCocoaTouchPluginVersion">1179</string>
+       </data>
+</archive>
diff --git a/client/iOS/Resources/RDPSessionView.xib b/client/iOS/Resources/RDPSessionView.xib
new file mode 100644 (file)
index 0000000..5d2b595
--- /dev/null
@@ -0,0 +1,553 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
+       <data>
+               <int key="IBDocument.SystemTarget">1296</int>
+               <string key="IBDocument.SystemVersion">11D50b</string>
+               <string key="IBDocument.InterfaceBuilderVersion">2182</string>
+               <string key="IBDocument.AppKitVersion">1138.32</string>
+               <string key="IBDocument.HIToolboxVersion">568.00</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                       <string key="NS.object.0">1179</string>
+               </object>
+               <array key="IBDocument.IntegratedClassDependencies">
+                       <string>IBUITextField</string>
+                       <string>IBUIBarButtonItem</string>
+                       <string>IBUIToolbar</string>
+                       <string>IBUIView</string>
+                       <string>IBUIScrollView</string>
+                       <string>IBProxyObject</string>
+               </array>
+               <array key="IBDocument.PluginDependencies">
+                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+               </array>
+               <object class="NSMutableDictionary" key="IBDocument.Metadata">
+                       <string key="NS.key.0">PluginDependencyRecalculationVersion</string>
+                       <integer value="1" key="NS.object.0"/>
+               </object>
+               <array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+                       <object class="IBProxyObject" id="372490531">
+                               <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                       </object>
+                       <object class="IBProxyObject" id="975951072">
+                               <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                       </object>
+                       <object class="IBUIView" id="191373211">
+                               <reference key="NSNextResponder"/>
+                               <int key="NSvFlags">274</int>
+                               <array class="NSMutableArray" key="NSSubviews">
+                                       <object class="IBUITextField" id="774128306">
+                                               <reference key="NSNextResponder" ref="191373211"/>
+                                               <int key="NSvFlags">292</int>
+                                               <string key="NSFrameSize">{0, 31}</string>
+                                               <reference key="NSSuperview" ref="191373211"/>
+                                               <reference key="NSWindow"/>
+                                               <reference key="NSNextKeyView" ref="791392364"/>
+                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                               <bool key="IBUIOpaque">NO</bool>
+                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                               <int key="IBUIContentVerticalAlignment">0</int>
+                                               <string key="IBUIText">UserInput</string>
+                                               <int key="IBUIBorderStyle">3</int>
+                                               <object class="NSColor" key="IBUITextColor">
+                                                       <int key="NSColorSpace">3</int>
+                                                       <bytes key="NSWhite">MAA</bytes>
+                                                       <object class="NSColorSpace" key="NSCustomColorSpace" id="239224178">
+                                                               <int key="NSID">2</int>
+                                                       </object>
+                                               </object>
+                                               <bool key="IBUIAdjustsFontSizeToFit">YES</bool>
+                                               <float key="IBUIMinimumFontSize">17</float>
+                                               <object class="IBUITextInputTraits" key="IBUITextInputTraits">
+                                                       <int key="IBUIAutocorrectionType">1</int>
+                                                       <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                               </object>
+                                               <object class="IBUIFontDescription" key="IBUIFontDescription">
+                                                       <int key="type">1</int>
+                                                       <double key="pointSize">14</double>
+                                               </object>
+                                               <object class="NSFont" key="IBUIFont">
+                                                       <string key="NSName">Helvetica</string>
+                                                       <double key="NSSize">14</double>
+                                                       <int key="NSfFlags">16</int>
+                                               </object>
+                                       </object>
+                                       <object class="IBUIScrollView" id="791392364">
+                                               <reference key="NSNextResponder" ref="191373211"/>
+                                               <int key="NSvFlags">274</int>
+                                               <array class="NSMutableArray" key="NSSubviews">
+                                                       <object class="IBUIView" id="111719994">
+                                                               <reference key="NSNextResponder" ref="791392364"/>
+                                                               <int key="NSvFlags">292</int>
+                                                               <string key="NSFrameSize">{320, 460}</string>
+                                                               <reference key="NSSuperview" ref="791392364"/>
+                                                               <reference key="NSWindow"/>
+                                                               <reference key="NSNextKeyView" ref="462653931"/>
+                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                               <object class="NSColor" key="IBUIBackgroundColor">
+                                                                       <int key="NSColorSpace">3</int>
+                                                                       <bytes key="NSWhite">MQA</bytes>
+                                                                       <reference key="NSCustomColorSpace" ref="239224178"/>
+                                                               </object>
+                                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                                       </object>
+                                               </array>
+                                               <string key="NSFrameSize">{320, 460}</string>
+                                               <reference key="NSSuperview" ref="191373211"/>
+                                               <reference key="NSWindow"/>
+                                               <reference key="NSNextKeyView" ref="111719994"/>
+                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                               <object class="NSColor" key="IBUIBackgroundColor" id="916436089">
+                                                       <int key="NSColorSpace">3</int>
+                                                       <bytes key="NSWhite">MAA</bytes>
+                                               </object>
+                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                               <bool key="IBUIMultipleTouchEnabled">YES</bool>
+                                               <array key="IBUIGestureRecognizers" id="0"/>
+                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                               <bool key="IBUICanCancelContentTouches">NO</bool>
+                                               <float key="IBUIMaximumZoomScale">2</float>
+                                       </object>
+                                       <object class="IBUIView" id="462653931">
+                                               <reference key="NSNextResponder" ref="191373211"/>
+                                               <int key="NSvFlags">-2147483374</int>
+                                               <string key="NSFrameSize">{320, 460}</string>
+                                               <reference key="NSSuperview" ref="191373211"/>
+                                               <reference key="NSWindow"/>
+                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                               <object class="NSColor" key="IBUIBackgroundColor">
+                                                       <int key="NSColorSpace">3</int>
+                                                       <bytes key="NSWhite">MSAwAA</bytes>
+                                                       <reference key="NSCustomColorSpace" ref="239224178"/>
+                                               </object>
+                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                       </object>
+                                       <object class="IBUIToolbar" id="902223647">
+                                               <reference key="NSNextResponder" ref="191373211"/>
+                                               <int key="NSvFlags">290</int>
+                                               <string key="NSFrame">{{0, -66}, {320, 44}}</string>
+                                               <reference key="NSSuperview" ref="191373211"/>
+                                               <reference key="NSWindow"/>
+                                               <reference key="NSNextKeyView" ref="774128306"/>
+                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                               <bool key="IBUIOpaque">NO</bool>
+                                               <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                               <int key="IBUIBarStyle">2</int>
+                                               <array class="NSMutableArray" key="IBUIItems">
+                                                       <object class="IBUIBarButtonItem" id="1053104">
+                                                               <object class="NSCustomResource" key="IBUIImage">
+                                                                       <string key="NSClassName">NSImage</string>
+                                                                       <string key="NSResourceName">toolbar_icon_keyboard.png</string>
+                                                               </object>
+                                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                                               <reference key="IBUIToolbar" ref="902223647"/>
+                                                       </object>
+                                                       <object class="IBUIBarButtonItem" id="610739936">
+                                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                                               <float key="IBUIWidth">20</float>
+                                                               <reference key="IBUIToolbar" ref="902223647"/>
+                                                               <int key="IBUISystemItemIdentifier">6</int>
+                                                       </object>
+                                                       <object class="IBUIBarButtonItem" id="619296838">
+                                                               <object class="NSCustomResource" key="IBUIImage">
+                                                                       <string key="NSClassName">NSImage</string>
+                                                                       <string key="NSResourceName">toolbar_icon_extkeyboad.png</string>
+                                                               </object>
+                                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                                               <reference key="IBUIToolbar" ref="902223647"/>
+                                                       </object>
+                                                       <object class="IBUIBarButtonItem" id="638922886">
+                                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                                               <float key="IBUIWidth">20</float>
+                                                               <reference key="IBUIToolbar" ref="902223647"/>
+                                                               <int key="IBUISystemItemIdentifier">6</int>
+                                                       </object>
+                                                       <object class="IBUIBarButtonItem" id="771290196">
+                                                               <object class="NSCustomResource" key="IBUIImage">
+                                                                       <string key="NSClassName">NSImage</string>
+                                                                       <string key="NSResourceName">toolbar_icon_touchpointer.png</string>
+                                                               </object>
+                                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                                               <reference key="IBUIToolbar" ref="902223647"/>
+                                                       </object>
+                                                       <object class="IBUIBarButtonItem" id="1053225403">
+                                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                                               <reference key="IBUIToolbar" ref="902223647"/>
+                                                               <int key="IBUISystemItemIdentifier">5</int>
+                                                       </object>
+                                                       <object class="IBUIBarButtonItem" id="977115063">
+                                                               <object class="NSCustomResource" key="IBUIImage">
+                                                                       <string key="NSClassName">NSImage</string>
+                                                                       <string key="NSResourceName">toolbar_icon_disconnect.png</string>
+                                                               </object>
+                                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                                               <reference key="IBUIToolbar" ref="902223647"/>
+                                                       </object>
+                                               </array>
+                                       </object>
+                               </array>
+                               <string key="NSFrame">{{0, 20}, {320, 460}}</string>
+                               <reference key="NSSuperview"/>
+                               <reference key="NSWindow"/>
+                               <reference key="NSNextKeyView" ref="902223647"/>
+                               <reference key="IBUIBackgroundColor" ref="916436089"/>
+                               <object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                       </object>
+               </array>
+               <object class="IBObjectContainer" key="IBDocument.Objects">
+                       <array class="NSMutableArray" key="connectionRecords">
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">view</string>
+                                               <reference key="source" ref="372490531"/>
+                                               <reference key="destination" ref="191373211"/>
+                                       </object>
+                                       <int key="connectionID">21</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_dummy_textfield</string>
+                                               <reference key="source" ref="372490531"/>
+                                               <reference key="destination" ref="774128306"/>
+                                       </object>
+                                       <int key="connectionID">22</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_session_scrollview</string>
+                                               <reference key="source" ref="372490531"/>
+                                               <reference key="destination" ref="791392364"/>
+                                       </object>
+                                       <int key="connectionID">23</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_touchpointer_view</string>
+                                               <reference key="source" ref="372490531"/>
+                                               <reference key="destination" ref="462653931"/>
+                                       </object>
+                                       <int key="connectionID">25</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_session_view</string>
+                                               <reference key="source" ref="372490531"/>
+                                               <reference key="destination" ref="111719994"/>
+                                       </object>
+                                       <int key="connectionID">26</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_session_toolbar</string>
+                                               <reference key="source" ref="372490531"/>
+                                               <reference key="destination" ref="902223647"/>
+                                       </object>
+                                       <int key="connectionID">27</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchEventConnection" key="connection">
+                                               <string key="label">toggleKeyboard:</string>
+                                               <reference key="source" ref="1053104"/>
+                                               <reference key="destination" ref="372490531"/>
+                                       </object>
+                                       <int key="connectionID">33</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchEventConnection" key="connection">
+                                               <string key="label">toggleTouchPointer:</string>
+                                               <reference key="source" ref="771290196"/>
+                                               <reference key="destination" ref="372490531"/>
+                                       </object>
+                                       <int key="connectionID">34</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchEventConnection" key="connection">
+                                               <string key="label">disconnectSession:</string>
+                                               <reference key="source" ref="977115063"/>
+                                               <reference key="destination" ref="372490531"/>
+                                       </object>
+                                       <int key="connectionID">31</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">delegate</string>
+                                               <reference key="source" ref="791392364"/>
+                                               <reference key="destination" ref="372490531"/>
+                                       </object>
+                                       <int key="connectionID">28</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">delegate</string>
+                                               <reference key="source" ref="774128306"/>
+                                               <reference key="destination" ref="372490531"/>
+                                       </object>
+                                       <int key="connectionID">29</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">delegate</string>
+                                               <reference key="source" ref="462653931"/>
+                                               <reference key="destination" ref="372490531"/>
+                                       </object>
+                                       <int key="connectionID">30</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchEventConnection" key="connection">
+                                               <string key="label">toggleShiftKey:</string>
+                                               <reference key="source" ref="638922886"/>
+                                               <reference key="destination" ref="372490531"/>
+                                       </object>
+                                       <int key="connectionID">38</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchEventConnection" key="connection">
+                                               <string key="label">toggleExtKeyboard:</string>
+                                               <reference key="source" ref="619296838"/>
+                                               <reference key="destination" ref="372490531"/>
+                                       </object>
+                                       <int key="connectionID">39</int>
+                               </object>
+                       </array>
+                       <object class="IBMutableOrderedSet" key="objectRecords">
+                               <array key="orderedObjects">
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">0</int>
+                                               <reference key="object" ref="0"/>
+                                               <reference key="children" ref="1000"/>
+                                               <nil key="parent"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">1</int>
+                                               <reference key="object" ref="191373211"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="902223647"/>
+                                                       <reference ref="791392364"/>
+                                                       <reference ref="774128306"/>
+                                                       <reference ref="462653931"/>
+                                               </array>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-1</int>
+                                               <reference key="object" ref="372490531"/>
+                                               <reference key="parent" ref="0"/>
+                                               <string key="objectName">File's Owner</string>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-2</int>
+                                               <reference key="object" ref="975951072"/>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">3</int>
+                                               <reference key="object" ref="902223647"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="1053104"/>
+                                                       <reference ref="610739936"/>
+                                                       <reference ref="771290196"/>
+                                                       <reference ref="1053225403"/>
+                                                       <reference ref="977115063"/>
+                                                       <reference ref="638922886"/>
+                                                       <reference ref="619296838"/>
+                                               </array>
+                                               <reference key="parent" ref="191373211"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">4</int>
+                                               <reference key="object" ref="1053104"/>
+                                               <reference key="parent" ref="902223647"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">5</int>
+                                               <reference key="object" ref="610739936"/>
+                                               <reference key="parent" ref="902223647"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">6</int>
+                                               <reference key="object" ref="771290196"/>
+                                               <reference key="parent" ref="902223647"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">9</int>
+                                               <reference key="object" ref="1053225403"/>
+                                               <reference key="parent" ref="902223647"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">10</int>
+                                               <reference key="object" ref="977115063"/>
+                                               <reference key="parent" ref="902223647"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">11</int>
+                                               <reference key="object" ref="791392364"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="111719994"/>
+                                               </array>
+                                               <reference key="parent" ref="191373211"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">12</int>
+                                               <reference key="object" ref="774128306"/>
+                                               <reference key="parent" ref="191373211"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">13</int>
+                                               <reference key="object" ref="111719994"/>
+                                               <array class="NSMutableArray" key="children"/>
+                                               <reference key="parent" ref="791392364"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">14</int>
+                                               <reference key="object" ref="462653931"/>
+                                               <reference key="parent" ref="191373211"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">35</int>
+                                               <reference key="object" ref="638922886"/>
+                                               <reference key="parent" ref="902223647"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">36</int>
+                                               <reference key="object" ref="619296838"/>
+                                               <reference key="parent" ref="902223647"/>
+                                       </object>
+                               </array>
+                       </object>
+                       <dictionary class="NSMutableDictionary" key="flattenedProperties">
+                               <string key="-1.CustomClassName">RDPSessionViewController</string>
+                               <string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="-2.CustomClassName">UIResponder</string>
+                               <string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="10.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="11.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="12.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="13.CustomClassName">RDPSessionView</string>
+                               <string key="13.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="14.CustomClassName">TouchPointerView</string>
+                               <string key="14.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="3.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="35.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="36.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="4.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="5.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="6.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="9.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                       </dictionary>
+                       <dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
+                       <nil key="activeLocalization"/>
+                       <dictionary class="NSMutableDictionary" key="localizations"/>
+                       <nil key="sourceID"/>
+                       <int key="maxID">39</int>
+               </object>
+               <object class="IBClassDescriber" key="IBDocument.Classes">
+                       <array class="NSMutableArray" key="referencedPartialClassDescriptions">
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">RDPSessionView</string>
+                                       <string key="superclassName">UIView</string>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/RDPSessionView.h</string>
+                                       </object>
+                               </object>
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">RDPSessionViewController</string>
+                                       <string key="superclassName">UIViewController</string>
+                                       <dictionary class="NSMutableDictionary" key="outlets">
+                                               <string key="_cancel_connect_button">UIButton</string>
+                                               <string key="_connecting_indicator_view">UIActivityIndicatorView</string>
+                                               <string key="_connecting_view">UIView</string>
+                                               <string key="_dummy_textfield">UITextField</string>
+                                               <string key="_lbl_connecting">UILabel</string>
+                                               <string key="_session_scrollview">UIScrollView</string>
+                                               <string key="_session_toolbar">UIToolbar</string>
+                                               <string key="_session_view">RDPSessionView</string>
+                                               <string key="_touchpointer_view">TouchPointerView</string>
+                                       </dictionary>
+                                       <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <object class="IBToOneOutletInfo" key="_cancel_connect_button">
+                                                       <string key="name">_cancel_connect_button</string>
+                                                       <string key="candidateClassName">UIButton</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_connecting_indicator_view">
+                                                       <string key="name">_connecting_indicator_view</string>
+                                                       <string key="candidateClassName">UIActivityIndicatorView</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_connecting_view">
+                                                       <string key="name">_connecting_view</string>
+                                                       <string key="candidateClassName">UIView</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_dummy_textfield">
+                                                       <string key="name">_dummy_textfield</string>
+                                                       <string key="candidateClassName">UITextField</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_lbl_connecting">
+                                                       <string key="name">_lbl_connecting</string>
+                                                       <string key="candidateClassName">UILabel</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_session_scrollview">
+                                                       <string key="name">_session_scrollview</string>
+                                                       <string key="candidateClassName">UIScrollView</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_session_toolbar">
+                                                       <string key="name">_session_toolbar</string>
+                                                       <string key="candidateClassName">UIToolbar</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_session_view">
+                                                       <string key="name">_session_view</string>
+                                                       <string key="candidateClassName">RDPSessionView</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_touchpointer_view">
+                                                       <string key="name">_touchpointer_view</string>
+                                                       <string key="candidateClassName">TouchPointerView</string>
+                                               </object>
+                                       </dictionary>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/RDPSessionViewController.h</string>
+                                       </object>
+                               </object>
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">TouchPointerView</string>
+                                       <string key="superclassName">UIView</string>
+                                       <object class="NSMutableDictionary" key="outlets">
+                                               <string key="NS.key.0">delegate</string>
+                                               <string key="NS.object.0">NSObject</string>
+                                       </object>
+                                       <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <string key="NS.key.0">delegate</string>
+                                               <object class="IBToOneOutletInfo" key="NS.object.0">
+                                                       <string key="name">delegate</string>
+                                                       <string key="candidateClassName">NSObject</string>
+                                               </object>
+                                       </object>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/TouchPointerView.h</string>
+                                       </object>
+                               </object>
+                       </array>
+               </object>
+               <int key="IBDocument.localizationMode">0</int>
+               <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+                       <real value="1296" key="NS.object.0"/>
+               </object>
+               <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+               <int key="IBDocument.defaultPropertyAccessControl">3</int>
+               <dictionary class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
+                       <string key="toolbar_icon_disconnect.png">{24, 24}</string>
+                       <string key="toolbar_icon_extkeyboad.png">{24, 24}</string>
+                       <string key="toolbar_icon_keyboard.png">{35, 24}</string>
+                       <string key="toolbar_icon_touchpointer.png">{24, 24}</string>
+               </dictionary>
+               <string key="IBCocoaTouchPluginVersion">1179</string>
+       </data>
+</archive>
diff --git a/client/iOS/Resources/SessionTableViewCell.xib b/client/iOS/Resources/SessionTableViewCell.xib
new file mode 100644 (file)
index 0000000..2e80c7c
--- /dev/null
@@ -0,0 +1,574 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="7.10">
+       <data>
+               <int key="IBDocument.SystemTarget">1296</int>
+               <string key="IBDocument.SystemVersion">11D50b</string>
+               <string key="IBDocument.InterfaceBuilderVersion">2182</string>
+               <string key="IBDocument.AppKitVersion">1138.32</string>
+               <string key="IBDocument.HIToolboxVersion">568.00</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                       <string key="NS.object.0">1179</string>
+               </object>
+               <object class="NSArray" key="IBDocument.IntegratedClassDependencies">
+                       <bool key="EncodedWithXMLCoder">YES</bool>
+                       <string>IBUITableViewCell</string>
+                       <string>IBUIImageView</string>
+                       <string>IBUILabel</string>
+                       <string>IBUIButton</string>
+                       <string>IBProxyObject</string>
+               </object>
+               <object class="NSArray" key="IBDocument.PluginDependencies">
+                       <bool key="EncodedWithXMLCoder">YES</bool>
+                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+               </object>
+               <object class="NSMutableDictionary" key="IBDocument.Metadata">
+                       <string key="NS.key.0">PluginDependencyRecalculationVersion</string>
+                       <integer value="1" key="NS.object.0"/>
+               </object>
+               <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+                       <bool key="EncodedWithXMLCoder">YES</bool>
+                       <object class="IBProxyObject" id="372490531">
+                               <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+                               <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+                       </object>
+                       <object class="IBProxyObject" id="975951072">
+                               <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+                               <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+                       </object>
+                       <object class="IBUITableViewCell" id="660975430">
+                               <reference key="NSNextResponder"/>
+                               <int key="NSvFlags">292</int>
+                               <object class="NSMutableArray" key="NSSubviews">
+                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                       <object class="IBUIView" id="64247618">
+                                               <reference key="NSNextResponder" ref="660975430"/>
+                                               <int key="NSvFlags">256</int>
+                                               <object class="NSMutableArray" key="NSSubviews">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <object class="IBUIImageView" id="60336238">
+                                                               <reference key="NSNextResponder" ref="64247618"/>
+                                                               <int key="NSvFlags">300</int>
+                                                               <string key="NSFrame">{{20, 12}, {63, 47}}</string>
+                                                               <reference key="NSSuperview" ref="64247618"/>
+                                                               <reference key="NSWindow"/>
+                                                               <reference key="NSNextKeyView" ref="695281447"/>
+                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                               <bool key="IBUIUserInteractionEnabled">NO</bool>
+                                                               <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+                                                       </object>
+                                                       <object class="IBUILabel" id="695281447">
+                                                               <reference key="NSNextResponder" ref="64247618"/>
+                                                               <int key="NSvFlags">290</int>
+                                                               <string key="NSFrame">{{91, 12}, {168, 21}}</string>
+                                                               <reference key="NSSuperview" ref="64247618"/>
+                                                               <reference key="NSWindow"/>
+                                                               <reference key="NSNextKeyView" ref="583414824"/>
+                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                               <bool key="IBUIOpaque">NO</bool>
+                                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                                               <int key="IBUIContentMode">7</int>
+                                                               <bool key="IBUIUserInteractionEnabled">NO</bool>
+                                                               <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+                                                               <string key="IBUIText">Label</string>
+                                                               <object class="NSColor" key="IBUITextColor" id="852118610">
+                                                                       <int key="NSColorSpace">1</int>
+                                                                       <bytes key="NSRGB">MCAwIDAAA</bytes>
+                                                               </object>
+                                                               <object class="NSColor" key="IBUIHighlightedColor" id="645846245">
+                                                                       <int key="NSColorSpace">3</int>
+                                                                       <bytes key="NSWhite">MQA</bytes>
+                                                               </object>
+                                                               <int key="IBUIBaselineAdjustment">0</int>
+                                                               <float key="IBUIMinimumFontSize">10</float>
+                                                               <object class="IBUIFontDescription" key="IBUIFontDescription">
+                                                                       <int key="type">2</int>
+                                                                       <double key="pointSize">18</double>
+                                                               </object>
+                                                               <object class="NSFont" key="IBUIFont">
+                                                                       <string key="NSName">Helvetica-Bold</string>
+                                                                       <double key="NSSize">18</double>
+                                                                       <int key="NSfFlags">16</int>
+                                                               </object>
+                                                               <bool key="IBUIAdjustsFontSizeToFit">NO</bool>
+                                                       </object>
+                                                       <object class="IBUILabel" id="583414824">
+                                                               <reference key="NSNextResponder" ref="64247618"/>
+                                                               <int key="NSvFlags">290</int>
+                                                               <string key="NSFrame">{{91, 25}, {168, 21}}</string>
+                                                               <reference key="NSSuperview" ref="64247618"/>
+                                                               <reference key="NSWindow"/>
+                                                               <reference key="NSNextKeyView" ref="597512619"/>
+                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                               <bool key="IBUIOpaque">NO</bool>
+                                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                                               <int key="IBUIContentMode">7</int>
+                                                               <bool key="IBUIUserInteractionEnabled">NO</bool>
+                                                               <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+                                                               <string key="IBUIText">Label</string>
+                                                               <reference key="IBUITextColor" ref="852118610"/>
+                                                               <reference key="IBUIHighlightedColor" ref="645846245"/>
+                                                               <int key="IBUIBaselineAdjustment">0</int>
+                                                               <float key="IBUIMinimumFontSize">10</float>
+                                                               <object class="IBUIFontDescription" key="IBUIFontDescription" id="263878792">
+                                                                       <int key="type">1</int>
+                                                                       <double key="pointSize">14</double>
+                                                               </object>
+                                                               <object class="NSFont" key="IBUIFont" id="649156643">
+                                                                       <string key="NSName">Helvetica</string>
+                                                                       <double key="NSSize">14</double>
+                                                                       <int key="NSfFlags">16</int>
+                                                               </object>
+                                                               <bool key="IBUIAdjustsFontSizeToFit">NO</bool>
+                                                       </object>
+                                                       <object class="IBUILabel" id="597512619">
+                                                               <reference key="NSNextResponder" ref="64247618"/>
+                                                               <int key="NSvFlags">290</int>
+                                                               <string key="NSFrame">{{91, 41}, {168, 21}}</string>
+                                                               <reference key="NSSuperview" ref="64247618"/>
+                                                               <reference key="NSWindow"/>
+                                                               <reference key="NSNextKeyView" ref="30378675"/>
+                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                               <bool key="IBUIOpaque">NO</bool>
+                                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                                               <int key="IBUIContentMode">7</int>
+                                                               <bool key="IBUIUserInteractionEnabled">NO</bool>
+                                                               <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+                                                               <string key="IBUIText">Label</string>
+                                                               <reference key="IBUITextColor" ref="852118610"/>
+                                                               <reference key="IBUIHighlightedColor" ref="645846245"/>
+                                                               <int key="IBUIBaselineAdjustment">0</int>
+                                                               <float key="IBUIMinimumFontSize">10</float>
+                                                               <reference key="IBUIFontDescription" ref="263878792"/>
+                                                               <reference key="IBUIFont" ref="649156643"/>
+                                                               <bool key="IBUIAdjustsFontSizeToFit">NO</bool>
+                                                       </object>
+                                                       <object class="IBUIButton" id="30378675">
+                                                               <reference key="NSNextResponder" ref="64247618"/>
+                                                               <int key="NSvFlags">297</int>
+                                                               <string key="NSFrame">{{267, 19}, {33, 33}}</string>
+                                                               <reference key="NSSuperview" ref="64247618"/>
+                                                               <reference key="NSWindow"/>
+                                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                               <bool key="IBUIOpaque">NO</bool>
+                                                               <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+                                                               <int key="IBUIContentHorizontalAlignment">0</int>
+                                                               <int key="IBUIContentVerticalAlignment">0</int>
+                                                               <int key="IBUIButtonType">1</int>
+                                                               <reference key="IBUIHighlightedTitleColor" ref="645846245"/>
+                                                               <object class="NSColor" key="IBUINormalTitleColor">
+                                                                       <int key="NSColorSpace">1</int>
+                                                                       <bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
+                                                               </object>
+                                                               <object class="NSColor" key="IBUINormalTitleShadowColor">
+                                                                       <int key="NSColorSpace">3</int>
+                                                                       <bytes key="NSWhite">MC41AA</bytes>
+                                                               </object>
+                                                               <object class="NSCustomResource" key="IBUINormalImage">
+                                                                       <string key="NSClassName">NSImage</string>
+                                                                       <string key="NSResourceName">toolbar_icon_disconnect.png</string>
+                                                               </object>
+                                                               <object class="NSCustomResource" key="IBUINormalBackgroundImage">
+                                                                       <string key="NSClassName">NSImage</string>
+                                                                       <string key="NSResourceName">cancel_button_background.png</string>
+                                                               </object>
+                                                               <object class="IBUIFontDescription" key="IBUIFontDescription">
+                                                                       <int key="type">2</int>
+                                                                       <double key="pointSize">15</double>
+                                                               </object>
+                                                               <object class="NSFont" key="IBUIFont">
+                                                                       <string key="NSName">Helvetica-Bold</string>
+                                                                       <double key="NSSize">15</double>
+                                                                       <int key="NSfFlags">16</int>
+                                                               </object>
+                                                       </object>
+                                               </object>
+                                               <string key="NSFrameSize">{320, 71}</string>
+                                               <reference key="NSSuperview" ref="660975430"/>
+                                               <reference key="NSWindow"/>
+                                               <reference key="NSNextKeyView" ref="60336238"/>
+                                               <string key="NSReuseIdentifierKey">_NS:11</string>
+                                               <object class="NSColor" key="IBUIBackgroundColor">
+                                                       <int key="NSColorSpace">3</int>
+                                                       <bytes key="NSWhite">MCAwAA</bytes>
+                                               </object>
+                                               <bool key="IBUIOpaque">NO</bool>
+                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                               <int key="IBUIContentMode">4</int>
+                                               <bool key="IBUIMultipleTouchEnabled">YES</bool>
+                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                       </object>
+                               </object>
+                               <string key="NSFrameSize">{320, 72}</string>
+                               <reference key="NSSuperview"/>
+                               <reference key="NSWindow"/>
+                               <reference key="NSNextKeyView" ref="64247618"/>
+                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                               <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+                               <reference key="IBUIContentView" ref="64247618"/>
+                               <real value="72" key="IBUIRowHeight"/>
+                       </object>
+               </object>
+               <object class="IBObjectContainer" key="IBDocument.Objects">
+                       <object class="NSMutableArray" key="connectionRecords">
+                               <bool key="EncodedWithXMLCoder">YES</bool>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">sessTableCell</string>
+                                               <reference key="source" ref="372490531"/>
+                                               <reference key="destination" ref="660975430"/>
+                                       </object>
+                                       <int key="connectionID">34</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_disconnect_button</string>
+                                               <reference key="source" ref="660975430"/>
+                                               <reference key="destination" ref="30378675"/>
+                                       </object>
+                                       <int key="connectionID">29</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_screenshot</string>
+                                               <reference key="source" ref="660975430"/>
+                                               <reference key="destination" ref="60336238"/>
+                                       </object>
+                                       <int key="connectionID">30</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_server</string>
+                                               <reference key="source" ref="660975430"/>
+                                               <reference key="destination" ref="583414824"/>
+                                       </object>
+                                       <int key="connectionID">31</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_title</string>
+                                               <reference key="source" ref="660975430"/>
+                                               <reference key="destination" ref="695281447"/>
+                                       </object>
+                                       <int key="connectionID">32</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_username</string>
+                                               <reference key="source" ref="660975430"/>
+                                               <reference key="destination" ref="597512619"/>
+                                       </object>
+                                       <int key="connectionID">33</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchEventConnection" key="connection">
+                                               <string key="label">disconnectButtonPressed:</string>
+                                               <reference key="source" ref="30378675"/>
+                                               <reference key="destination" ref="372490531"/>
+                                               <int key="IBEventType">7</int>
+                                       </object>
+                                       <int key="connectionID">35</int>
+                               </object>
+                       </object>
+                       <object class="IBMutableOrderedSet" key="objectRecords">
+                               <object class="NSArray" key="orderedObjects">
+                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">0</int>
+                                               <object class="NSArray" key="object" id="0">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                               </object>
+                                               <reference key="children" ref="1000"/>
+                                               <nil key="parent"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-1</int>
+                                               <reference key="object" ref="372490531"/>
+                                               <reference key="parent" ref="0"/>
+                                               <string key="objectName">File's Owner</string>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-2</int>
+                                               <reference key="object" ref="975951072"/>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">23</int>
+                                               <reference key="object" ref="660975430"/>
+                                               <object class="NSMutableArray" key="children">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <reference ref="695281447"/>
+                                                       <reference ref="597512619"/>
+                                                       <reference ref="583414824"/>
+                                                       <reference ref="60336238"/>
+                                                       <reference ref="30378675"/>
+                                               </object>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">24</int>
+                                               <reference key="object" ref="695281447"/>
+                                               <reference key="parent" ref="660975430"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">25</int>
+                                               <reference key="object" ref="60336238"/>
+                                               <reference key="parent" ref="660975430"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">26</int>
+                                               <reference key="object" ref="583414824"/>
+                                               <reference key="parent" ref="660975430"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">27</int>
+                                               <reference key="object" ref="597512619"/>
+                                               <reference key="parent" ref="660975430"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">28</int>
+                                               <reference key="object" ref="30378675"/>
+                                               <reference key="parent" ref="660975430"/>
+                                       </object>
+                               </object>
+                       </object>
+                       <object class="NSMutableDictionary" key="flattenedProperties">
+                               <bool key="EncodedWithXMLCoder">YES</bool>
+                               <object class="NSArray" key="dict.sortedKeys">
+                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                       <string>-1.CustomClassName</string>
+                                       <string>-1.IBPluginDependency</string>
+                                       <string>-2.CustomClassName</string>
+                                       <string>-2.IBPluginDependency</string>
+                                       <string>23.CustomClassName</string>
+                                       <string>23.IBPluginDependency</string>
+                                       <string>24.IBPluginDependency</string>
+                                       <string>25.IBPluginDependency</string>
+                                       <string>26.IBPluginDependency</string>
+                                       <string>27.IBPluginDependency</string>
+                                       <string>28.IBPluginDependency</string>
+                               </object>
+                               <object class="NSArray" key="dict.values">
+                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                       <string>BookmarkListController</string>
+                                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                                       <string>UIResponder</string>
+                                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                                       <string>SessionTableCell</string>
+                                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               </object>
+                       </object>
+                       <object class="NSMutableDictionary" key="unlocalizedProperties">
+                               <bool key="EncodedWithXMLCoder">YES</bool>
+                               <reference key="dict.sortedKeys" ref="0"/>
+                               <reference key="dict.values" ref="0"/>
+                       </object>
+                       <nil key="activeLocalization"/>
+                       <object class="NSMutableDictionary" key="localizations">
+                               <bool key="EncodedWithXMLCoder">YES</bool>
+                               <reference key="dict.sortedKeys" ref="0"/>
+                               <reference key="dict.values" ref="0"/>
+                       </object>
+                       <nil key="sourceID"/>
+                       <int key="maxID">35</int>
+               </object>
+               <object class="IBClassDescriber" key="IBDocument.Classes">
+                       <object class="NSMutableArray" key="referencedPartialClassDescriptions">
+                               <bool key="EncodedWithXMLCoder">YES</bool>
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">BookmarkListController</string>
+                                       <string key="superclassName">UIViewController</string>
+                                       <object class="NSMutableDictionary" key="outlets">
+                                               <bool key="EncodedWithXMLCoder">YES</bool>
+                                               <object class="NSArray" key="dict.sortedKeys">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <string>bmTableCell</string>
+                                                       <string>searchBar</string>
+                                                       <string>sessTableCell</string>
+                                                       <string>tableView</string>
+                                               </object>
+                                               <object class="NSArray" key="dict.values">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <string>BookmarkTableCell</string>
+                                                       <string>UISearchBar</string>
+                                                       <string>SessionTableCell</string>
+                                                       <string>UITableView</string>
+                                               </object>
+                                       </object>
+                                       <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <bool key="EncodedWithXMLCoder">YES</bool>
+                                               <object class="NSArray" key="dict.sortedKeys">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <string>bmTableCell</string>
+                                                       <string>searchBar</string>
+                                                       <string>sessTableCell</string>
+                                                       <string>tableView</string>
+                                               </object>
+                                               <object class="NSArray" key="dict.values">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">bmTableCell</string>
+                                                               <string key="candidateClassName">BookmarkTableCell</string>
+                                                       </object>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">searchBar</string>
+                                                               <string key="candidateClassName">UISearchBar</string>
+                                                       </object>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">sessTableCell</string>
+                                                               <string key="candidateClassName">SessionTableCell</string>
+                                                       </object>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">tableView</string>
+                                                               <string key="candidateClassName">UITableView</string>
+                                                       </object>
+                                               </object>
+                                       </object>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/BookmarkListController.h</string>
+                                       </object>
+                               </object>
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">BookmarkTableCell</string>
+                                       <string key="superclassName">UITableViewCell</string>
+                                       <object class="NSMutableDictionary" key="outlets">
+                                               <bool key="EncodedWithXMLCoder">YES</bool>
+                                               <object class="NSArray" key="dict.sortedKeys">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <string>_connection_state_icon</string>
+                                                       <string>_sub_title</string>
+                                                       <string>_title</string>
+                                               </object>
+                                               <object class="NSArray" key="dict.values">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <string>UIImageView</string>
+                                                       <string>UILabel</string>
+                                                       <string>UILabel</string>
+                                               </object>
+                                       </object>
+                                       <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <bool key="EncodedWithXMLCoder">YES</bool>
+                                               <object class="NSArray" key="dict.sortedKeys">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <string>_connection_state_icon</string>
+                                                       <string>_sub_title</string>
+                                                       <string>_title</string>
+                                               </object>
+                                               <object class="NSArray" key="dict.values">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">_connection_state_icon</string>
+                                                               <string key="candidateClassName">UIImageView</string>
+                                                       </object>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">_sub_title</string>
+                                                               <string key="candidateClassName">UILabel</string>
+                                                       </object>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">_title</string>
+                                                               <string key="candidateClassName">UILabel</string>
+                                                       </object>
+                                               </object>
+                                       </object>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/BookmarkTableCell.h</string>
+                                       </object>
+                               </object>
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">SessionTableCell</string>
+                                       <string key="superclassName">UITableViewCell</string>
+                                       <object class="NSMutableDictionary" key="outlets">
+                                               <bool key="EncodedWithXMLCoder">YES</bool>
+                                               <object class="NSArray" key="dict.sortedKeys">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <string>_disconnect_button</string>
+                                                       <string>_screenshot</string>
+                                                       <string>_server</string>
+                                                       <string>_title</string>
+                                                       <string>_username</string>
+                                               </object>
+                                               <object class="NSArray" key="dict.values">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <string>UIButton</string>
+                                                       <string>UIImageView</string>
+                                                       <string>UILabel</string>
+                                                       <string>UILabel</string>
+                                                       <string>UILabel</string>
+                                               </object>
+                                       </object>
+                                       <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <bool key="EncodedWithXMLCoder">YES</bool>
+                                               <object class="NSArray" key="dict.sortedKeys">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <string>_disconnect_button</string>
+                                                       <string>_screenshot</string>
+                                                       <string>_server</string>
+                                                       <string>_title</string>
+                                                       <string>_username</string>
+                                               </object>
+                                               <object class="NSArray" key="dict.values">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">_disconnect_button</string>
+                                                               <string key="candidateClassName">UIButton</string>
+                                                       </object>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">_screenshot</string>
+                                                               <string key="candidateClassName">UIImageView</string>
+                                                       </object>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">_server</string>
+                                                               <string key="candidateClassName">UILabel</string>
+                                                       </object>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">_title</string>
+                                                               <string key="candidateClassName">UILabel</string>
+                                                       </object>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">_username</string>
+                                                               <string key="candidateClassName">UILabel</string>
+                                                       </object>
+                                               </object>
+                                       </object>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/SessionTableCell.h</string>
+                                       </object>
+                               </object>
+                       </object>
+               </object>
+               <int key="IBDocument.localizationMode">0</int>
+               <string key="IBDocument.TargetRuntimeIdentifier">IBIPadFramework</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+                       <real value="1296" key="NS.object.0"/>
+               </object>
+               <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
+                       <integer value="3100" key="NS.object.0"/>
+               </object>
+               <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+               <int key="IBDocument.defaultPropertyAccessControl">3</int>
+               <object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
+                       <bool key="EncodedWithXMLCoder">YES</bool>
+                       <object class="NSArray" key="dict.sortedKeys">
+                               <bool key="EncodedWithXMLCoder">YES</bool>
+                               <string>cancel_button_background.png</string>
+                               <string>toolbar_icon_disconnect.png</string>
+                       </object>
+                       <object class="NSArray" key="dict.values">
+                               <bool key="EncodedWithXMLCoder">YES</bool>
+                               <string>{63, 33}</string>
+                               <string>{24, 24}</string>
+                       </object>
+               </object>
+               <string key="IBCocoaTouchPluginVersion">1179</string>
+       </data>
+</archive>
diff --git a/client/iOS/Resources/VerifyCertificateView.xib b/client/iOS/Resources/VerifyCertificateView.xib
new file mode 100644 (file)
index 0000000..eb97205
--- /dev/null
@@ -0,0 +1,386 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
+       <data>
+               <int key="IBDocument.SystemTarget">1296</int>
+               <string key="IBDocument.SystemVersion">11D50b</string>
+               <string key="IBDocument.InterfaceBuilderVersion">2182</string>
+               <string key="IBDocument.AppKitVersion">1138.32</string>
+               <string key="IBDocument.HIToolboxVersion">568.00</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                       <string key="NS.object.0">1179</string>
+               </object>
+               <array key="IBDocument.IntegratedClassDependencies">
+                       <string>IBUIButton</string>
+                       <string>IBUIView</string>
+                       <string>IBUILabel</string>
+                       <string>IBProxyObject</string>
+               </array>
+               <array key="IBDocument.PluginDependencies">
+                       <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+               </array>
+               <object class="NSMutableDictionary" key="IBDocument.Metadata">
+                       <string key="NS.key.0">PluginDependencyRecalculationVersion</string>
+                       <integer value="1" key="NS.object.0"/>
+               </object>
+               <array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+                       <object class="IBProxyObject" id="372490531">
+                               <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                       </object>
+                       <object class="IBProxyObject" id="975951072">
+                               <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                       </object>
+                       <object class="IBUIView" id="191373211">
+                               <reference key="NSNextResponder"/>
+                               <int key="NSvFlags">319</int>
+                               <array class="NSMutableArray" key="NSSubviews">
+                                       <object class="IBUIButton" id="683207246">
+                                               <reference key="NSNextResponder" ref="191373211"/>
+                                               <int key="NSvFlags">291</int>
+                                               <string key="NSFrame">{{152, 237}, {95, 37}}</string>
+                                               <reference key="NSSuperview" ref="191373211"/>
+                                               <reference key="NSWindow"/>
+                                               <bool key="IBUIOpaque">NO</bool>
+                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                               <int key="IBUIContentHorizontalAlignment">0</int>
+                                               <int key="IBUIContentVerticalAlignment">0</int>
+                                               <int key="IBUIButtonType">1</int>
+                                               <string key="IBUINormalTitle">No</string>
+                                               <object class="NSColor" key="IBUIHighlightedTitleColor" id="1032157260">
+                                                       <int key="NSColorSpace">3</int>
+                                                       <bytes key="NSWhite">MQA</bytes>
+                                               </object>
+                                               <object class="NSColor" key="IBUINormalTitleColor">
+                                                       <int key="NSColorSpace">1</int>
+                                                       <bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
+                                               </object>
+                                               <object class="NSColor" key="IBUINormalTitleShadowColor" id="417359316">
+                                                       <int key="NSColorSpace">3</int>
+                                                       <bytes key="NSWhite">MC41AA</bytes>
+                                               </object>
+                                               <object class="IBUIFontDescription" key="IBUIFontDescription" id="733176724">
+                                                       <string key="name">Helvetica-Bold</string>
+                                                       <string key="family">Helvetica</string>
+                                                       <int key="traits">2</int>
+                                                       <double key="pointSize">15</double>
+                                               </object>
+                                               <object class="NSFont" key="IBUIFont" id="197322835">
+                                                       <string key="NSName">Helvetica-Bold</string>
+                                                       <double key="NSSize">15</double>
+                                                       <int key="NSfFlags">16</int>
+                                               </object>
+                                       </object>
+                                       <object class="IBUIButton" id="985957052">
+                                               <reference key="NSNextResponder" ref="191373211"/>
+                                               <int key="NSvFlags">294</int>
+                                               <string key="NSFrame">{{20, 237}, {95, 37}}</string>
+                                               <reference key="NSSuperview" ref="191373211"/>
+                                               <reference key="NSWindow"/>
+                                               <reference key="NSNextKeyView" ref="683207246"/>
+                                               <bool key="IBUIOpaque">NO</bool>
+                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                               <int key="IBUIContentHorizontalAlignment">0</int>
+                                               <int key="IBUIContentVerticalAlignment">0</int>
+                                               <int key="IBUIButtonType">1</int>
+                                               <string key="IBUINormalTitle">Yes</string>
+                                               <reference key="IBUIHighlightedTitleColor" ref="1032157260"/>
+                                               <object class="NSColor" key="IBUINormalTitleColor">
+                                                       <int key="NSColorSpace">1</int>
+                                                       <bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
+                                               </object>
+                                               <reference key="IBUINormalTitleShadowColor" ref="417359316"/>
+                                               <reference key="IBUIFontDescription" ref="733176724"/>
+                                               <reference key="IBUIFont" ref="197322835"/>
+                                       </object>
+                                       <object class="IBUILabel" id="830896437">
+                                               <reference key="NSNextResponder" ref="191373211"/>
+                                               <int key="NSvFlags">290</int>
+                                               <string key="NSFrame">{{20, 20}, {227, 94}}</string>
+                                               <reference key="NSSuperview" ref="191373211"/>
+                                               <reference key="NSWindow"/>
+                                               <reference key="NSNextKeyView" ref="485908522"/>
+                                               <bool key="IBUIOpaque">NO</bool>
+                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                               <int key="IBUIContentMode">7</int>
+                                               <bool key="IBUIUserInteractionEnabled">NO</bool>
+                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                               <string key="IBUIText">The identity of the remote computer cannot be verified. Do you want to connect anyway?</string>
+                                               <object class="NSColor" key="IBUITextColor" id="232026869">
+                                                       <int key="NSColorSpace">1</int>
+                                                       <bytes key="NSRGB">MCAwIDAAA</bytes>
+                                               </object>
+                                               <nil key="IBUIHighlightedColor"/>
+                                               <int key="IBUIBaselineAdjustment">1</int>
+                                               <float key="IBUIMinimumFontSize">10</float>
+                                               <int key="IBUINumberOfLines">4</int>
+                                               <int key="IBUILineBreakMode">0</int>
+                                               <object class="IBUIFontDescription" key="IBUIFontDescription" id="820193683">
+                                                       <int key="type">1</int>
+                                                       <double key="pointSize">17</double>
+                                               </object>
+                                               <object class="NSFont" key="IBUIFont" id="784496446">
+                                                       <string key="NSName">Helvetica</string>
+                                                       <double key="NSSize">17</double>
+                                                       <int key="NSfFlags">16</int>
+                                               </object>
+                                       </object>
+                                       <object class="IBUILabel" id="485908522">
+                                               <reference key="NSNextResponder" ref="191373211"/>
+                                               <int key="NSvFlags">294</int>
+                                               <string key="NSFrame">{{20, 136}, {59, 21}}</string>
+                                               <reference key="NSSuperview" ref="191373211"/>
+                                               <reference key="NSWindow"/>
+                                               <reference key="NSNextKeyView" ref="23899749"/>
+                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                               <bool key="IBUIOpaque">NO</bool>
+                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                               <int key="IBUIContentMode">7</int>
+                                               <bool key="IBUIUserInteractionEnabled">NO</bool>
+                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                               <string key="IBUIText">Issuer:</string>
+                                               <reference key="IBUITextColor" ref="232026869"/>
+                                               <nil key="IBUIHighlightedColor"/>
+                                               <int key="IBUIBaselineAdjustment">0</int>
+                                               <float key="IBUIMinimumFontSize">10</float>
+                                               <reference key="IBUIFontDescription" ref="820193683"/>
+                                               <reference key="IBUIFont" ref="784496446"/>
+                                       </object>
+                                       <object class="IBUILabel" id="23899749">
+                                               <reference key="NSNextResponder" ref="191373211"/>
+                                               <int key="NSvFlags">291</int>
+                                               <string key="NSFrame">{{87, 136}, {160, 21}}</string>
+                                               <reference key="NSSuperview" ref="191373211"/>
+                                               <reference key="NSWindow"/>
+                                               <reference key="NSNextKeyView" ref="985957052"/>
+                                               <string key="NSReuseIdentifierKey">_NS:9</string>
+                                               <bool key="IBUIOpaque">NO</bool>
+                                               <bool key="IBUIClipsSubviews">YES</bool>
+                                               <int key="IBUIContentMode">7</int>
+                                               <bool key="IBUIUserInteractionEnabled">NO</bool>
+                                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                                               <string key="IBUIText">Label</string>
+                                               <reference key="IBUITextColor" ref="232026869"/>
+                                               <nil key="IBUIHighlightedColor"/>
+                                               <int key="IBUIBaselineAdjustment">0</int>
+                                               <float key="IBUIMinimumFontSize">10</float>
+                                               <reference key="IBUIFontDescription" ref="820193683"/>
+                                               <reference key="IBUIFont" ref="784496446"/>
+                                       </object>
+                               </array>
+                               <string key="NSFrameSize">{267, 294}</string>
+                               <reference key="NSSuperview"/>
+                               <reference key="NSWindow"/>
+                               <reference key="NSNextKeyView" ref="830896437"/>
+                               <object class="NSColor" key="IBUIBackgroundColor">
+                                       <int key="NSColorSpace">3</int>
+                                       <bytes key="NSWhite">MQA</bytes>
+                                       <object class="NSColorSpace" key="NSCustomColorSpace">
+                                               <int key="NSID">2</int>
+                                       </object>
+                               </object>
+                               <object class="IBUISimulatedSizeMetrics" key="IBUISimulatedDestinationMetrics">
+                                       <string key="IBUISimulatedSizeMetricsClass">IBUISimulatedFreeformSizeMetricsSentinel</string>
+                                       <string key="IBUIDisplayName">Freeform</string>
+                               </object>
+                               <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+                       </object>
+               </array>
+               <object class="IBObjectContainer" key="IBDocument.Objects">
+                       <array class="NSMutableArray" key="connectionRecords">
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">view</string>
+                                               <reference key="source" ref="372490531"/>
+                                               <reference key="destination" ref="191373211"/>
+                                       </object>
+                                       <int key="connectionID">8</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_btn_accept</string>
+                                               <reference key="source" ref="372490531"/>
+                                               <reference key="destination" ref="985957052"/>
+                                       </object>
+                                       <int key="connectionID">9</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_btn_decline</string>
+                                               <reference key="source" ref="372490531"/>
+                                               <reference key="destination" ref="683207246"/>
+                                       </object>
+                                       <int key="connectionID">10</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_label_issuer</string>
+                                               <reference key="source" ref="372490531"/>
+                                               <reference key="destination" ref="23899749"/>
+                                       </object>
+                                       <int key="connectionID">11</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_label_message</string>
+                                               <reference key="source" ref="372490531"/>
+                                               <reference key="destination" ref="830896437"/>
+                                       </object>
+                                       <int key="connectionID">14</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchOutletConnection" key="connection">
+                                               <string key="label">_label_for_issuer</string>
+                                               <reference key="source" ref="372490531"/>
+                                               <reference key="destination" ref="485908522"/>
+                                       </object>
+                                       <int key="connectionID">16</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchEventConnection" key="connection">
+                                               <string key="label">declinePressed:</string>
+                                               <reference key="source" ref="683207246"/>
+                                               <reference key="destination" ref="372490531"/>
+                                               <int key="IBEventType">7</int>
+                                       </object>
+                                       <int key="connectionID">13</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBCocoaTouchEventConnection" key="connection">
+                                               <string key="label">acceptPressed:</string>
+                                               <reference key="source" ref="985957052"/>
+                                               <reference key="destination" ref="372490531"/>
+                                               <int key="IBEventType">7</int>
+                                       </object>
+                                       <int key="connectionID">12</int>
+                               </object>
+                       </array>
+                       <object class="IBMutableOrderedSet" key="objectRecords">
+                               <array key="orderedObjects">
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">0</int>
+                                               <array key="object" id="0"/>
+                                               <reference key="children" ref="1000"/>
+                                               <nil key="parent"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">1</int>
+                                               <reference key="object" ref="191373211"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="830896437"/>
+                                                       <reference ref="485908522"/>
+                                                       <reference ref="23899749"/>
+                                                       <reference ref="985957052"/>
+                                                       <reference ref="683207246"/>
+                                               </array>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-1</int>
+                                               <reference key="object" ref="372490531"/>
+                                               <reference key="parent" ref="0"/>
+                                               <string key="objectName">File's Owner</string>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-2</int>
+                                               <reference key="object" ref="975951072"/>
+                                               <reference key="parent" ref="0"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">3</int>
+                                               <reference key="object" ref="683207246"/>
+                                               <reference key="parent" ref="191373211"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">4</int>
+                                               <reference key="object" ref="985957052"/>
+                                               <reference key="parent" ref="191373211"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">5</int>
+                                               <reference key="object" ref="830896437"/>
+                                               <reference key="parent" ref="191373211"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">6</int>
+                                               <reference key="object" ref="485908522"/>
+                                               <reference key="parent" ref="191373211"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">7</int>
+                                               <reference key="object" ref="23899749"/>
+                                               <reference key="parent" ref="191373211"/>
+                                       </object>
+                               </array>
+                       </object>
+                       <dictionary class="NSMutableDictionary" key="flattenedProperties">
+                               <string key="-1.CustomClassName">VerifyCertificateController</string>
+                               <string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="-2.CustomClassName">UIResponder</string>
+                               <string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="3.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="4.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="5.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="6.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                               <string key="7.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+                       </dictionary>
+                       <dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
+                       <nil key="activeLocalization"/>
+                       <dictionary class="NSMutableDictionary" key="localizations"/>
+                       <nil key="sourceID"/>
+                       <int key="maxID">16</int>
+               </object>
+               <object class="IBClassDescriber" key="IBDocument.Classes">
+                       <array class="NSMutableArray" key="referencedPartialClassDescriptions">
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">VerifyCertificateController</string>
+                                       <string key="superclassName">UIViewController</string>
+                                       <dictionary class="NSMutableDictionary" key="outlets">
+                                               <string key="_btn_accept">UIButton</string>
+                                               <string key="_btn_decline">UIButton</string>
+                                               <string key="_label_for_issuer">UILabel</string>
+                                               <string key="_label_issuer">UILabel</string>
+                                               <string key="_label_message">UILabel</string>
+                                       </dictionary>
+                                       <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <object class="IBToOneOutletInfo" key="_btn_accept">
+                                                       <string key="name">_btn_accept</string>
+                                                       <string key="candidateClassName">UIButton</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_btn_decline">
+                                                       <string key="name">_btn_decline</string>
+                                                       <string key="candidateClassName">UIButton</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_label_for_issuer">
+                                                       <string key="name">_label_for_issuer</string>
+                                                       <string key="candidateClassName">UILabel</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_label_issuer">
+                                                       <string key="name">_label_issuer</string>
+                                                       <string key="candidateClassName">UILabel</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="_label_message">
+                                                       <string key="name">_label_message</string>
+                                                       <string key="candidateClassName">UILabel</string>
+                                               </object>
+                                       </dictionary>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/VerifyCertificateController.h</string>
+                                       </object>
+                               </object>
+                       </array>
+               </object>
+               <int key="IBDocument.localizationMode">0</int>
+               <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+                       <real value="1296" key="NS.object.0"/>
+               </object>
+               <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+               <int key="IBDocument.defaultPropertyAccessControl">3</int>
+               <string key="IBCocoaTouchPluginVersion">1179</string>
+       </data>
+</archive>
diff --git a/client/iOS/Resources/about_page/FreeRDP_Logo.png b/client/iOS/Resources/about_page/FreeRDP_Logo.png
new file mode 100755 (executable)
index 0000000..3b2d02f
Binary files /dev/null and b/client/iOS/Resources/about_page/FreeRDP_Logo.png differ
diff --git a/client/iOS/Resources/about_page/about.html b/client/iOS/Resources/about_page/about.html
new file mode 100755 (executable)
index 0000000..6ee406d
--- /dev/null
@@ -0,0 +1,203 @@
+<html>
+       <head>
+               <meta name='viewport' content='width=device-width; initial-scale=1.0; maximum-scale=1.0;' />
+        
+              <script language="javascript"> 
+function toggle() {
+       var ele = document.getElementById("toggleText");
+       var text = document.getElementById("displayText");
+       if(ele.style.display == "block") {
+               ele.style.display = "none";
+               text.innerHTML = "show";
+       }
+       else {
+               ele.style.display = "block";
+               text.innerHTML = "<b>hide</b>";
+       }
+} 
+</script>
+
+        <style type="text/css">
+        @charset "utf-8";
+body {
+       font: 100%%/1.4 Helvetica;
+       background-color:#E9EBF8;
+       height: 100%%; width: 100%%; margin: 0;
+       background-image:url(back.jpg);
+       background-position:center;
+
+       text-align:center;
+}
+
+.centered-table {
+  margin-left: auto;
+       margin-right: auto;
+}
+
+#headline{
+
+  background-color:#353639;
+  opacity:0.9;
+
+  color:FFF;
+  text-align:center;
+
+
+       }
+       
+       #footer{
+       padding-top:10px;
+       }
+       
+#footer img{
+       padding top:10 px;
+       }
+#article{
+
+
+background-color:#FFFFFF;
+opacity: 0.8;
+z-index:0;
+margin-bottom:3%%;
+padding-bottom:0.1%%;
+border-radius: 15px;
+border-top-left-radius:0px;
+border-top-right-radius:0px;
+color:#000;
+margin: 10px auto;
+position:relative;
+
+       }
+       
+       
+#introduction_headline{
+  width:inherit;
+  background-color:#353639;
+  opacity:0.9;
+  color:FFF;
+  text-align:center;
+  border-bottom-left-radius:15px;
+  border-bottom-right-radius:15px;
+
+
+       }
+       
+#introduction{
+
+
+background-color:#FFFFFF;
+opacity: 0.8;
+z-index:0;
+margin-bottom:3%%;
+padding-bottom:0.1%%;
+border-radius: 10px;
+color:#000;
+       }
+       
+#container
+{
+       margin-left: auto;
+       margin-right: auto;
+       width: 50em;
+       width:420px;
+}
+/* ~~ Element/tag selectors ~~ */
+ul, ol, dl { /* Due to variations between browsers, it's best practices to zero padding and margin on lists. For consistency, you can either specify the amounts you want here, or on the list items (LI, DT, DD) they contain. Remember that what you do here will cascade to the .nav list unless you write a more specific selector. */
+       padding: 0;
+       margin: 0;
+}
+h1, h2, h3, h4, h5, h6, p {
+       margin-top: 0;   /* removing the top margin gets around an issue where margins can escape from their containing div. The remaining bottom margin will hold it away from any elements that follow. */
+       padding-right: 1px;
+       padding-left: 1px; /* adding the padding to the sides of the elements within the divs, instead of the divs themselves, gets rid of any box model math. A nested div with side padding can also be used as an alternate method. */
+}
+a img { /* this selector removes the default blue border displayed in some browsers around an image when it is surrounded by a link */
+       border: none;
+       alignment: right;}
+}
+
+/* ~~ Styling for your site's links must remain in this order - including the group of selectors that create the hover effect. ~~ */
+/*a:link {
+       color:#414958;
+       text-decoration: underline;  unless you style your links to look extremely unique, it's best to provide underlines for quick visual identification */
+
+
+a:hover, a:active, a:focus { /* this group of selectors will give a keyboard navigator the same hover experience as the person using a mouse. */
+       text-decoration: none;}
+
+
+
+       
+       a:link { color:#0000FF; }
+
+
+
+* {
+    -webkit-touch-callout: none;
+    -webkit-user-select: none; /* Disable selection/Copy of UIWebView */
+}
+
+
+
+       </style>
+       </head>
+       <body>
+    
+
+
+
+       <div id="container">
+       
+       
+       <div id="introduction_headline"> 
+       <h2>iFreeRDP </br>Remote Desktop Client</h2>
+       </div>
+    <p>
+    <img src="FreeRDP_Logo.png" width="30%%"></p>
+        <div id="introduction">
+        
+               iFreeRDP is an open source client
+               capable of natively using Remote Desktop Protocol (RDP) in order to remotely access your Windows desktop.</div>
+               
+        
+               <div id="article">
+               <div id="headline"><h3>Version Information</h3></div>
+        <p>
+               <table class="centered-table" border=0 cellspacing=1 cellpadding=3  >
+                       <tr>    
+            <td>iFreeRDP Version</td>          <td>%@</td>             </tr>
+                       <tr>    <td>System Name</td>                    <td>%@</td>             </tr>
+                       <tr>    <td>System Version</td>                 <td>%@</td>             </tr>
+                       <tr>    <td>Model</td>                                  <td>%@</td>             </tr>
+               </table>
+        </p>
+               </div>
+<div id="article">
+
+            <div id="headline">
+                               <h3>Credits</h3>
+            </div>
+
+                       iFreeRDP is a part of  <a href="http://www.freerdp.com/">FreeRDP</a>
+               
+</div>
+
+<div id="article"> 
+               <div id="headline">
+               <h3>License</h3>
+        </div>
+             
+               This program is free software; you can redistribute it and/or modify it under the terms of the Mozilla Public License, v. 2.0.
+        You can obtain an online version of the License from <a href="http://mozilla.org/MPL/2.0/">http://mozilla.org/MPL/2.0/</a>.
+               </p>
+               <p>
+               This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+               MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+               </p>
+               <p>
+               A copy of the product's source code can be obtained from the FreeRDP GitHub repository at <a
+               href="https://github.com/FreeRDP/FreeRDP">https://github.com/FreeRDP/FreeRDP</a>.<br />
+               </p>
+        <br></div>
+       </body>
+</html>
diff --git a/client/iOS/Resources/about_page/about_phone.html b/client/iOS/Resources/about_page/about_phone.html
new file mode 100755 (executable)
index 0000000..7e40ef2
--- /dev/null
@@ -0,0 +1,201 @@
+<html>
+       <head>
+               <meta name='viewport' content='width=device-width; initial-scale=1.0; maximum-scale=1.0;' />
+        
+       <script language="javascript"> 
+function toggle() {
+       var ele = document.getElementById("toggleText");
+       var text = document.getElementById("displayText");
+       if(ele.style.display == "block") {
+               ele.style.display = "none";
+               text.innerHTML = "show";
+       }
+       else {
+               ele.style.display = "block";
+               text.innerHTML = "<b>hide</b>";
+       }
+} 
+</script>
+        
+        <style type="text/css">
+        @charset "utf-8";
+body {
+       font: 100%%/1 Helvetica;
+       background-color:#E9EBF8;
+       height: 100%%; width: 100%%; margin: 0;
+       background-image:url(back.jpg);
+       background-position:center;
+
+       text-align:center;
+}
+
+.centered-table {
+  margin-left: auto;
+       margin-right: auto;
+}
+
+#headline{
+
+  background-color:#353639;
+  opacity:0.9;
+
+  color:FFF;
+  text-align:center;
+
+
+       }
+       
+       #footer{
+       padding-top:10px;
+       }
+       
+#footer img{
+       padding top:10 px;
+       }
+#article{
+
+
+background-color:#FFFFFF;
+opacity: 0.8;
+z-index:0;
+margin-bottom:3%%;
+padding-bottom:0.1%%;
+border-radius: 15px;
+border-top-left-radius:0px;
+border-top-right-radius:0px;
+color:#000;
+margin: 10px auto;
+position:relative;
+
+       }
+       
+       
+#introduction_headline{
+  width:inherit;
+  background-color:#353639;
+  opacity:0.9;
+  color:FFF;
+  text-align:center;
+  border-bottom-left-radius:15px;
+  border-bottom-right-radius:15px;
+
+
+       }
+       
+#introduction{
+
+
+background-color:#FFFFFF;
+opacity: 0.8;
+z-index:0;
+margin-bottom:3%%;
+padding-bottom:0.1%%;
+border-radius: 10px;
+color:#000;
+       }
+       
+#container
+{
+       margin-left: auto;
+       margin-right: auto;
+       
+       width:300px;
+}
+/* ~~ Element/tag selectors ~~ */
+ul, ol, dl { /* Due to variations between browsers, it's best practices to zero padding and margin on lists. For consistency, you can either specify the amounts you want here, or on the list items (LI, DT, DD) they contain. Remember that what you do here will cascade to the .nav list unless you write a more specific selector. */
+       padding: 0;
+       margin: 0;
+}
+h1, h2, h3, h4, h5, h6, p {
+       margin-top: 0;   /* removing the top margin gets around an issue where margins can escape from their containing div. The remaining bottom margin will hold it away from any elements that follow. */
+       padding-right: 1px;
+       padding-left: 1px; /* adding the padding to the sides of the elements within the divs, instead of the divs themselves, gets rid of any box model math. A nested div with side padding can also be used as an alternate method. */
+}
+a img { /* this selector removes the default blue border displayed in some browsers around an image when it is surrounded by a link */
+       border: none;
+       alignment: right;}
+}
+
+/* ~~ Styling for your site's links must remain in this order - including the group of selectors that create the hover effect. ~~ */
+/*a:link {
+       color:#414958;
+       text-decoration: underline;  unless you style your links to look extremely unique, it's best to provide underlines for quick visual identification */
+
+
+a:hover, a:active, a:focus { /* this group of selectors will give a keyboard navigator the same hover experience as the person using a mouse. */
+       text-decoration: none;}
+
+
+
+       
+       a:link { color:#0000FF; }
+
+
+
+* {
+    -webkit-touch-callout: none;
+    -webkit-user-select: none; /* Disable selection/Copy of UIWebView */
+}
+
+
+
+}
+
+       </style>
+       </head>
+       <body>
+    
+
+
+
+       <div id="container">
+       
+       
+       <div id="introduction_headline"> 
+       <h2>iFreeRDP</br>Remote Desktop Client</h2>
+       </div>
+    <p>
+               <img src="FreeRDP_Logo.png" width="25%%"></p>
+        <div id="introduction">
+        
+               <b>iFreeRDP</b> is an open source client for Windows Remote Services using Remote Desktop Protocol (RDP) in order to remotely access your Windows desktop.</div>
+               
+        
+               <div id="article">
+               <div id="headline"><h3>Version Information</h3></div>
+        <p>
+               <table class="centered-table" border=0 cellspacing=1 cellpadding=3  >
+                       <tr>    
+                       <td>iFreerdp Version</td>               <td>%@</td>             </tr>
+                       <tr>    <td>System Name</td>                    <td>%@</td>             </tr>
+                       <tr>    <td>System Version</td>                 <td>%@</td>             </tr>
+                       <tr>    <td>Model</td>                                  <td>%@</td>             </tr>
+               </table>
+        </p>
+               </div>
+<div id="article">
+
+            <div id="headline">
+                               <h3>Credits</h3>
+            </div>
+                       iFreeRDP is part of <a href="http://www.freerdp.com/">FreeRDP</a>
+</div>
+<div id="article"> 
+               <div id="headline">
+               <h3>License</h3>
+        </div>
+             
+               This program is free software; you can redistribute it and/or modify it under the terms of the Mozilla Public License, v. 2.0.
+        You can obtain an online version of the License from <a href="http://mozilla.org/MPL/2.0/">http://mozilla.org/MPL/2.0/</a>.
+               </p>
+               <p>
+               This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+               MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+               </p>
+               <p>
+               A copy of the product's source code can be obtained from the FreeRDP GitHub repository at <a
+               href="https://github.com/FreeRDP/FreeRDP">https://github.com/FreeRDP/FreeRDP</a>.<br />
+               </p> </div>
+        </div>
+       </body>
+</html>
diff --git a/client/iOS/Resources/about_page/back.jpg b/client/iOS/Resources/about_page/back.jpg
new file mode 100755 (executable)
index 0000000..3bf3455
Binary files /dev/null and b/client/iOS/Resources/about_page/back.jpg differ
diff --git a/client/iOS/Resources/about_page/background_transparent.png b/client/iOS/Resources/about_page/background_transparent.png
new file mode 100755 (executable)
index 0000000..0eba5b5
Binary files /dev/null and b/client/iOS/Resources/about_page/background_transparent.png differ
diff --git a/client/iOS/Resources/cancel_button_background.png b/client/iOS/Resources/cancel_button_background.png
new file mode 100644 (file)
index 0000000..ae12d40
Binary files /dev/null and b/client/iOS/Resources/cancel_button_background.png differ
diff --git a/client/iOS/Resources/en.lproj/Localizable.strings b/client/iOS/Resources/en.lproj/Localizable.strings
new file mode 100644 (file)
index 0000000..3c0f663
Binary files /dev/null and b/client/iOS/Resources/en.lproj/Localizable.strings differ
diff --git a/client/iOS/Resources/help_page/back.jpg b/client/iOS/Resources/help_page/back.jpg
new file mode 100755 (executable)
index 0000000..3bf3455
Binary files /dev/null and b/client/iOS/Resources/help_page/back.jpg differ
diff --git a/client/iOS/Resources/help_page/gestures.html b/client/iOS/Resources/help_page/gestures.html
new file mode 100755 (executable)
index 0000000..8583877
--- /dev/null
@@ -0,0 +1,159 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">\r
+\r
+<html>\r
+\r
+<head>\r
+<meta charset="utf-8">\r
+<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0;" /> \r
+<title>Help</title>\r
+\r
+<style type="text/css">\r
+\r
+@charset "utf-8";\r
+\r
+\r
+#container{\r
+       \r
+       text-align:center;\r
+       }\r
+\r
+body{\r
+  margin:0;\r
+  padding:<length> 0 0 0;\r
+  font: 100%/1.4 Helvetica;\r
+  background-image:url(back.jpg);\r
+  background-position:center;\r
+  color:#000;\r
+\r
\r
+ }\r
\r
+ #headline{\r
+\r
+  background-color:#353639;\r
+  opacity:0.9;\r
+\r
+  color:#000;\r
+  text-align:center;\r
+\r
+\r
+       }\r
\r
+ #article{\r
+\r
+\r
+background-color:#FFFFFF;\r
+opacity: 0.8;\r
+z-index:0;\r
+margin-bottom:3%;\r
+padding-bottom:0.1%;\r
+border-radius: 15px;\r
+border-top-left-radius:0px;\r
+border-top-right-radius:0px;\r
+color:#000;\r
+margin: 10px auto;\r
+position:relative;\r
+\r
+\r
+       }\r
\r
+#header{\r
+\r
+  height:auto;\r
+  width:100%;\r
+  background-color:#353639;\r
+  padding-bottom:5px;\r
+  padding-left:5px;\r
+  padding-right:5px;\r
+  padding-top:10px;    \r
+  position: fixed;\r
+  top: 0;\r
+  left: 0;\r
+  height:40px;\r
+  overflow:visible;\r
+  min-width:400px;\r
+  z-index:20;\r
+  \r
+  \r
+ }\r
\r
+\r
+\r
+\r
+#content{\r
+       padding-top:70px;\r
+       z-index:-20;\r
+       max-width:420px;\r
+       \r
+       }\r
+       \r
+\r
+\r
+/* ~~ Element/tag selectors ~~ */\r
+ul, ol, dl { /* Due to variations between browsers, it's best practices to zero padding and margin on lists. For consistency, you can either specify the amounts you want here, or on the list items (LI, DT, DD) they contain. Remember that what you do here will cascade to the .nav list unless you write a more specific selector. */\r
+       padding: 0;\r
+       margin: 0;\r
+}\r
+\r
+h1, h2, h3, h4, h5, h6, p {\r
+       margin-top: 0;   /* removing the top margin gets around an issue where margins can escape from their containing div. The remaining bottom margin will hold it away from any elements that follow. */\r
+       padding-right: 1px;\r
+       padding-left: 1px; /* adding the padding to the sides of the elements within the divs, instead of the divs themselves, gets rid of any box model math. A nested div with side padding can also be used as an alternate method.\r
+ */\r
+ color:#000;\r
\r
+}\r
+\r
+a img { /* this selector removes the default blue border displayed in some browsers around an image when it is surrounded by a link */\r
+       border: none;\r
+       \r
+}\r
+\r
+/* ~~ Styling for your site's links must remain in this order - including the group of selectors that create the hover effect. ~~ */\r
+/*a:link {\r
+       color:#414958;\r
+       text-decoration: underline;  unless you style your links to look extremely unique, it's best to provide underlines for quick visual identification */\r
+\r
+\r
+a:hover, a:active, a:focus { /* this group of selectors will give a keyboard navigator the same hover experience as the person using a mouse. */\r
+       text-decoration: none;}\r
+\r
+\r
+* {\r
+    -webkit-touch-callout: none;\r
+    -webkit-user-select: none; /* Disable selection/Copy of UIWebView */\r
+}\r
+\r
+\r
+\r
+\r
+       \r
+       \r
+</style>\r
+\r
+\r
+\r
+</head>\r
+\r
+<body>\r
+<div id="container">\r
+<center>\r
+<div id="header">\r
+       <a href="gestures.html"><img src="nav_gestures.png"></a>\r
+       <a href="toolbar.html"><img src="nav_toolbar.png"></a>\r
+       <a href="touch_pointer.html"><img src="nav_touch_pointer.png"></a>\r
+\r
+</div>\r
+\r
+<div id="content"> \r
+<h1>Gestures</h1>\r
+<p>\r
+aFreeRDP is designed for touch sensitive devices.\r
+These gestures let you do the most usual operations with your fingers.</p>\r
+<p>  <img src="gestures.png"></p>\r
+\r
+</div>\r
+</div>\r
+\r
+</body>\r
+</html>\r
diff --git a/client/iOS/Resources/help_page/gestures.png b/client/iOS/Resources/help_page/gestures.png
new file mode 100755 (executable)
index 0000000..e49a45b
Binary files /dev/null and b/client/iOS/Resources/help_page/gestures.png differ
diff --git a/client/iOS/Resources/help_page/gestures_phone.html b/client/iOS/Resources/help_page/gestures_phone.html
new file mode 100755 (executable)
index 0000000..156d7c9
--- /dev/null
@@ -0,0 +1,159 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">\r
+\r
+<html>\r
+\r
+<head>\r
+<meta charset="utf-8">\r
+<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0;" /> \r
+<title>Help</title>\r
+\r
+<style type="text/css">\r
+\r
+@charset "utf-8";\r
+\r
+\r
+#container{\r
+       \r
+       text-align:center;\r
+       color:#000;}\r
+\r
+body{\r
+  margin:0;\r
+  padding:<length> 0 0 0;\r
+  font: 100% Helvetica;\r
+  background-image:url(back.jpg);\r
+  background-position:center;\r
+\r
\r
+ }\r
\r
+ #headline{\r
+\r
+  background-color:#353639;\r
+  opacity:0.9;\r
+\r
+  color:FFF;\r
+  text-align:center;\r
+\r
+\r
+       }\r
\r
+ #article{\r
+\r
+\r
+background-color:#FFFFFF;\r
+opacity: 0.8;\r
+z-index:0;\r
+margin-bottom:3%;\r
+padding-bottom:0.1%;\r
+border-radius: 15px;\r
+border-top-left-radius:0px;\r
+border-top-right-radius:0px;\r
+color:#000;\r
+margin: 10px auto;\r
+position:relative;\r
+\r
+\r
+       }\r
\r
+#header{\r
+\r
+  \r
+  width:100%;\r
+  background-color:#353639;\r
+  padding-bottom:1px;\r
+  padding-left:5px;\r
+  padding-right:5px;\r
+  padding-top:5px;     \r
+  position: fixed;\r
+  top: 0;\r
+  left: 0;\r
+  height:30px;\r
+  \r
+  min-width:250px;\r
+  z-index:20;\r
+  \r
+  \r
+ }\r
\r
+\r
+\r
+\r
+#content{\r
+       padding-top:40px;\r
+       z-index:-20;\r
+       max-width:300px;\r
+       \r
+       }\r
+       \r
+/* ~~ Element/tag selectors ~~ */\r
+ul, ol, dl { /* Due to variations between browsers, it's best practices to zero padding and margin on lists. For consistency, you can either specify the amounts you want here, or on the list items (LI, DT, DD) they contain. Remember that what you do here will cascade to the .nav list unless you write a more specific selector. */\r
+       padding: 0;\r
+       margin: 0;\r
+}\r
+\r
+h1, h2, h3, h4, h5, h6, p {\r
+       margin-top: 0;   /* removing the top margin gets around an issue where margins can escape from their containing div. The remaining bottom margin will hold it away from any elements that follow. */\r
+       padding-right: 1px;\r
+       padding-left: 1px; /* adding the padding to the sides of the elements within the divs, instead of the divs themselves, gets rid of any box model math. A nested div with side padding can also be used as an alternate method.\r
+ */\r
+ color:#000;\r
\r
+}\r
+\r
+a img { /* this selector removes the default blue border displayed in some browsers around an image when it is surrounded by a link */\r
+       border: none;\r
+       \r
+}\r
+\r
+/* ~~ Styling for your site's links must remain in this order - including the group of selectors that create the hover effect. ~~ */\r
+/*a:link {\r
+       color:#414958;\r
+       text-decoration: underline;  unless you style your links to look extremely unique, it's best to provide underlines for quick visual identification */\r
+\r
+\r
+a:hover, a:active, a:focus { /* this group of selectors will give a keyboard navigator the same hover experience as the person using a mouse. */\r
+       text-decoration: none;}\r
+\r
+\r
+* {\r
+    -webkit-touch-callout: none;\r
+    -webkit-user-select: none; /* Disable selection/Copy of UIWebView */\r
+}\r
+\r
+\r
+\r
+       \r
+</style>\r
+\r
+\r
+\r
+</head>\r
+\r
+\r
+\r
+\r
+<body>\r
+<div id="container">\r
+<center>\r
+<div id="header">\r
+\r
+<a href="gestures_phone.html"><img src="nav_gestures.png" height="90%"></a>\r
+       <a href="toolbar_phone.html"><img src="nav_toolbar.png" height="90%"></a>\r
+       <a href="touch_pointer_phone.html"><img src="nav_touch_pointer.png" height="90%""></a>\r
+\r
+</div>\r
+\r
+<div id="content"> \r
+<h2> Gestures</h2>\r
+<p>\r
+aFreeRDP is designed for touch sensitive devices.\r
+These gestures let you do the most usual operations with your fingers.</p>\r
+<p>  <img src="gestures_phone.png"></p>\r
+\r
+\r
+</div>\r
+</div>\r
+\r
+</body>\r
+</html>\r
diff --git a/client/iOS/Resources/help_page/gestures_phone.png b/client/iOS/Resources/help_page/gestures_phone.png
new file mode 100755 (executable)
index 0000000..1b90a1f
Binary files /dev/null and b/client/iOS/Resources/help_page/gestures_phone.png differ
diff --git a/client/iOS/Resources/help_page/nav_gestures.png b/client/iOS/Resources/help_page/nav_gestures.png
new file mode 100755 (executable)
index 0000000..ab1b36f
Binary files /dev/null and b/client/iOS/Resources/help_page/nav_gestures.png differ
diff --git a/client/iOS/Resources/help_page/nav_toolbar.png b/client/iOS/Resources/help_page/nav_toolbar.png
new file mode 100755 (executable)
index 0000000..703c001
Binary files /dev/null and b/client/iOS/Resources/help_page/nav_toolbar.png differ
diff --git a/client/iOS/Resources/help_page/nav_touch_pointer.png b/client/iOS/Resources/help_page/nav_touch_pointer.png
new file mode 100755 (executable)
index 0000000..30e0456
Binary files /dev/null and b/client/iOS/Resources/help_page/nav_touch_pointer.png differ
diff --git a/client/iOS/Resources/help_page/toolbar.html b/client/iOS/Resources/help_page/toolbar.html
new file mode 100755 (executable)
index 0000000..e9ea27a
--- /dev/null
@@ -0,0 +1,178 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">\r
+\r
+<html>\r
+\r
+<head>\r
+<meta charset="utf-8">\r
+<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0;" /> \r
+<title>Help</title>\r
+\r
+<style type="text/css">\r
+\r
+@charset "utf-8";\r
+\r
+\r
+#container{\r
+       \r
+       text-align:center;\r
+       color:#FFFFFF;}\r
+\r
+body{\r
+  margin:0;\r
+  padding:<length> 0 0 0;\r
+  font: 100%/1.4 Helvetica;\r
+  background-image:url(back.jpg);\r
+  background-position:center;\r
+\r
\r
+ }\r
\r
+ #headline{\r
+\r
+  background-color:#353639;\r
+  \r
+\r
+  color:#FFF;\r
+  text-align:center;\r
+\r
+\r
+       }\r
\r
+ #article{\r
+\r
+\r
+background-color:#FFFFFF;\r
+opacity: 0.8;\r
+z-index:0;\r
+margin-bottom:3%;\r
+padding-bottom:0.1%;\r
+border-radius: 15px;\r
+border-top-left-radius:0px;\r
+border-top-right-radius:0px;\r
+color:#000;\r
+margin: 10px auto;\r
+position:relative;\r
+\r
+\r
+       }\r
\r
+#header{\r
+\r
+  height:auto;\r
+  width:100%;\r
+  background-color:#353639;\r
+  padding-bottom:5px;\r
+  padding-left:5px;\r
+  padding-right:5px;\r
+  padding-top:10px;    \r
+  position: fixed;\r
+  top: 0;\r
+  left: 0;\r
+  height:40px;\r
+  overflow:visible;\r
+  min-width:400px;\r
+  z-index:20;\r
+  \r
+  \r
+ }\r
\r
+\r
+\r
+\r
+#content{\r
+       padding-top:70px;\r
+       z-index:-20;\r
+       max-width:420px;\r
+       \r
+       }\r
+       \r
+\r
+/* ~~ Element/tag selectors ~~ */\r
+ul, ol, dl { /* Due to variations between browsers, it's best practices to zero padding and margin on lists. For consistency, you can either specify the amounts you want here, or on the list items (LI, DT, DD) they contain. Remember that what you do here will cascade to the .nav list unless you write a more specific selector. */\r
+       padding: 0;\r
+       margin: 0;\r
+}\r
+\r
+h1, h2, h3, h4, h5, h6, p {\r
+       margin-top: 0;   /* removing the top margin gets around an issue where margins can escape from their containing div. The remaining bottom margin will hold it away from any elements that follow. */\r
+       padding-right: 1px;\r
+       padding-left: 1px; /* adding the padding to the sides of the elements within the divs, instead of the divs themselves, gets rid of any box model math. A nested div with side padding can also be used as an alternate method.\r
+ */\r
+color:#000;\r
\r
+}\r
+\r
+a img { /* this selector removes the default blue border displayed in some browsers around an image when it is surrounded by a link */\r
+       border: none;\r
+       \r
+}\r
+\r
+/* ~~ Styling for your site's links must remain in this order - including the group of selectors that create the hover effect. ~~ */\r
+/*a:link {\r
+       color:#414958;\r
+       text-decoration: underline;  unless you style your links to look extremely unique, it's best to provide underlines for quick visual identification */\r
+\r
+\r
+a:hover, a:active, a:focus { /* this group of selectors will give a keyboard navigator the same hover experience as the person using a mouse. */\r
+       text-decoration: none;}\r
+\r
+\r
+* {\r
+    -webkit-touch-callout: none;\r
+    -webkit-user-select: none; /* Disable selection/Copy of UIWebView */\r
+}\r
+\r
+\r
+\r
+\r
+       \r
+       \r
+</style>\r
+\r
+\r
+\r
+</head>\r
+\r
+\r
+\r
+\r
+<body>\r
+<div id="container">\r
+\r
+\r
+<center>\r
+\r
+\r
+<div id="header">\r
+\r
+       <a href="gestures.html"><img src="nav_gestures.png"></a>\r
+       <a href="toolbar.html"><img src="nav_toolbar.png"></a>\r
+       <a href="touch_pointer.html"><img src="nav_touch_pointer.png"></a>\r
+\r
+</div>\r
+\r
+<div id="content"> \r
+\r
+<h1>Toolbar</h1>\r
+<p>\r
+With the toolbar you'll be able to display and hide the main tools in your session. This allows together with the touch pointer and the gestures an intuitiv workflow for remote computing on touch sensitive screens. \r
+</p>\r
+<p><img src="toolbar.png"></p>\r
+\r
+<div id="article">\r
+<div id="headline">\r
+<h3><span style="color:white">Keyboards</span></h3></div>\r
+Display/hide the default keyboard as well as an extended keyboard with function keys</div>\r
+<div id="article">\r
+<div id="headline"><h3><span style="color:white">Touch Pointer</span></h3></div>\r
+Display/hide the gesture controlled cursor</div>\r
+<div id="article">\r
+<div id="headline"><h3><span style="color:white">Disconnect</span></h3></div>\r
+Disconnect your current session. Please be aware that a disconnect is not the same as a log out.</div>\r
+\r
+</div>\r
+\r
+\r
+</div></center>\r
+</body>\r
+</html>\r
diff --git a/client/iOS/Resources/help_page/toolbar.png b/client/iOS/Resources/help_page/toolbar.png
new file mode 100755 (executable)
index 0000000..10c23b6
Binary files /dev/null and b/client/iOS/Resources/help_page/toolbar.png differ
diff --git a/client/iOS/Resources/help_page/toolbar_phone.html b/client/iOS/Resources/help_page/toolbar_phone.html
new file mode 100755 (executable)
index 0000000..f810d4b
--- /dev/null
@@ -0,0 +1,176 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">\r
+\r
+<html>\r
+\r
+<head>\r
+<meta charset="utf-8">\r
+<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0;" /> \r
+<title>Help</title>\r
+\r
+<style type="text/css">\r
+\r
+@charset "utf-8";\r
+\r
+\r
+#container{\r
+       \r
+       text-align:center;\r
+       color:#FFFFFF;}\r
+\r
+body{\r
+  margin:0;\r
+  padding:<length> 0 0 0;\r
+  font: 100% Helvetica;\r
+  background-image:url(back.jpg);\r
+  background-position:center;\r
+\r
\r
+ }\r
\r
+ #headline{\r
+\r
+  background-color:#353639;\r
+  opacity:0.9;\r
+\r
+  color:FFF;\r
+  text-align:center;\r
+\r
+\r
+       }\r
\r
+ #article{\r
+\r
+\r
+background-color:#FFFFFF;\r
+opacity: 0.8;\r
+z-index:0;\r
+margin-bottom:3%;\r
+padding-bottom:0.1%;\r
+border-radius: 15px;\r
+border-top-left-radius:0px;\r
+border-top-right-radius:0px;\r
+color:#000;\r
+margin: 10px auto;\r
+position:relative;\r
+\r
+\r
+       }\r
\r
+#header{\r
+\r
+  \r
+  width:100%;\r
+  background-color:#353639;\r
+  padding-bottom:1px;\r
+  padding-left:5px;\r
+  padding-right:5px;\r
+  padding-top:5px;     \r
+  position: fixed;\r
+  top: 0;\r
+  left: 0;\r
+  height:30px;\r
+  \r
+  min-width:250px;\r
+  z-index:20;\r
+  \r
+  \r
+ }\r
\r
+\r
+\r
+\r
+#content{\r
+       padding-top:40px;\r
+       z-index:-20;\r
+       max-width:300px;\r
+       \r
+       }\r
+       \r
+\r
+/* ~~ Element/tag selectors ~~ */\r
+ul, ol, dl { /* Due to variations between browsers, it's best practices to zero padding and margin on lists. For consistency, you can either specify the amounts you want here, or on the list items (LI, DT, DD) they contain. Remember that what you do here will cascade to the .nav list unless you write a more specific selector. */\r
+       padding: 0;\r
+       margin: 0;\r
+}\r
+\r
+h1, h2, h3, h4, h5, h6, p {\r
+       margin-top: 0;   /* removing the top margin gets around an issue where margins can escape from their containing div. The remaining bottom margin will hold it away from any elements that follow. */\r
+       padding-right: 1px;\r
+       padding-left: 1px; /* adding the padding to the sides of the elements within the divs, instead of the divs themselves, gets rid of any box model math. A nested div with side padding can also be used as an alternate method.\r
+ */\r
+color:#000;\r
\r
+}\r
+\r
+a img { /* this selector removes the default blue border displayed in some browsers around an image when it is surrounded by a link */\r
+       border: none;\r
+       \r
+}\r
+\r
+/* ~~ Styling for your site's links must remain in this order - including the group of selectors that create the hover effect. ~~ */\r
+/*a:link {\r
+       color:#414958;\r
+       text-decoration: underline;  unless you style your links to look extremely unique, it's best to provide underlines for quick visual identification */\r
+\r
+\r
+a:hover, a:active, a:focus { /* this group of selectors will give a keyboard navigator the same hover experience as the person using a mouse. */\r
+       text-decoration: none;}\r
+\r
+\r
+* {\r
+    -webkit-touch-callout: none;\r
+    -webkit-user-select: none; /* Disable selection/Copy of UIWebView */\r
+}\r
+\r
+\r
+\r
+       \r
+</style>\r
+\r
+\r
+\r
+</head>\r
+\r
+\r
+\r
+\r
+<body>\r
+<div id="container">\r
+\r
+\r
+<center>\r
+\r
+\r
+<div id="header">\r
+\r
+<a href="gestures_phone.html"><img src="nav_gestures.png" height="90%"></a>\r
+       <a href="toolbar_phone.html"><img src="nav_toolbar.png" height="90%"></a>\r
+       <a href="touch_pointer_phone.html"><img src="nav_touch_pointer.png" height="90%""></a>\r
+\r
+</div>\r
+\r
+<div id="content"> \r
+\r
+<h2>Toolbar</h2>\r
+<p>\r
+With the toolbar you'll be able to display and hide the main tools in your session. This allows together with the touch pointer and the gestures an intuitiv workflow for remote computing on touch sensitive screens. \r
+</p>\r
+<p><img src="toolbar_phone.png"></p>\r
+\r
+<div id="article">\r
+<div id="headline">\r
+<h4><span style="color:white">Keyboards</h4></span></div>\r
+Display/hide the default keyboard as well as an extended keyboard with function keys</div>\r
+<div id="article">\r
+<div id="headline"><h4><span style="color:white">Touch Pointer</h4></div>\r
+Display/hide the gesture controlled cursor</div></span>\r
+<div id="article">\r
+<div id="headline"><h4><span style="color:white">Disconnect</span></h4></div>\r
+Disconnect your current session. Please be aware that a disconnect is not the same as a log out.</div>\r
+\r
+</div>\r
+\r
+\r
+</div></center>\r
+</body>\r
+</html>\r
diff --git a/client/iOS/Resources/help_page/toolbar_phone.png b/client/iOS/Resources/help_page/toolbar_phone.png
new file mode 100755 (executable)
index 0000000..a01279c
Binary files /dev/null and b/client/iOS/Resources/help_page/toolbar_phone.png differ
diff --git a/client/iOS/Resources/help_page/touch_pointer.html b/client/iOS/Resources/help_page/touch_pointer.html
new file mode 100755 (executable)
index 0000000..8072a1b
--- /dev/null
@@ -0,0 +1,164 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">\r
+\r
+<html>\r
+\r
+<head>\r
+<meta charset="utf-8">\r
+<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0;" /> \r
+<title>Help</title>\r
+\r
+<style type="text/css">\r
+\r
+@charset "utf-8";\r
+\r
+\r
+#container{\r
+       \r
+       text-align:center;\r
+       color:#FFFFFF;}\r
+\r
+body{\r
+  margin:0;\r
+  padding:<length> 0 0 0;\r
+  font: 100%/1.4 Helvetica;\r
+  background-image:url(back.jpg);\r
+  background-position:center;\r
+\r
\r
+ }\r
\r
+ #headline{\r
+\r
+  background-color:#353639;\r
+  opacity:0.9;\r
+\r
+  color:FFF;\r
+  text-align:center;\r
+\r
+\r
+       }\r
\r
+ #article{\r
+\r
+\r
+background-color:#FFFFFF;\r
+opacity: 0.8;\r
+z-index:0;\r
+margin-bottom:3%;\r
+padding-bottom:0.1%;\r
+border-radius: 15px;\r
+border-top-left-radius:0px;\r
+border-top-right-radius:0px;\r
+color:#000;\r
+margin: 10px auto;\r
+position:relative;\r
+\r
+\r
+       }\r
\r
+#header{\r
+\r
+  height:auto;\r
+  width:100%;\r
+  background-color:#353639;\r
+  padding-bottom:5px;\r
+  padding-left:5px;\r
+  padding-right:5px;\r
+  padding-top:10px;    \r
+  position: fixed;\r
+  top: 0;\r
+  left: 0;\r
+  height:40px;\r
+  overflow:visible;\r
+  min-width:400px;\r
+  z-index:20;\r
+  \r
+  \r
+ }\r
\r
+\r
+\r
+\r
+#content{\r
+       padding-top:70px;\r
+       z-index:-20;\r
+       max-width:420px;\r
+       \r
+       }\r
+       \r
+\r
+/* ~~ Element/tag selectors ~~ */\r
+ul, ol, dl { /* Due to variations between browsers, it's best practices to zero padding and margin on lists. For consistency, you can either specify the amounts you want here, or on the list items (LI, DT, DD) they contain. Remember that what you do here will cascade to the .nav list unless you write a more specific selector. */\r
+       padding: 0;\r
+       margin: 0;\r
+}\r
+\r
+h1, h2, h3, h4, h5, h6, p {\r
+       margin-top: 0;   /* removing the top margin gets around an issue where margins can escape from their containing div. The remaining bottom margin will hold it away from any elements that follow. */\r
+       padding-right: 1px;\r
+       padding-left: 1px; /* adding the padding to the sides of the elements within the divs, instead of the divs themselves, gets rid of any box model math. A nested div with side padding can also be used as an alternate method.\r
+ */\r
+ color:#000;\r
\r
+}\r
+\r
+a img { /* this selector removes the default blue border displayed in some browsers around an image when it is surrounded by a link */\r
+       border: none;\r
+       \r
+}\r
+\r
+/* ~~ Styling for your site's links must remain in this order - including the group of selectors that create the hover effect. ~~ */\r
+/*a:link {\r
+       color:#414958;\r
+       text-decoration: underline;  unless you style your links to look extremely unique, it's best to provide underlines for quick visual identification */\r
+\r
+\r
+a:hover, a:active, a:focus { /* this group of selectors will give a keyboard navigator the same hover experience as the person using a mouse. */\r
+       text-decoration: none;}\r
+\r
+\r
+* {\r
+    -webkit-touch-callout: none;\r
+    -webkit-user-select: none; /* Disable selection/Copy of UIWebView */\r
+}\r
+\r
+\r
+\r
+\r
+       \r
+       \r
+</style>\r
+\r
+\r
+\r
+</head>\r
+\r
+\r
+\r
+\r
+<body>\r
+<div id="container">\r
+\r
+\r
+<center>\r
+\r
+\r
+<div id="header">\r
+\r
+       <a href="gestures.html"><img src="nav_gestures.png"></a>\r
+       <a href="toolbar.html"><img src="nav_toolbar.png"></a>\r
+       <a href="touch_pointer.html"><img src="nav_touch_pointer.png"></a>\r
+\r
+</div>\r
+\r
+<div id="content"> \r
+\r
+<h1>Touch Pointer</h1>\r
+<p><img src="touch_pointer.png">\r
+</div>\r
+\r
+</center>\r
+</div>\r
+\r
+</body>\r
+</html>\r
diff --git a/client/iOS/Resources/help_page/touch_pointer.png b/client/iOS/Resources/help_page/touch_pointer.png
new file mode 100755 (executable)
index 0000000..f06e388
Binary files /dev/null and b/client/iOS/Resources/help_page/touch_pointer.png differ
diff --git a/client/iOS/Resources/help_page/touch_pointer_phone.html b/client/iOS/Resources/help_page/touch_pointer_phone.html
new file mode 100755 (executable)
index 0000000..89d2e8d
--- /dev/null
@@ -0,0 +1,161 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">\r
+\r
+<html>\r
+\r
+<head>\r
+<meta charset="utf-8">\r
+<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0;" /> \r
+<title>Help</title>\r
+\r
+<style type="text/css">\r
+\r
+@charset "utf-8";\r
+\r
+\r
+#container{\r
+       \r
+       text-align:center;\r
+       color:#FFFFFF;}\r
+\r
+body{\r
+  margin:0;\r
+  padding:<length> 0 0 0;\r
+  font: 100% Helvetica;\r
+  background-image:url(back.jpg);\r
+  background-position:center;\r
+\r
\r
+ }\r
\r
+ #headline{\r
+\r
+  background-color:#353639;\r
+  opacity:0.9;\r
+\r
+  color:FFF;\r
+  text-align:center;\r
+\r
+\r
+       }\r
\r
+ #article{\r
+\r
+\r
+background-color:#FFFFFF;\r
+opacity: 0.8;\r
+z-index:0;\r
+margin-bottom:3%;\r
+padding-bottom:0.1%;\r
+border-radius: 15px;\r
+border-top-left-radius:0px;\r
+border-top-right-radius:0px;\r
+color:#000;\r
+margin: 10px auto;\r
+position:relative;\r
+\r
+\r
+       }\r
\r
+#header{\r
+\r
+  \r
+  width:100%;\r
+  background-color:#353639;\r
+  padding-bottom:1px;\r
+  padding-left:5px;\r
+  padding-right:5px;\r
+  padding-top:5px;     \r
+  position: fixed;\r
+  top: 0;\r
+  left: 0;\r
+  height:30px;\r
+  \r
+  min-width:250px;\r
+  z-index:20;\r
+  \r
+  \r
+ }\r
\r
+\r
+#content{\r
+       padding-top:40px;\r
+       z-index:-20;\r
+       max-width:300px;\r
+       \r
+       }\r
+       \r
+\r
+/* ~~ Element/tag selectors ~~ */\r
+ul, ol, dl { /* Due to variations between browsers, it's best practices to zero padding and margin on lists. For consistency, you can either specify the amounts you want here, or on the list items (LI, DT, DD) they contain. Remember that what you do here will cascade to the .nav list unless you write a more specific selector. */\r
+       padding: 0;\r
+       margin: 0;\r
+}\r
+\r
+h1, h2, h3, h4, h5, h6, p {\r
+       margin-top: 0;   /* removing the top margin gets around an issue where margins can escape from their containing div. The remaining bottom margin will hold it away from any elements that follow. */\r
+       padding-right: 1px;\r
+       padding-left: 1px; /* adding the padding to the sides of the elements within the divs, instead of the divs themselves, gets rid of any box model math. A nested div with side padding can also be used as an alternate method.\r
+ */\r
+color:#000;\r
\r
+}\r
+\r
+a img { /* this selector removes the default blue border displayed in some browsers around an image when it is surrounded by a link */\r
+       border: none;\r
+       \r
+}\r
+\r
+/* ~~ Styling for your site's links must remain in this order - including the group of selectors that create the hover effect. ~~ */\r
+/*a:link {\r
+       color:#414958;\r
+       text-decoration: underline;  unless you style your links to look extremely unique, it's best to provide underlines for quick visual identification */\r
+\r
+\r
+a:hover, a:active, a:focus { /* this group of selectors will give a keyboard navigator the same hover experience as the person using a mouse. */\r
+       text-decoration: none;}\r
+\r
+\r
+* {\r
+    -webkit-touch-callout: none;\r
+    -webkit-user-select: none; /* Disable selection/Copy of UIWebView */\r
+}\r
+\r
+\r
+\r
+       \r
+</style>\r
+\r
+\r
+\r
+</head>\r
+\r
+\r
+\r
+\r
+<body>\r
+<div id="container">\r
+\r
+\r
+<center>\r
+\r
+\r
+<div id="header">\r
+\r
+<a href="gestures_phone.html"><img src="nav_gestures.png" height="90%"></a>\r
+       <a href="toolbar_phone.html"><img src="nav_toolbar.png" height="90%"></a>\r
+       <a href="touch_pointer_phone.html"><img src="nav_touch_pointer.png" height="90%""></a>\r
+\r
+</div>\r
+\r
+<div id="content"> \r
+\r
+<h2>Touch Pointer</h2>\r
+<p><img src="touch_pointer_phone.png">\r
+</p>\r
+</div>\r
+\r
+</center>\r
+</div>\r
+\r
+</body>\r
+</html>\r
diff --git a/client/iOS/Resources/help_page/touch_pointer_phone.png b/client/iOS/Resources/help_page/touch_pointer_phone.png
new file mode 100755 (executable)
index 0000000..168749f
Binary files /dev/null and b/client/iOS/Resources/help_page/touch_pointer_phone.png differ
diff --git a/client/iOS/Resources/icon_accessory_star_off.png b/client/iOS/Resources/icon_accessory_star_off.png
new file mode 100755 (executable)
index 0000000..f0f1eb8
Binary files /dev/null and b/client/iOS/Resources/icon_accessory_star_off.png differ
diff --git a/client/iOS/Resources/icon_accessory_star_on.png b/client/iOS/Resources/icon_accessory_star_on.png
new file mode 100755 (executable)
index 0000000..cf5ed35
Binary files /dev/null and b/client/iOS/Resources/icon_accessory_star_on.png differ
diff --git a/client/iOS/Resources/icon_key_arrow_down.png b/client/iOS/Resources/icon_key_arrow_down.png
new file mode 100755 (executable)
index 0000000..3baf19c
Binary files /dev/null and b/client/iOS/Resources/icon_key_arrow_down.png differ
diff --git a/client/iOS/Resources/icon_key_arrow_left.png b/client/iOS/Resources/icon_key_arrow_left.png
new file mode 100755 (executable)
index 0000000..4c0c8eb
Binary files /dev/null and b/client/iOS/Resources/icon_key_arrow_left.png differ
diff --git a/client/iOS/Resources/icon_key_arrow_right.png b/client/iOS/Resources/icon_key_arrow_right.png
new file mode 100755 (executable)
index 0000000..10c7d8e
Binary files /dev/null and b/client/iOS/Resources/icon_key_arrow_right.png differ
diff --git a/client/iOS/Resources/icon_key_arrow_up.png b/client/iOS/Resources/icon_key_arrow_up.png
new file mode 100755 (executable)
index 0000000..b8e3f28
Binary files /dev/null and b/client/iOS/Resources/icon_key_arrow_up.png differ
diff --git a/client/iOS/Resources/icon_key_arrows.png b/client/iOS/Resources/icon_key_arrows.png
new file mode 100755 (executable)
index 0000000..56c9153
Binary files /dev/null and b/client/iOS/Resources/icon_key_arrows.png differ
diff --git a/client/iOS/Resources/icon_key_backspace.png b/client/iOS/Resources/icon_key_backspace.png
new file mode 100755 (executable)
index 0000000..7e9d295
Binary files /dev/null and b/client/iOS/Resources/icon_key_backspace.png differ
diff --git a/client/iOS/Resources/icon_key_menu.png b/client/iOS/Resources/icon_key_menu.png
new file mode 100755 (executable)
index 0000000..0b44452
Binary files /dev/null and b/client/iOS/Resources/icon_key_menu.png differ
diff --git a/client/iOS/Resources/icon_key_return.png b/client/iOS/Resources/icon_key_return.png
new file mode 100755 (executable)
index 0000000..9311ad1
Binary files /dev/null and b/client/iOS/Resources/icon_key_return.png differ
diff --git a/client/iOS/Resources/icon_key_win.png b/client/iOS/Resources/icon_key_win.png
new file mode 100755 (executable)
index 0000000..1ab7b2b
Binary files /dev/null and b/client/iOS/Resources/icon_key_win.png differ
diff --git a/client/iOS/Resources/keyboard_button_background.png b/client/iOS/Resources/keyboard_button_background.png
new file mode 100755 (executable)
index 0000000..c6cd579
Binary files /dev/null and b/client/iOS/Resources/keyboard_button_background.png differ
diff --git a/client/iOS/Resources/tabbar_icon_about.png b/client/iOS/Resources/tabbar_icon_about.png
new file mode 100755 (executable)
index 0000000..8d03924
Binary files /dev/null and b/client/iOS/Resources/tabbar_icon_about.png differ
diff --git a/client/iOS/Resources/tabbar_icon_help.png b/client/iOS/Resources/tabbar_icon_help.png
new file mode 100755 (executable)
index 0000000..0732b7d
Binary files /dev/null and b/client/iOS/Resources/tabbar_icon_help.png differ
diff --git a/client/iOS/Resources/tabbar_icon_settings.png b/client/iOS/Resources/tabbar_icon_settings.png
new file mode 100755 (executable)
index 0000000..04578f0
Binary files /dev/null and b/client/iOS/Resources/tabbar_icon_settings.png differ
diff --git a/client/iOS/Resources/toolbar_icon_disconnect.png b/client/iOS/Resources/toolbar_icon_disconnect.png
new file mode 100755 (executable)
index 0000000..cb823d4
Binary files /dev/null and b/client/iOS/Resources/toolbar_icon_disconnect.png differ
diff --git a/client/iOS/Resources/toolbar_icon_extkeyboad.png b/client/iOS/Resources/toolbar_icon_extkeyboad.png
new file mode 100755 (executable)
index 0000000..9436c07
Binary files /dev/null and b/client/iOS/Resources/toolbar_icon_extkeyboad.png differ
diff --git a/client/iOS/Resources/toolbar_icon_home.png b/client/iOS/Resources/toolbar_icon_home.png
new file mode 100755 (executable)
index 0000000..afcd9e4
Binary files /dev/null and b/client/iOS/Resources/toolbar_icon_home.png differ
diff --git a/client/iOS/Resources/toolbar_icon_keyboard.png b/client/iOS/Resources/toolbar_icon_keyboard.png
new file mode 100755 (executable)
index 0000000..c2a0685
Binary files /dev/null and b/client/iOS/Resources/toolbar_icon_keyboard.png differ
diff --git a/client/iOS/Resources/toolbar_icon_touchpointer.png b/client/iOS/Resources/toolbar_icon_touchpointer.png
new file mode 100755 (executable)
index 0000000..fc44508
Binary files /dev/null and b/client/iOS/Resources/toolbar_icon_touchpointer.png differ
diff --git a/client/iOS/Resources/toolbar_icon_win.png b/client/iOS/Resources/toolbar_icon_win.png
new file mode 100755 (executable)
index 0000000..73328db
Binary files /dev/null and b/client/iOS/Resources/toolbar_icon_win.png differ
diff --git a/client/iOS/Resources/touch_pointer_active.png b/client/iOS/Resources/touch_pointer_active.png
new file mode 100755 (executable)
index 0000000..c153de4
Binary files /dev/null and b/client/iOS/Resources/touch_pointer_active.png differ
diff --git a/client/iOS/Resources/touch_pointer_default.png b/client/iOS/Resources/touch_pointer_default.png
new file mode 100755 (executable)
index 0000000..ba16a47
Binary files /dev/null and b/client/iOS/Resources/touch_pointer_default.png differ
diff --git a/client/iOS/Resources/touch_pointer_extkeyboard.png b/client/iOS/Resources/touch_pointer_extkeyboard.png
new file mode 100755 (executable)
index 0000000..6f0c8cd
Binary files /dev/null and b/client/iOS/Resources/touch_pointer_extkeyboard.png differ
diff --git a/client/iOS/Resources/touch_pointer_keyboard.png b/client/iOS/Resources/touch_pointer_keyboard.png
new file mode 100755 (executable)
index 0000000..1a6d60d
Binary files /dev/null and b/client/iOS/Resources/touch_pointer_keyboard.png differ
diff --git a/client/iOS/Resources/touch_pointer_lclick.png b/client/iOS/Resources/touch_pointer_lclick.png
new file mode 100755 (executable)
index 0000000..447d8ab
Binary files /dev/null and b/client/iOS/Resources/touch_pointer_lclick.png differ
diff --git a/client/iOS/Resources/touch_pointer_rclick.png b/client/iOS/Resources/touch_pointer_rclick.png
new file mode 100755 (executable)
index 0000000..ad3ca85
Binary files /dev/null and b/client/iOS/Resources/touch_pointer_rclick.png differ
diff --git a/client/iOS/Resources/touch_pointer_reset.png b/client/iOS/Resources/touch_pointer_reset.png
new file mode 100755 (executable)
index 0000000..41ef840
Binary files /dev/null and b/client/iOS/Resources/touch_pointer_reset.png differ
diff --git a/client/iOS/Resources/touch_pointer_scroll.png b/client/iOS/Resources/touch_pointer_scroll.png
new file mode 100755 (executable)
index 0000000..2855e01
Binary files /dev/null and b/client/iOS/Resources/touch_pointer_scroll.png differ
diff --git a/client/iOS/Views/AdvancedKeyboardView.h b/client/iOS/Views/AdvancedKeyboardView.h
new file mode 100644 (file)
index 0000000..c24dad2
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ Advanced keyboard view interface
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+
+#import <UIKit/UIKit.h>
+
+// forward declaration
+@protocol AdvancedKeyboardDelegate <NSObject>
+@optional
+// called when a function key was pressed and a virtual keycode is provided
+//  @key: virtual key code
+-(void)advancedKeyPressedVKey:(int)key;
+// called when a function key was pressed and the keys unicode is provided
+//  @key: unicode character
+-(void)advancedKeyPressedUnicode:(int)key;
+@end
+
+
+@interface AdvancedKeyboardView : UIView 
+{
+@private
+    // view containing function keys (F-keys) and function block (ins, del, home, end, ...)
+    UIView* _function_keys_view;
+
+    // view containing numpad keys (0-9, +-/*)
+    UIView* _numpad_keys_view;
+    
+    // view containing cursor keys (up, down, left, right)
+    UIView* _cursor_keys_view;
+    
+    // currently visible view
+    UIView* _cur_view;
+
+    // delegate
+       NSObject<AdvancedKeyboardDelegate>* _delegate;
+}
+
+@property (assign) NSObject<AdvancedKeyboardDelegate>* delegate;
+
+// init keyboard view with frame and delegate
+- (id)initWithFrame:(CGRect)frame delegate:(NSObject<AdvancedKeyboardDelegate>*)delegate;
+
+@end
+
diff --git a/client/iOS/Views/AdvancedKeyboardView.m b/client/iOS/Views/AdvancedKeyboardView.m
new file mode 100644 (file)
index 0000000..cadaf63
--- /dev/null
@@ -0,0 +1,346 @@
+/*
+ Advanced keyboard view interface
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+
+#import "AdvancedKeyboardView.h"
+#include <freerdp/locale/keyboard.h>
+
+// helper struct to define button layouts/settings
+struct ButtonItem
+{
+    NSString* title;
+    int tag;
+};
+
+@interface AdvancedKeyboardView (Private)
+- (UIView*)keyboardViewForItems:(struct ButtonItem*)items columns:(int)columns rows:(int)rows;
+@end
+
+@implementation AdvancedKeyboardView
+
+@synthesize delegate = _delegate;
+
+// defines for the different views
+#define KEY_SHOW_FUNCVIEW    0x1000
+#define KEY_SHOW_CURSORVIEW  0x1001
+#define KEY_SHOW_NUMPADVIEW  0x1002
+#define KEY_SKIP             0x8000
+#define KEY_MERGE_COLUMN     0x8001
+
+#define KEYCODE_UNICODE      0x80000000
+
+struct ButtonItem functionKeysItems[24] = 
+{
+    { @"F1", VK_F1 },
+    { @"F2", VK_F2 },
+    { @"F3", VK_F3 },
+    { @"F4", VK_F4 },
+    { @"F5", VK_F5 },
+    { @"F6", VK_F6 },
+    { @"F7", VK_F7 },
+    { @"F8", VK_F8 },
+    { @"F9", VK_F9 },
+    { @"F10", VK_F10 },
+    { @"F11", VK_F11 },
+    { @"F12", VK_F12 },
+    
+    { @"img:icon_key_arrows", KEY_SHOW_CURSORVIEW },
+    { @"Tab", VK_TAB },
+    { @"Ins", VK_INSERT },
+    { @"Home", VK_HOME },
+    { @"PgUp", VK_PRIOR },
+    { @"img:icon_key_win", VK_LWIN },
+
+    { @"123", KEY_SHOW_NUMPADVIEW },
+    { @"Print", VK_PRINT },
+    { @"Del", VK_DELETE },
+    { @"End", VK_END },
+    { @"PgDn", VK_NEXT },
+    { @"img:icon_key_menu", VK_APPS }
+};
+
+
+struct ButtonItem numPadKeysItems[24] = 
+{
+    { @"(", KEYCODE_UNICODE | 40 },
+    { @")", KEYCODE_UNICODE | 41 },
+    { @"7", VK_NUMPAD7 },
+    { @"8", VK_NUMPAD8 },
+    { @"9", VK_NUMPAD9 },
+    { @"-", VK_SUBTRACT },
+
+    { @"/", VK_DIVIDE },
+    { @"*", VK_MULTIPLY },
+    { @"4", VK_NUMPAD4 },
+    { @"5", VK_NUMPAD5 },
+    { @"6", VK_NUMPAD6 },
+    { @"+", VK_ADD },
+
+    { @"Fn", KEY_SHOW_FUNCVIEW },
+    { @"Num", VK_NUMLOCK },
+    { @"1", VK_NUMPAD1 },
+    { @"2", VK_NUMPAD2 },
+    { @"3", VK_NUMPAD3 },
+    { @"img:icon_key_backspace", VK_BACK },
+
+    { @"img:icon_key_arrows", KEY_SHOW_CURSORVIEW },
+    { @"=", KEYCODE_UNICODE | 61 },
+    { @"", KEY_MERGE_COLUMN },
+    { @"0", VK_NUMPAD0 },
+    { @".", VK_DECIMAL },
+    { @"img:icon_key_return", VK_RETURN }
+};
+
+
+struct ButtonItem cursorKeysItems[24] = 
+{
+    { @"", KEY_SKIP },
+    { @"", KEY_SKIP },
+    { @"", KEY_SKIP },
+    { @"", KEY_SKIP },
+    { @"", KEY_SKIP },
+    { @"", KEY_SKIP },
+
+    { @"", KEY_SKIP },
+    { @"", KEY_SKIP },
+    { @"", KEY_SKIP },
+    { @"img:icon_key_arrow_up", VK_UP },
+    { @"", KEY_SKIP },
+    { @"", KEY_SKIP },
+    
+    { @"Fn", KEY_SHOW_FUNCVIEW },
+    { @"", KEY_SKIP },
+    { @"img:icon_key_arrow_left", VK_LEFT },
+    { @"", KEY_SKIP },
+    { @"img:icon_key_arrow_right", VK_RIGHT },
+    { @"img:icon_key_backspace", VK_BACK },
+    
+    { @"123", KEY_SHOW_NUMPADVIEW },
+    { @"", KEY_SKIP },
+    { @"", KEY_SKIP },
+    { @"img:icon_key_arrow_down", VK_DOWN },
+    { @"", KEY_SKIP },
+    { @"img:icon_key_return", VK_RETURN }
+};
+
+
+- (void)initFunctionKeysView
+{
+    _function_keys_view = [[self keyboardViewForItems:functionKeysItems columns:6 rows:4] retain];
+    [self addSubview:_function_keys_view];
+}
+
+- (void)initNumPadKeysView
+{
+    _numpad_keys_view = [[self keyboardViewForItems:numPadKeysItems columns:6 rows:4] retain];
+    [self addSubview:_numpad_keys_view];
+}
+
+- (void)initCursorKeysView
+{
+    _cursor_keys_view = [[self keyboardViewForItems:cursorKeysItems columns:6 rows:4] retain];
+    [self addSubview:_cursor_keys_view];
+}
+
+
+- (id)initWithFrame:(CGRect)frame delegate:(NSObject<AdvancedKeyboardDelegate>*)delegate
+{
+    self = [super initWithFrame:frame];
+    if (self) 
+    {
+        _delegate = delegate;
+        
+        self.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
+        self.backgroundColor = [UIColor blackColor];
+        // Initialization code
+        
+        [self initCursorKeysView];
+        [self initNumPadKeysView];
+        [self initFunctionKeysView];
+        
+        // set function keys view to the initial view and hide others
+        _cur_view = _function_keys_view;
+        [_numpad_keys_view setHidden:YES];
+        [_cursor_keys_view setHidden:YES];
+    }
+    return self;
+}
+
+
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect
+{
+    // Drawing code
+}
+*/
+
+- (void)drawRect:(CGRect)rect 
+{
+    // draw a nice background gradient
+    CGContextRef currentContext = UIGraphicsGetCurrentContext();
+    
+    CGGradientRef glossGradient;
+    CGColorSpaceRef rgbColorspace;
+    size_t num_locations = 2;
+    CGFloat locations[2] = { 0.0, 1.0 };
+    CGFloat components[8] = { 1.0, 1.0, 1.0, 0.35,  // Start color
+                              1.0, 1.0, 1.0, 0.06 }; // End color
+    
+    rgbColorspace = CGColorSpaceCreateDeviceRGB();
+    glossGradient = CGGradientCreateWithColorComponents(rgbColorspace, components, locations, num_locations);
+    
+    CGRect currentBounds = self.bounds;
+    CGPoint topCenter = CGPointMake(CGRectGetMidX(currentBounds), 0.0f);
+    CGPoint midCenter = CGPointMake(CGRectGetMidX(currentBounds), currentBounds.size.height);
+    CGContextDrawLinearGradient(currentContext, glossGradient, topCenter, midCenter, 0);
+    
+    CGGradientRelease(glossGradient);
+    CGColorSpaceRelease(rgbColorspace); 
+}
+
+
+- (void)dealloc
+{
+    [_function_keys_view autorelease];
+    [_numpad_keys_view autorelease];
+    [_cursor_keys_view autorelease];
+    [super dealloc];
+}
+
+#pragma mark -
+#pragma mark button events
+
+-(IBAction)keyPressed:(id)sender
+{
+    UIButton* btn = (UIButton*)sender;
+    switch([btn tag])
+    {
+        case KEY_SHOW_CURSORVIEW:
+            // switch to cursor view
+            [_cur_view setHidden:YES];
+            [_cursor_keys_view setHidden:NO];
+            _cur_view = _cursor_keys_view;
+            break;
+            
+        case KEY_SHOW_NUMPADVIEW:
+            // switch to numpad view
+            [_cur_view setHidden:YES];
+            [_numpad_keys_view setHidden:NO];
+            _cur_view = _numpad_keys_view;
+            break;
+            
+        case KEY_SHOW_FUNCVIEW:
+            // switch to function keys view
+            [_cur_view setHidden:YES];
+            [_function_keys_view setHidden:NO];
+            _cur_view = _function_keys_view;
+            break;
+            
+        default:
+            if([btn tag] & KEYCODE_UNICODE)
+            {                                        
+                if ([[self delegate] respondsToSelector:@selector(advancedKeyPressedUnicode:)])
+                    [[self delegate] advancedKeyPressedUnicode:([btn tag] & ~KEYCODE_UNICODE)];
+            }
+            else
+            {
+                if ([[self delegate] respondsToSelector:@selector(advancedKeyPressedVKey:)])
+                    [[self delegate] advancedKeyPressedVKey:[btn tag]];
+            }
+            break;
+    }
+}
+
+@end
+
+
+#pragma mark -
+@implementation AdvancedKeyboardView (Private)
+    
+- (UIView*)keyboardViewForItems:(struct ButtonItem*)items columns:(int)columns rows:(int)rows
+{
+    UIView* result_view = [[[UIView alloc] initWithFrame:self.bounds] autorelease];
+    result_view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
+    
+    // calculate maximum button size
+    int max_btn_width = result_view.bounds.size.width / ((columns * 2) + 1);
+    int max_btn_height = result_view.bounds.size.height / ((rows * 2) + 1);
+    
+    // ensure minimum button size
+    CGSize btn_size = CGSizeMake(45, 30);
+    if(btn_size.width < max_btn_width)
+        btn_size.width = max_btn_width;
+    if(btn_size.height < max_btn_height)
+        btn_size.height = max_btn_height;
+    
+    // calc distance width and height between buttons
+    int dist_width = (result_view.bounds.size.width - (columns * btn_size.width)) / (columns + 1);
+    int dist_height = (result_view.bounds.size.height - (rows * btn_size.height)) / (rows + 1);
+    
+       UIImage* btn_background_img = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"keyboard_button_background" ofType:@"png"]];
+    for(int j = 0; j < rows; j++)
+    {
+        for(int i = 0; i < columns; i++)
+        {
+            struct ButtonItem* curItem = &items[j * columns + i];
+            
+            // skip this spot?
+            if(curItem->tag == KEY_SKIP)
+                continue;
+            
+            // create button, set autoresizing mask and add action handler
+            UIButton* btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
+            [btn setAutoresizingMask:(UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];
+            [btn addTarget:self action:@selector(keyPressed:) forControlEvents:UIControlEventTouchUpInside];
+            
+            // if merge is specified we merge this button's position with the next one
+            if(curItem->tag == KEY_MERGE_COLUMN)
+            {
+                // calc merged frame
+                [btn setFrame:CGRectMake(dist_width + (i * dist_width) + (i * btn_size.width), 
+                                         dist_height + (j * dist_height) + (j * btn_size.height), 
+                                         btn_size.width * 2 + dist_width, btn_size.height)];
+                
+                // proceed to the next column item
+                i++;    
+                curItem = &items[j * columns + i];
+            }
+            else
+            {
+                [btn setFrame:CGRectMake(dist_width + (i * dist_width) + (i * btn_size.width), 
+                                         dist_height + (j * dist_height) + (j * btn_size.height), 
+                                         btn_size.width, btn_size.height)];
+            }
+            
+            // set button text or image parameters
+            if([curItem->title hasPrefix:@"img:"] == YES)
+            {
+                UIImage* btn_image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[curItem->title substringFromIndex:4] ofType:@"png"]];
+                [btn setImage:btn_image forState:UIControlStateNormal];
+            }
+            else
+            {
+                [btn setTitle:curItem->title forState:UIControlStateNormal];
+                [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];                
+            }
+            
+            [btn setBackgroundImage:btn_background_img forState:UIControlStateNormal];    
+            [btn setTag:curItem->tag];
+            
+            // add button to view
+            [result_view addSubview:btn];
+        }
+    }
+    
+    return result_view;
+}
+
+@end
diff --git a/client/iOS/Views/BookmarkTableCell.h b/client/iOS/Views/BookmarkTableCell.h
new file mode 100644 (file)
index 0000000..4d89095
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ Custom bookmark table cell
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import <UIKit/UIKit.h>
+
+
+@interface BookmarkTableCell : UITableViewCell 
+{
+       IBOutlet UILabel* _title;
+       IBOutlet UILabel* _sub_title;
+       IBOutlet UIImageView* _connection_state_icon;
+}
+
+@property (retain, nonatomic) UILabel* title;
+@property (retain, nonatomic) UILabel* subTitle;
+@property (retain, nonatomic) UIImageView* connectionStateIcon;
+
+
+@end
diff --git a/client/iOS/Views/BookmarkTableCell.m b/client/iOS/Views/BookmarkTableCell.m
new file mode 100644 (file)
index 0000000..83fbf70
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ Custom bookmark table cell
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "BookmarkTableCell.h"
+
+
+@implementation BookmarkTableCell
+
+@synthesize title = _title, subTitle = _sub_title, connectionStateIcon = _connection_state_icon;
+
+- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
+    if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {
+        // Initialization code
+    }
+    return self;
+}
+
+
+- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
+
+    [super setSelected:selected animated:animated];
+
+    // Configure the view for the selected state
+}
+
+
+- (void)dealloc {
+    [super dealloc];
+}
+
+
+@end
diff --git a/client/iOS/Views/EditButtonTableViewCell.h b/client/iOS/Views/EditButtonTableViewCell.h
new file mode 100644 (file)
index 0000000..7c755ae
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ Custom table cell with a button
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import <UIKit/UIKit.h>
+
+@interface EditButtonTableViewCell : UITableViewCell
+{
+    IBOutlet UILabel* _label;
+    IBOutlet UIButton* _button;
+}
+
+@property (retain, nonatomic) UILabel* label;
+@property (retain, nonatomic) UIButton* button;
+
+@end
diff --git a/client/iOS/Views/EditButtonTableViewCell.m b/client/iOS/Views/EditButtonTableViewCell.m
new file mode 100644 (file)
index 0000000..bf627ab
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ Custom table cell with a button
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "EditButtonTableViewCell.h"
+
+@implementation EditButtonTableViewCell
+
+@synthesize label = _label, button = _button;
+
+- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
+{
+    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
+    if (self) {
+        // Initialization code
+    }
+    return self;
+}
+
+- (void)setSelected:(BOOL)selected animated:(BOOL)animated
+{
+    [super setSelected:selected animated:animated];
+
+    // Configure the view for the selected state
+}
+
+@end
diff --git a/client/iOS/Views/EditFlagTableViewCell.h b/client/iOS/Views/EditFlagTableViewCell.h
new file mode 100644 (file)
index 0000000..f8a9f77
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ Custom table cell with toggle switch
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import <UIKit/UIKit.h>
+
+@interface EditFlagTableViewCell : UITableViewCell
+{
+       IBOutlet UILabel* _label;
+       IBOutlet UISwitch* _toggle;    
+}
+
+@property (retain, nonatomic) UILabel* label;
+@property (retain, nonatomic) UISwitch* toggle;
+
+@end
diff --git a/client/iOS/Views/EditFlagTableViewCell.m b/client/iOS/Views/EditFlagTableViewCell.m
new file mode 100644 (file)
index 0000000..0b7fa69
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ Custom table cell with toggle switch
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "EditFlagTableViewCell.h"
+
+@implementation EditFlagTableViewCell
+
+@synthesize label = _label, toggle = _toggle;
+
+- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
+{
+    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
+    if (self) {
+        // Initialization code
+    }
+    return self;
+}
+
+- (void)setSelected:(BOOL)selected animated:(BOOL)animated
+{
+    [super setSelected:selected animated:animated];
+
+    // Configure the view for the selected state
+}
+
+@end
diff --git a/client/iOS/Views/EditSecretTextTableViewCell.h b/client/iOS/Views/EditSecretTextTableViewCell.h
new file mode 100644 (file)
index 0000000..aef3b51
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ Custom table cell with secret edit text field
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import <UIKit/UIKit.h>
+
+@interface EditSecretTextTableViewCell : UITableViewCell
+{
+       IBOutlet UILabel* _label;
+       IBOutlet UITextField* _textfield;    
+       IBOutlet UIButton* _unhide_button;
+}
+
+@property (retain, nonatomic) UILabel* label;
+@property (retain, nonatomic) UITextField* textfield;
+
+- (void)setEnabled:(BOOL)enabled;
+
+@end
diff --git a/client/iOS/Views/EditSecretTextTableViewCell.m b/client/iOS/Views/EditSecretTextTableViewCell.m
new file mode 100644 (file)
index 0000000..a9b8887
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ Custom table cell with secret edit text field
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "EditSecretTextTableViewCell.h"
+
+@implementation EditSecretTextTableViewCell
+
+@synthesize label = _label, textfield = _textfield;
+
+- (void)awakeFromNib
+{
+    [super awakeFromNib];
+    [_unhide_button setTitle:NSLocalizedString(@"Unhide", @"Button title 'Unhide'") forState:UIControlStateNormal];
+    [_unhide_button addTarget:self action:@selector(togglePasswordMode:) forControlEvents:UIControlEventTouchUpInside];     
+}
+
+- (void)setEnabled:(BOOL)enabled
+{
+    [_label setEnabled:enabled];
+    [_textfield setEnabled:enabled];
+    [_unhide_button setEnabled:enabled];
+}
+
+#pragma mark - action handlers
+- (void)togglePasswordMode:(id)sender
+{
+    BOOL isSecure = [_textfield isSecureTextEntry];
+
+    if (isSecure)
+    {
+        [_unhide_button setTitle:NSLocalizedString(@"Hide", @"Button title 'Hide'") forState:UIControlStateNormal];
+        [_textfield setSecureTextEntry:NO];        
+    }
+    else
+    {
+        BOOL first_responder = [_textfield isFirstResponder];
+        // little trick to make non-secure to secure transition working - this seems to be an ios bug:
+        // http://stackoverflow.com/questions/6710019/uitextfield-securetextentry-works-going-from-yes-to-no-but-changing-back-to-y
+        [_textfield setEnabled:NO];   
+        [_unhide_button setTitle:NSLocalizedString(@"Unhide", @"Button title 'Unhide'") forState:UIControlStateNormal];        
+        [_textfield setSecureTextEntry:YES];        
+        [_textfield setEnabled:YES];
+        if (first_responder)
+            [_textfield becomeFirstResponder];
+    }
+}
+
+@end
diff --git a/client/iOS/Views/EditSelectionTableViewCell.h b/client/iOS/Views/EditSelectionTableViewCell.h
new file mode 100644 (file)
index 0000000..0023ce6
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ Custom table cell with a label on the right, showing the current selection
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import <UIKit/UIKit.h>
+
+@interface EditSelectionTableViewCell : UITableViewCell
+{
+       IBOutlet UILabel* _label;
+       IBOutlet UILabel* _selection;    
+}
+
+@property (retain, nonatomic) UILabel* label;
+@property (retain, nonatomic) UILabel* selection;
+
+@end
diff --git a/client/iOS/Views/EditSelectionTableViewCell.m b/client/iOS/Views/EditSelectionTableViewCell.m
new file mode 100644 (file)
index 0000000..4ad6233
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ Custom table cell with a label on the right, showing the current selection
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "EditSelectionTableViewCell.h"
+
+@implementation EditSelectionTableViewCell
+
+@synthesize label = _label, selection = _selection;
+
+- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
+{
+    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
+    if (self) {
+        // Initialization code
+    }
+    return self;
+}
+
+- (void)setSelected:(BOOL)selected animated:(BOOL)animated
+{
+    [super setSelected:selected animated:animated];
+
+    // Configure the view for the selected state
+}
+
+@end
diff --git a/client/iOS/Views/EditSubEditTableViewCell.h b/client/iOS/Views/EditSubEditTableViewCell.h
new file mode 100644 (file)
index 0000000..541a7c7
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ Custom table cell indicating a switch to a sub-view
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import <UIKit/UIKit.h>
+
+@interface EditSubEditTableViewCell : UITableViewCell
+{
+       IBOutlet UILabel* _label;
+}
+
+@property (retain, nonatomic) UILabel* label;
+
+@end
diff --git a/client/iOS/Views/EditSubEditTableViewCell.m b/client/iOS/Views/EditSubEditTableViewCell.m
new file mode 100644 (file)
index 0000000..0ecc37f
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ Custom table cell indicating a switch to a sub-view
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "EditSubEditTableViewCell.h"
+
+@implementation EditSubEditTableViewCell
+
+@synthesize label = _label;
+
+- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
+{
+    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
+    if (self) {
+        // Initialization code
+    }
+    return self;
+}
+
+- (void)setSelected:(BOOL)selected animated:(BOOL)animated
+{
+    [super setSelected:selected animated:animated];
+
+    // Configure the view for the selected state
+}
+
+@end
diff --git a/client/iOS/Views/EditTextTableViewCell.h b/client/iOS/Views/EditTextTableViewCell.h
new file mode 100644 (file)
index 0000000..22a55a6
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ Custom table cell with edit text field
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import <UIKit/UIKit.h>
+
+@interface EditTextTableViewCell : UITableViewCell
+{
+       IBOutlet UILabel* _label;
+       IBOutlet UITextField* _textfield;    
+}
+
+@property (retain, nonatomic) UILabel* label;
+@property (retain, nonatomic) UITextField* textfield;
+
+@end
diff --git a/client/iOS/Views/EditTextTableViewCell.m b/client/iOS/Views/EditTextTableViewCell.m
new file mode 100644 (file)
index 0000000..afbf417
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ Custom table cell with edit text field
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "EditTextTableViewCell.h"
+
+@implementation EditTextTableViewCell
+
+@synthesize label = _label, textfield = _textfield;
+
+- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
+{
+    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
+    if (self) {
+        // Initialization code
+    }
+    return self;
+}
+
+- (void)setSelected:(BOOL)selected animated:(BOOL)animated
+{
+    [super setSelected:selected animated:animated];
+
+    // Configure the view for the selected state
+}
+
+@end
diff --git a/client/iOS/Views/RDPSessionView.h b/client/iOS/Views/RDPSessionView.h
new file mode 100644 (file)
index 0000000..17eb174
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ RDP Session View
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import <UIKit/UIKit.h>
+#import "RDPSession.h"
+
+@interface RDPSessionView : UIView
+{
+    RDPSession* _session;
+}
+
+- (void)setSession:(RDPSession*)session;
+
+@end
diff --git a/client/iOS/Views/RDPSessionView.m b/client/iOS/Views/RDPSessionView.m
new file mode 100644 (file)
index 0000000..d36f315
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ RDP Session View
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "RDPSessionView.h"
+
+@implementation RDPSessionView
+
+- (void)setSession:(RDPSession*)session
+{
+    _session = session;
+}
+
+- (void)awakeFromNib
+{
+    [super awakeFromNib];
+    _session = nil;
+}
+
+- (void)drawRect:(CGRect)rect 
+{
+       if(_session != nil)
+       {
+               CGContextRef context = UIGraphicsGetCurrentContext();
+               CGImageRef cgImage = CGBitmapContextCreateImage([_session bitmapContext]);
+
+        CGContextTranslateCTM(context, 0, [self bounds].size.height);
+        CGContextScaleCTM(context, 1.0, -1.0);      
+        CGContextClipToRect(context, CGRectMake(rect.origin.x, [self bounds].size.height - rect.origin.y - rect.size.height, rect.size.width, rect.size.height));
+        CGContextDrawImage(context, CGRectMake(0, 0, [self bounds].size.width, [self bounds].size.height), cgImage);        
+               
+        CGImageRelease(cgImage);
+       }
+    else
+    {
+        // just clear the screen with black
+        [[UIColor blackColor] set];
+        UIRectFill([self bounds]);        
+    }
+}
+
+- (void)dealloc {
+    [super dealloc];
+}
+
+@end
diff --git a/client/iOS/Views/SessionTableCell.h b/client/iOS/Views/SessionTableCell.h
new file mode 100644 (file)
index 0000000..5090fa5
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ Custom session table cell
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import <UIKit/UIKit.h>
+
+
+@interface SessionTableCell : UITableViewCell 
+{
+       IBOutlet UILabel* _title;
+       IBOutlet UILabel* _server;
+       IBOutlet UILabel* _username;
+       IBOutlet UIImageView* _screenshot;
+       IBOutlet UIButton* _disconnect_button;
+}
+
+@property (retain, nonatomic) UILabel* title;
+@property (retain, nonatomic) UILabel* server;
+@property (retain, nonatomic) UILabel* username;
+@property (retain, nonatomic) UIImageView* screenshot;
+@property (retain, nonatomic) UIButton* disconnectButton;
+
+@end
diff --git a/client/iOS/Views/SessionTableCell.m b/client/iOS/Views/SessionTableCell.m
new file mode 100644 (file)
index 0000000..f57a4c8
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ Custom session table cell
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "SessionTableCell.h"
+
+
+@implementation SessionTableCell
+
+@synthesize title = _title, server = _server, username = _username, screenshot = _screenshot, disconnectButton = _disconnect_button;
+
+- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
+    
+    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
+    if (self) {
+        // Initialization code.
+    }
+    return self;
+}
+
+
+- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
+    
+    [super setSelected:selected animated:animated];
+    
+    // Configure the view for the selected state.
+}
+
+
+- (void)dealloc {
+    [super dealloc];
+}
+
+
+@end
diff --git a/client/iOS/Views/TouchPointerView.h b/client/iOS/Views/TouchPointerView.h
new file mode 100644 (file)
index 0000000..1c0b036
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ RDP Touch Pointer View 
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import <UIKit/UIKit.h>
+
+// protocol for touch pointer callbacks
+@protocol TouchPointerDelegate
+// callback if touch pointer should be closed
+-(void)touchPointerClose;
+// callback for a left click action
+-(void)touchPointerLeftClick:(CGPoint)pos down:(BOOL)down;
+// callback for a right click action
+-(void)touchPointerRightClick:(CGPoint)pos down:(BOOL)down;
+// callback for pointer move action
+-(void)touchPointerMove:(CGPoint)pos;
+// callback if scrolling is performed
+-(void)touchPointerScrollDown:(BOOL)down;
+// callback for toggling the standard keyboard
+-(void)touchPointerToggleKeyboard;
+// callback for toggling the extended keyboard
+-(void)touchPointerToggleExtendedKeyboard;
+// callback for reset session view
+-(void)touchPointerResetSessionView;
+@end
+
+
+@interface TouchPointerView : UIView
+{
+    // transformation and image currently drawn
+    CGAffineTransform _pointer_transformation;
+    UIImage* _cur_pointer_img;
+
+    // action images
+    UIImage* _default_pointer_img;
+    UIImage* _active_pointer_img;
+    UIImage* _lclick_pointer_img;
+    UIImage* _rclick_pointer_img;
+    UIImage* _scroll_pointer_img;
+    UIImage* _extkeyboard_pointer_img;
+    UIImage* _keyboard_pointer_img;
+    UIImage* _reset_pointer_img;
+
+    // predefined areas for all actions
+    CGRect _pointer_areas[9]; 
+    
+    // scroll/drag n drop handling
+    CGPoint _prev_touch_location;
+    BOOL _pointer_moving;
+    BOOL _pointer_scrolling;
+    
+    NSObject<TouchPointerDelegate>* _delegate;
+}
+
+@property (assign) IBOutlet NSObject<TouchPointerDelegate>* delegate;
+
+// positions the pointer on screen if it got offscreen after an orentation change or after displaying the keyboard
+-(void)ensurePointerIsVisible;
+
+// returns the extent required for the scrollview to use the touch pointer near the edges of the session view
+-(UIEdgeInsets)getEdgeInsets;
+
+// return pointer dimension and position information
+- (CGPoint)getPointerPosition;
+- (int)getPointerWidth;
+- (int)getPointerHeight;
+
+@end
diff --git a/client/iOS/Views/TouchPointerView.m b/client/iOS/Views/TouchPointerView.m
new file mode 100644 (file)
index 0000000..db2108d
--- /dev/null
@@ -0,0 +1,328 @@
+/*
+ RDP Touch Pointer View 
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "TouchPointerView.h"
+#import "Utils.h"
+
+
+#define RESET_DEFAULT_POINTER_IMAGE_DELAY 0.15
+
+#define POINTER_ACTION_CURSOR   0
+#define POINTER_ACTION_CLOSE    3
+#define POINTER_ACTION_RCLICK   2
+#define POINTER_ACTION_LCLICK   4
+#define POINTER_ACTION_MOVE     4
+#define POINTER_ACTION_SCROLL   5
+#define POINTER_ACTION_KEYBOARD 7
+#define POINTER_ACTION_EXTKEYBOARD 8
+#define POINTER_ACTION_RESET 6
+
+@interface TouchPointerView (Private)
+- (void)setCurrentPointerImage:(UIImage*)image;
+- (void)displayPointerActionImage:(UIImage*)image;
+- (BOOL)pointInsidePointer:(CGPoint)point;
+- (BOOL)pointInsidePointerArea:(int)area point:(CGPoint)point;
+- (CGPoint)getCursorPosition;
+- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;
+- (void)handleSingleTap:(UITapGestureRecognizer*)gesture;
+- (void)handlerForGesture:(UIGestureRecognizer*)gesture sendClick:(BOOL)sendClick;
+@end
+
+@implementation TouchPointerView
+
+@synthesize delegate = _delegate;
+
+- (void)awakeFromNib
+{
+    [super awakeFromNib];
+    
+    // set content mode when rotating (keep aspect ratio)
+    [self setContentMode:UIViewContentModeTopLeft];
+    
+    // load touchPointerImage
+    _default_pointer_img = [[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"touch_pointer_default" ofType:@"png"]] retain];
+    _active_pointer_img = [[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"touch_pointer_active" ofType:@"png"]] retain];
+    _lclick_pointer_img = [[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"touch_pointer_lclick" ofType:@"png"]] retain];
+    _rclick_pointer_img = [[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"touch_pointer_rclick" ofType:@"png"]] retain];
+    _scroll_pointer_img = [[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"touch_pointer_scroll" ofType:@"png"]] retain];
+    _extkeyboard_pointer_img = [[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"touch_pointer_ext_keyboard" ofType:@"png"]] retain];
+    _keyboard_pointer_img = [[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"touch_pointer_keyboard" ofType:@"png"]] retain];
+    _reset_pointer_img = [[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"touch_pointer_reset" ofType:@"png"]] retain];        
+    _cur_pointer_img = _default_pointer_img;
+    _pointer_transformation = CGAffineTransformMake(1, 0, 0, 1, 0, 0);
+    
+    // init flags
+    _pointer_moving = NO;
+    _pointer_scrolling = NO;
+    
+    // create areas array
+    int i, j;
+    CGFloat area_width = [_cur_pointer_img size].width / 3.0f;
+    CGFloat area_height = [_cur_pointer_img size].height / 3.0f;
+    for(i = 0; i < 3; i++)
+    {
+        for(j = 0; j < 3; j++)
+        {
+            _pointer_areas[j + i * 3] = CGRectMake(j * area_width, i * area_height, area_width, area_height);
+        }
+    }
+    
+    // init gesture recognizers
+    UITapGestureRecognizer* singleTapRecognizer = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)] autorelease];
+    [singleTapRecognizer setNumberOfTouchesRequired:1];
+    [singleTapRecognizer setNumberOfTapsRequired:1];
+    
+    UILongPressGestureRecognizer* dragDropRecognizer = [[[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleDragDrop:)] autorelease];
+    dragDropRecognizer.minimumPressDuration = 0.4;
+    //        dragDropRecognizer.allowableMovement = 1000.0;        
+    
+    UILongPressGestureRecognizer* pointerMoveScrollRecognizer = [[[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handlePointerMoveScroll:)] autorelease];
+    pointerMoveScrollRecognizer.minimumPressDuration = 0.15;
+    pointerMoveScrollRecognizer.allowableMovement = 1000.0;
+    [pointerMoveScrollRecognizer requireGestureRecognizerToFail:dragDropRecognizer];
+    
+    [self addGestureRecognizer:singleTapRecognizer];
+    [self addGestureRecognizer:dragDropRecognizer];
+    [self addGestureRecognizer:pointerMoveScrollRecognizer];    
+}
+
+- (void)dealloc
+{
+    [super dealloc];
+    [_default_pointer_img autorelease];
+    [_active_pointer_img autorelease];
+    [_lclick_pointer_img autorelease];
+    [_rclick_pointer_img autorelease];
+    [_scroll_pointer_img autorelease];
+    [_extkeyboard_pointer_img autorelease];
+    [_keyboard_pointer_img autorelease];
+    [_reset_pointer_img autorelease];
+}
+
+#pragma mark - Public interface
+
+// positions the pointer on screen if it got offscreen after an orentation change
+-(void)ensurePointerIsVisible
+{
+    CGRect bounds = [self bounds];
+    if(_pointer_transformation.tx > (bounds.size.width - _cur_pointer_img.size.width))
+        _pointer_transformation.tx = bounds.size.width - _cur_pointer_img.size.width;
+    if(_pointer_transformation.ty > (bounds.size.height - _cur_pointer_img.size.height))
+        _pointer_transformation.ty = bounds.size.height - _cur_pointer_img.size.height;
+    [self setNeedsDisplay];
+}
+
+// show/hides the touch pointer
+-(void)setHidden:(BOOL)hidden
+{  
+    [super setHidden:hidden];
+
+    // if shown center pointer in view
+    if(!hidden)
+    {
+        _pointer_transformation = CGAffineTransformMakeTranslation(([self bounds].size.width - [_cur_pointer_img size].width) / 2, 
+                                                                  ([self bounds].size.height - [_cur_pointer_img size].height) / 2);
+       [self setNeedsDisplay];
+    }    
+}
+
+-(UIEdgeInsets)getEdgeInsets
+{
+    return UIEdgeInsetsMake(0, 0, [_cur_pointer_img size].width, [_cur_pointer_img size].height);
+}
+
+- (CGPoint)getPointerPosition
+{
+    return CGPointMake(_pointer_transformation.tx, _pointer_transformation.ty);        
+}
+
+- (int)getPointerWidth
+{
+    return [_cur_pointer_img size].width;    
+}
+
+- (int)getPointerHeight
+{
+    return [_cur_pointer_img size].height;
+}
+
+
+@end
+
+@implementation TouchPointerView (Private)
+
+- (void)setCurrentPointerImage:(UIImage*)image
+{
+    _cur_pointer_img = image;
+    [self setNeedsDisplay];
+}
+
+- (void)displayPointerActionImage:(UIImage*)image
+{
+    [self setCurrentPointerImage:image];
+    [self performSelector:@selector(setCurrentPointerImage:) withObject:_default_pointer_img afterDelay:RESET_DEFAULT_POINTER_IMAGE_DELAY];
+}
+
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect
+{
+    // Drawing code
+    CGContextRef context = UIGraphicsGetCurrentContext();
+    CGContextSaveGState(context);
+    CGContextConcatCTM(context, _pointer_transformation);
+    CGContextDrawImage(context, CGRectMake(0, 0, [_cur_pointer_img size].width, [_cur_pointer_img size].height), [_cur_pointer_img CGImage]);
+    CGContextRestoreGState(context);
+}
+
+// helper that returns YES if the given point is within the pointer
+-(BOOL) pointInsidePointer:(CGPoint)point
+{
+    CGRect rec = CGRectMake(0, 0, [_cur_pointer_img size].width, [_cur_pointer_img size].height);
+    return CGRectContainsPoint(CGRectApplyAffineTransform(rec, _pointer_transformation), point);
+}
+
+// helper that returns YES if the given point is within the given pointer area
+-(BOOL) pointInsidePointerArea:(int)area point:(CGPoint)point
+{
+    CGRect rec = _pointer_areas[area];
+    return CGRectContainsPoint(CGRectApplyAffineTransform(rec, _pointer_transformation), point);
+}
+
+// returns the position of the cursor
+-(CGPoint) getCursorPosition
+{
+    CGRect transPointerArea = CGRectApplyAffineTransform(_pointer_areas[POINTER_ACTION_CURSOR], _pointer_transformation);
+    return CGPointMake(CGRectGetMidX(transPointerArea), CGRectGetMidY(transPointerArea));
+}
+
+// this filters events - if the pointer was clicked the scrollview won't get any events
+-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
+{
+    return [self pointInsidePointer:point];
+}
+
+#pragma mark - Action handlers
+
+// handles single tap gestures, returns YES if the event was handled by the pointer, NO otherwise
+-(void) handleSingleTap:(UITapGestureRecognizer*)gesture
+{
+    // get touch position within our view
+    CGPoint touchPos = [gesture locationInView:self];
+    
+    // look if pointer was in one of our action areas
+    if([self pointInsidePointerArea:POINTER_ACTION_CLOSE point:touchPos])
+        [[self delegate] touchPointerClose];
+    else if([self pointInsidePointerArea:POINTER_ACTION_LCLICK point:touchPos])
+    {
+        [self displayPointerActionImage:_lclick_pointer_img];
+        [[self delegate] touchPointerLeftClick:[self getCursorPosition] down:YES];        
+        [[self delegate] touchPointerLeftClick:[self getCursorPosition] down:NO];        
+    }
+    else if([self pointInsidePointerArea:POINTER_ACTION_RCLICK point:touchPos])
+    {
+        [self displayPointerActionImage:_rclick_pointer_img];
+        [[self delegate] touchPointerRightClick:[self getCursorPosition] down:YES];        
+        [[self delegate] touchPointerRightClick:[self getCursorPosition] down:NO];        
+    }
+    else if([self pointInsidePointerArea:POINTER_ACTION_KEYBOARD point:touchPos])
+    {
+        [self displayPointerActionImage:_keyboard_pointer_img];
+        [[self delegate] touchPointerToggleKeyboard];
+    }
+    else if([self pointInsidePointerArea:POINTER_ACTION_EXTKEYBOARD point:touchPos])
+    {
+        [self displayPointerActionImage:_extkeyboard_pointer_img];
+        [[self delegate] touchPointerToggleExtendedKeyboard];
+    }
+    else if([self pointInsidePointerArea:POINTER_ACTION_RESET point:touchPos])
+    {
+        [self displayPointerActionImage:_reset_pointer_img];
+        [[self delegate] touchPointerResetSessionView];
+    }
+}
+
+-(void) handlerForGesture:(UIGestureRecognizer*)gesture sendClick:(BOOL)sendClick
+{
+    if([gesture state] == UIGestureRecognizerStateBegan)
+    {
+        CGPoint touchPos = [gesture locationInView:self];
+        if([self pointInsidePointerArea:POINTER_ACTION_LCLICK point:touchPos])
+        {
+            _prev_touch_location = touchPos;
+            _pointer_moving = YES;
+            if(sendClick == YES)
+            {
+                [[self delegate] touchPointerLeftClick:[self getCursorPosition] down:YES];        
+                [self setCurrentPointerImage:_active_pointer_img];                
+            }   
+        }
+        else if([self pointInsidePointerArea:POINTER_ACTION_SCROLL point:touchPos])
+        {
+            [self setCurrentPointerImage:_scroll_pointer_img];                
+            _prev_touch_location = touchPos;
+            _pointer_scrolling = YES;
+        }
+    }
+    else if([gesture state] == UIGestureRecognizerStateChanged)
+    {
+        if(_pointer_moving)
+        {
+            CGPoint touchPos = [gesture locationInView:self];
+            _pointer_transformation = CGAffineTransformTranslate(_pointer_transformation, touchPos.x - _prev_touch_location.x, touchPos.y - _prev_touch_location.y);                                    
+            [[self delegate] touchPointerMove:[self getCursorPosition]];
+            _prev_touch_location = touchPos;
+            [self setNeedsDisplay];
+        }
+        else if(_pointer_scrolling)
+        {
+            CGPoint touchPos = [gesture locationInView:self];
+            float delta = touchPos.y - _prev_touch_location.y;
+            if(delta > GetScrollGestureDelta())
+            {
+                [[self delegate] touchPointerScrollDown:YES];
+                _prev_touch_location = touchPos;
+            }
+            else if(delta < -GetScrollGestureDelta())
+            {
+                [[self delegate] touchPointerScrollDown:NO];
+                _prev_touch_location = touchPos;
+            }
+        }
+    }
+    else if([gesture state] == UIGestureRecognizerStateEnded)
+    {
+        if(_pointer_moving)
+        {
+            if(sendClick == YES)
+                [[self delegate] touchPointerLeftClick:[self getCursorPosition] down:NO];        
+            _pointer_moving = NO;
+            [self setCurrentPointerImage:_default_pointer_img];
+        }
+
+        if(_pointer_scrolling)
+        {
+            [self setCurrentPointerImage:_default_pointer_img];
+            _pointer_scrolling = NO;            
+        }
+    }    
+}
+
+// handles long press gestures
+-(void) handleDragDrop:(UILongPressGestureRecognizer*)gesture
+{
+    [self handlerForGesture:gesture sendClick:YES];
+}
+
+-(void) handlePointerMoveScroll:(UILongPressGestureRecognizer*)gesture
+{
+    [self handlerForGesture:gesture sendClick:NO];
+}
+
+@end
diff --git a/client/iOS/iFreeRDP-Prefix.pch b/client/iOS/iFreeRDP-Prefix.pch
new file mode 100644 (file)
index 0000000..ecb2e5a
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ PCH
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+//
+// Prefix header for all source files of the 'iFreeRDP' target in the 'iFreeRDP' project
+//
+
+#import <Availability.h>
+
+#ifndef __IPHONE_3_0
+#warning "This project uses features only available in iPhone SDK 3.0 and later."
+#endif
+
+#ifdef __OBJC__
+    #import <UIKit/UIKit.h>
+    #import <Foundation/Foundation.h>
+#endif
diff --git a/client/iOS/iFreeRDP.plist b/client/iOS/iFreeRDP.plist
new file mode 100644 (file)
index 0000000..b6d842f
--- /dev/null
@@ -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>CFBundleDevelopmentRegion</key>
+       <string>English</string>
+       <key>CFBundleDisplayName</key>
+       <string>iFreeRDP</string>
+       <key>CFBundleExecutable</key>
+       <string>${EXECUTABLE_NAME}</string>
+       <key>CFBundleIconFiles</key>
+       <array>
+               <string>Icon.png</string>
+               <string>Icon-72.png</string>
+               <string>Icon@2x.png</string>
+               <string>Icon-72@2x.png</string>
+       </array>
+       <key>CFBundleIdentifier</key>
+       <string>at.thinstuff.rdc</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundleName</key>
+       <string>${PRODUCT_NAME}</string>
+       <key>CFBundlePackageType</key>
+       <string>APPL</string>
+       <key>CFBundleShortVersionString</key>
+       <string>1.0</string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>0</string>
+       <key>LSRequiresIPhoneOS</key>
+       <true/>
+       <key>NSMainNibFile</key>
+       <string>MainWindow</string>
+       <key>UIPrerenderedIcon</key>
+       <true/>
+       <key>UISupportedInterfaceOrientations</key>
+       <array>
+               <string>UIInterfaceOrientationPortrait</string>
+               <string>UIInterfaceOrientationPortraitUpsideDown</string>
+               <string>UIInterfaceOrientationLandscapeLeft</string>
+               <string>UIInterfaceOrientationLandscapeRight</string>
+       </array>
+       <key>UISupportedInterfaceOrientations~ipad</key>
+       <array>
+               <string>UIInterfaceOrientationPortrait</string>
+               <string>UIInterfaceOrientationPortraitUpsideDown</string>
+               <string>UIInterfaceOrientationLandscapeLeft</string>
+               <string>UIInterfaceOrientationLandscapeRight</string>
+       </array>
+</dict>
+</plist>
diff --git a/client/iOS/iFreeRDP.xcodeproj/project.pbxproj.cmake b/client/iOS/iFreeRDP.xcodeproj/project.pbxproj.cmake
new file mode 100644 (file)
index 0000000..4a92220
--- /dev/null
@@ -0,0 +1,863 @@
+// !$*UTF8*$!
+{
+       archiveVersion = 1;
+       classes = {
+       };
+       objectVersion = 46;
+       objects = {
+
+/* Begin PBXBuildFile section */
+               C495EE3416B8372D0041304E /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C495EE3316B8372D0041304E /* UIKit.framework */; };
+               C495EE3616B8372D0041304E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C495EE3516B8372D0041304E /* Foundation.framework */; };
+               C495EE3816B8372D0041304E /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C495EE3716B8372D0041304E /* CoreGraphics.framework */; };
+               C495EE7016B9107D0041304E /* Defaults.plist in Resources */ = {isa = PBXBuildFile; fileRef = C495EE6F16B9107D0041304E /* Defaults.plist */; };
+               C495EE7716B910BC0041304E /* OrderedDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EE7216B910BC0041304E /* OrderedDictionary.m */; };
+               C495EE7816B910BC0041304E /* Toast+UIView.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EE7416B910BC0041304E /* Toast+UIView.m */; };
+               C495EE7916B910BC0041304E /* TSXAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EE7616B910BC0041304E /* TSXAdditions.m */; };
+               C495EE9B16B910DE0041304E /* AboutController.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EE7C16B910DE0041304E /* AboutController.m */; };
+               C495EE9C16B910DE0041304E /* AdvancedBookmarkEditorController.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EE7E16B910DE0041304E /* AdvancedBookmarkEditorController.m */; };
+               C495EE9D16B910DE0041304E /* AppSettingsController.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EE8016B910DE0041304E /* AppSettingsController.m */; };
+               C495EE9E16B910DE0041304E /* BookmarkEditorController.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EE8216B910DE0041304E /* BookmarkEditorController.m */; };
+               C495EE9F16B910DE0041304E /* BookmarkListController.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EE8416B910DE0041304E /* BookmarkListController.m */; };
+               C495EEA016B910DE0041304E /* CredentialsEditorController.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EE8616B910DE0041304E /* CredentialsEditorController.m */; };
+               C495EEA116B910DE0041304E /* CredentialsInputController.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EE8816B910DE0041304E /* CredentialsInputController.m */; };
+               C495EEA216B910DE0041304E /* EditorBaseController.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EE8A16B910DE0041304E /* EditorBaseController.m */; };
+               C495EEA316B910DE0041304E /* EditorSelectionController.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EE8C16B910DE0041304E /* EditorSelectionController.m */; };
+               C495EEA416B910DE0041304E /* EncryptionController.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EE8E16B910DE0041304E /* EncryptionController.m */; };
+               C495EEA516B910DE0041304E /* HelpController.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EE9016B910DE0041304E /* HelpController.m */; };
+               C495EEA616B910DE0041304E /* MainTabBarController.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EE9216B910DE0041304E /* MainTabBarController.m */; };
+               C495EEA716B910DE0041304E /* PerformanceEditorController.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EE9416B910DE0041304E /* PerformanceEditorController.m */; };
+               C495EEA816B910DE0041304E /* RDPSessionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EE9616B910DE0041304E /* RDPSessionViewController.m */; };
+               C495EEA916B910DE0041304E /* ScreenSelectionController.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EE9816B910DE0041304E /* ScreenSelectionController.m */; };
+               C495EEAA16B910DE0041304E /* VerifyCertificateController.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EE9A16B910DE0041304E /* VerifyCertificateController.m */; };
+               C495EEB216B910F60041304E /* ios_freerdp_events.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EEAD16B910F60041304E /* ios_freerdp_events.m */; };
+               C495EEB316B910F60041304E /* ios_freerdp_ui.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EEAF16B910F60041304E /* ios_freerdp_ui.m */; };
+               C495EEB416B910F60041304E /* ios_freerdp.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EEB116B910F60041304E /* ios_freerdp.m */; };
+               C495EEBD16B9111A0041304E /* Reachability.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EEB716B9111A0041304E /* Reachability.m */; };
+               C495EEBE16B9111A0041304E /* SFHFKeychainUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EEB916B9111A0041304E /* SFHFKeychainUtils.m */; };
+               C495EEBF16B9111A0041304E /* Utils.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EEBC16B9111A0041304E /* Utils.m */; };
+               C495EECD16B911290041304E /* Bookmark.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EEC216B911290041304E /* Bookmark.m */; };
+               C495EECE16B911290041304E /* ConnectionParams.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EEC416B911290041304E /* ConnectionParams.m */; };
+               C495EECF16B911290041304E /* Encryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EEC616B911290041304E /* Encryptor.m */; };
+               C495EED016B911290041304E /* GlobalDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EEC816B911290041304E /* GlobalDefaults.m */; };
+               C495EED116B911290041304E /* RDPKeyboard.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EECA16B911290041304E /* RDPKeyboard.m */; };
+               C495EED216B911290041304E /* RDPSession.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EECC16B911290041304E /* RDPSession.m */; };
+               C495EF3216B911450041304E /* BookmarkListView.xib in Resources */ = {isa = PBXBuildFile; fileRef = C495EEDA16B911450041304E /* BookmarkListView.xib */; };
+               C495EF3316B911450041304E /* BookmarkTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = C495EEDB16B911450041304E /* BookmarkTableViewCell.xib */; };
+               C495EF3416B911450041304E /* cancel_button_background.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EEDC16B911450041304E /* cancel_button_background.png */; };
+               C495EF3516B911450041304E /* CredentialsInputView.xib in Resources */ = {isa = PBXBuildFile; fileRef = C495EEDD16B911450041304E /* CredentialsInputView.xib */; };
+               C495EF3616B911450041304E /* Default-Landscape@2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EEDE16B911450041304E /* Default-Landscape@2x~ipad.png */; };
+               C495EF3716B911450041304E /* Default-Landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EEDF16B911450041304E /* Default-Landscape~ipad.png */; };
+               C495EF3816B911450041304E /* Default-Portrait@2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EEE016B911450041304E /* Default-Portrait@2x~ipad.png */; };
+               C495EF3916B911450041304E /* Default-Portrait~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EEE116B911450041304E /* Default-Portrait~ipad.png */; };
+               C495EF3A16B911450041304E /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EEE216B911450041304E /* Default.png */; };
+               C495EF3B16B911450041304E /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EEE316B911450041304E /* Default@2x.png */; };
+               C495EF3C16B911450041304E /* EditButtonTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = C495EEE416B911450041304E /* EditButtonTableViewCell.xib */; };
+               C495EF3D16B911450041304E /* EditFlagTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = C495EEE516B911450041304E /* EditFlagTableViewCell.xib */; };
+               C495EF3E16B911450041304E /* EditSecretTextTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = C495EEE616B911450041304E /* EditSecretTextTableViewCell.xib */; };
+               C495EF3F16B911450041304E /* EditSelectionTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = C495EEE716B911450041304E /* EditSelectionTableViewCell.xib */; };
+               C495EF4016B911450041304E /* EditSubEditTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = C495EEE816B911450041304E /* EditSubEditTableViewCell.xib */; };
+               C495EF4116B911450041304E /* EditTextTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = C495EEE916B911450041304E /* EditTextTableViewCell.xib */; };
+               C495EF5316B911450041304E /* icon_accessory_star_off.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EEFE16B911450041304E /* icon_accessory_star_off.png */; };
+               C495EF5416B911450041304E /* icon_accessory_star_on.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EEFF16B911450041304E /* icon_accessory_star_on.png */; };
+               C495EF5516B911450041304E /* icon_key_arrow_down.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EF0016B911450041304E /* icon_key_arrow_down.png */; };
+               C495EF5616B911450041304E /* icon_key_arrow_left.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EF0116B911450041304E /* icon_key_arrow_left.png */; };
+               C495EF5716B911450041304E /* icon_key_arrow_right.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EF0216B911450041304E /* icon_key_arrow_right.png */; };
+               C495EF5816B911450041304E /* icon_key_arrow_up.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EF0316B911450041304E /* icon_key_arrow_up.png */; };
+               C495EF5916B911450041304E /* icon_key_arrows.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EF0416B911450041304E /* icon_key_arrows.png */; };
+               C495EF5A16B911450041304E /* icon_key_backspace.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EF0516B911450041304E /* icon_key_backspace.png */; };
+               C495EF5B16B911450041304E /* icon_key_menu.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EF0616B911450041304E /* icon_key_menu.png */; };
+               C495EF5C16B911450041304E /* icon_key_return.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EF0716B911450041304E /* icon_key_return.png */; };
+               C495EF5D16B911450041304E /* icon_key_win.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EF0816B911450041304E /* icon_key_win.png */; };
+               C495EF5E16B911450041304E /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EF0916B911450041304E /* Icon-72.png */; };
+               C495EF5F16B911450041304E /* Icon-72@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EF0A16B911450041304E /* Icon-72@2x.png */; };
+               C495EF6016B911450041304E /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EF0B16B911450041304E /* Icon.png */; };
+               C495EF6116B911450041304E /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EF0C16B911450041304E /* Icon@2x.png */; };
+               C495EF6216B911450041304E /* keyboard_button_background.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EF0D16B911450041304E /* keyboard_button_background.png */; };
+               C495EF6316B911450041304E /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = C495EF0E16B911450041304E /* MainWindow.xib */; };
+               C495EF6416B911450041304E /* RDPConnectingView.xib in Resources */ = {isa = PBXBuildFile; fileRef = C495EF0F16B911450041304E /* RDPConnectingView.xib */; };
+               C495EF6516B911450041304E /* RDPSessionView.xib in Resources */ = {isa = PBXBuildFile; fileRef = C495EF1016B911450041304E /* RDPSessionView.xib */; };
+               C495EF6616B911450041304E /* SessionTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = C495EF1116B911450041304E /* SessionTableViewCell.xib */; };
+               C495EF6716B911450041304E /* tabbar_icon_about.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EF1216B911450041304E /* tabbar_icon_about.png */; };
+               C495EF6816B911450041304E /* tabbar_icon_help.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EF1316B911450041304E /* tabbar_icon_help.png */; };
+               C495EF6916B911450041304E /* tabbar_icon_settings.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EF1416B911450041304E /* tabbar_icon_settings.png */; };
+               C495EF6A16B911450041304E /* toolbar_icon_disconnect.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EF1516B911450041304E /* toolbar_icon_disconnect.png */; };
+               C495EF6B16B911450041304E /* toolbar_icon_extkeyboad.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EF1616B911450041304E /* toolbar_icon_extkeyboad.png */; };
+               C495EF6C16B911450041304E /* toolbar_icon_home.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EF1716B911450041304E /* toolbar_icon_home.png */; };
+               C495EF6D16B911450041304E /* toolbar_icon_keyboard.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EF1816B911450041304E /* toolbar_icon_keyboard.png */; };
+               C495EF6E16B911450041304E /* toolbar_icon_touchpointer.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EF1916B911450041304E /* toolbar_icon_touchpointer.png */; };
+               C495EF6F16B911450041304E /* toolbar_icon_win.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EF1A16B911450041304E /* toolbar_icon_win.png */; };
+               C495EF7016B911450041304E /* touch_pointer_active.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EF1B16B911450041304E /* touch_pointer_active.png */; };
+               C495EF7116B911450041304E /* touch_pointer_default.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EF1C16B911450041304E /* touch_pointer_default.png */; };
+               C495EF7216B911450041304E /* touch_pointer_extkeyboard.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EF1D16B911450041304E /* touch_pointer_extkeyboard.png */; };
+               C495EF7316B911450041304E /* touch_pointer_keyboard.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EF1E16B911450041304E /* touch_pointer_keyboard.png */; };
+               C495EF7416B911450041304E /* touch_pointer_lclick.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EF1F16B911450041304E /* touch_pointer_lclick.png */; };
+               C495EF7516B911450041304E /* touch_pointer_rclick.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EF2016B911450041304E /* touch_pointer_rclick.png */; };
+               C495EF7616B911450041304E /* touch_pointer_reset.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EF2116B911450041304E /* touch_pointer_reset.png */; };
+               C495EF7716B911450041304E /* touch_pointer_scroll.png in Resources */ = {isa = PBXBuildFile; fileRef = C495EF2216B911450041304E /* touch_pointer_scroll.png */; };
+               C495EF7816B911450041304E /* VerifyCertificateView.xib in Resources */ = {isa = PBXBuildFile; fileRef = C495EF2316B911450041304E /* VerifyCertificateView.xib */; };
+               C495EF9A16B911AC0041304E /* AdvancedKeyboardView.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EF8316B911AB0041304E /* AdvancedKeyboardView.m */; };
+               C495EF9B16B911AC0041304E /* BookmarkTableCell.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EF8516B911AB0041304E /* BookmarkTableCell.m */; };
+               C495EF9C16B911AC0041304E /* EditButtonTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EF8716B911AB0041304E /* EditButtonTableViewCell.m */; };
+               C495EF9D16B911AC0041304E /* EditFlagTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EF8916B911AB0041304E /* EditFlagTableViewCell.m */; };
+               C495EF9E16B911AC0041304E /* EditSecretTextTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EF8B16B911AB0041304E /* EditSecretTextTableViewCell.m */; };
+               C495EF9F16B911AC0041304E /* EditSelectionTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EF8D16B911AB0041304E /* EditSelectionTableViewCell.m */; };
+               C495EFA016B911AC0041304E /* EditSubEditTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EF8F16B911AB0041304E /* EditSubEditTableViewCell.m */; };
+               C495EFA116B911AC0041304E /* EditTextTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EF9116B911AB0041304E /* EditTextTableViewCell.m */; };
+               C495EFA216B911AC0041304E /* RDPSessionView.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EF9316B911AB0041304E /* RDPSessionView.m */; };
+               C495EFA316B911AC0041304E /* SessionTableCell.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EF9516B911AB0041304E /* SessionTableCell.m */; };
+               C495EFA416B911AC0041304E /* TouchPointerView.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EF9716B911AB0041304E /* TouchPointerView.m */; };
+               C495EFAB16B912C40041304E /* libfreerdp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C495EFAA16B912C40041304E /* libfreerdp.a */; };
+               C495EFAE16B913980041304E /* libwinpr.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C495EFAD16B913980041304E /* libwinpr.a */; };
+               C495EFBB16B92E170041304E /* about_page in Resources */ = {isa = PBXBuildFile; fileRef = C495EFBA16B92E170041304E /* about_page */; };
+               C495EFBD16B92E270041304E /* help_page in Resources */ = {isa = PBXBuildFile; fileRef = C495EFBC16B92E270041304E /* help_page */; };
+               C495EFC216B92EA20041304E /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = C495EFC016B92EA20041304E /* Localizable.strings */; };
+               C495EFCB16B933230041304E /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EFC916B933230041304E /* AppDelegate.m */; };
+               C495EFCC16B933230041304E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C495EFCA16B933230041304E /* main.m */; };
+               C495F01716B937F90041304E /* libcrypto.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C495F01516B937F80041304E /* libcrypto.a */; };
+               C495F01816B937F90041304E /* libssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C495F01616B937F90041304E /* libssl.a */; };
+               C495F01A16B938210041304E /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C495F01916B938210041304E /* Security.framework */; };
+               C495F01E16B938CB0041304E /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C495F01D16B938CA0041304E /* SystemConfiguration.framework */; };
+               C4C31C6F16BAD1890087BB12 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = C4C31C6E16BAD1890087BB12 /* Default-568h@2x.png */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+               C495EE2F16B8372D0041304E /* iFreeRDP.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iFreeRDP.app; sourceTree = BUILT_PRODUCTS_DIR; };
+               C495EE3316B8372D0041304E /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
+               C495EE3516B8372D0041304E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+               C495EE3716B8372D0041304E /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
+               C495EE4116B8372D0041304E /* iFreeRDP-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "iFreeRDP-Prefix.pch"; sourceTree = "<group>"; };
+               C495EE6D16B910510041304E /* iFreeRDP.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = iFreeRDP.plist; sourceTree = SOURCE_ROOT; };
+               C495EE6F16B9107D0041304E /* Defaults.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Defaults.plist; sourceTree = SOURCE_ROOT; };
+               C495EE7116B910BC0041304E /* OrderedDictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OrderedDictionary.h; path = Additions/OrderedDictionary.h; sourceTree = SOURCE_ROOT; };
+               C495EE7216B910BC0041304E /* OrderedDictionary.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OrderedDictionary.m; path = Additions/OrderedDictionary.m; sourceTree = SOURCE_ROOT; };
+               C495EE7316B910BC0041304E /* Toast+UIView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "Toast+UIView.h"; path = "Additions/Toast+UIView.h"; sourceTree = SOURCE_ROOT; };
+               C495EE7416B910BC0041304E /* Toast+UIView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "Toast+UIView.m"; path = "Additions/Toast+UIView.m"; sourceTree = SOURCE_ROOT; };
+               C495EE7516B910BC0041304E /* TSXAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TSXAdditions.h; path = Additions/TSXAdditions.h; sourceTree = SOURCE_ROOT; };
+               C495EE7616B910BC0041304E /* TSXAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TSXAdditions.m; path = Additions/TSXAdditions.m; sourceTree = SOURCE_ROOT; };
+               C495EE7B16B910DE0041304E /* AboutController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AboutController.h; path = Controllers/AboutController.h; sourceTree = SOURCE_ROOT; };
+               C495EE7C16B910DE0041304E /* AboutController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AboutController.m; path = Controllers/AboutController.m; sourceTree = SOURCE_ROOT; };
+               C495EE7D16B910DE0041304E /* AdvancedBookmarkEditorController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AdvancedBookmarkEditorController.h; path = Controllers/AdvancedBookmarkEditorController.h; sourceTree = SOURCE_ROOT; };
+               C495EE7E16B910DE0041304E /* AdvancedBookmarkEditorController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AdvancedBookmarkEditorController.m; path = Controllers/AdvancedBookmarkEditorController.m; sourceTree = SOURCE_ROOT; };
+               C495EE7F16B910DE0041304E /* AppSettingsController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppSettingsController.h; path = Controllers/AppSettingsController.h; sourceTree = SOURCE_ROOT; };
+               C495EE8016B910DE0041304E /* AppSettingsController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppSettingsController.m; path = Controllers/AppSettingsController.m; sourceTree = SOURCE_ROOT; };
+               C495EE8116B910DE0041304E /* BookmarkEditorController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BookmarkEditorController.h; path = Controllers/BookmarkEditorController.h; sourceTree = SOURCE_ROOT; };
+               C495EE8216B910DE0041304E /* BookmarkEditorController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BookmarkEditorController.m; path = Controllers/BookmarkEditorController.m; sourceTree = SOURCE_ROOT; };
+               C495EE8316B910DE0041304E /* BookmarkListController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BookmarkListController.h; path = Controllers/BookmarkListController.h; sourceTree = SOURCE_ROOT; };
+               C495EE8416B910DE0041304E /* BookmarkListController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BookmarkListController.m; path = Controllers/BookmarkListController.m; sourceTree = SOURCE_ROOT; };
+               C495EE8516B910DE0041304E /* CredentialsEditorController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CredentialsEditorController.h; path = Controllers/CredentialsEditorController.h; sourceTree = SOURCE_ROOT; };
+               C495EE8616B910DE0041304E /* CredentialsEditorController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CredentialsEditorController.m; path = Controllers/CredentialsEditorController.m; sourceTree = SOURCE_ROOT; };
+               C495EE8716B910DE0041304E /* CredentialsInputController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CredentialsInputController.h; path = Controllers/CredentialsInputController.h; sourceTree = SOURCE_ROOT; };
+               C495EE8816B910DE0041304E /* CredentialsInputController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CredentialsInputController.m; path = Controllers/CredentialsInputController.m; sourceTree = SOURCE_ROOT; };
+               C495EE8916B910DE0041304E /* EditorBaseController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EditorBaseController.h; path = Controllers/EditorBaseController.h; sourceTree = SOURCE_ROOT; };
+               C495EE8A16B910DE0041304E /* EditorBaseController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = EditorBaseController.m; path = Controllers/EditorBaseController.m; sourceTree = SOURCE_ROOT; };
+               C495EE8B16B910DE0041304E /* EditorSelectionController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EditorSelectionController.h; path = Controllers/EditorSelectionController.h; sourceTree = SOURCE_ROOT; };
+               C495EE8C16B910DE0041304E /* EditorSelectionController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = EditorSelectionController.m; path = Controllers/EditorSelectionController.m; sourceTree = SOURCE_ROOT; };
+               C495EE8D16B910DE0041304E /* EncryptionController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EncryptionController.h; path = Controllers/EncryptionController.h; sourceTree = SOURCE_ROOT; };
+               C495EE8E16B910DE0041304E /* EncryptionController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = EncryptionController.m; path = Controllers/EncryptionController.m; sourceTree = SOURCE_ROOT; };
+               C495EE8F16B910DE0041304E /* HelpController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HelpController.h; path = Controllers/HelpController.h; sourceTree = SOURCE_ROOT; };
+               C495EE9016B910DE0041304E /* HelpController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HelpController.m; path = Controllers/HelpController.m; sourceTree = SOURCE_ROOT; };
+               C495EE9116B910DE0041304E /* MainTabBarController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MainTabBarController.h; path = Controllers/MainTabBarController.h; sourceTree = SOURCE_ROOT; };
+               C495EE9216B910DE0041304E /* MainTabBarController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MainTabBarController.m; path = Controllers/MainTabBarController.m; sourceTree = SOURCE_ROOT; };
+               C495EE9316B910DE0041304E /* PerformanceEditorController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PerformanceEditorController.h; path = Controllers/PerformanceEditorController.h; sourceTree = SOURCE_ROOT; };
+               C495EE9416B910DE0041304E /* PerformanceEditorController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PerformanceEditorController.m; path = Controllers/PerformanceEditorController.m; sourceTree = SOURCE_ROOT; };
+               C495EE9516B910DE0041304E /* RDPSessionViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RDPSessionViewController.h; path = Controllers/RDPSessionViewController.h; sourceTree = SOURCE_ROOT; };
+               C495EE9616B910DE0041304E /* RDPSessionViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RDPSessionViewController.m; path = Controllers/RDPSessionViewController.m; sourceTree = SOURCE_ROOT; };
+               C495EE9716B910DE0041304E /* ScreenSelectionController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ScreenSelectionController.h; path = Controllers/ScreenSelectionController.h; sourceTree = SOURCE_ROOT; };
+               C495EE9816B910DE0041304E /* ScreenSelectionController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ScreenSelectionController.m; path = Controllers/ScreenSelectionController.m; sourceTree = SOURCE_ROOT; };
+               C495EE9916B910DE0041304E /* VerifyCertificateController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VerifyCertificateController.h; path = Controllers/VerifyCertificateController.h; sourceTree = SOURCE_ROOT; };
+               C495EE9A16B910DE0041304E /* VerifyCertificateController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VerifyCertificateController.m; path = Controllers/VerifyCertificateController.m; sourceTree = SOURCE_ROOT; };
+               C495EEAC16B910F60041304E /* ios_freerdp_events.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ios_freerdp_events.h; path = FreeRDP/ios_freerdp_events.h; sourceTree = SOURCE_ROOT; };
+               C495EEAD16B910F60041304E /* ios_freerdp_events.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ios_freerdp_events.m; path = FreeRDP/ios_freerdp_events.m; sourceTree = SOURCE_ROOT; };
+               C495EEAE16B910F60041304E /* ios_freerdp_ui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ios_freerdp_ui.h; path = FreeRDP/ios_freerdp_ui.h; sourceTree = SOURCE_ROOT; };
+               C495EEAF16B910F60041304E /* ios_freerdp_ui.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ios_freerdp_ui.m; path = FreeRDP/ios_freerdp_ui.m; sourceTree = SOURCE_ROOT; };
+               C495EEB016B910F60041304E /* ios_freerdp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ios_freerdp.h; path = FreeRDP/ios_freerdp.h; sourceTree = SOURCE_ROOT; };
+               C495EEB116B910F60041304E /* ios_freerdp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ios_freerdp.m; path = FreeRDP/ios_freerdp.m; sourceTree = SOURCE_ROOT; };
+               C495EEB616B9111A0041304E /* Reachability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Reachability.h; path = Misc/Reachability.h; sourceTree = SOURCE_ROOT; };
+               C495EEB716B9111A0041304E /* Reachability.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Reachability.m; path = Misc/Reachability.m; sourceTree = SOURCE_ROOT; };
+               C495EEB816B9111A0041304E /* SFHFKeychainUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SFHFKeychainUtils.h; path = Misc/SFHFKeychainUtils.h; sourceTree = SOURCE_ROOT; };
+               C495EEB916B9111A0041304E /* SFHFKeychainUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SFHFKeychainUtils.m; path = Misc/SFHFKeychainUtils.m; sourceTree = SOURCE_ROOT; };
+               C495EEBA16B9111A0041304E /* TSXTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TSXTypes.h; path = Misc/TSXTypes.h; sourceTree = SOURCE_ROOT; };
+               C495EEBB16B9111A0041304E /* Utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Utils.h; path = Misc/Utils.h; sourceTree = SOURCE_ROOT; };
+               C495EEBC16B9111A0041304E /* Utils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Utils.m; path = Misc/Utils.m; sourceTree = SOURCE_ROOT; };
+               C495EEC116B911290041304E /* Bookmark.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Bookmark.h; path = Models/Bookmark.h; sourceTree = SOURCE_ROOT; };
+               C495EEC216B911290041304E /* Bookmark.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Bookmark.m; path = Models/Bookmark.m; sourceTree = SOURCE_ROOT; };
+               C495EEC316B911290041304E /* ConnectionParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ConnectionParams.h; path = Models/ConnectionParams.h; sourceTree = SOURCE_ROOT; };
+               C495EEC416B911290041304E /* ConnectionParams.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ConnectionParams.m; path = Models/ConnectionParams.m; sourceTree = SOURCE_ROOT; };
+               C495EEC516B911290041304E /* Encryptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Encryptor.h; path = Models/Encryptor.h; sourceTree = SOURCE_ROOT; };
+               C495EEC616B911290041304E /* Encryptor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Encryptor.m; path = Models/Encryptor.m; sourceTree = SOURCE_ROOT; };
+               C495EEC716B911290041304E /* GlobalDefaults.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GlobalDefaults.h; path = Models/GlobalDefaults.h; sourceTree = SOURCE_ROOT; };
+               C495EEC816B911290041304E /* GlobalDefaults.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GlobalDefaults.m; path = Models/GlobalDefaults.m; sourceTree = SOURCE_ROOT; };
+               C495EEC916B911290041304E /* RDPKeyboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RDPKeyboard.h; path = Models/RDPKeyboard.h; sourceTree = SOURCE_ROOT; };
+               C495EECA16B911290041304E /* RDPKeyboard.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RDPKeyboard.m; path = Models/RDPKeyboard.m; sourceTree = SOURCE_ROOT; };
+               C495EECB16B911290041304E /* RDPSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RDPSession.h; path = Models/RDPSession.h; sourceTree = SOURCE_ROOT; };
+               C495EECC16B911290041304E /* RDPSession.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RDPSession.m; path = Models/RDPSession.m; sourceTree = SOURCE_ROOT; };
+               C495EEDA16B911450041304E /* BookmarkListView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = BookmarkListView.xib; path = Resources/BookmarkListView.xib; sourceTree = SOURCE_ROOT; };
+               C495EEDB16B911450041304E /* BookmarkTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = BookmarkTableViewCell.xib; path = Resources/BookmarkTableViewCell.xib; sourceTree = SOURCE_ROOT; };
+               C495EEDC16B911450041304E /* cancel_button_background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = cancel_button_background.png; path = Resources/cancel_button_background.png; sourceTree = SOURCE_ROOT; };
+               C495EEDD16B911450041304E /* CredentialsInputView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = CredentialsInputView.xib; path = Resources/CredentialsInputView.xib; sourceTree = SOURCE_ROOT; };
+               C495EEDE16B911450041304E /* Default-Landscape@2x~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-Landscape@2x~ipad.png"; path = "Resources/Default-Landscape@2x~ipad.png"; sourceTree = SOURCE_ROOT; };
+               C495EEDF16B911450041304E /* Default-Landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-Landscape~ipad.png"; path = "Resources/Default-Landscape~ipad.png"; sourceTree = SOURCE_ROOT; };
+               C495EEE016B911450041304E /* Default-Portrait@2x~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-Portrait@2x~ipad.png"; path = "Resources/Default-Portrait@2x~ipad.png"; sourceTree = SOURCE_ROOT; };
+               C495EEE116B911450041304E /* Default-Portrait~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-Portrait~ipad.png"; path = "Resources/Default-Portrait~ipad.png"; sourceTree = SOURCE_ROOT; };
+               C495EEE216B911450041304E /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Default.png; path = Resources/Default.png; sourceTree = SOURCE_ROOT; };
+               C495EEE316B911450041304E /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default@2x.png"; path = "Resources/Default@2x.png"; sourceTree = SOURCE_ROOT; };
+               C495EEE416B911450041304E /* EditButtonTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = EditButtonTableViewCell.xib; path = Resources/EditButtonTableViewCell.xib; sourceTree = SOURCE_ROOT; };
+               C495EEE516B911450041304E /* EditFlagTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = EditFlagTableViewCell.xib; path = Resources/EditFlagTableViewCell.xib; sourceTree = SOURCE_ROOT; };
+               C495EEE616B911450041304E /* EditSecretTextTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = EditSecretTextTableViewCell.xib; path = Resources/EditSecretTextTableViewCell.xib; sourceTree = SOURCE_ROOT; };
+               C495EEE716B911450041304E /* EditSelectionTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = EditSelectionTableViewCell.xib; path = Resources/EditSelectionTableViewCell.xib; sourceTree = SOURCE_ROOT; };
+               C495EEE816B911450041304E /* EditSubEditTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = EditSubEditTableViewCell.xib; path = Resources/EditSubEditTableViewCell.xib; sourceTree = SOURCE_ROOT; };
+               C495EEE916B911450041304E /* EditTextTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = EditTextTableViewCell.xib; path = Resources/EditTextTableViewCell.xib; sourceTree = SOURCE_ROOT; };
+               C495EEFE16B911450041304E /* icon_accessory_star_off.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = icon_accessory_star_off.png; path = Resources/icon_accessory_star_off.png; sourceTree = SOURCE_ROOT; };
+               C495EEFF16B911450041304E /* icon_accessory_star_on.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = icon_accessory_star_on.png; path = Resources/icon_accessory_star_on.png; sourceTree = SOURCE_ROOT; };
+               C495EF0016B911450041304E /* icon_key_arrow_down.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = icon_key_arrow_down.png; path = Resources/icon_key_arrow_down.png; sourceTree = SOURCE_ROOT; };
+               C495EF0116B911450041304E /* icon_key_arrow_left.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = icon_key_arrow_left.png; path = Resources/icon_key_arrow_left.png; sourceTree = SOURCE_ROOT; };
+               C495EF0216B911450041304E /* icon_key_arrow_right.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = icon_key_arrow_right.png; path = Resources/icon_key_arrow_right.png; sourceTree = SOURCE_ROOT; };
+               C495EF0316B911450041304E /* icon_key_arrow_up.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = icon_key_arrow_up.png; path = Resources/icon_key_arrow_up.png; sourceTree = SOURCE_ROOT; };
+               C495EF0416B911450041304E /* icon_key_arrows.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = icon_key_arrows.png; path = Resources/icon_key_arrows.png; sourceTree = SOURCE_ROOT; };
+               C495EF0516B911450041304E /* icon_key_backspace.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = icon_key_backspace.png; path = Resources/icon_key_backspace.png; sourceTree = SOURCE_ROOT; };
+               C495EF0616B911450041304E /* icon_key_menu.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = icon_key_menu.png; path = Resources/icon_key_menu.png; sourceTree = SOURCE_ROOT; };
+               C495EF0716B911450041304E /* icon_key_return.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = icon_key_return.png; path = Resources/icon_key_return.png; sourceTree = SOURCE_ROOT; };
+               C495EF0816B911450041304E /* icon_key_win.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = icon_key_win.png; path = Resources/icon_key_win.png; sourceTree = SOURCE_ROOT; };
+               C495EF0916B911450041304E /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "Resources/Icon-72.png"; sourceTree = SOURCE_ROOT; };
+               C495EF0A16B911450041304E /* Icon-72@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72@2x.png"; path = "Resources/Icon-72@2x.png"; sourceTree = SOURCE_ROOT; };
+               C495EF0B16B911450041304E /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = Resources/Icon.png; sourceTree = SOURCE_ROOT; };
+               C495EF0C16B911450041304E /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "Resources/Icon@2x.png"; sourceTree = SOURCE_ROOT; };
+               C495EF0D16B911450041304E /* keyboard_button_background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = keyboard_button_background.png; path = Resources/keyboard_button_background.png; sourceTree = SOURCE_ROOT; };
+               C495EF0E16B911450041304E /* MainWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = MainWindow.xib; path = Resources/MainWindow.xib; sourceTree = SOURCE_ROOT; };
+               C495EF0F16B911450041304E /* RDPConnectingView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = RDPConnectingView.xib; path = Resources/RDPConnectingView.xib; sourceTree = SOURCE_ROOT; };
+               C495EF1016B911450041304E /* RDPSessionView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = RDPSessionView.xib; path = Resources/RDPSessionView.xib; sourceTree = SOURCE_ROOT; };
+               C495EF1116B911450041304E /* SessionTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = SessionTableViewCell.xib; path = Resources/SessionTableViewCell.xib; sourceTree = SOURCE_ROOT; };
+               C495EF1216B911450041304E /* tabbar_icon_about.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = tabbar_icon_about.png; path = Resources/tabbar_icon_about.png; sourceTree = SOURCE_ROOT; };
+               C495EF1316B911450041304E /* tabbar_icon_help.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = tabbar_icon_help.png; path = Resources/tabbar_icon_help.png; sourceTree = SOURCE_ROOT; };
+               C495EF1416B911450041304E /* tabbar_icon_settings.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = tabbar_icon_settings.png; path = Resources/tabbar_icon_settings.png; sourceTree = SOURCE_ROOT; };
+               C495EF1516B911450041304E /* toolbar_icon_disconnect.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = toolbar_icon_disconnect.png; path = Resources/toolbar_icon_disconnect.png; sourceTree = SOURCE_ROOT; };
+               C495EF1616B911450041304E /* toolbar_icon_extkeyboad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = toolbar_icon_extkeyboad.png; path = Resources/toolbar_icon_extkeyboad.png; sourceTree = SOURCE_ROOT; };
+               C495EF1716B911450041304E /* toolbar_icon_home.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = toolbar_icon_home.png; path = Resources/toolbar_icon_home.png; sourceTree = SOURCE_ROOT; };
+               C495EF1816B911450041304E /* toolbar_icon_keyboard.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = toolbar_icon_keyboard.png; path = Resources/toolbar_icon_keyboard.png; sourceTree = SOURCE_ROOT; };
+               C495EF1916B911450041304E /* toolbar_icon_touchpointer.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = toolbar_icon_touchpointer.png; path = Resources/toolbar_icon_touchpointer.png; sourceTree = SOURCE_ROOT; };
+               C495EF1A16B911450041304E /* toolbar_icon_win.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = toolbar_icon_win.png; path = Resources/toolbar_icon_win.png; sourceTree = SOURCE_ROOT; };
+               C495EF1B16B911450041304E /* touch_pointer_active.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = touch_pointer_active.png; path = Resources/touch_pointer_active.png; sourceTree = SOURCE_ROOT; };
+               C495EF1C16B911450041304E /* touch_pointer_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = touch_pointer_default.png; path = Resources/touch_pointer_default.png; sourceTree = SOURCE_ROOT; };
+               C495EF1D16B911450041304E /* touch_pointer_extkeyboard.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = touch_pointer_extkeyboard.png; path = Resources/touch_pointer_extkeyboard.png; sourceTree = SOURCE_ROOT; };
+               C495EF1E16B911450041304E /* touch_pointer_keyboard.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = touch_pointer_keyboard.png; path = Resources/touch_pointer_keyboard.png; sourceTree = SOURCE_ROOT; };
+               C495EF1F16B911450041304E /* touch_pointer_lclick.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = touch_pointer_lclick.png; path = Resources/touch_pointer_lclick.png; sourceTree = SOURCE_ROOT; };
+               C495EF2016B911450041304E /* touch_pointer_rclick.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = touch_pointer_rclick.png; path = Resources/touch_pointer_rclick.png; sourceTree = SOURCE_ROOT; };
+               C495EF2116B911450041304E /* touch_pointer_reset.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = touch_pointer_reset.png; path = Resources/touch_pointer_reset.png; sourceTree = SOURCE_ROOT; };
+               C495EF2216B911450041304E /* touch_pointer_scroll.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = touch_pointer_scroll.png; path = Resources/touch_pointer_scroll.png; sourceTree = SOURCE_ROOT; };
+               C495EF2316B911450041304E /* VerifyCertificateView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = VerifyCertificateView.xib; path = Resources/VerifyCertificateView.xib; sourceTree = SOURCE_ROOT; };
+               C495EF8216B911AB0041304E /* AdvancedKeyboardView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AdvancedKeyboardView.h; path = Views/AdvancedKeyboardView.h; sourceTree = SOURCE_ROOT; };
+               C495EF8316B911AB0041304E /* AdvancedKeyboardView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AdvancedKeyboardView.m; path = Views/AdvancedKeyboardView.m; sourceTree = SOURCE_ROOT; };
+               C495EF8416B911AB0041304E /* BookmarkTableCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BookmarkTableCell.h; path = Views/BookmarkTableCell.h; sourceTree = SOURCE_ROOT; };
+               C495EF8516B911AB0041304E /* BookmarkTableCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BookmarkTableCell.m; path = Views/BookmarkTableCell.m; sourceTree = SOURCE_ROOT; };
+               C495EF8616B911AB0041304E /* EditButtonTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EditButtonTableViewCell.h; path = Views/EditButtonTableViewCell.h; sourceTree = SOURCE_ROOT; };
+               C495EF8716B911AB0041304E /* EditButtonTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = EditButtonTableViewCell.m; path = Views/EditButtonTableViewCell.m; sourceTree = SOURCE_ROOT; };
+               C495EF8816B911AB0041304E /* EditFlagTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EditFlagTableViewCell.h; path = Views/EditFlagTableViewCell.h; sourceTree = SOURCE_ROOT; };
+               C495EF8916B911AB0041304E /* EditFlagTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = EditFlagTableViewCell.m; path = Views/EditFlagTableViewCell.m; sourceTree = SOURCE_ROOT; };
+               C495EF8A16B911AB0041304E /* EditSecretTextTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EditSecretTextTableViewCell.h; path = Views/EditSecretTextTableViewCell.h; sourceTree = SOURCE_ROOT; };
+               C495EF8B16B911AB0041304E /* EditSecretTextTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = EditSecretTextTableViewCell.m; path = Views/EditSecretTextTableViewCell.m; sourceTree = SOURCE_ROOT; };
+               C495EF8C16B911AB0041304E /* EditSelectionTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EditSelectionTableViewCell.h; path = Views/EditSelectionTableViewCell.h; sourceTree = SOURCE_ROOT; };
+               C495EF8D16B911AB0041304E /* EditSelectionTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = EditSelectionTableViewCell.m; path = Views/EditSelectionTableViewCell.m; sourceTree = SOURCE_ROOT; };
+               C495EF8E16B911AB0041304E /* EditSubEditTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EditSubEditTableViewCell.h; path = Views/EditSubEditTableViewCell.h; sourceTree = SOURCE_ROOT; };
+               C495EF8F16B911AB0041304E /* EditSubEditTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = EditSubEditTableViewCell.m; path = Views/EditSubEditTableViewCell.m; sourceTree = SOURCE_ROOT; };
+               C495EF9016B911AB0041304E /* EditTextTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EditTextTableViewCell.h; path = Views/EditTextTableViewCell.h; sourceTree = SOURCE_ROOT; };
+               C495EF9116B911AB0041304E /* EditTextTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = EditTextTableViewCell.m; path = Views/EditTextTableViewCell.m; sourceTree = SOURCE_ROOT; };
+               C495EF9216B911AB0041304E /* RDPSessionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RDPSessionView.h; path = Views/RDPSessionView.h; sourceTree = SOURCE_ROOT; };
+               C495EF9316B911AB0041304E /* RDPSessionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RDPSessionView.m; path = Views/RDPSessionView.m; sourceTree = SOURCE_ROOT; };
+               C495EF9416B911AB0041304E /* SessionTableCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SessionTableCell.h; path = Views/SessionTableCell.h; sourceTree = SOURCE_ROOT; };
+               C495EF9516B911AB0041304E /* SessionTableCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SessionTableCell.m; path = Views/SessionTableCell.m; sourceTree = SOURCE_ROOT; };
+               C495EF9616B911AB0041304E /* TouchPointerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TouchPointerView.h; path = Views/TouchPointerView.h; sourceTree = SOURCE_ROOT; };
+               C495EF9716B911AB0041304E /* TouchPointerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TouchPointerView.m; path = Views/TouchPointerView.m; sourceTree = SOURCE_ROOT; };
+               C495EFAA16B912C40041304E /* libfreerdp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libfreerdp.a; path = ../../libfreerdp/libfreerdp.a; sourceTree = "<group>"; };
+               C495EFAD16B913980041304E /* libwinpr.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libwinpr.a; path = ../../winpr/libwinpr/libwinpr.a; sourceTree = "<group>"; };
+               C495EFBA16B92E170041304E /* about_page */ = {isa = PBXFileReference; lastKnownFileType = folder; name = about_page; path = Resources/about_page; sourceTree = SOURCE_ROOT; };
+               C495EFBC16B92E270041304E /* help_page */ = {isa = PBXFileReference; lastKnownFileType = folder; name = help_page; path = Resources/help_page; sourceTree = SOURCE_ROOT; };
+               C495EFC116B92EA20041304E /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = Resources/en.lproj/Localizable.strings; sourceTree = SOURCE_ROOT; };
+               C495EFC816B933220041304E /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = SOURCE_ROOT; };
+               C495EFC916B933230041304E /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = SOURCE_ROOT; };
+               C495EFCA16B933230041304E /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = SOURCE_ROOT; };
+               C495F01516B937F80041304E /* libcrypto.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcrypto.a; path = @FREERDP_IOS_EXTERNAL_SSL_PATH@/lib/libcrypto.a; sourceTree = "<group>"; };
+               C495F01616B937F90041304E /* libssl.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libssl.a; path = @FREERDP_IOS_EXTERNAL_SSL_PATH@/lib/libssl.a; sourceTree = "<group>"; };
+               C495F01916B938210041304E /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
+               C495F01D16B938CA0041304E /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
+               C4C31C6E16BAD1890087BB12 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-568h@2x.png"; path = "Resources/Default-568h@2x.png"; sourceTree = SOURCE_ROOT; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+               C495EE2C16B8372D0041304E /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               C495F01716B937F90041304E /* libcrypto.a in Frameworks */,
+                               C495F01816B937F90041304E /* libssl.a in Frameworks */,
+                               C495EFAE16B913980041304E /* libwinpr.a in Frameworks */,
+                               C495EFAB16B912C40041304E /* libfreerdp.a in Frameworks */,
+                               C495EE3416B8372D0041304E /* UIKit.framework in Frameworks */,
+                               C495EE3616B8372D0041304E /* Foundation.framework in Frameworks */,
+                               C495EE3816B8372D0041304E /* CoreGraphics.framework in Frameworks */,
+                               C495F01A16B938210041304E /* Security.framework in Frameworks */,
+                               C495F01E16B938CB0041304E /* SystemConfiguration.framework in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+               C495EE2416B8372D0041304E = {
+                       isa = PBXGroup;
+                       children = (
+                               C495EE3916B8372D0041304E /* iFreeRDP */,
+                               C495EE3216B8372D0041304E /* Frameworks */,
+                               C495EE3016B8372D0041304E /* Products */,
+                       );
+                       sourceTree = "<group>";
+               };
+               C495EE3016B8372D0041304E /* Products */ = {
+                       isa = PBXGroup;
+                       children = (
+                               C495EE2F16B8372D0041304E /* iFreeRDP.app */,
+                       );
+                       name = Products;
+                       sourceTree = "<group>";
+               };
+               C495EE3216B8372D0041304E /* Frameworks */ = {
+                       isa = PBXGroup;
+                       children = (
+                               C495EFAA16B912C40041304E /* libfreerdp.a */,
+                               C495EFAD16B913980041304E /* libwinpr.a */,
+                               C495F01516B937F80041304E /* libcrypto.a */,
+                               C495F01616B937F90041304E /* libssl.a */,
+                               C495F01D16B938CA0041304E /* SystemConfiguration.framework */,
+                               C495F01916B938210041304E /* Security.framework */,
+                               C495EE3316B8372D0041304E /* UIKit.framework */,
+                               C495EE3516B8372D0041304E /* Foundation.framework */,
+                               C495EE3716B8372D0041304E /* CoreGraphics.framework */,
+                       );
+                       name = Frameworks;
+                       sourceTree = "<group>";
+               };
+               C495EE3916B8372D0041304E /* iFreeRDP */ = {
+                       isa = PBXGroup;
+                       children = (
+                               C495EE3A16B8372D0041304E /* Cocoa and Foundation Additions */,
+                               C495EE7A16B910CB0041304E /* Controllers */,
+                               C495EEAB16B910E90041304E /* FreeRDP */,
+                               C495EEB516B910FA0041304E /* Misc */,
+                               C495EEC016B9111E0041304E /* Models */,
+                               C495EED316B9112E0041304E /* Resources */,
+                               C495EF8116B911940041304E /* Views */,
+                               C495EFC816B933220041304E /* AppDelegate.h */,
+                               C495EFC916B933230041304E /* AppDelegate.m */,
+                               C495EFCA16B933230041304E /* main.m */,
+                               C495EE6F16B9107D0041304E /* Defaults.plist */,
+                               C495EE6D16B910510041304E /* iFreeRDP.plist */,
+                               C495EE4116B8372D0041304E /* iFreeRDP-Prefix.pch */,
+                       );
+                       path = iFreeRDP;
+                       sourceTree = "<group>";
+               };
+               C495EE3A16B8372D0041304E /* Cocoa and Foundation Additions */ = {
+                       isa = PBXGroup;
+                       children = (
+                               C495EE7116B910BC0041304E /* OrderedDictionary.h */,
+                               C495EE7216B910BC0041304E /* OrderedDictionary.m */,
+                               C495EE7316B910BC0041304E /* Toast+UIView.h */,
+                               C495EE7416B910BC0041304E /* Toast+UIView.m */,
+                               C495EE7516B910BC0041304E /* TSXAdditions.h */,
+                               C495EE7616B910BC0041304E /* TSXAdditions.m */,
+                       );
+                       name = "Cocoa and Foundation Additions";
+                       sourceTree = "<group>";
+               };
+               C495EE7A16B910CB0041304E /* Controllers */ = {
+                       isa = PBXGroup;
+                       children = (
+                               C495EE7B16B910DE0041304E /* AboutController.h */,
+                               C495EE7C16B910DE0041304E /* AboutController.m */,
+                               C495EE7D16B910DE0041304E /* AdvancedBookmarkEditorController.h */,
+                               C495EE7E16B910DE0041304E /* AdvancedBookmarkEditorController.m */,
+                               C495EE7F16B910DE0041304E /* AppSettingsController.h */,
+                               C495EE8016B910DE0041304E /* AppSettingsController.m */,
+                               C495EE8116B910DE0041304E /* BookmarkEditorController.h */,
+                               C495EE8216B910DE0041304E /* BookmarkEditorController.m */,
+                               C495EE8316B910DE0041304E /* BookmarkListController.h */,
+                               C495EE8416B910DE0041304E /* BookmarkListController.m */,
+                               C495EE8516B910DE0041304E /* CredentialsEditorController.h */,
+                               C495EE8616B910DE0041304E /* CredentialsEditorController.m */,
+                               C495EE8716B910DE0041304E /* CredentialsInputController.h */,
+                               C495EE8816B910DE0041304E /* CredentialsInputController.m */,
+                               C495EE8916B910DE0041304E /* EditorBaseController.h */,
+                               C495EE8A16B910DE0041304E /* EditorBaseController.m */,
+                               C495EE8B16B910DE0041304E /* EditorSelectionController.h */,
+                               C495EE8C16B910DE0041304E /* EditorSelectionController.m */,
+                               C495EE8D16B910DE0041304E /* EncryptionController.h */,
+                               C495EE8E16B910DE0041304E /* EncryptionController.m */,
+                               C495EE8F16B910DE0041304E /* HelpController.h */,
+                               C495EE9016B910DE0041304E /* HelpController.m */,
+                               C495EE9116B910DE0041304E /* MainTabBarController.h */,
+                               C495EE9216B910DE0041304E /* MainTabBarController.m */,
+                               C495EE9316B910DE0041304E /* PerformanceEditorController.h */,
+                               C495EE9416B910DE0041304E /* PerformanceEditorController.m */,
+                               C495EE9516B910DE0041304E /* RDPSessionViewController.h */,
+                               C495EE9616B910DE0041304E /* RDPSessionViewController.m */,
+                               C495EE9716B910DE0041304E /* ScreenSelectionController.h */,
+                               C495EE9816B910DE0041304E /* ScreenSelectionController.m */,
+                               C495EE9916B910DE0041304E /* VerifyCertificateController.h */,
+                               C495EE9A16B910DE0041304E /* VerifyCertificateController.m */,
+                       );
+                       name = Controllers;
+                       sourceTree = "<group>";
+               };
+               C495EEAB16B910E90041304E /* FreeRDP */ = {
+                       isa = PBXGroup;
+                       children = (
+                               C495EEAC16B910F60041304E /* ios_freerdp_events.h */,
+                               C495EEAD16B910F60041304E /* ios_freerdp_events.m */,
+                               C495EEAE16B910F60041304E /* ios_freerdp_ui.h */,
+                               C495EEAF16B910F60041304E /* ios_freerdp_ui.m */,
+                               C495EEB016B910F60041304E /* ios_freerdp.h */,
+                               C495EEB116B910F60041304E /* ios_freerdp.m */,
+                       );
+                       name = FreeRDP;
+                       sourceTree = "<group>";
+               };
+               C495EEB516B910FA0041304E /* Misc */ = {
+                       isa = PBXGroup;
+                       children = (
+                               C495EEB616B9111A0041304E /* Reachability.h */,
+                               C495EEB716B9111A0041304E /* Reachability.m */,
+                               C495EEB816B9111A0041304E /* SFHFKeychainUtils.h */,
+                               C495EEB916B9111A0041304E /* SFHFKeychainUtils.m */,
+                               C495EEBA16B9111A0041304E /* TSXTypes.h */,
+                               C495EEBB16B9111A0041304E /* Utils.h */,
+                               C495EEBC16B9111A0041304E /* Utils.m */,
+                       );
+                       name = Misc;
+                       sourceTree = "<group>";
+               };
+               C495EEC016B9111E0041304E /* Models */ = {
+                       isa = PBXGroup;
+                       children = (
+                               C495EEC116B911290041304E /* Bookmark.h */,
+                               C495EEC216B911290041304E /* Bookmark.m */,
+                               C495EEC316B911290041304E /* ConnectionParams.h */,
+                               C495EEC416B911290041304E /* ConnectionParams.m */,
+                               C495EEC516B911290041304E /* Encryptor.h */,
+                               C495EEC616B911290041304E /* Encryptor.m */,
+                               C495EEC716B911290041304E /* GlobalDefaults.h */,
+                               C495EEC816B911290041304E /* GlobalDefaults.m */,
+                               C495EEC916B911290041304E /* RDPKeyboard.h */,
+                               C495EECA16B911290041304E /* RDPKeyboard.m */,
+                               C495EECB16B911290041304E /* RDPSession.h */,
+                               C495EECC16B911290041304E /* RDPSession.m */,
+                       );
+                       name = Models;
+                       sourceTree = "<group>";
+               };
+               C495EED316B9112E0041304E /* Resources */ = {
+                       isa = PBXGroup;
+                       children = (
+                               C4C31C6E16BAD1890087BB12 /* Default-568h@2x.png */,
+                               C495EFC016B92EA20041304E /* Localizable.strings */,
+                               C495EFBC16B92E270041304E /* help_page */,
+                               C495EFBA16B92E170041304E /* about_page */,
+                               C495EEDC16B911450041304E /* cancel_button_background.png */,
+                               C495EEDE16B911450041304E /* Default-Landscape@2x~ipad.png */,
+                               C495EEDF16B911450041304E /* Default-Landscape~ipad.png */,
+                               C495EEE016B911450041304E /* Default-Portrait@2x~ipad.png */,
+                               C495EEE116B911450041304E /* Default-Portrait~ipad.png */,
+                               C495EEE216B911450041304E /* Default.png */,
+                               C495EEE316B911450041304E /* Default@2x.png */,
+                               C495EEFE16B911450041304E /* icon_accessory_star_off.png */,
+                               C495EEFF16B911450041304E /* icon_accessory_star_on.png */,
+                               C495EF0016B911450041304E /* icon_key_arrow_down.png */,
+                               C495EF0116B911450041304E /* icon_key_arrow_left.png */,
+                               C495EF0216B911450041304E /* icon_key_arrow_right.png */,
+                               C495EF0316B911450041304E /* icon_key_arrow_up.png */,
+                               C495EF0416B911450041304E /* icon_key_arrows.png */,
+                               C495EF0516B911450041304E /* icon_key_backspace.png */,
+                               C495EF0616B911450041304E /* icon_key_menu.png */,
+                               C495EF0716B911450041304E /* icon_key_return.png */,
+                               C495EF0816B911450041304E /* icon_key_win.png */,
+                               C495EF0916B911450041304E /* Icon-72.png */,
+                               C495EF0A16B911450041304E /* Icon-72@2x.png */,
+                               C495EF0B16B911450041304E /* Icon.png */,
+                               C495EF0C16B911450041304E /* Icon@2x.png */,
+                               C495EF0D16B911450041304E /* keyboard_button_background.png */,
+                               C495EF1216B911450041304E /* tabbar_icon_about.png */,
+                               C495EF1316B911450041304E /* tabbar_icon_help.png */,
+                               C495EF1416B911450041304E /* tabbar_icon_settings.png */,
+                               C495EF1516B911450041304E /* toolbar_icon_disconnect.png */,
+                               C495EF1616B911450041304E /* toolbar_icon_extkeyboad.png */,
+                               C495EF1716B911450041304E /* toolbar_icon_home.png */,
+                               C495EF1816B911450041304E /* toolbar_icon_keyboard.png */,
+                               C495EF1916B911450041304E /* toolbar_icon_touchpointer.png */,
+                               C495EF1A16B911450041304E /* toolbar_icon_win.png */,
+                               C495EF1B16B911450041304E /* touch_pointer_active.png */,
+                               C495EF1C16B911450041304E /* touch_pointer_default.png */,
+                               C495EF1D16B911450041304E /* touch_pointer_extkeyboard.png */,
+                               C495EF1E16B911450041304E /* touch_pointer_keyboard.png */,
+                               C495EF1F16B911450041304E /* touch_pointer_lclick.png */,
+                               C495EF2016B911450041304E /* touch_pointer_rclick.png */,
+                               C495EF2116B911450041304E /* touch_pointer_reset.png */,
+                               C495EF2216B911450041304E /* touch_pointer_scroll.png */,
+                       );
+                       name = Resources;
+                       sourceTree = "<group>";
+               };
+               C495EF8116B911940041304E /* Views */ = {
+                       isa = PBXGroup;
+                       children = (
+                               C495EEDA16B911450041304E /* BookmarkListView.xib */,
+                               C495EEDB16B911450041304E /* BookmarkTableViewCell.xib */,
+                               C495EEDD16B911450041304E /* CredentialsInputView.xib */,
+                               C495EEE416B911450041304E /* EditButtonTableViewCell.xib */,
+                               C495EEE516B911450041304E /* EditFlagTableViewCell.xib */,
+                               C495EEE616B911450041304E /* EditSecretTextTableViewCell.xib */,
+                               C495EEE716B911450041304E /* EditSelectionTableViewCell.xib */,
+                               C495EEE816B911450041304E /* EditSubEditTableViewCell.xib */,
+                               C495EEE916B911450041304E /* EditTextTableViewCell.xib */,
+                               C495EF0E16B911450041304E /* MainWindow.xib */,
+                               C495EF0F16B911450041304E /* RDPConnectingView.xib */,
+                               C495EF1016B911450041304E /* RDPSessionView.xib */,
+                               C495EF1116B911450041304E /* SessionTableViewCell.xib */,
+                               C495EF2316B911450041304E /* VerifyCertificateView.xib */,
+                               C495EF8216B911AB0041304E /* AdvancedKeyboardView.h */,
+                               C495EF8316B911AB0041304E /* AdvancedKeyboardView.m */,
+                               C495EF8416B911AB0041304E /* BookmarkTableCell.h */,
+                               C495EF8516B911AB0041304E /* BookmarkTableCell.m */,
+                               C495EF8616B911AB0041304E /* EditButtonTableViewCell.h */,
+                               C495EF8716B911AB0041304E /* EditButtonTableViewCell.m */,
+                               C495EF8816B911AB0041304E /* EditFlagTableViewCell.h */,
+                               C495EF8916B911AB0041304E /* EditFlagTableViewCell.m */,
+                               C495EF8A16B911AB0041304E /* EditSecretTextTableViewCell.h */,
+                               C495EF8B16B911AB0041304E /* EditSecretTextTableViewCell.m */,
+                               C495EF8C16B911AB0041304E /* EditSelectionTableViewCell.h */,
+                               C495EF8D16B911AB0041304E /* EditSelectionTableViewCell.m */,
+                               C495EF8E16B911AB0041304E /* EditSubEditTableViewCell.h */,
+                               C495EF8F16B911AB0041304E /* EditSubEditTableViewCell.m */,
+                               C495EF9016B911AB0041304E /* EditTextTableViewCell.h */,
+                               C495EF9116B911AB0041304E /* EditTextTableViewCell.m */,
+                               C495EF9216B911AB0041304E /* RDPSessionView.h */,
+                               C495EF9316B911AB0041304E /* RDPSessionView.m */,
+                               C495EF9416B911AB0041304E /* SessionTableCell.h */,
+                               C495EF9516B911AB0041304E /* SessionTableCell.m */,
+                               C495EF9616B911AB0041304E /* TouchPointerView.h */,
+                               C495EF9716B911AB0041304E /* TouchPointerView.m */,
+                       );
+                       name = Views;
+                       sourceTree = "<group>";
+               };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+               C495EE2E16B8372D0041304E /* iFreeRDP */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = C495EE6216B8372D0041304E /* Build configuration list for PBXNativeTarget "iFreeRDP" */;
+                       buildPhases = (
+                               C495EE2B16B8372D0041304E /* Sources */,
+                               C495EE2C16B8372D0041304E /* Frameworks */,
+                               C495EE2D16B8372D0041304E /* Resources */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = iFreeRDP;
+                       productName = iFreeRDP;
+                       productReference = C495EE2F16B8372D0041304E /* iFreeRDP.app */;
+                       productType = "com.apple.product-type.application";
+               };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+               C495EE2616B8372D0041304E /* Project object */ = {
+                       isa = PBXProject;
+                       attributes = {
+                               LastUpgradeCheck = 0450;
+                               ORGANIZATIONNAME = freerdp;
+                       };
+                       buildConfigurationList = C495EE2916B8372D0041304E /* Build configuration list for PBXProject "iFreeRDP" */;
+                       compatibilityVersion = "Xcode 3.2";
+                       developmentRegion = English;
+                       hasScannedForEncodings = 0;
+                       knownRegions = (
+                               en,
+                       );
+                       mainGroup = C495EE2416B8372D0041304E;
+                       productRefGroup = C495EE3016B8372D0041304E /* Products */;
+                       projectDirPath = "";
+                       projectRoot = "";
+                       targets = (
+                               C495EE2E16B8372D0041304E /* iFreeRDP */,
+                       );
+               };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+               C495EE2D16B8372D0041304E /* Resources */ = {
+                       isa = PBXResourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               C495EE7016B9107D0041304E /* Defaults.plist in Resources */,
+                               C495EF3216B911450041304E /* BookmarkListView.xib in Resources */,
+                               C495EF3316B911450041304E /* BookmarkTableViewCell.xib in Resources */,
+                               C495EF3416B911450041304E /* cancel_button_background.png in Resources */,
+                               C495EF3516B911450041304E /* CredentialsInputView.xib in Resources */,
+                               C495EF3616B911450041304E /* Default-Landscape@2x~ipad.png in Resources */,
+                               C495EF3716B911450041304E /* Default-Landscape~ipad.png in Resources */,
+                               C495EF3816B911450041304E /* Default-Portrait@2x~ipad.png in Resources */,
+                               C495EF3916B911450041304E /* Default-Portrait~ipad.png in Resources */,
+                               C495EF3A16B911450041304E /* Default.png in Resources */,
+                               C495EF3B16B911450041304E /* Default@2x.png in Resources */,
+                               C495EF3C16B911450041304E /* EditButtonTableViewCell.xib in Resources */,
+                               C495EF3D16B911450041304E /* EditFlagTableViewCell.xib in Resources */,
+                               C495EF3E16B911450041304E /* EditSecretTextTableViewCell.xib in Resources */,
+                               C495EF3F16B911450041304E /* EditSelectionTableViewCell.xib in Resources */,
+                               C495EF4016B911450041304E /* EditSubEditTableViewCell.xib in Resources */,
+                               C495EF4116B911450041304E /* EditTextTableViewCell.xib in Resources */,
+                               C495EF5316B911450041304E /* icon_accessory_star_off.png in Resources */,
+                               C495EF5416B911450041304E /* icon_accessory_star_on.png in Resources */,
+                               C495EF5516B911450041304E /* icon_key_arrow_down.png in Resources */,
+                               C495EF5616B911450041304E /* icon_key_arrow_left.png in Resources */,
+                               C495EF5716B911450041304E /* icon_key_arrow_right.png in Resources */,
+                               C495EF5816B911450041304E /* icon_key_arrow_up.png in Resources */,
+                               C495EF5916B911450041304E /* icon_key_arrows.png in Resources */,
+                               C495EF5A16B911450041304E /* icon_key_backspace.png in Resources */,
+                               C495EF5B16B911450041304E /* icon_key_menu.png in Resources */,
+                               C495EF5C16B911450041304E /* icon_key_return.png in Resources */,
+                               C495EF5D16B911450041304E /* icon_key_win.png in Resources */,
+                               C495EF5E16B911450041304E /* Icon-72.png in Resources */,
+                               C495EF5F16B911450041304E /* Icon-72@2x.png in Resources */,
+                               C495EF6016B911450041304E /* Icon.png in Resources */,
+                               C495EF6116B911450041304E /* Icon@2x.png in Resources */,
+                               C495EF6216B911450041304E /* keyboard_button_background.png in Resources */,
+                               C495EF6316B911450041304E /* MainWindow.xib in Resources */,
+                               C495EF6416B911450041304E /* RDPConnectingView.xib in Resources */,
+                               C495EF6516B911450041304E /* RDPSessionView.xib in Resources */,
+                               C495EF6616B911450041304E /* SessionTableViewCell.xib in Resources */,
+                               C495EF6716B911450041304E /* tabbar_icon_about.png in Resources */,
+                               C495EF6816B911450041304E /* tabbar_icon_help.png in Resources */,
+                               C495EF6916B911450041304E /* tabbar_icon_settings.png in Resources */,
+                               C495EF6A16B911450041304E /* toolbar_icon_disconnect.png in Resources */,
+                               C495EF6B16B911450041304E /* toolbar_icon_extkeyboad.png in Resources */,
+                               C495EF6C16B911450041304E /* toolbar_icon_home.png in Resources */,
+                               C495EF6D16B911450041304E /* toolbar_icon_keyboard.png in Resources */,
+                               C495EF6E16B911450041304E /* toolbar_icon_touchpointer.png in Resources */,
+                               C495EF6F16B911450041304E /* toolbar_icon_win.png in Resources */,
+                               C495EF7016B911450041304E /* touch_pointer_active.png in Resources */,
+                               C495EF7116B911450041304E /* touch_pointer_default.png in Resources */,
+                               C495EF7216B911450041304E /* touch_pointer_extkeyboard.png in Resources */,
+                               C495EF7316B911450041304E /* touch_pointer_keyboard.png in Resources */,
+                               C495EF7416B911450041304E /* touch_pointer_lclick.png in Resources */,
+                               C495EF7516B911450041304E /* touch_pointer_rclick.png in Resources */,
+                               C495EF7616B911450041304E /* touch_pointer_reset.png in Resources */,
+                               C495EF7716B911450041304E /* touch_pointer_scroll.png in Resources */,
+                               C495EF7816B911450041304E /* VerifyCertificateView.xib in Resources */,
+                               C495EFBB16B92E170041304E /* about_page in Resources */,
+                               C495EFBD16B92E270041304E /* help_page in Resources */,
+                               C495EFC216B92EA20041304E /* Localizable.strings in Resources */,
+                               C4C31C6F16BAD1890087BB12 /* Default-568h@2x.png in Resources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+               C495EE2B16B8372D0041304E /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               C495EE7716B910BC0041304E /* OrderedDictionary.m in Sources */,
+                               C495EE7816B910BC0041304E /* Toast+UIView.m in Sources */,
+                               C495EE7916B910BC0041304E /* TSXAdditions.m in Sources */,
+                               C495EE9B16B910DE0041304E /* AboutController.m in Sources */,
+                               C495EE9C16B910DE0041304E /* AdvancedBookmarkEditorController.m in Sources */,
+                               C495EE9D16B910DE0041304E /* AppSettingsController.m in Sources */,
+                               C495EE9E16B910DE0041304E /* BookmarkEditorController.m in Sources */,
+                               C495EE9F16B910DE0041304E /* BookmarkListController.m in Sources */,
+                               C495EEA016B910DE0041304E /* CredentialsEditorController.m in Sources */,
+                               C495EEA116B910DE0041304E /* CredentialsInputController.m in Sources */,
+                               C495EEA216B910DE0041304E /* EditorBaseController.m in Sources */,
+                               C495EEA316B910DE0041304E /* EditorSelectionController.m in Sources */,
+                               C495EEA416B910DE0041304E /* EncryptionController.m in Sources */,
+                               C495EEA516B910DE0041304E /* HelpController.m in Sources */,
+                               C495EEA616B910DE0041304E /* MainTabBarController.m in Sources */,
+                               C495EEA716B910DE0041304E /* PerformanceEditorController.m in Sources */,
+                               C495EEA816B910DE0041304E /* RDPSessionViewController.m in Sources */,
+                               C495EEA916B910DE0041304E /* ScreenSelectionController.m in Sources */,
+                               C495EEAA16B910DE0041304E /* VerifyCertificateController.m in Sources */,
+                               C495EEB216B910F60041304E /* ios_freerdp_events.m in Sources */,
+                               C495EEB316B910F60041304E /* ios_freerdp_ui.m in Sources */,
+                               C495EEB416B910F60041304E /* ios_freerdp.m in Sources */,
+                               C495EEBD16B9111A0041304E /* Reachability.m in Sources */,
+                               C495EEBE16B9111A0041304E /* SFHFKeychainUtils.m in Sources */,
+                               C495EEBF16B9111A0041304E /* Utils.m in Sources */,
+                               C495EECD16B911290041304E /* Bookmark.m in Sources */,
+                               C495EECE16B911290041304E /* ConnectionParams.m in Sources */,
+                               C495EECF16B911290041304E /* Encryptor.m in Sources */,
+                               C495EED016B911290041304E /* GlobalDefaults.m in Sources */,
+                               C495EED116B911290041304E /* RDPKeyboard.m in Sources */,
+                               C495EED216B911290041304E /* RDPSession.m in Sources */,
+                               C495EF9A16B911AC0041304E /* AdvancedKeyboardView.m in Sources */,
+                               C495EF9B16B911AC0041304E /* BookmarkTableCell.m in Sources */,
+                               C495EF9C16B911AC0041304E /* EditButtonTableViewCell.m in Sources */,
+                               C495EF9D16B911AC0041304E /* EditFlagTableViewCell.m in Sources */,
+                               C495EF9E16B911AC0041304E /* EditSecretTextTableViewCell.m in Sources */,
+                               C495EF9F16B911AC0041304E /* EditSelectionTableViewCell.m in Sources */,
+                               C495EFA016B911AC0041304E /* EditSubEditTableViewCell.m in Sources */,
+                               C495EFA116B911AC0041304E /* EditTextTableViewCell.m in Sources */,
+                               C495EFA216B911AC0041304E /* RDPSessionView.m in Sources */,
+                               C495EFA316B911AC0041304E /* SessionTableCell.m in Sources */,
+                               C495EFA416B911AC0041304E /* TouchPointerView.m in Sources */,
+                               C495EFCB16B933230041304E /* AppDelegate.m in Sources */,
+                               C495EFCC16B933230041304E /* main.m in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+               C495EFC016B92EA20041304E /* Localizable.strings */ = {
+                       isa = PBXVariantGroup;
+                       children = (
+                               C495EFC116B92EA20041304E /* en */,
+                       );
+                       name = Localizable.strings;
+                       sourceTree = "<group>";
+               };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+               C495EE6016B8372D0041304E /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+                               CLANG_CXX_LIBRARY = "libc++";
+                               CLANG_ENABLE_OBJC_ARC = NO;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               CODE_SIGN_IDENTITY = "iPhone Developer";
+                               "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+                               COPY_PHASE_STRIP = NO;
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "DEBUG=1",
+                               );
+                               GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               IPHONEOS_DEPLOYMENT_TARGET = 3.2;
+                               ONLY_ACTIVE_ARCH = YES;
+                               PROVISIONING_PROFILE = "";
+                               SDKROOT = iphoneos;
+                               TARGETED_DEVICE_FAMILY = "1,2";
+                       };
+                       name = Debug;
+               };
+               C495EE6116B8372D0041304E /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+                               CLANG_CXX_LIBRARY = "libc++";
+                               CLANG_ENABLE_OBJC_ARC = NO;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               CODE_SIGN_IDENTITY = "iPhone Developer";
+                               "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+                               COPY_PHASE_STRIP = YES;
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               IPHONEOS_DEPLOYMENT_TARGET = 3.2;
+                               OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
+                               PROVISIONING_PROFILE = "";
+                               SDKROOT = iphoneos;
+                               TARGETED_DEVICE_FAMILY = "1,2";
+                               VALIDATE_PRODUCT = YES;
+                       };
+                       name = Release;
+               };
+               C495EE6316B8372D0041304E /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               CLANG_ENABLE_OBJC_ARC = "$(INHERIT)";
+                               DEAD_CODE_STRIPPING = "$(INHERIT)";
+                               GCC_PRECOMPILE_PREFIX_HEADER = YES;
+                               GCC_PREFIX_HEADER = "$(SRCROOT)/iFreeRDP-Prefix.pch";
+                               HEADER_SEARCH_PATHS = (
+                                       "\"$(SRCROOT)/../../include\"",
+                                       "\"$(SRCROOT)/../../winpr/include\"",
+                                       "\"$(SRCROOT)/../../\"",
+                                       "\"@FREERDP_IOS_EXTERNAL_SSL_PATH@/include\"",
+                               );
+                               INFOPLIST_FILE = "$(SRCROOT)/iFreeRDP.plist";
+                               IPHONEOS_DEPLOYMENT_TARGET = 3.2;
+                               LIBRARY_SEARCH_PATHS = (
+                                       "\"$(SRCROOT)/../../libfreerdp\"",
+                                       "\"$(SRCROOT)/../../winpr/libwinpr\"",
+                                       "\"@FREERDP_IOS_EXTERNAL_SSL_PATH@/lib\"",
+                                       "\"$(SRCROOT)/../common\"",
+                               );
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               WRAPPER_EXTENSION = app;
+                       };
+                       name = Debug;
+               };
+               C495EE6416B8372D0041304E /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               CLANG_ENABLE_OBJC_ARC = "$(INHERIT)";
+                               DEAD_CODE_STRIPPING = "$(INHERIT)";
+                               GCC_PRECOMPILE_PREFIX_HEADER = YES;
+                               GCC_PREFIX_HEADER = "$(SRCROOT)/iFreeRDP-Prefix.pch";
+                               HEADER_SEARCH_PATHS = (
+                                       "\"$(SRCROOT)/../../include\"",
+                                       "\"$(SRCROOT)/../../winpr/include\"",
+                                       "\"$(SRCROOT)/../../\"",
+                                       "\"@FREERDP_IOS_EXTERNAL_SSL_PATH@/include\"",
+                               );
+                               INFOPLIST_FILE = "$(SRCROOT)/iFreeRDP.plist";
+                               IPHONEOS_DEPLOYMENT_TARGET = 3.2;
+                               LIBRARY_SEARCH_PATHS = (
+                                       "\"$(SRCROOT)/../../libfreerdp\"",
+                                       "\"$(SRCROOT)/../../winpr/libwinpr\"",
+                                       "\"@FREERDP_IOS_EXTERNAL_SSL_PATH@/lib\"",
+                                       "\"$(SRCROOT)/../common\"",
+                               );
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               WRAPPER_EXTENSION = app;
+                       };
+                       name = Release;
+               };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+               C495EE2916B8372D0041304E /* Build configuration list for PBXProject "iFreeRDP" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               C495EE6016B8372D0041304E /* Debug */,
+                               C495EE6116B8372D0041304E /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               C495EE6216B8372D0041304E /* Build configuration list for PBXNativeTarget "iFreeRDP" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               C495EE6316B8372D0041304E /* Debug */,
+                               C495EE6416B8372D0041304E /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+/* End XCConfigurationList section */
+       };
+       rootObject = C495EE2616B8372D0041304E /* Project object */;
+}
diff --git a/client/iOS/main.m b/client/iOS/main.m
new file mode 100644 (file)
index 0000000..99cabbb
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ Main App Entry
+ Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+ If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import <UIKit/UIKit.h>
+
+int main(int argc, char *argv[])
+{ 
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    int retVal = UIApplicationMain(argc, argv, nil, nil);
+    [pool release];
+    return retVal;
+}
index ae76963..8568454 100644 (file)
@@ -39,3 +39,9 @@ endif(MONOLITHIC_BUILD)
 if(${CMAKE_VERSION} VERSION_LESS 2.8.2)
        message(WARNING "GetGitRevisionDescription reqires (FindGit) cmake >= 2.8.2 to work properly - GIT_REVISION will be set to n/a")
 endif()
+
+# Since cmake 2.8.9 modules/library names without lib/.so can be used
+# for dependencies
+if(IOS AND ${CMAKE_VERSION} VERSION_LESS 2.8.9)
+       message(FATAL_ERROR "CMAKE version >= 2.8.9 required to build the IOS client")
+endif()
index ab51258..11b048b 100644 (file)
@@ -39,7 +39,7 @@ option(BUILD_TESTING "Build unit tests" OFF)
 option(WITH_SAMPLE "Build sample code" OFF)
 
 if(${CMAKE_VERSION} VERSION_GREATER 2.8.8)
-       if(ANDROID)
+       if(ANDROID OR IOS)
                option(MONOLITHIC_BUILD "Use monolithic build" ON)
        else()
                option(MONOLITHIC_BUILD "Use monolithic build" OFF)
@@ -102,3 +102,7 @@ option(WITH_DEBUG_XV "Print XVideo debug messages" ${DEFAULT_DEBUG_OPTION})
 if(ANDROID)
 include(ConfigOptionsAndroid)
 endif(ANDROID)
+
+if(IOS)
+include(ConfigOptionsiOS)
+endif(IOS)
diff --git a/cmake/ConfigOptionsiOS.cmake b/cmake/ConfigOptionsiOS.cmake
new file mode 100644 (file)
index 0000000..2890576
--- /dev/null
@@ -0,0 +1,24 @@
+# FreeRDP cmake ios options
+#
+# Copyright 2013 Thinstuff Technologies GmbH
+# Copyright 2013 Martin Fleisz <mfleisz@thinstuff.at>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+option(IOS_BUILD_OBJC "Automatically build iOS objective-c code - build type depends on CMAKE_BUILD_TYPE" ON)
+option(IOS_BUILD_OBJC_DEBUG "Create an iOS debug package" ON)
+if (NOT FREERDP_IOS_EXTERNAL_SSL_PATH)
+       set(FREERDP_IOS_EXTERNAL_SSL_PATH "${CMAKE_CURRENT_SOURCE_DIR}/external/openssl")
+endif()
+mark_as_advanced(FREERDP_IOS_EXTERNAL_SSL_PATH)
+
index 2c68dc2..6635e98 100644 (file)
@@ -10,7 +10,7 @@
 #   SIMULATOR - used to build for the Simulator platforms, which have an x86 arch.
 #
 # CMAKE_IOS_DEVELOPER_ROOT = automatic(default) or /path/to/platform/Developer folder
-#   By default this location is automatically chosen based on the IOS_PLATFORM value above.
+#   By default this location is automatcially chosen based on the IOS_PLATFORM value above.
 #   If set manually, it will override the default location and force the user of a particular Developer Platform
 #
 # CMAKE_IOS_SDK_ROOT = automatic(default) or /path/to/platform/Developer/SDKs/SDK folder
@@ -36,10 +36,6 @@ set (UNIX True)
 set (APPLE True)
 set (IOS True)
 
-# Workaround for FindThreads.cmake
-set(Threads_FOUND TRUE)
-set(CMAKE_THREAD_LIBS_INIT "-pthread")
-
 # Determine the cmake host system version so we know where to find the iOS SDKs
 find_program (CMAKE_UNAME uname /bin /usr/bin /usr/local/bin)
 if (CMAKE_UNAME)
@@ -48,13 +44,15 @@ if (CMAKE_UNAME)
 endif (CMAKE_UNAME)
 
 # Force the compilers to gcc for iOS
-include (CMakeForceCompiler)
-CMAKE_FORCE_C_COMPILER (gcc gcc)
-CMAKE_FORCE_CXX_COMPILER (g++ g++)
+if(NOT CMAKE_C_COMPILER)
+       include (CMakeForceCompiler)
+       CMAKE_FORCE_C_COMPILER (gcc gcc)
+       CMAKE_FORCE_CXX_COMPILER (g++ g++)
+endif()
 
 # Skip the platform compiler checks for cross compiling
-set (CMAKE_CXX_COMPILER_WORKS TRUE)
-set (CMAKE_C_COMPILER_WORKS TRUE)
+#set (CMAKE_CXX_COMPILER_WORKS TRUE)
+#set (CMAKE_C_COMPILER_WORKS TRUE)
 
 # All iOS/Darwin specific settings - some may be redundant
 set (CMAKE_SHARED_LIBRARY_PREFIX "lib")
@@ -125,7 +123,7 @@ if (NOT DEFINED CMAKE_IOS_DEVELOPER_ROOT)
 endif (NOT DEFINED CMAKE_IOS_DEVELOPER_ROOT)
 set (CMAKE_IOS_DEVELOPER_ROOT ${CMAKE_IOS_DEVELOPER_ROOT} CACHE PATH "Location of iOS Platform")
 
-# Find and use the most recent iOS SDK unless specified manually with CMAKE_IOS_SDK_ROOT
+# Find and use the most recent iOS sdk unless specified manually with CMAKE_IOS_SDK_ROOT
 if (NOT DEFINED CMAKE_IOS_SDK_ROOT)
        file (GLOB _CMAKE_IOS_SDKS "${CMAKE_IOS_DEVELOPER_ROOT}/SDKs/*")
        if (_CMAKE_IOS_SDKS) 
@@ -133,9 +131,9 @@ if (NOT DEFINED CMAKE_IOS_SDK_ROOT)
                list (REVERSE _CMAKE_IOS_SDKS)
                list (GET _CMAKE_IOS_SDKS 0 CMAKE_IOS_SDK_ROOT)
        else (_CMAKE_IOS_SDKS)
-               message (FATAL_ERROR "No iOS SDK's found in default search path ${CMAKE_IOS_DEVELOPER_ROOT}. Manually set CMAKE_IOS_SDK_ROOT or install the iOS SDK.")
+               message (FATAL_ERROR "No iOS SDK's found in default seach path ${CMAKE_IOS_DEVELOPER_ROOT}. Manually set CMAKE_IOS_SDK_ROOT or install the iOS SDK.")
        endif (_CMAKE_IOS_SDKS)
-       message (STATUS "iOS SDK root: ${CMAKE_IOS_SDK_ROOT}")
+       message (STATUS "Toolchain using default iOS SDK: ${CMAKE_IOS_SDK_ROOT}")
 endif (NOT DEFINED CMAKE_IOS_SDK_ROOT)
 set (CMAKE_IOS_SDK_ROOT ${CMAKE_IOS_SDK_ROOT} CACHE PATH "Location of the selected iOS SDK")
 
@@ -145,16 +143,13 @@ set (CMAKE_OSX_SYSROOT ${CMAKE_IOS_SDK_ROOT} CACHE PATH "Sysroot used for iOS su
 # set the architecture for iOS 
 # NOTE: Currently both ARCHS_STANDARD_32_BIT and ARCHS_UNIVERSAL_IPHONE_OS set armv7 only, so set both manually
 if (${IOS_PLATFORM} STREQUAL "OS")
-       set (IOS_ARCH armv6 armv7)
+       set (IOS_ARCH armv7 armv7s)
 else (${IOS_PLATFORM} STREQUAL "OS")
        set (IOS_ARCH i386)
 endif (${IOS_PLATFORM} STREQUAL "OS")
 
 set (CMAKE_OSX_ARCHITECTURES ${IOS_ARCH} CACHE string  "Build architecture for iOS")
 
-set (CMAKE_PREFIX_PATH "${CMAKE_IOS_SDK_ROOT}/usr")
-set (CMAKE_REQUIRED_INCLUDES "${CMAKE_IOS_SDK_ROOT}/usr/include")
-
 # Set the find root to the iOS developer roots and to user defined paths
 set (CMAKE_FIND_ROOT_PATH ${CMAKE_IOS_DEVELOPER_ROOT} ${CMAKE_IOS_SDK_ROOT} ${CMAKE_PREFIX_PATH} CACHE string  "iOS find search path root")
 
@@ -165,13 +160,15 @@ set (CMAKE_FIND_FRAMEWORK FIRST)
 set (CMAKE_SYSTEM_FRAMEWORK_PATH
        ${CMAKE_IOS_SDK_ROOT}/System/Library/Frameworks
        ${CMAKE_IOS_SDK_ROOT}/System/Library/PrivateFrameworks
-       ${CMAKE_IOS_SDK_ROOT}/Developer/Library/Frameworks)
+       ${CMAKE_IOS_SDK_ROOT}/Developer/Library/Frameworks
+)
 
 # only search the iOS sdks, not the remainder of the host filesystem
 set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY)
 set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
 set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
 
+
 # This little macro lets you set any XCode specific property
 macro (set_xcode_property TARGET XCODE_PROPERTY XCODE_VALUE)
        set_property (TARGET ${TARGET} PROPERTY XCODE_ATTRIBUTE_${XCODE_PROPERTY} ${XCODE_VALUE})
diff --git a/docs/README.ios b/docs/README.ios
new file mode 100644 (file)
index 0000000..bc4a0c4
--- /dev/null
@@ -0,0 +1,99 @@
+Overview
+========
+
+The FreeRDP iOS port allows users to enjoy FreeRDP features on Apple iOS devices.
+The application was written to be compatible with devices running iOS 3.2 or higher. 
+Please note that Apple dropped armv6 support in their latest Xcode releases.
+If you want to compile for armv6 devices you will have to use an older Xcode version and build the OpenSSL libraries for armv6 as well.
+
+For building the GUI part there are two possibilities:
+* integrated build - have cmake to operate Xcode and build everything
+* manual build - build FreeRDP libraries and invoke xcodebuild or Xcode manually for the frontend
+
+Manual builds should be used for development.
+
+
+Build requirements
+==================
+
+The following prerequisites are required in order to build the iOS port:
+
+- cmake version >= 2.8.9
+- latest Xcode installed (>= 4.6)
+- installed "Command Line Tools" component
+- installed Provisioning Profile and iOS Developer Certificate for code signing
+- pre-build static OpenSSL libraries (see below)
+
+FreeRDP requires OpenSSL libraries for building but they are not part of the iOS SDK and therefore they need to be pre-build manually.
+There are various versions and builds of static OpenSSL libraries floating around like iOSPorts.
+At the time of writing we have tested and used a small script (OpenSSL-DownloadAndBuild.command) that downloads and builds armv7, armv7s and i386 versions of the OpenSSL 1.0.0e libraries.
+
+If you don't care about modifying the OpenSSL build you can run the following command in the FreeRDP root directory:
+
+./scripts/OpenSSL-DownloadAndBuild.command 
+
+The script is using the latest iOS SDK 6.1 to build the OpenSSL libraries.
+If you want to use a different SDK version simply edit the OpenSSL-iFreeRDP.diff file and modify the -isysroot parameters to point to the SDK version you want to build with.
+
+When the script finishes the external/openssl/lib subfolder will contain libcrypto.a and libssl.a, both universal binary libraries containing arm and i386 targets in order to compile FreeRDP for iOS devices and the simulator.
+
+If you build OpenSSL youself you need to set FREERDP_IOS_EXTERNAL_SSL_PATH when running cmake.
+
+
+Building
+========
+
+Integrated build
+----------------
+
+Run the following commands in the top level FreeRDP directory:
+
+cmake -DCMAKE_TOOLCHAIN_FILE=cmake/iOSToolchain.cmake
+make
+
+After that you should have a client/iOS/bin/<Debug or Release>/iFreeRDP.app application package.
+
+Manual iOS builds
+-----------------
+
+First run cmake to prepare the build:
+
+cmake -DCMAKE_TOOLCHAIN_FILE=cmake/iOSToolchain.cmake -DIOS_BUILD_OBJC=OFF
+make
+
+Now you can run your favourite xcodebuild command in client/iOS like this:
+
+cd client/iOS
+xcodebuild -project iFreeRDP.xcodeproj -configuration Debug -sdk iphoneos6.1 install
+
+Notes: 
+     
+* XCode, by default will build the application into its derived data location (usually in ~/Library/Developer/...).
+If you want to specify an output directory add CONFIGURATION_BUILD_DIR=<output-path-here> to the end of above command line.
+
+* If using XCode choose "Open Other" from the welcome screen, browse to the client/iOS directory in your FreeRDP folder and select iFreeRDP.xcodeproj.
+
+
+cmake variables
+===============
+
+CMAKE_TOOLCHAIN_FILE
+* the toolchain file to use must be cmake/iOSToolchain.cmake
+
+IOS_PLATFORM (OS (default), SIMULATOR)
+* the platform for which to build iFreeRDP. OS compiles for iOS devices (using armv7 and armv7s ABIs) and SIMULATOR compiles for the iOS Simulator (i386)
+
+CMAKE_IOS_DEVELOPER_ROOT (used by toolchain file)
+* absolute path to the iOS developer platform (i.e. /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer) the toolchain file will usually auto-detect the correct Developer platform depending on IOS_PLATFORM
+
+CMAKE_IOS_SDK_ROOT (used by toolchain file)
+* absolute path to the iOS SDK (i.e. /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk) the toolchain file will usually auto-detect the correct SDK, depending on IOS_PLATFORM 
+
+FREERDP_IOS_EXTERNAL_SSL_PATH (used by FindOpenSSL)
+* absolut root path to the pre-built static OpenSSL libraries
+
+IOS_BUILD_OBJC (used by client/iOS/CMakeLists.txt)
+* can be ON/OFF (default ON) whether or not to build the objective-c UI with cmake
+
+IOS_BUILD_OBJC_DEBUG (used by client/iOS/CMakeLists.txt)
+* can be ON/OFF (default ON) whether or not to build a debug version of the objective-c UI
diff --git a/scripts/OpenSSL-DownloadAndBuild.command b/scripts/OpenSSL-DownloadAndBuild.command
new file mode 100755 (executable)
index 0000000..58901fe
--- /dev/null
@@ -0,0 +1,104 @@
+#!/bin/sh
+# 
+# Copyright 2013 Thinstuff Technologies GmbH
+# 
+# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
+# If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# This script will download and build openssl for iOS (armv7, armv7s) and i386
+#
+
+OPENSSLVERSION="1.0.0e"
+MD5SUM="7040b89c4c58c7a1016c0dfa6e821c86"
+OPENSSLPATCH="../../scripts/OpenSSL-iFreeRDP.diff"
+CORES=`sysctl hw.ncpu | awk '{print $2}'`
+
+MAKEOPTS="-j $CORES"
+# disable parallell builds since openssl build
+# fails sometimes
+MAKEOPTS=""
+
+cd external
+if [ ! -d openssl ];then
+       mkdir openssl
+fi
+cd openssl
+CS=`md5 -q "openssl-$OPENSSLVERSION.tar.gz" 2>/dev/null`
+if [ ! "$CS" = "$MD5SUM" ]; then
+    echo "Downloading OpenSSL Version $OPENSSLVERSION ..."
+    rm -f "openssl-$OPENSSLVERSION.tar.gz"
+    curl -o "openssl-$OPENSSLVERSION.tar.gz" http://www.openssl.org/source/openssl-$OPENSSLVERSION.tar.gz
+
+    CS=`md5 -q "openssl-$OPENSSLVERSION.tar.gz" 2>/dev/null`
+    if [ ! "$CS" = "$MD5SUM" ]; then
+       echo "Download failed or invalid checksum. Have a nice day."
+       exit 1
+    fi
+fi
+
+rm -rf openssltmp
+mkdir openssltmp
+cd openssltmp
+
+echo "Unpacking OpenSSL ..."
+tar xfz "../openssl-$OPENSSLVERSION.tar.gz"
+if [ ! $? = 0 ]; then
+    echo "Unpacking failed."
+    exit 1
+fi
+echo
+
+echo "Applying iFreeRDP patch ..."
+
+cd "openssl-$OPENSSLVERSION"
+patch -p1 < "../../$OPENSSLPATCH"
+
+if [ ! $? = 0 ]; then
+    echo "Patch failed."
+    exit 1
+fi
+echo
+
+mkdir -p ../../include/openssl
+rm -f ../../include/openssl/*.h
+
+mkdir -p ../../lib
+rm -f ../../lib/*.a
+
+echo "Copying header hiles ..."
+cp include/openssl/*.h ../../include/openssl/
+echo
+
+echo "Building sim version (for simulator). Please wait ..."
+./Configure darwin-sim-cc >BuildLog.darwin-sim.txt
+make ${MAKEOPTS} >>BuildLog.darwin-sim.txt 2>&1
+echo "Done. Build log saved in BuildLog.darwin-sim.txt"
+cp libcrypto.a ../../lib/libcrypto_sim.a
+cp libssl.a ../../lib/libssl_sim.a
+make clean >/dev/null 2>&1
+echo
+
+echo "Building armv7 version (for iPhone). Please wait ..."
+./Configure darwin-armv7-cc >BuildLog.darwin-armv7.txt
+make ${MAKEOPTS} >>BuildLog.darwin-armv7.txt 2>&1
+echo "Done. Build log saved in BuildLog.darwin-armv7.txt"
+cp libcrypto.a ../../lib/libcrypto_armv7.a
+cp libssl.a ../../lib/libssl_armv7.a
+make clean >/dev/null 2>&1
+echo
+
+echo "Building armv7s version (for iPhone). Please wait ..."
+./Configure darwin-armv7s-cc >BuildLog.darwin-armv7s.txt
+make ${MAKEOPTS} >>BuildLog.darwin-armv7s.txt 2>&1
+echo "Done. Build log saved in BuildLog.darwin-armv7s.txt"
+cp libcrypto.a ../../lib/libcrypto_armv7s.a
+cp libssl.a ../../lib/libssl_armv7s.a
+make clean >/dev/null 2>&1
+echo
+
+echo "Combining to unversal binary"
+lipo -create ../../lib/libcrypto_sim.a ../../lib/libcrypto_armv7.a ../../lib/libcrypto_armv7s.a -o ../../lib/libcrypto.a
+lipo -create ../../lib/libssl_sim.a ../../lib/libssl_armv7.a ../../lib/libssl_armv7s.a -o ../../lib/libssl.a
+
+echo "Finished. Please verify the contens of the openssl folder in your main project folder"
+
diff --git a/scripts/OpenSSL-iFreeRDP.diff b/scripts/OpenSSL-iFreeRDP.diff
new file mode 100644 (file)
index 0000000..1348cdb
--- /dev/null
@@ -0,0 +1,25 @@
+diff -rupN openssl-1.0.0e-ori/Configure openssl-1.0.0e/Configure
+--- openssl-1.0.0e-ori/Configure       2012-02-06 14:44:42.000000000 +0100
++++ openssl-1.0.0e/Configure   2012-02-06 14:45:31.000000000 +0100
+@@ -555,6 +555,9 @@ my %table=(
+ "debug-darwin-i386-cc","cc:-arch i386 -g3 -DL_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:BN_LLONG RC4_INT RC4_CHUNK DES_UNROLL BF_PTR:${x86_asm}:macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch i386 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
+ "darwin64-x86_64-cc","cc:-arch x86_64 -O3 -DL_ENDIAN -DMD32_REG_T=int -Wall::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch x86_64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
+ "debug-darwin-ppc-cc","cc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DB_ENDIAN -g -Wall -O::-D_REENTRANT:MACOSX::BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${ppc32_asm}:osx32:dlfcn:darwin-shared:-fPIC:-dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
++"darwin-armv7s-cc","/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc:-arch armv7s -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk -O3 -fomit-frame-pointer -DL_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${no_asm}:dlfcn:darwin-shared:-fPIC -fno-common:-arch armv4 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
++"darwin-armv7-cc","/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc:-arch armv7 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk -O3 -fomit-frame-pointer -DL_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${no_asm}:dlfcn:darwin-shared:-fPIC -fno-common:-arch armv4 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
++"darwin-sim-cc","/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/gcc: -arch i386 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.1.sdk -O3 -fomit-frame-pointer -DL_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${no_asm}:dlfcn:darwin-shared:-fPIC -fno-common: -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
+ ##### A/UX
+ "aux3-gcc","gcc:-O2 -DTERMIO::(unknown):AUX:-lbsd:RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:::",
+diff -rupN openssl-1.0.0e-ori/crypto/ui/ui_openssl.c openssl-1.0.0e/crypto/ui/ui_openssl.c
+--- openssl-1.0.0e-ori/crypto/ui/ui_openssl.c  2012-02-06 14:44:43.000000000 +0100
++++ openssl-1.0.0e/crypto/ui/ui_openssl.c      2012-02-06 14:46:10.000000000 +0100
+@@ -404,7 +404,7 @@ static int read_till_nl(FILE *in)
+       return 1;
+       }
+-static volatile sig_atomic_t intr_signal;
++static volatile int intr_signal;
+ #endif
+ static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl)
index 085c0d3..7fb0220 100644 (file)
 #endif
 
 #ifndef __OBJC__
+#if defined(__APPLE__)
+typedef signed char BOOL;
+#else
 typedef int BOOL;
 #endif
+#endif
 
 typedef BOOL *PBOOL, *LPBOOL;