Updated iOS client.
This commit is contained in:
parent
081b57905f
commit
f0864108f9
@ -107,7 +107,7 @@ set_target_properties(${MODULE_NAME} PROPERTIES RESOURCE "${${MODULE_NAME}_RESOU
|
||||
set(EXECUTABLE_NAME "\${EXECUTABLE_NAME}")
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${IOS_CLIENT_DIR}/iFreeRDP.plist)
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET "4.3")
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET "6.3")
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "gnu++0x")
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC NO)
|
||||
|
@ -11,7 +11,7 @@
|
||||
#import "ConnectionParams.h"
|
||||
#import "Utils.h"
|
||||
|
||||
@interface PerformanceEditorController (Private)
|
||||
@interface PerformanceEditorController(Private)
|
||||
-(NSString*)keyPathForKey:(NSString*)key;
|
||||
@end
|
||||
|
||||
@ -19,134 +19,177 @@
|
||||
|
||||
- (id)initWithConnectionParams:(ConnectionParams*)params
|
||||
{
|
||||
return [self initWithConnectionParams:params keyPath:nil];
|
||||
return [self initWithConnectionParams:params keyPath:nil];
|
||||
}
|
||||
|
||||
- (id)initWithConnectionParams:(ConnectionParams*)params keyPath:(NSString*)keyPath;
|
||||
- (id)initWithConnectionParams:(ConnectionParams*)params keyPath:
|
||||
(NSString*)keyPath;
|
||||
{
|
||||
self = [super initWithStyle:UITableViewStyleGrouped];
|
||||
if (self) {
|
||||
_params = [params retain];
|
||||
_keyPath = (keyPath != nil ? [keyPath retain] : nil);
|
||||
}
|
||||
return self;
|
||||
self = [super initWithStyle:UITableViewStyleGrouped];
|
||||
|
||||
if (self)
|
||||
{
|
||||
_params = [params retain];
|
||||
_keyPath = (keyPath != nil ? [keyPath retain] : nil);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
[super viewDidLoad];
|
||||
// Do any additional setup after loading the view.
|
||||
}
|
||||
|
||||
- (void)viewDidUnload
|
||||
{
|
||||
[super viewDidUnload];
|
||||
// Release any retained subviews of the main view.
|
||||
[super viewDidUnload];
|
||||
// Release any retained subviews of the main view.
|
||||
}
|
||||
|
||||
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
|
||||
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)
|
||||
interfaceOrientation
|
||||
{
|
||||
return YES;
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(NSString*)keyPathForKey:(NSString*)key
|
||||
{
|
||||
if (_keyPath)
|
||||
return [_keyPath stringByAppendingFormat:@".%@", key];
|
||||
return key;
|
||||
if (_keyPath)
|
||||
return [_keyPath stringByAppendingFormat:@".%@", key];
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[super dealloc];
|
||||
[_params release];
|
||||
[super dealloc];
|
||||
[_params release];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Table view data source
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
|
||||
// Return the number of sections.
|
||||
return 1;
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView
|
||||
{
|
||||
// Return the number of sections.
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||
return 7;
|
||||
- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:
|
||||
(NSInteger)section
|
||||
{
|
||||
return 7;
|
||||
}
|
||||
|
||||
|
||||
// set section headers
|
||||
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
|
||||
- (NSString*)tableView:(UITableView*)tableView titleForHeaderInSection:
|
||||
(NSInteger)section
|
||||
{
|
||||
return NSLocalizedString(@"Performance Settings", @"'Performance Settings': performance settings header");
|
||||
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];
|
||||
- (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;
|
||||
}
|
||||
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 1:
|
||||
{
|
||||
[[cell label] setText:NSLocalizedString(@"GFX", @"GFX performance setting")];
|
||||
[[cell toggle] setOn:[_params boolForKeyPath:[self keyPathForKey:@"perf_gfx"]]];
|
||||
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 2:
|
||||
{
|
||||
[[cell label] setText:NSLocalizedString(@"H264", @"H264 performance setting")];
|
||||
[[cell toggle] setOn:[_params boolForKeyPath:[self keyPathForKey:
|
||||
@"perf_h264"]]];
|
||||
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 3:
|
||||
{
|
||||
[[cell label] setText:NSLocalizedString(@"Desktop Background",
|
||||
@"Desktop background performance setting")];
|
||||
[[cell toggle] setOn:[_params boolForKeyPath:[self keyPathForKey:
|
||||
@"perf_show_desktop"]]];
|
||||
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 4:
|
||||
{
|
||||
[[cell label] setText:NSLocalizedString(@"Font Smoothing",
|
||||
@"Font smoothing performance setting")];
|
||||
[[cell toggle] setOn:[_params boolForKeyPath:[self keyPathForKey:
|
||||
@"perf_font_smoothing"]]];
|
||||
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 5:
|
||||
{
|
||||
[[cell label] setText:NSLocalizedString(@"Desktop Composition",
|
||||
@"Desktop composition performance setting")];
|
||||
[[cell toggle] setOn:[_params boolForKeyPath:[self keyPathForKey:
|
||||
@"perf_desktop_composition"]]];
|
||||
break;
|
||||
}
|
||||
|
||||
case 6:
|
||||
{
|
||||
[[cell label] setText:NSLocalizedString(@"Visual Styles", @"Use Themes performance setting")];
|
||||
[[cell toggle] setOn:[_params boolForKeyPath:[self keyPathForKey:@"perf_windows_themes"]]];
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
[[cell label] setText:NSLocalizedString(@"Window contents while dragging",
|
||||
@"Window Dragging performance setting")];
|
||||
[[cell toggle] setOn:[_params boolForKeyPath:[self keyPathForKey:
|
||||
@"perf_window_dragging"]]];
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
[[cell label] setText:NSLocalizedString(@"Menu Animation",
|
||||
@"Menu Animations performance setting")];
|
||||
[[cell toggle] setOn:[_params boolForKeyPath:[self keyPathForKey:
|
||||
@"perf_menu_animation"]]];
|
||||
break;
|
||||
}
|
||||
|
||||
[[cell toggle] setTag:GET_TAG_FROM_PATH(indexPath)];
|
||||
[[cell toggle] addTarget:self action:@selector(togglePerformanceSetting:) forControlEvents:UIControlEventValueChanged];
|
||||
return cell;
|
||||
case 8:
|
||||
{
|
||||
[[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 -
|
||||
@ -154,40 +197,58 @@
|
||||
|
||||
- (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;
|
||||
UISwitch* valueSwitch = (UISwitch*)sender;
|
||||
|
||||
case GET_TAG(0, 1):
|
||||
[_params setBool:[valueSwitch isOn] forKeyPath:[self keyPathForKey:@"perf_show_desktop"]];
|
||||
break;
|
||||
switch (valueSwitch.tag)
|
||||
{
|
||||
case GET_TAG(0, 0):
|
||||
[_params setBool:[valueSwitch isOn] forKeyPath:[self keyPathForKey:
|
||||
@"perf_remotefx"]];
|
||||
break;
|
||||
|
||||
case GET_TAG(0, 2):
|
||||
[_params setBool:[valueSwitch isOn] forKeyPath:[self keyPathForKey:@"perf_font_smoothing"]];
|
||||
break;
|
||||
case GET_TAG(0, 1):
|
||||
[_params setBool:[valueSwitch isOn] forKeyPath:[self keyPathForKey:
|
||||
@"perf_gfx"]];
|
||||
break;
|
||||
|
||||
case GET_TAG(0, 3):
|
||||
[_params setBool:[valueSwitch isOn] forKeyPath:[self keyPathForKey:@"perf_desktop_composition"]];
|
||||
break;
|
||||
case GET_TAG(0, 2):
|
||||
[_params setBool:[valueSwitch isOn] forKeyPath:[self keyPathForKey:
|
||||
@"perf_h264"]];
|
||||
break;
|
||||
|
||||
case GET_TAG(0, 4):
|
||||
[_params setBool:[valueSwitch isOn] forKeyPath:[self keyPathForKey:@"perf_window_dragging"]];
|
||||
break;
|
||||
case GET_TAG(0, 3):
|
||||
[_params setBool:[valueSwitch isOn] forKeyPath:[self keyPathForKey:
|
||||
@"perf_show_desktop"]];
|
||||
break;
|
||||
|
||||
case GET_TAG(0, 5):
|
||||
[_params setBool:[valueSwitch isOn] forKeyPath:[self keyPathForKey:@"perf_menu_animation"]];
|
||||
break;
|
||||
case GET_TAG(0, 4):
|
||||
[_params setBool:[valueSwitch isOn] forKeyPath:[self keyPathForKey:
|
||||
@"perf_font_smoothing"]];
|
||||
break;
|
||||
|
||||
case GET_TAG(0, 6):
|
||||
[_params setBool:[valueSwitch isOn] forKeyPath:[self keyPathForKey:@"perf_windows_themes"]];
|
||||
break;
|
||||
case GET_TAG(0, 5):
|
||||
[_params setBool:[valueSwitch isOn] forKeyPath:[self keyPathForKey:
|
||||
@"perf_desktop_composition"]];
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
case GET_TAG(0, 6):
|
||||
[_params setBool:[valueSwitch isOn] forKeyPath:[self keyPathForKey:
|
||||
@"perf_window_dragging"]];
|
||||
break;
|
||||
|
||||
case GET_TAG(0, 7):
|
||||
[_params setBool:[valueSwitch isOn] forKeyPath:[self keyPathForKey:
|
||||
@"perf_menu_animation"]];
|
||||
break;
|
||||
|
||||
case GET_TAG(0, 8):
|
||||
[_params setBool:[valueSwitch isOn] forKeyPath:[self keyPathForKey:
|
||||
@"perf_windows_themes"]];
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -28,6 +28,10 @@
|
||||
<false/>
|
||||
<key>perf_remotefx</key>
|
||||
<false/>
|
||||
<key>perf_gfx</key>
|
||||
<false/>
|
||||
<key>perf_h264</key>
|
||||
<false/>
|
||||
<key>perf_desktop_composition</key>
|
||||
<false/>
|
||||
<key>enable_3g_settings</key>
|
||||
@ -44,6 +48,10 @@
|
||||
<integer>16</integer>
|
||||
<key>perf_remotefx</key>
|
||||
<false/>
|
||||
<key>perf_gfx</key>
|
||||
<false/>
|
||||
<key>perf_h264</key>
|
||||
<false/>
|
||||
<key>perf_desktop_composition</key>
|
||||
<false/>
|
||||
<key>perf_windows_themes</key>
|
||||
|
@ -12,6 +12,7 @@
|
||||
#import <freerdp/client/channels.h>
|
||||
#import <freerdp/client/cmdline.h>
|
||||
#import <freerdp/freerdp.h>
|
||||
#import <freerdp/gdi/gfx.h>
|
||||
|
||||
#import "ios_freerdp.h"
|
||||
#import "ios_freerdp_ui.h"
|
||||
@ -20,23 +21,99 @@
|
||||
#import "RDPSession.h"
|
||||
#import "Utils.h"
|
||||
|
||||
#define TAG FREERDP_TAG("iOS")
|
||||
|
||||
#pragma mark Connection helpers
|
||||
|
||||
static void ios_OnChannelConnectedEventHandler(
|
||||
rdpContext* context,
|
||||
ChannelConnectedEventArgs* e)
|
||||
{
|
||||
rdpSettings* settings;
|
||||
mfContext* afc;
|
||||
|
||||
if (!context || !e)
|
||||
{
|
||||
WLog_FATAL(TAG, "%s(context=%p, EventArgs=%p",
|
||||
__FUNCTION__, context, e);
|
||||
return;
|
||||
}
|
||||
|
||||
afc = (mfContext*) context;
|
||||
settings = context->settings;
|
||||
|
||||
if (strcmp(e->name, RDPGFX_DVC_CHANNEL_NAME) == 0)
|
||||
{
|
||||
if (settings->SoftwareGdi)
|
||||
{
|
||||
gdi_graphics_pipeline_init(context->gdi,
|
||||
(RdpgfxClientContext*) e->pInterface);
|
||||
}
|
||||
else
|
||||
{
|
||||
WLog_WARN(TAG, "GFX without software GDI requested. "
|
||||
" This is not supported, add /gdi:sw");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ios_OnChannelDisconnectedEventHandler(
|
||||
rdpContext* context, ChannelDisconnectedEventArgs* e)
|
||||
{
|
||||
rdpSettings* settings;
|
||||
mfContext* afc;
|
||||
|
||||
if (!context || !e)
|
||||
{
|
||||
WLog_FATAL(TAG, "%s(context=%p, EventArgs=%p",
|
||||
__FUNCTION__, context, e);
|
||||
return;
|
||||
}
|
||||
|
||||
afc = (mfContext*) context;
|
||||
settings = context->settings;
|
||||
|
||||
if (strcmp(e->name, RDPGFX_DVC_CHANNEL_NAME) == 0)
|
||||
{
|
||||
if (settings->SoftwareGdi)
|
||||
{
|
||||
gdi_graphics_pipeline_uninit(context->gdi,
|
||||
(RdpgfxClientContext*) e->pInterface);
|
||||
}
|
||||
else
|
||||
{
|
||||
WLog_WARN(TAG, "GFX without software GDI requested. "
|
||||
" This is not supported, add /gdi:sw");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL ios_pre_connect(freerdp* instance)
|
||||
{
|
||||
rdpSettings* settings = instance->settings;
|
||||
int rc;
|
||||
rdpSettings* settings;
|
||||
|
||||
settings->AutoLogonEnabled = settings->Password && (strlen(settings->Password) > 0);
|
||||
if (!instance || !instance->settings)
|
||||
return FALSE;
|
||||
|
||||
settings = instance->settings;
|
||||
|
||||
if (!settings->OrderSupport)
|
||||
return FALSE;
|
||||
|
||||
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))
|
||||
if ((settings->DesktopWidth < 64) || (settings->DesktopHeight < 64)
|
||||
|| (settings->DesktopWidth > 4096) || (settings->DesktopHeight > 4096))
|
||||
{
|
||||
NSLog(@"%s: invalid dimensions %d %d", __func__, settings->DesktopWidth, settings->DesktopHeight);
|
||||
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;
|
||||
@ -61,38 +138,154 @@ static BOOL ios_pre_connect(freerdp* instance)
|
||||
settings->OrderSupport[NEG_POLYGON_CB_INDEX] = FALSE;
|
||||
settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = FALSE;
|
||||
settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE;
|
||||
rc = PubSub_SubscribeChannelConnected(
|
||||
instance->context->pubSub,
|
||||
(pChannelConnectedEventHandler)
|
||||
ios_OnChannelConnectedEventHandler);
|
||||
|
||||
settings->FrameAcknowledge = 10;
|
||||
|
||||
if (!freerdp_client_load_addins(instance->context->channels, instance->settings))
|
||||
if (rc != CHANNEL_RC_OK)
|
||||
{
|
||||
WLog_ERR(TAG, "Could not subscribe to connect event handler [%l08X]", rc);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (freerdp_channels_pre_connect(instance->context->channels, instance) != CHANNEL_RC_OK)
|
||||
rc = PubSub_SubscribeChannelDisconnected(
|
||||
instance->context->pubSub,
|
||||
(pChannelDisconnectedEventHandler)
|
||||
ios_OnChannelDisconnectedEventHandler);
|
||||
|
||||
if (rc != CHANNEL_RC_OK)
|
||||
{
|
||||
WLog_ERR(TAG, "Could not subscribe to disconnect event handler [%l08X]", rc);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!freerdp_client_load_addins(instance->context->channels,
|
||||
instance->settings))
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to load addins [%l08X]", GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rc = freerdp_channels_pre_connect(instance->context->channels, instance);
|
||||
|
||||
if (rc != CHANNEL_RC_OK)
|
||||
{
|
||||
WLog_ERR(TAG, "freerdp_channels_pre_connect failed with %l08X", rc);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL ios_Pointer_New(rdpContext* context, rdpPointer* pointer)
|
||||
{
|
||||
if (!context || !pointer || !context->gdi)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void ios_Pointer_Free(rdpContext* context, rdpPointer* pointer)
|
||||
{
|
||||
if (!context || !pointer)
|
||||
return;
|
||||
}
|
||||
|
||||
static BOOL ios_Pointer_Set(rdpContext* context,
|
||||
const rdpPointer* pointer)
|
||||
{
|
||||
if (!context)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL ios_Pointer_SetPosition(rdpContext* context,
|
||||
UINT32 x, UINT32 y)
|
||||
{
|
||||
if (!context)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL ios_Pointer_SetNull(rdpContext* context)
|
||||
{
|
||||
if (!context)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL ios_Pointer_SetDefault(rdpContext* context)
|
||||
{
|
||||
if (!context)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL ios_register_pointer(rdpGraphics* graphics)
|
||||
{
|
||||
rdpPointer pointer;
|
||||
|
||||
if (!graphics)
|
||||
return FALSE;
|
||||
|
||||
pointer.size = sizeof(pointer);
|
||||
pointer.New = ios_Pointer_New;
|
||||
pointer.Free = ios_Pointer_Free;
|
||||
pointer.Set = ios_Pointer_Set;
|
||||
pointer.SetNull = ios_Pointer_SetNull;
|
||||
pointer.SetDefault = ios_Pointer_SetDefault;
|
||||
pointer.SetPosition = ios_Pointer_SetPosition;
|
||||
graphics_register_pointer(graphics, &pointer);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL ios_post_connect(freerdp* instance)
|
||||
{
|
||||
mfInfo* mfi = MFI_FROM_INSTANCE(instance);
|
||||
mfInfo* mfi;
|
||||
|
||||
instance->context->cache = cache_new(instance->settings);
|
||||
if (!instance)
|
||||
return FALSE;
|
||||
|
||||
mfi = MFI_FROM_INSTANCE(instance);
|
||||
|
||||
if (!mfi)
|
||||
return FALSE;
|
||||
|
||||
if (!gdi_init(instance, PIXEL_FORMAT_BGRA32))
|
||||
return FALSE;
|
||||
|
||||
if (!ios_register_pointer(instance->context->graphics))
|
||||
return FALSE;
|
||||
|
||||
// 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;
|
||||
pointer_cache_register_callbacks(instance->update);
|
||||
|
||||
// Channel allocation
|
||||
if (freerdp_channels_post_connect(instance->context->channels, instance) != CHANNEL_RC_OK)
|
||||
if (freerdp_channels_post_connect(instance->context->channels,
|
||||
instance) != CHANNEL_RC_OK)
|
||||
return FALSE;
|
||||
|
||||
[mfi->session performSelectorOnMainThread:@selector(sessionDidConnect) withObject:nil waitUntilDone:YES];
|
||||
[mfi->session performSelectorOnMainThread:@selector(sessionDidConnect)
|
||||
withObject:nil waitUntilDone:YES];
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void ios_post_disconnect(freerdp* instance)
|
||||
{
|
||||
if (instance && instance->context)
|
||||
freerdp_channels_disconnect(instance->context->channels, instance);
|
||||
|
||||
gdi_free(instance);
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Running the connection
|
||||
|
||||
@ -101,7 +294,6 @@ 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))
|
||||
@ -114,7 +306,6 @@ int ios_run_freerdp(freerdp* instance)
|
||||
return MF_EXIT_CONN_CANCELED;
|
||||
|
||||
mfi->connection_state = TSXConnectionConnected;
|
||||
|
||||
// Connection main loop
|
||||
NSAutoreleasePool* pool;
|
||||
int i;
|
||||
@ -128,14 +319,12 @@ int ios_run_freerdp(freerdp* instance)
|
||||
fd_set wfds_set;
|
||||
struct timeval timeout;
|
||||
int select_status;
|
||||
|
||||
memset(rfds, 0, sizeof(rfds));
|
||||
memset(wfds, 0, sizeof(wfds));
|
||||
|
||||
while (!freerdp_shall_disconnect(instance))
|
||||
{
|
||||
rcount = wcount = 0;
|
||||
|
||||
pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
|
||||
@ -144,7 +333,8 @@ int ios_run_freerdp(freerdp* instance)
|
||||
break;
|
||||
}
|
||||
|
||||
if (freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount) != TRUE)
|
||||
if (freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds,
|
||||
&wcount) != TRUE)
|
||||
{
|
||||
NSLog(@"%s: freerdp_chanman_get_fds failed", __func__);
|
||||
break;
|
||||
@ -173,24 +363,23 @@ int ios_run_freerdp(freerdp* instance)
|
||||
if (max_fds == 0)
|
||||
break;
|
||||
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_usec = 0;
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_usec = 0;
|
||||
select_status = select(max_fds + 1, &rfds_set, NULL, NULL, &timeout);
|
||||
|
||||
select_status = select(max_fds + 1, &rfds_set, NULL, NULL, &timeout);
|
||||
|
||||
// timeout?
|
||||
if (select_status == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (select_status == -1)
|
||||
{
|
||||
/* these are not really errors */
|
||||
if (!((errno == EAGAIN) ||
|
||||
(errno == EWOULDBLOCK) ||
|
||||
(errno == EINPROGRESS) ||
|
||||
(errno == EINTR))) /* signal occurred */
|
||||
// timeout?
|
||||
if (select_status == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (select_status == -1)
|
||||
{
|
||||
/* these are not really errors */
|
||||
if (!((errno == EAGAIN) ||
|
||||
(errno == EWOULDBLOCK) ||
|
||||
(errno == EINPROGRESS) ||
|
||||
(errno == EINTR))) /* signal occurred */
|
||||
{
|
||||
NSLog(@"%s: select failed!", __func__);
|
||||
break;
|
||||
}
|
||||
@ -218,121 +407,129 @@ int ios_run_freerdp(freerdp* instance)
|
||||
break;
|
||||
}
|
||||
|
||||
[pool release]; pool = nil;
|
||||
[pool release];
|
||||
pool = nil;
|
||||
}
|
||||
|
||||
CGContextRelease(mfi->bitmap_context);
|
||||
mfi->bitmap_context = NULL;
|
||||
mfi->connection_state = TSXConnectionDisconnected;
|
||||
|
||||
// Cleanup
|
||||
freerdp_channels_disconnect(channels, instance);
|
||||
freerdp_disconnect(instance);
|
||||
gdi_free(instance);
|
||||
cache_free(instance->context->cache);
|
||||
|
||||
[pool release]; pool = nil;
|
||||
[pool release];
|
||||
pool = nil;
|
||||
return MF_EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Context callbacks
|
||||
|
||||
BOOL ios_context_new(freerdp* instance, rdpContext* context)
|
||||
static BOOL ios_client_new(freerdp* instance, rdpContext* context)
|
||||
{
|
||||
mfInfo* mfi;
|
||||
mfContext* ctx = (mfContext*)context;
|
||||
|
||||
if (!instance || !context)
|
||||
return FALSE;
|
||||
|
||||
if (!(context->channels = freerdp_channels_new()))
|
||||
return FALSE;
|
||||
|
||||
if ((ctx->mfi = calloc(1, sizeof(mfInfo))) == NULL)
|
||||
return FALSE;
|
||||
|
||||
ctx->mfi->context = (mfContext*)context;
|
||||
ctx->mfi->_context = context;
|
||||
ctx->mfi->context->settings = instance->settings;
|
||||
ctx->mfi->instance = instance;
|
||||
|
||||
if (!ios_events_create_pipe(ctx->mfi))
|
||||
return FALSE;
|
||||
|
||||
instance->PreConnect = ios_pre_connect;
|
||||
instance->PostConnect = ios_post_connect;
|
||||
instance->PostDisconnect = ios_post_disconnect;
|
||||
instance->Authenticate = ios_ui_authenticate;
|
||||
instance->GatewayAuthenticate = ios_ui_gw_authenticate;
|
||||
instance->VerifyCertificate = ios_ui_verify_certificate;
|
||||
instance->VerifyChangedCertificate = ios_ui_verify_changed_certificate;
|
||||
instance->LogonErrorInfo = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void ios_client_free(freerdp* instance, rdpContext* context)
|
||||
{
|
||||
mfInfo* mfi;
|
||||
|
||||
if (!(mfi = (mfInfo*)calloc(1, sizeof(mfInfo))))
|
||||
goto fail_mfi;
|
||||
if (!context)
|
||||
return;
|
||||
|
||||
if (!(context->channels = freerdp_channels_new()))
|
||||
goto fail_channels;
|
||||
mfi = ((mfContext*) context)->mfi;
|
||||
|
||||
if (!ios_events_create_pipe(mfi))
|
||||
goto fail_events;
|
||||
if (context->channels)
|
||||
{
|
||||
freerdp_channels_close(context->channels, instance);
|
||||
freerdp_channels_free(context->channels);
|
||||
context->channels = NULL;
|
||||
}
|
||||
|
||||
((mfContext*) context)->mfi = mfi;
|
||||
mfi->_context = context;
|
||||
mfi->context = (mfContext*)context;
|
||||
mfi->context->settings = instance->settings;
|
||||
mfi->instance = instance;
|
||||
return TRUE;
|
||||
|
||||
fail_events:
|
||||
freerdp_channels_free(context->channels);
|
||||
context->channels = NULL;
|
||||
fail_channels:
|
||||
free(mfi);
|
||||
fail_mfi:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void ios_context_free(freerdp* instance, rdpContext* context)
|
||||
{
|
||||
mfInfo* mfi = ((mfContext*) context)->mfi;
|
||||
freerdp_channels_close(context->channels, instance);
|
||||
freerdp_channels_free(context->channels);
|
||||
ios_events_free_pipe(mfi);
|
||||
free(mfi);
|
||||
}
|
||||
|
||||
static int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints)
|
||||
{
|
||||
ZeroMemory(pEntryPoints, sizeof(RDP_CLIENT_ENTRY_POINTS));
|
||||
pEntryPoints->Version = RDP_CLIENT_INTERFACE_VERSION;
|
||||
pEntryPoints->Size = sizeof(RDP_CLIENT_ENTRY_POINTS_V1);
|
||||
pEntryPoints->GlobalInit = NULL;
|
||||
pEntryPoints->GlobalUninit = NULL;
|
||||
pEntryPoints->ContextSize = sizeof(mfContext);
|
||||
pEntryPoints->ClientNew = ios_client_new;
|
||||
pEntryPoints->ClientFree = ios_client_free;
|
||||
pEntryPoints->ClientStart = NULL;
|
||||
pEntryPoints->ClientStop = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Initialization and cleanup
|
||||
|
||||
freerdp* ios_freerdp_new()
|
||||
{
|
||||
freerdp* inst = freerdp_new();
|
||||
if (!inst)
|
||||
rdpContext* context;
|
||||
RDP_CLIENT_ENTRY_POINTS clientEntryPoints;
|
||||
RdpClientEntry(&clientEntryPoints);
|
||||
context = freerdp_client_context_new(&clientEntryPoints);
|
||||
|
||||
if (!context)
|
||||
return NULL;
|
||||
|
||||
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->ContextSize = 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 = strdup([[home_path stringByAppendingPathComponent:@".freerdp"] UTF8String]);
|
||||
if (!inst->settings->HomePath || !inst->settings->ConfigPath)
|
||||
{
|
||||
free(inst->settings->HomePath);
|
||||
free(inst->settings->ConfigPath);
|
||||
freerdp_context_free(inst);
|
||||
freerdp_free(inst);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return inst;
|
||||
return context->instance;
|
||||
}
|
||||
|
||||
void ios_freerdp_free(freerdp* instance)
|
||||
{
|
||||
freerdp_context_free(instance);
|
||||
freerdp_free(instance);
|
||||
if (!instance || !instance->context)
|
||||
return;
|
||||
|
||||
freerdp_client_context_free(instance->context);
|
||||
}
|
||||
|
||||
void ios_init_freerdp()
|
||||
{
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
freerdp_register_addin_provider(freerdp_channels_load_static_addin_entry, 0);
|
||||
}
|
||||
|
||||
void ios_uninit_freerdp()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/* compatibilty functions */
|
||||
size_t fwrite$UNIX2003( const void *ptr, size_t size, size_t nmemb, FILE *stream )
|
||||
size_t fwrite$UNIX2003(const void* ptr, size_t size, size_t nmemb, FILE* stream)
|
||||
{
|
||||
return fwrite(ptr, size , nmemb, stream);
|
||||
}
|
||||
|
@ -9,20 +9,27 @@
|
||||
|
||||
#import "ios_freerdp.h"
|
||||
|
||||
BOOL ios_ui_begin_paint(rdpContext * context);
|
||||
BOOL ios_ui_end_paint(rdpContext * context);
|
||||
BOOL ios_ui_resize_window(rdpContext * context);
|
||||
BOOL ios_ui_begin_paint(rdpContext* context);
|
||||
BOOL ios_ui_end_paint(rdpContext* context);
|
||||
BOOL ios_ui_resize_window(rdpContext* context);
|
||||
|
||||
BOOL ios_ui_authenticate(freerdp * instance, char** username, char** password, char** domain);
|
||||
DWORD ios_ui_check_certificate(freerdp * instance, const char* common_name,
|
||||
const char * subject, const char * issuer,
|
||||
const char * fingerprint, BOOL host_mismatch);
|
||||
DWORD ios_ui_check_changed_certificate(freerdp * instance,
|
||||
const char* common_name,
|
||||
const char * subject,
|
||||
const char * issuer,
|
||||
const char * new_fingerprint,
|
||||
const char * old_fingerprint);
|
||||
BOOL ios_ui_authenticate(freerdp* instance, char** username, char** password,
|
||||
char** domain);
|
||||
BOOL ios_ui_gw_authenticate(freerdp* instance, char** username, char** password,
|
||||
char** domain);
|
||||
DWORD ios_ui_verify_certificate(freerdp* instance,
|
||||
const char* common_name,
|
||||
const char* subject,
|
||||
const char* issuer,
|
||||
const char* fingerprint,
|
||||
BOOL host_mismatch);
|
||||
DWORD ios_ui_verify_changed_certificate(freerdp* instance,
|
||||
const char* common_name,
|
||||
const char* subject,
|
||||
const char* issuer,
|
||||
const char* new_fingerprint,
|
||||
const char* old_subject,
|
||||
const char* old_issuer,
|
||||
const char* old_fingerprint);
|
||||
|
||||
void ios_allocate_display_buffer(mfInfo* mfi);
|
||||
void ios_resize_display_buffer(mfInfo* mfi);
|
||||
|
@ -17,24 +17,26 @@
|
||||
#pragma mark -
|
||||
#pragma mark Certificate authentication
|
||||
|
||||
BOOL ios_ui_authenticate(freerdp * instance, char** username, char** password, char** domain)
|
||||
static void ios_resize_display_buffer(mfInfo* mfi);
|
||||
static BOOL ios_ui_authenticate_raw(freerdp* instance, char** username,
|
||||
char** password,
|
||||
char** domain, const char* title)
|
||||
{
|
||||
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];
|
||||
(*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])
|
||||
{
|
||||
@ -46,7 +48,6 @@ BOOL ios_ui_authenticate(freerdp * instance, char** username, char** password, c
|
||||
free(*username);
|
||||
free(*password);
|
||||
free(*domain);
|
||||
|
||||
// set values back
|
||||
*username = strdup([[params objectForKey:@"username"] UTF8String]);
|
||||
*password = strdup([[params objectForKey:@"password"] UTF8String]);
|
||||
@ -63,24 +64,40 @@ BOOL ios_ui_authenticate(freerdp * instance, char** username, char** password, c
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DWORD ios_ui_check_certificate(freerdp * instance, const char* common_name,
|
||||
const char * subject, const char * issuer,
|
||||
const char * fingerprint, BOOL host_mismatch)
|
||||
BOOL ios_ui_authenticate(freerdp* instance, char** username, char** password,
|
||||
char** domain)
|
||||
{
|
||||
return ios_ui_authenticate_raw(instance, username, password, domain, "");
|
||||
}
|
||||
|
||||
BOOL ios_ui_gw_authenticate(freerdp* instance, char** username, char** password,
|
||||
char** domain)
|
||||
{
|
||||
return ios_ui_authenticate_raw(instance, username, password, domain, "gateway");
|
||||
}
|
||||
|
||||
|
||||
DWORD ios_ui_verify_certificate(freerdp* instance,
|
||||
const char* common_name,
|
||||
const char* subject,
|
||||
const char* issuer,
|
||||
const char* fingerprint,
|
||||
BOOL host_mismatch)
|
||||
{
|
||||
// check whether we accept all certificates
|
||||
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"security.accept_certificates"] == YES)
|
||||
if ([[NSUserDefaults standardUserDefaults] boolForKey:
|
||||
@"security.accept_certificates"] == YES)
|
||||
return 2;
|
||||
|
||||
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];
|
||||
|
||||
(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];
|
||||
|
||||
[mfi->session performSelectorOnMainThread:@selector(
|
||||
sessionVerifyCertificateWithParams:) withObject:params waitUntilDone:YES];
|
||||
// wait for UI request to be completed
|
||||
[[mfi->session uiRequestCompleted] lock];
|
||||
[[mfi->session uiRequestCompleted] wait];
|
||||
@ -95,44 +112,63 @@ DWORD ios_ui_check_certificate(freerdp * instance, const char* common_name,
|
||||
return 1;
|
||||
}
|
||||
|
||||
DWORD ios_ui_check_changed_certificate(freerdp * instance,
|
||||
const char * common_name,
|
||||
const char * subject,
|
||||
const char * issuer,
|
||||
const char * new_fingerprint,
|
||||
const char * old_fingerprint)
|
||||
DWORD ios_ui_verify_changed_certificate(freerdp* instance,
|
||||
const char* common_name,
|
||||
const char* subject,
|
||||
const char* issuer,
|
||||
const char* new_fingerprint,
|
||||
const char* old_subject,
|
||||
const char* old_issuer,
|
||||
const char* old_fingerprint)
|
||||
{
|
||||
return ios_ui_check_certificate(instance, common_name, subject, issuer,
|
||||
new_fingerprint, FALSE);
|
||||
return ios_ui_verify_certificate(instance, common_name, subject, issuer,
|
||||
new_fingerprint, FALSE);
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Graphics updates
|
||||
|
||||
BOOL ios_ui_begin_paint(rdpContext * context)
|
||||
BOOL ios_ui_begin_paint(rdpContext* context)
|
||||
{
|
||||
rdpGdi *gdi = context->gdi;
|
||||
rdpGdi* gdi = context->gdi;
|
||||
gdi->primary->hdc->hwnd->invalid->null = 1;
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL ios_ui_end_paint(rdpContext * context)
|
||||
BOOL 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);
|
||||
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);
|
||||
|
||||
if (gdi->primary->hdc->hwnd->invalid->null == 0)
|
||||
[mfi->session performSelectorOnMainThread:@selector(setNeedsDisplayInRectAsValue:) withObject:[NSValue valueWithCGRect:dirty_rect] waitUntilDone:NO];
|
||||
return TRUE;
|
||||
[mfi->session performSelectorOnMainThread:@selector(
|
||||
setNeedsDisplayInRectAsValue:) withObject:[NSValue valueWithCGRect:dirty_rect]
|
||||
waitUntilDone:NO];
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL ios_ui_resize_window(rdpContext * context)
|
||||
BOOL ios_ui_resize_window(rdpContext* context)
|
||||
{
|
||||
rdpSettings* settings;
|
||||
rdpGdi* gdi;
|
||||
|
||||
if (!context || !context->settings)
|
||||
return FALSE;
|
||||
|
||||
settings = context->settings;
|
||||
gdi = context->gdi;
|
||||
|
||||
if (!gdi_resize(gdi, settings->DesktopWidth, settings->DesktopHeight))
|
||||
return FALSE;
|
||||
|
||||
ios_resize_display_buffer(MFI_FROM_INSTANCE(context->instance));
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@ -141,22 +177,27 @@ BOOL ios_ui_resize_window(rdpContext * context)
|
||||
|
||||
static void ios_create_bitmap_context(mfInfo* mfi)
|
||||
{
|
||||
[mfi->session performSelectorOnMainThread:@selector(sessionBitmapContextWillChange) withObject:nil waitUntilDone:YES];
|
||||
[mfi->session performSelectorOnMainThread:@selector(
|
||||
sessionBitmapContextWillChange) withObject:nil waitUntilDone:YES];
|
||||
rdpGdi* gdi = mfi->instance->context->gdi;
|
||||
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||
|
||||
rdpGdi* gdi = mfi->instance->context->gdi;
|
||||
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||
if (GetBytesPerPixel(gdi->dstFormat) == 2)
|
||||
mfi->bitmap_context = CGBitmapContextCreate(gdi->primary_buffer, gdi->width, gdi->height, 5, gdi->stride, colorSpace, kCGBitmapByteOrder16Little | kCGImageAlphaNoneSkipFirst);
|
||||
mfi->bitmap_context = CGBitmapContextCreate(gdi->primary_buffer, gdi->width,
|
||||
gdi->height, 5, gdi->stride, colorSpace,
|
||||
kCGBitmapByteOrder16Little | kCGImageAlphaNoneSkipFirst);
|
||||
else
|
||||
mfi->bitmap_context = CGBitmapContextCreate(gdi->primary_buffer, gdi->width, gdi->height, 8, gdi->stride, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst);
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
mfi->bitmap_context = CGBitmapContextCreate(gdi->primary_buffer, gdi->width,
|
||||
gdi->height, 8, gdi->stride, colorSpace,
|
||||
kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst);
|
||||
|
||||
[mfi->session performSelectorOnMainThread:@selector(sessionBitmapContextDidChange) withObject:nil waitUntilDone:YES];
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
[mfi->session performSelectorOnMainThread:@selector(
|
||||
sessionBitmapContextDidChange) withObject:nil waitUntilDone:YES];
|
||||
}
|
||||
|
||||
void ios_allocate_display_buffer(mfInfo* mfi)
|
||||
{
|
||||
gdi_init(mfi->instance, PIXEL_FORMAT_XRGB32);
|
||||
ios_create_bitmap_context(mfi);
|
||||
}
|
||||
|
||||
@ -166,7 +207,6 @@ void ios_resize_display_buffer(mfInfo* mfi)
|
||||
CGContextRef old_context = mfi->bitmap_context;
|
||||
mfi->bitmap_context = NULL;
|
||||
CGContextRelease(old_context);
|
||||
|
||||
// Create the new context
|
||||
ios_create_bitmap_context(mfi);
|
||||
}
|
||||
|
@ -21,14 +21,17 @@
|
||||
#include <ifaddrs.h>
|
||||
#include <net/if_dl.h>
|
||||
|
||||
BOOL ScanHostNameAndPort(NSString* address, NSString** host, unsigned short* port)
|
||||
BOOL ScanHostNameAndPort(NSString* address, NSString** host,
|
||||
unsigned short* port)
|
||||
{
|
||||
*host = @""; *port = 0;
|
||||
*host = @"";
|
||||
*port = 0;
|
||||
|
||||
if (![address length])
|
||||
return NO;
|
||||
|
||||
NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:@"rdp://%@", address]];
|
||||
NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:@"rdp://%@",
|
||||
address]];
|
||||
|
||||
if (!url || ![[url host] length])
|
||||
return NO;
|
||||
@ -43,17 +46,21 @@ BOOL ScanHostNameAndPort(NSString* address, NSString** host, unsigned short* por
|
||||
|
||||
NSString* LocalizedFitScreen()
|
||||
{
|
||||
return NSLocalizedString(@"Automatic", @"Screen resolution selector: Automatic resolution (Full Screen on iPad, reasonable size on iPhone)");
|
||||
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");
|
||||
return NSLocalizedString(@"Custom", @"Screen resolution selector: Custom");
|
||||
}
|
||||
|
||||
BOOL ScanScreenResolution(NSString* description, int* width, int* height, TSXScreenOptions* type)
|
||||
BOOL ScanScreenResolution(NSString* description, int* width, int* height,
|
||||
TSXScreenOptions* type)
|
||||
{
|
||||
*height = 0; *width = 0; *type = TSXScreenOptionFixed;
|
||||
*height = 0;
|
||||
*width = 0;
|
||||
*type = TSXScreenOptionFixed;
|
||||
|
||||
if ([description isEqualToString:LocalizedFitScreen()])
|
||||
{
|
||||
@ -66,7 +73,9 @@ BOOL ScanScreenResolution(NSString* description, int* width, int* height, TSXScr
|
||||
return YES;
|
||||
}
|
||||
|
||||
NSArray* resolution_components = [description componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"x*×"]];
|
||||
NSArray* resolution_components = [description
|
||||
componentsSeparatedByCharactersInSet:[NSCharacterSet
|
||||
characterSetWithCharactersInString:@"x*×"]];
|
||||
|
||||
if ([resolution_components count] != 2)
|
||||
return NO;
|
||||
@ -76,7 +85,8 @@ BOOL ScanScreenResolution(NSString* description, int* width, int* height, TSXScr
|
||||
return YES;
|
||||
}
|
||||
|
||||
NSString* ScreenResolutionDescription(TSXScreenOptions type, int width, int height)
|
||||
NSString* ScreenResolutionDescription(TSXScreenOptions type, int width,
|
||||
int height)
|
||||
{
|
||||
if (type == TSXScreenOptionFitScreen)
|
||||
return LocalizedFitScreen();
|
||||
@ -89,34 +99,42 @@ NSString* ScreenResolutionDescription(TSXScreenOptions type, int width, int heig
|
||||
|
||||
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;
|
||||
OrderedDictionary* dict = [OrderedDictionary dictionaryWithCapacity:3];
|
||||
[dict setValue:[NSNumber numberWithInt:8] forKey:NSLocalizedString(
|
||||
@"Palette Color (8 Bit)", @"8 bit color selection")];
|
||||
[dict setValue:[NSNumber numberWithInt:15] forKey:NSLocalizedString(
|
||||
@"High Color (15 Bit)", @"15 bit color selection")];
|
||||
[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;
|
||||
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");
|
||||
return NSLocalizedString(@"Automatic", @"Automatic protocl security selection");
|
||||
}
|
||||
|
||||
NSString* ProtocolSecurityDescription(TSXProtocolSecurityOptions type)
|
||||
@ -131,7 +149,8 @@ NSString* ProtocolSecurityDescription(TSXProtocolSecurityOptions type)
|
||||
return LocalizedAutomaticSecurity();
|
||||
}
|
||||
|
||||
BOOL ScanProtocolSecurity(NSString* description, TSXProtocolSecurityOptions* type)
|
||||
BOOL ScanProtocolSecurity(NSString* description,
|
||||
TSXProtocolSecurityOptions* type)
|
||||
{
|
||||
*type = TSXProtocolSecurityRDP;
|
||||
|
||||
@ -161,12 +180,16 @@ BOOL ScanProtocolSecurity(NSString* description, TSXProtocolSecurityOptions* typ
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@ -178,47 +201,52 @@ NSDictionary* SelectionForSecuritySetting()
|
||||
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];
|
||||
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]];
|
||||
for (ComputerBookmark * cur_bookmark in bookmarks)
|
||||
{
|
||||
double match_score = 0.0;
|
||||
|
||||
if (![val isKindOfClass:[NSString class]] || ![val length])
|
||||
continue;
|
||||
for (int i = 0; i < [searched_keys count]; i++)
|
||||
{
|
||||
NSString* val = [cur_bookmark valueForKeyPath:[searched_keys objectAtIndex:i]];
|
||||
|
||||
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 (![val isKindOfClass:[NSString class]] || ![val length])
|
||||
continue;
|
||||
|
||||
if (match_score > 0.001)
|
||||
[matching_items addObject:[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
cur_bookmark, @"bookmark",
|
||||
[NSNumber numberWithFloat:match_score], @"score",
|
||||
nil]];
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
[matching_items sortUsingComparator:^NSComparisonResult(NSDictionary* obj1, NSDictionary* obj2) {
|
||||
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];
|
||||
}
|
||||
NSMutableArray* result = [NSMutableArray array];
|
||||
|
||||
return result;
|
||||
for (NSString * item in history)
|
||||
{
|
||||
if ([item rangeOfString:filterStr].location != NSNotFound)
|
||||
[result addObject:item];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#pragma mark Version Info
|
||||
@ -232,18 +260,18 @@ NSString* TSXAppFullVersion()
|
||||
BOOL IsPad()
|
||||
{
|
||||
#ifdef UI_USER_INTERFACE_IDIOM
|
||||
return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
|
||||
return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
|
||||
#else
|
||||
return NO;
|
||||
return NO;
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOL IsPhone()
|
||||
{
|
||||
#ifdef UI_USER_INTERFACE_IDIOM
|
||||
return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone);
|
||||
return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone);
|
||||
#else
|
||||
return NO;
|
||||
return NO;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -251,121 +279,127 @@ BOOL IsPhone()
|
||||
static BOOL g_swap_mouse_buttons = NO;
|
||||
void SetSwapMouseButtonsFlag(BOOL swapped)
|
||||
{
|
||||
g_swap_mouse_buttons = swapped;
|
||||
g_swap_mouse_buttons = swapped;
|
||||
}
|
||||
|
||||
// set invert scrolling flag
|
||||
static BOOL g_invert_scrolling = NO;
|
||||
void SetInvertScrollingFlag(BOOL invert)
|
||||
{
|
||||
g_invert_scrolling = 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));
|
||||
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));
|
||||
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 (PTR_FLAGS_MOVE);
|
||||
}
|
||||
|
||||
// return mouse wheel event
|
||||
int GetMouseWheelEvent(BOOL down)
|
||||
{
|
||||
if (g_invert_scrolling)
|
||||
down = !down;
|
||||
if (g_invert_scrolling)
|
||||
down = !down;
|
||||
|
||||
if(down)
|
||||
return (PTR_FLAGS_WHEEL | PTR_FLAGS_WHEEL_NEGATIVE | (0x0088));
|
||||
else
|
||||
return (PTR_FLAGS_WHEEL | (0x0078));
|
||||
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;
|
||||
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
|
||||
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* TSXGetPrimaryMACAddress(NSString* sep)
|
||||
{
|
||||
NSString* macaddress = @"";
|
||||
NSString* macaddress = @"";
|
||||
struct ifaddrs* addrs;
|
||||
|
||||
struct ifaddrs *addrs;
|
||||
if (getifaddrs(&addrs) < 0)
|
||||
{
|
||||
NSLog(@"getPrimaryMACAddress: getifaddrs failed.");
|
||||
return macaddress;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
||||
freeifaddrs(addrs);
|
||||
if (dlAddr->sdl_alen != 6)
|
||||
continue;
|
||||
|
||||
return macaddress;
|
||||
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:
|
||||
@"/Applications/Cydia.app/"])
|
||||
return YES;
|
||||
|
||||
if ([[NSFileManager defaultManager] fileExistsAtPath:@"/etc/apt/"])
|
||||
return YES;
|
||||
if ([[NSFileManager defaultManager] fileExistsAtPath:@"/etc/apt/"])
|
||||
return YES;
|
||||
|
||||
return NO;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -35,13 +35,15 @@
|
||||
return nil;
|
||||
|
||||
ComputerBookmark* bookmark = nil;
|
||||
NSData* bookmark_data = [[NSUserDefaults standardUserDefaults] objectForKey:@"TSXSharedGlobalDefaultBookmark"];
|
||||
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];
|
||||
bookmark = [[[ComputerBookmark alloc] initWithBaseDefaultParameters]
|
||||
autorelease];
|
||||
|
||||
_default_bookmark = [bookmark retain];
|
||||
return self;
|
||||
@ -55,11 +57,12 @@
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@synthesize bookmark=_default_bookmark;
|
||||
@synthesize bookmark = _default_bookmark;
|
||||
|
||||
- (ComputerBookmark*)newBookmark
|
||||
{
|
||||
return [[ComputerBookmark alloc] initWithConnectionParameters:[[self newParams] autorelease]];
|
||||
return [[ComputerBookmark alloc] initWithConnectionParameters:[[self newParams]
|
||||
autorelease]];
|
||||
}
|
||||
|
||||
- (ConnectionParams*)newParams
|
||||
@ -70,14 +73,16 @@
|
||||
|
||||
- (ComputerBookmark*)newTestServerBookmark
|
||||
{
|
||||
ComputerBookmark* bm = [self newBookmark];
|
||||
[bm setLabel:@"Test Server"];
|
||||
[[bm params] setValue:@"testservice.ifreerdp.com" forKey:@"hostname"];
|
||||
[[bm params] setInt:0 forKey:@"screen_resolution_type"];
|
||||
[[bm params] setInt:1024 forKey:@"width"];
|
||||
[[bm params] setInt:768 forKey:@"height"];
|
||||
[[bm params] setInt:32 forKey:@"colors"];
|
||||
[[bm params] setBool:YES forKey:@"perf_remotefx"];
|
||||
ComputerBookmark* bm = [self newBookmark];
|
||||
[bm setLabel:@"Test Server"];
|
||||
[[bm params] setValue:@"testservice.ifreerdp.com" forKey:@"hostname"];
|
||||
[[bm params] setInt:0 forKey:@"screen_resolution_type"];
|
||||
[[bm params] setInt:1024 forKey:@"width"];
|
||||
[[bm params] setInt:768 forKey:@"height"];
|
||||
[[bm params] setInt:32 forKey:@"colors"];
|
||||
[[bm params] setBool:YES forKey:@"perf_remotefx"];
|
||||
[[bm params] setBool:YES forKey:@"perf_gfx"];
|
||||
[[bm params] setBool:YES forKey:@"perf_h264"];
|
||||
return bm;
|
||||
}
|
||||
|
||||
|
@ -17,9 +17,10 @@
|
||||
#import "ConnectionParams.h"
|
||||
|
||||
NSString* TSXSessionDidDisconnectNotification = @"TSXSessionDidDisconnect";
|
||||
NSString* TSXSessionDidFailToConnectNotification = @"TSXSessionDidFailToConnect";
|
||||
NSString* TSXSessionDidFailToConnectNotification =
|
||||
@"TSXSessionDidFailToConnect";
|
||||
|
||||
@interface RDPSession (Private)
|
||||
@interface RDPSession(Private)
|
||||
- (void)runSession;
|
||||
- (void)runSessionFinished:(NSNumber*)result;
|
||||
- (mfInfo*)mfi;
|
||||
@ -35,201 +36,269 @@ NSString* TSXSessionDidFailToConnectNotification = @"TSXSessionDidFailToConnect"
|
||||
|
||||
@implementation RDPSession
|
||||
|
||||
@synthesize delegate=_delegate, params=_params, toolbarVisible = _toolbar_visible, uiRequestCompleted = _ui_request_completed, bookmark = _bookmark;
|
||||
@synthesize delegate = _delegate, params = _params,
|
||||
toolbarVisible = _toolbar_visible, uiRequestCompleted = _ui_request_completed,
|
||||
bookmark = _bookmark;
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
ios_init_freerdp();
|
||||
ios_init_freerdp();
|
||||
}
|
||||
|
||||
static BOOL addArgument(int* argc, char** *argv, const char* fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char* arg = NULL;
|
||||
char** tmp = realloc(*argv, (*argc + 1) * sizeof(char*));
|
||||
|
||||
if (!tmp)
|
||||
return FALSE;
|
||||
|
||||
*argv = tmp;
|
||||
*argc = *argc + 1;
|
||||
va_start(ap, fmt);
|
||||
vasprintf(&arg, fmt, ap);
|
||||
va_end(ap);
|
||||
(*argv)[*argc - 1] = arg;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL addFlag(int* argc, char** *argv, const char* str, BOOL flag)
|
||||
{
|
||||
return addArgument(argc, argv, "%s%s", flag ? "+" : "-", str);
|
||||
}
|
||||
|
||||
static void freeArguments(int argc, char** argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
free(argv[i]);
|
||||
|
||||
free(argv);
|
||||
}
|
||||
|
||||
// Designated initializer.
|
||||
- (id)initWithBookmark:(ComputerBookmark *)bookmark
|
||||
- (id)initWithBookmark:(ComputerBookmark*)bookmark
|
||||
{
|
||||
int status;
|
||||
char** argv = NULL;
|
||||
int argc = 0;
|
||||
|
||||
if (!(self = [super init]))
|
||||
return nil;
|
||||
|
||||
if (!bookmark)
|
||||
[NSException raise:NSInvalidArgumentException format:@"%s: params may not be nil.", __func__];
|
||||
[NSException raise:NSInvalidArgumentException format:
|
||||
@"%s: params may not be nil.", __func__];
|
||||
|
||||
_bookmark = [bookmark retain];
|
||||
_bookmark = [bookmark retain];
|
||||
_params = [[bookmark params] copy];
|
||||
_name = [[bookmark label] retain];
|
||||
_delegate = nil;
|
||||
_toolbar_visible = YES;
|
||||
_name = [[bookmark label] retain];
|
||||
_delegate = nil;
|
||||
_toolbar_visible = YES;
|
||||
_freerdp = ios_freerdp_new();
|
||||
rdpSettings* settings = _freerdp->settings;
|
||||
_ui_request_completed = [[NSCondition alloc] init];
|
||||
_ui_request_completed = [[NSCondition alloc] init];
|
||||
BOOL connected_via_3g = ![bookmark conntectedViaWLAN];
|
||||
|
||||
BOOL connected_via_3g = ![bookmark conntectedViaWLAN];
|
||||
if (!addArgument(&argc, &argv, "iFreeRDP"))
|
||||
goto out_free;
|
||||
|
||||
if (!addArgument(&argc, &argv, "/gdi:sw"))
|
||||
goto out_free;
|
||||
|
||||
// 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 (!addArgument(&argc, &argv,
|
||||
"/bpp:%d", [_params intForKey:@"colors" with3GEnabled:
|
||||
connected_via_3g]))
|
||||
goto out_free;
|
||||
|
||||
if ([_params hasValueForKey:@"port"])
|
||||
settings->ServerPort = [_params intForKey:@"port"];
|
||||
if (!addArgument(&argc, &argv, "/port:%d", [_params intForKey:@"port"]))
|
||||
goto out_free;
|
||||
|
||||
if ([_params boolForKey:@"console"])
|
||||
settings->ConsoleSession = 1;
|
||||
if (!addArgument(&argc, &argv, "/admin"))
|
||||
goto out_free;
|
||||
|
||||
// connection info
|
||||
if (!(settings->ServerHostname = strdup([_params UTF8StringForKey:@"hostname"])))
|
||||
if (!addArgument(&argc, &argv, "/v:%s", [_params UTF8StringForKey:
|
||||
@"hostname"]))
|
||||
goto out_free;
|
||||
|
||||
// String settings
|
||||
if ([[_params StringForKey:@"username"] length])
|
||||
{
|
||||
settings->Username = strdup([_params UTF8StringForKey:@"username"]);
|
||||
if (!settings->Username)
|
||||
if (!addArgument(&argc, &argv, "/u:%s", [_params UTF8StringForKey:
|
||||
@"username"]))
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if ([[_params StringForKey:@"password"] length])
|
||||
{
|
||||
settings->Password = strdup([_params UTF8StringForKey:@"password"]);
|
||||
if (!settings->Password)
|
||||
if (!addArgument(&argc, &argv, "/p:%s", [_params UTF8StringForKey:
|
||||
@"password"]))
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if ([[_params StringForKey:@"domain"] length])
|
||||
{
|
||||
settings->Domain = strdup([_params UTF8StringForKey:@"domain"]);
|
||||
if (!settings->Domain)
|
||||
if (!addArgument(&argc, &argv, "/d:%s", [_params UTF8StringForKey:
|
||||
@"domain"]))
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
settings->ShellWorkingDirectory = strdup([_params UTF8StringForKey:@"working_directory"]);
|
||||
settings->AlternateShell = strdup([_params UTF8StringForKey:@"remote_program"]);
|
||||
if ([[_params StringForKey:@"working_directory"] length])
|
||||
{
|
||||
if (!addArgument(&argc, &argv, "/shell-dir:%s", [_params UTF8StringForKey:
|
||||
@"working_directory"]))
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if (!settings->ShellWorkingDirectory || !settings->AlternateShell)
|
||||
if ([[_params StringForKey:@"remote_program"] length])
|
||||
{
|
||||
if (!addArgument(&argc, &argv, "/shell:%s", [_params UTF8StringForKey:
|
||||
@"remote_program"]))
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
// RemoteFX
|
||||
if ([_params boolForKey:@"perf_remotefx" with3GEnabled:connected_via_3g])
|
||||
if (!addArgument(&argc, &argv, "/rfx"))
|
||||
goto out_free;
|
||||
|
||||
if ([_params boolForKey:@"perf_gfx" with3GEnabled:connected_via_3g])
|
||||
if (!addArgument(&argc, &argv, "/gfx"))
|
||||
goto out_free;
|
||||
|
||||
if ([_params boolForKey:@"perf_h264" with3GEnabled:connected_via_3g])
|
||||
if (!addArgument(&argc, &argv, "/gfx-h264"))
|
||||
goto out_free;
|
||||
|
||||
if (![_params boolForKey:@"perf_remotefx" with3GEnabled:connected_via_3g] &&
|
||||
![_params boolForKey:@"perf_gfx" with3GEnabled:connected_via_3g] &&
|
||||
![_params boolForKey:@"perf_h264" with3GEnabled:connected_via_3g])
|
||||
if (!addArgument(&argc, &argv, "/nsc"))
|
||||
goto out_free;
|
||||
|
||||
if (!addFlag(&argc, &argv, "bitmap-cache", TRUE))
|
||||
goto out_free;
|
||||
|
||||
// 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;
|
||||
settings->FrameAcknowledge = 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
// enable NSCodec if remotefx is not used
|
||||
settings->NSCodec = TRUE;
|
||||
}
|
||||
if (!addFlag(&argc, &argv, "wallpaper", [_params boolForKey:@"perf_show_desktop"
|
||||
with3GEnabled:connected_via_3g]))
|
||||
goto out_free;
|
||||
|
||||
settings->BitmapCacheV3Enabled = TRUE;
|
||||
if (!addFlag(&argc, &argv,
|
||||
"window-drag", [_params boolForKey:@"perf_window_dragging"
|
||||
with3GEnabled:connected_via_3g]))
|
||||
goto out_free;
|
||||
|
||||
// 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];
|
||||
if (!addFlag(&argc, &argv,
|
||||
"menu-anims", [_params boolForKey:@"perf_menu_animation"
|
||||
with3GEnabled:connected_via_3g]))
|
||||
goto out_free;
|
||||
|
||||
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 (!addFlag(&argc, &argv, "themes", [_params boolForKey:@"perf_windows_themes"
|
||||
with3GEnabled:connected_via_3g]))
|
||||
goto out_free;
|
||||
|
||||
if (!addFlag(&argc, &argv, "fonts", [_params boolForKey:@"perf_font_smoothing"
|
||||
with3GEnabled:connected_via_3g]))
|
||||
goto out_free;
|
||||
|
||||
if (!addFlag(&argc, &argv, "aero", [_params boolForKey:
|
||||
@"perf_desktop_composition" with3GEnabled:connected_via_3g]))
|
||||
goto out_free;
|
||||
|
||||
if ([_params hasValueForKey:@"width"])
|
||||
settings->DesktopWidth = [_params intForKey:@"width"];
|
||||
if (!addArgument(&argc, &argv, "/w:%d", [_params intForKey:@"width"]))
|
||||
goto out_free;
|
||||
|
||||
if ([_params hasValueForKey:@"height"])
|
||||
settings->DesktopHeight = [_params intForKey:@"height"];
|
||||
if (!addArgument(&argc, &argv, "/h:%d", [_params intForKey:@"height"]))
|
||||
goto out_free;
|
||||
|
||||
// security
|
||||
switch ([_params intForKey:@"security"])
|
||||
{
|
||||
case TSXProtocolSecurityNLA:
|
||||
settings->RdpSecurity = FALSE;
|
||||
settings->TlsSecurity = FALSE;
|
||||
settings->NlaSecurity = TRUE;
|
||||
settings->ExtSecurity = FALSE;
|
||||
break;
|
||||
// security
|
||||
switch ([_params intForKey:@"security"])
|
||||
{
|
||||
case TSXProtocolSecurityNLA:
|
||||
if (!addArgument(&argc, &argv, "/sec:NLA"))
|
||||
goto out_free;
|
||||
|
||||
case TSXProtocolSecurityTLS:
|
||||
settings->RdpSecurity = FALSE;
|
||||
settings->TlsSecurity = TRUE;
|
||||
settings->NlaSecurity = FALSE;
|
||||
settings->ExtSecurity = FALSE;
|
||||
break;
|
||||
break;
|
||||
|
||||
case TSXProtocolSecurityRDP:
|
||||
settings->RdpSecurity = TRUE;
|
||||
settings->TlsSecurity = FALSE;
|
||||
settings->NlaSecurity = FALSE;
|
||||
settings->ExtSecurity = FALSE;
|
||||
settings->UseRdpSecurityLayer = TRUE;
|
||||
break;
|
||||
case TSXProtocolSecurityTLS:
|
||||
if (!addArgument(&argc, &argv, "/sec:TLS"))
|
||||
goto out_free;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
// ts gateway settings
|
||||
if ([_params boolForKey:@"enable_tsg_settings"])
|
||||
{
|
||||
settings->GatewayHostname = strdup([_params UTF8StringForKey:@"tsg_hostname"]);
|
||||
settings->GatewayPort = [_params intForKey:@"tsg_port"];
|
||||
settings->GatewayUsername = strdup([_params UTF8StringForKey:@"tsg_username"]);
|
||||
settings->GatewayPassword = strdup([_params UTF8StringForKey:@"tsg_password"]);
|
||||
settings->GatewayDomain = strdup([_params UTF8StringForKey:@"tsg_domain"]);
|
||||
settings->GatewayUsageMethod = TSC_PROXY_MODE_DIRECT;
|
||||
settings->GatewayEnabled = TRUE;
|
||||
settings->GatewayUseSameCredentials = FALSE;
|
||||
case TSXProtocolSecurityRDP:
|
||||
if (!addArgument(&argc, &argv, "/sec:RDP"))
|
||||
goto out_free;
|
||||
|
||||
if (!settings->GatewayHostname || !settings->GatewayUsername || !settings->GatewayPassword
|
||||
|| !settings->GatewayDomain)
|
||||
{
|
||||
goto out_free;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// ts gateway settings
|
||||
if ([_params boolForKey:@"enable_tsg_settings"])
|
||||
{
|
||||
if (!addArgument(&argc, &argv,
|
||||
"/g:%s", [_params UTF8StringForKey:@"tsg_hostname"]))
|
||||
goto out_free;
|
||||
|
||||
if (!addArgument(&argc, &argv, "/gp:%d", [_params intForKey:@"tsg_port"]))
|
||||
goto out_free;
|
||||
|
||||
if (!addArgument(&argc, &argv, "/gu:%s", [_params intForKey:@"tsg_username"]))
|
||||
goto out_free;
|
||||
|
||||
if (!addArgument(&argc, &argv, "/gp:%s", [_params intForKey:@"tsg_password"]))
|
||||
goto out_free;
|
||||
|
||||
if (!addArgument(&argc, &argv, "/gd:%s", [_params intForKey:@"tsg_domain"]))
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
// Remote keyboard layout
|
||||
settings->KeyboardLayout = 0x409;
|
||||
if (!addArgument(&argc, &argv, "/kbd:%d", 0x409))
|
||||
goto out_free;
|
||||
|
||||
// Audio settings
|
||||
settings->AudioPlayback = FALSE;
|
||||
settings->AudioCapture = FALSE;
|
||||
status = freerdp_client_settings_parse_command_line(_freerdp->settings, argc,
|
||||
argv,
|
||||
FALSE);
|
||||
|
||||
if (0 != status)
|
||||
goto out_free;
|
||||
|
||||
freeArguments(argc, argv);
|
||||
[self mfi]->session = self;
|
||||
return self;
|
||||
|
||||
out_free:
|
||||
[self release];
|
||||
return nil;
|
||||
freeArguments(argc, argv);
|
||||
[self release];
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[self setDelegate:nil];
|
||||
[_bookmark release];
|
||||
[_name release];
|
||||
[_bookmark release];
|
||||
[_name release];
|
||||
[_params release];
|
||||
[_ui_request_completed release];
|
||||
|
||||
[_ui_request_completed release];
|
||||
ios_freerdp_free(_freerdp);
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (CGContextRef)bitmapContext
|
||||
{
|
||||
return [self mfi]->bitmap_context;
|
||||
return [self mfi]->bitmap_context;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
@ -238,26 +307,28 @@ out_free:
|
||||
- (void)connect
|
||||
{
|
||||
// Set Screen Size to automatic if widht or height are still 0
|
||||
rdpSettings* settings = _freerdp->settings;
|
||||
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];
|
||||
CGSize size = CGSizeZero;
|
||||
|
||||
if (!CGSizeEqualToSize(CGSizeZero, size))
|
||||
{
|
||||
[_params setInt:size.width forKey:@"width"];
|
||||
[_params setInt:size.height forKey:@"height"];
|
||||
settings->DesktopWidth = size.width;
|
||||
settings->DesktopHeight = size.height;
|
||||
}
|
||||
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);
|
||||
// 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];
|
||||
}
|
||||
@ -265,8 +336,8 @@ out_free:
|
||||
- (void)disconnect
|
||||
{
|
||||
mfInfo* mfi = [self mfi];
|
||||
|
||||
ios_events_send(mfi, [NSDictionary dictionaryWithObject:@"disconnect" forKey:@"type"]);
|
||||
ios_events_send(mfi, [NSDictionary dictionaryWithObject:@"disconnect" forKey:
|
||||
@"type"]);
|
||||
|
||||
if (mfi->connection_state == TSXConnectionConnecting)
|
||||
{
|
||||
@ -284,34 +355,34 @@ out_free:
|
||||
// suspends the session
|
||||
-(void)suspend
|
||||
{
|
||||
if(!_suspended)
|
||||
{
|
||||
_suspended = YES;
|
||||
// instance->update->SuppressOutput(instance->context, 0, NULL);
|
||||
}
|
||||
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];
|
||||
}
|
||||
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;
|
||||
return _suspended;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
@ -338,37 +409,34 @@ out_free:
|
||||
|
||||
- (UIImage*)getScreenshotWithSize:(CGSize)size
|
||||
{
|
||||
NSAssert([self mfi]->bitmap_context != nil, @"Screenshot requested while having no valid RDP drawing context");
|
||||
|
||||
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);
|
||||
CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0, size.height);
|
||||
CGContextScaleCTM(UIGraphicsGetCurrentContext(), 1.0, -1.0);
|
||||
CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, size.width, size.height), cgImage);
|
||||
|
||||
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
|
||||
|
||||
CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, size.width,
|
||||
size.height), cgImage);
|
||||
UIImage* viewImage = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
CGImageRelease(cgImage);
|
||||
|
||||
return viewImage;
|
||||
}
|
||||
|
||||
- (rdpSettings*)getSessionParams
|
||||
{
|
||||
return _freerdp->settings;
|
||||
return _freerdp->settings;
|
||||
}
|
||||
|
||||
- (NSString*)sessionName
|
||||
{
|
||||
return _name;
|
||||
return _name;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
@implementation RDPSession (Private)
|
||||
@implementation RDPSession(Private)
|
||||
|
||||
- (mfInfo*)mfi
|
||||
{
|
||||
@ -378,15 +446,15 @@ out_free:
|
||||
// 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];
|
||||
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.
|
||||
@ -399,14 +467,16 @@ out_free:
|
||||
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;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -427,7 +497,8 @@ out_free:
|
||||
|
||||
- (void)sessionDidFailToConnect:(int)reason
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:TSXSessionDidFailToConnectNotification object:self];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:
|
||||
TSXSessionDidFailToConnectNotification object:self];
|
||||
|
||||
if ([[self delegate] respondsToSelector:@selector(session:didFailToConnect:)])
|
||||
[[self delegate] session:self didFailToConnect:reason];
|
||||
@ -435,33 +506,38 @@ out_free:
|
||||
|
||||
- (void)sessionDidDisconnect
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:TSXSessionDidDisconnectNotification object:self];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:
|
||||
TSXSessionDidDisconnectNotification object:self];
|
||||
|
||||
if ([[self delegate] respondsToSelector:@selector(sessionDidDisconnect:)])
|
||||
if ([[self delegate] respondsToSelector:@selector(sessionDidDisconnect:)])
|
||||
[[self delegate] sessionDidDisconnect:self];
|
||||
}
|
||||
|
||||
- (void)sessionBitmapContextWillChange
|
||||
{
|
||||
if ([[self delegate] respondsToSelector:@selector(sessionBitmapContextWillChange:)])
|
||||
if ([[self delegate] respondsToSelector:@selector(
|
||||
sessionBitmapContextWillChange:)])
|
||||
[[self delegate] sessionBitmapContextWillChange:self];
|
||||
}
|
||||
|
||||
- (void)sessionBitmapContextDidChange
|
||||
{
|
||||
if ([[self delegate] respondsToSelector:@selector(sessionBitmapContextDidChange:)])
|
||||
if ([[self delegate] respondsToSelector:@selector(sessionBitmapContextDidChange
|
||||
:)])
|
||||
[[self delegate] sessionBitmapContextDidChange:self];
|
||||
}
|
||||
|
||||
- (void)sessionRequestsAuthenticationWithParams:(NSMutableDictionary*)params
|
||||
{
|
||||
if ([[self delegate] respondsToSelector:@selector(session:requestsAuthenticationWithParams:)])
|
||||
if ([[self delegate] respondsToSelector:@selector(session:
|
||||
requestsAuthenticationWithParams:)])
|
||||
[[self delegate] session:self requestsAuthenticationWithParams:params];
|
||||
}
|
||||
|
||||
- (void)sessionVerifyCertificateWithParams:(NSMutableDictionary*)params
|
||||
{
|
||||
if ([[self delegate] respondsToSelector:@selector(session:verifyCertificateWithParams:)])
|
||||
if ([[self delegate] respondsToSelector:@selector(session:
|
||||
verifyCertificateWithParams:)])
|
||||
[[self delegate] session:self verifyCertificateWithParams:params];
|
||||
}
|
||||
|
||||
|
@ -1,183 +1,36 @@
|
||||
<?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>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="10116" systemVersion="15G31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
|
||||
<dependencies>
|
||||
<deployment version="2352" identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="UIApplication">
|
||||
<connections>
|
||||
<outlet property="delegate" destination="11" id="12"/>
|
||||
</connections>
|
||||
</placeholder>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<customObject id="11" userLabel="AppDelegate" customClass="AppDelegate">
|
||||
<connections>
|
||||
<outlet property="tabBarController" destination="4" id="14"/>
|
||||
<outlet property="window" destination="2" id="13"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<window opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="2">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="480"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
</window>
|
||||
<tabBarController definesPresentationContext="YES" id="4" customClass="MainTabBarController">
|
||||
<extendedEdge key="edgesForExtendedLayout"/>
|
||||
<simulatedTabBarMetrics key="simulatedBottomBarMetrics"/>
|
||||
<tabBar key="tabBar" contentMode="scaleToFill" id="5">
|
||||
<rect key="frame" x="0.0" y="431" width="320" height="49"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
</tabBar>
|
||||
</tabBarController>
|
||||
</objects>
|
||||
</document>
|
||||
|
Loading…
Reference in New Issue
Block a user