Updated iOS client.

This commit is contained in:
Armin Novak 2016-08-05 13:14:55 +02:00 committed by Armin Novak
parent 081b57905f
commit f0864108f9
10 changed files with 1187 additions and 906 deletions

View File

@ -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)

View File

@ -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

View File

@ -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>

View File

@ -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);
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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];
}

View File

@ -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>