Blame client/Mac/cli/AppDelegate.m

Packit 1fb8d4
//
Packit 1fb8d4
//  AppDelegate.m
Packit 1fb8d4
//  MacClient2
Packit 1fb8d4
//
Packit 1fb8d4
//  Created by BenoƮt et Kathy on 2013-05-08.
Packit 1fb8d4
//
Packit 1fb8d4
//
Packit 1fb8d4
Packit 1fb8d4
#import "AppDelegate.h"
Packit 1fb8d4
#import "MacFreeRDP/mfreerdp.h"
Packit 1fb8d4
#import "MacFreeRDP/mf_client.h"
Packit 1fb8d4
#import "MacFreeRDP/MRDPView.h"
Packit 1fb8d4
#import <freerdp/client/cmdline.h>
Packit 1fb8d4
Packit Service 5a9772
static AppDelegate *_singleDelegate = nil;
Packit Service 5a9772
void AppDelegate_ConnectionResultEventHandler(void *context, ConnectionResultEventArgs *e);
Packit Service 5a9772
void AppDelegate_ErrorInfoEventHandler(void *ctx, ErrorInfoEventArgs *e);
Packit Service 5a9772
void AppDelegate_EmbedWindowEventHandler(void *context, EmbedWindowEventArgs *e);
Packit Service 5a9772
void AppDelegate_ResizeWindowEventHandler(void *context, ResizeWindowEventArgs *e);
Packit Service 5a9772
void mac_set_view_size(rdpContext *context, MRDPView *view);
Packit 1fb8d4
Packit 1fb8d4
@implementation AppDelegate
Packit 1fb8d4
Packit 1fb8d4
- (void)dealloc
Packit 1fb8d4
{
Packit 1fb8d4
	[super dealloc];
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
@synthesize window = window;
Packit 1fb8d4
Packit 1fb8d4
@synthesize context = context;
Packit 1fb8d4
Packit Service 5a9772
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
Packit 1fb8d4
{
Packit 1fb8d4
	int status;
Packit Service 5a9772
	mfContext *mfc;
Packit 1fb8d4
	_singleDelegate = self;
Packit 1fb8d4
	[self CreateContext];
Packit 1fb8d4
	status = [self ParseCommandLineArguments];
Packit Service 5a9772
	mfc = (mfContext *)context;
Packit Service 5a9772
	mfc->view = (void *)mrdpView;
Packit 1fb8d4
Packit Service 5a9772
	if (status == 0)
Packit 1fb8d4
	{
Packit Service 5a9772
		NSScreen *screen = [[NSScreen screens] objectAtIndex:0];
Packit 1fb8d4
		NSRect screenFrame = [screen frame];
Packit 1fb8d4
Packit 1fb8d4
		if (context->instance->settings->Fullscreen)
Packit 1fb8d4
		{
Packit Service 5a9772
			context->instance->settings->DesktopWidth = screenFrame.size.width;
Packit 1fb8d4
			context->instance->settings->DesktopHeight = screenFrame.size.height;
Packit 1fb8d4
		}
Packit 1fb8d4
Packit Service 5a9772
		PubSub_SubscribeConnectionResult(context->pubSub, AppDelegate_ConnectionResultEventHandler);
Packit 1fb8d4
		PubSub_SubscribeErrorInfo(context->pubSub, AppDelegate_ErrorInfoEventHandler);
Packit Service 5a9772
		PubSub_SubscribeEmbedWindow(context->pubSub, AppDelegate_EmbedWindowEventHandler);
Packit Service 5a9772
		PubSub_SubscribeResizeWindow(context->pubSub, AppDelegate_ResizeWindowEventHandler);
Packit 1fb8d4
		freerdp_client_start(context);
Packit Service 5a9772
		NSString *winTitle;
Packit 1fb8d4
Packit 1fb8d4
		if (mfc->context.settings->WindowTitle && mfc->context.settings->WindowTitle[0])
Packit 1fb8d4
		{
Packit Service 5a9772
			winTitle = [[NSString alloc] initWithCString:mfc->context.settings->WindowTitle];
Packit 1fb8d4
		}
Packit 1fb8d4
		else
Packit 1fb8d4
		{
Packit Service 5a9772
			winTitle = [[NSString alloc]
Packit Service 5a9772
			    initWithFormat:@"%@:%u",
Packit Service 5a9772
			                   [NSString stringWithCString:mfc->context.settings->ServerHostname
Packit Service 5a9772
			                                      encoding:NSUTF8StringEncoding],
Packit Service 5a9772
			                   mfc -> context.settings->ServerPort];
Packit 1fb8d4
		}
Packit 1fb8d4
Packit 1fb8d4
		[window setTitle:winTitle];
Packit 1fb8d4
	}
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
- (void)applicationWillBecomeActive:(NSNotification *)notification
Packit Service 5a9772
{
Packit Service 5a9772
	[mrdpView resume];
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
- (void)applicationWillResignActive:(NSNotification *)notification
Packit Service 5a9772
{
Packit Service 5a9772
	[mrdpView pause];
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
- (void)applicationWillTerminate:(NSNotification *)notification
Packit 1fb8d4
{
Packit 1fb8d4
	NSLog(@"Stopping...\n");
Packit 1fb8d4
	freerdp_client_stop(context);
Packit 1fb8d4
	[mrdpView releaseResources];
Packit 1fb8d4
	_singleDelegate = nil;
Packit 1fb8d4
	NSLog(@"Stopped.\n");
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
Packit 1fb8d4
{
Packit 1fb8d4
	return YES;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
- (int)ParseCommandLineArguments
Packit 1fb8d4
{
Packit 1fb8d4
	int i;
Packit 1fb8d4
	int length;
Packit 1fb8d4
	int status;
Packit Service 5a9772
	char *cptr;
Packit Service 5a9772
	NSArray *args = [[NSProcessInfo processInfo] arguments];
Packit Service 5a9772
	context->argc = (int)[args count];
Packit Service 5a9772
	context->argv = malloc(sizeof(char *) * context->argc);
Packit 1fb8d4
	i = 0;
Packit 1fb8d4
Packit Service 5a9772
	for (NSString *str in args)
Packit 1fb8d4
	{
Packit 1fb8d4
		/* filter out some arguments added by XCode */
Packit 1fb8d4
		if ([str isEqualToString:@"YES"])
Packit 1fb8d4
			continue;
Packit 1fb8d4
Packit 1fb8d4
		if ([str isEqualToString:@"-NSDocumentRevisionsDebugMode"])
Packit 1fb8d4
			continue;
Packit 1fb8d4
Packit 1fb8d4
		length = (int)([str length] + 1);
Packit Service 5a9772
		cptr = (char *)malloc(length);
Packit 1fb8d4
		sprintf_s(cptr, length, "%s", [str UTF8String]);
Packit 1fb8d4
		context->argv[i++] = cptr;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	context->argc = i;
Packit Service 5a9772
	status = freerdp_client_settings_parse_command_line(context->settings, context->argc,
Packit Service 5a9772
	                                                    context->argv, FALSE);
Packit Service 5a9772
	status = freerdp_client_settings_command_line_status_print(context->settings, status,
Packit Service 5a9772
	                                                           context->argc, context->argv);
Packit 1fb8d4
	return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
- (void)CreateContext
Packit 1fb8d4
{
Packit 1fb8d4
	RDP_CLIENT_ENTRY_POINTS clientEntryPoints;
Packit 1fb8d4
	ZeroMemory(&clientEntryPoints, sizeof(RDP_CLIENT_ENTRY_POINTS));
Packit 1fb8d4
	clientEntryPoints.Size = sizeof(RDP_CLIENT_ENTRY_POINTS);
Packit 1fb8d4
	clientEntryPoints.Version = RDP_CLIENT_INTERFACE_VERSION;
Packit 1fb8d4
	RdpClientEntry(&clientEntryPoints);
Packit 1fb8d4
	context = freerdp_client_context_new(&clientEntryPoints);
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
- (void)ReleaseContext
Packit 1fb8d4
{
Packit Service 5a9772
	mfContext *mfc;
Packit Service 5a9772
	MRDPView *view;
Packit Service 5a9772
	mfc = (mfContext *)context;
Packit Service 5a9772
	view = (MRDPView *)mfc->view;
Packit 1fb8d4
	[view exitFullScreenModeWithOptions:nil];
Packit 1fb8d4
	[view releaseResources];
Packit 1fb8d4
	[view release];
Packit 1fb8d4
	mfc->view = nil;
Packit 1fb8d4
	freerdp_client_context_free(context);
Packit 1fb8d4
	context = nil;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/** *********************************************************************
Packit 1fb8d4
 * called when we fail to connect to a RDP server - Make sure this is called from the main thread.
Packit 1fb8d4
 ***********************************************************************/
Packit 1fb8d4
Packit Service 5a9772
- (void)rdpConnectError:(NSString *)withMessage
Packit 1fb8d4
{
Packit Service 5a9772
	mfContext *mfc;
Packit Service 5a9772
	MRDPView *view;
Packit Service 5a9772
	mfc = (mfContext *)context;
Packit Service 5a9772
	view = (MRDPView *)mfc->view;
Packit 1fb8d4
	[view exitFullScreenModeWithOptions:nil];
Packit Service 5a9772
	NSString *message = withMessage ? withMessage : @"Error connecting to server";
Packit Service 5a9772
	NSAlert *alert = [[NSAlert alloc] init];
Packit 1fb8d4
	[alert setMessageText:message];
Packit 1fb8d4
	[alert beginSheetModalForWindow:[self window]
Packit Service 5a9772
	                  modalDelegate:self
Packit Service 5a9772
	                 didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:)
Packit Service 5a9772
	                    contextInfo:nil];
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/** *********************************************************************
Packit 1fb8d4
 * just a terminate selector for above call
Packit 1fb8d4
 ***********************************************************************/
Packit 1fb8d4
Packit Service 5a9772
- (void)alertDidEnd:(NSAlert *)a returnCode:(NSInteger)rc contextInfo:(void *)ci
Packit 1fb8d4
{
Packit 1fb8d4
	[NSApp terminate:nil];
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
@end
Packit 1fb8d4
Packit 1fb8d4
/** *********************************************************************
Packit 1fb8d4
 * On connection error, display message and quit application
Packit 1fb8d4
 ***********************************************************************/
Packit 1fb8d4
Packit Service 5a9772
void AppDelegate_ConnectionResultEventHandler(void *ctx, ConnectionResultEventArgs *e)
Packit 1fb8d4
{
Packit 1fb8d4
	NSLog(@"ConnectionResult event result:%d\n", e->result);
Packit 1fb8d4
Packit 1fb8d4
	if (_singleDelegate)
Packit 1fb8d4
	{
Packit 1fb8d4
		if (e->result != 0)
Packit 1fb8d4
		{
Packit Service 5a9772
			NSString *message = nil;
Packit 1fb8d4
Packit 1fb8d4
			if (connectErrorCode == AUTHENTICATIONERROR)
Packit 1fb8d4
			{
Packit Service 5a9772
				message = [NSString
Packit Service 5a9772
				    stringWithFormat:@"%@", @"Authentication failure, check credentials."];
Packit 1fb8d4
			}
Packit 1fb8d4
Packit 1fb8d4
			// Making sure this should be invoked on the main UI thread.
Packit 1fb8d4
			[_singleDelegate performSelectorOnMainThread:@selector(rdpConnectError:)
Packit Service 5a9772
			                                  withObject:message
Packit Service 5a9772
			                               waitUntilDone:FALSE];
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
void AppDelegate_ErrorInfoEventHandler(void *ctx, ErrorInfoEventArgs *e)
Packit 1fb8d4
{
Packit 1fb8d4
	NSLog(@"ErrorInfo event code:%d\n", e->code);
Packit 1fb8d4
Packit 1fb8d4
	if (_singleDelegate)
Packit 1fb8d4
	{
Packit 1fb8d4
		// Retrieve error message associated with error code
Packit Service 5a9772
		NSString *message = nil;
Packit 1fb8d4
Packit 1fb8d4
		if (e->code != ERRINFO_NONE)
Packit 1fb8d4
		{
Packit Service 5a9772
			const char *errorMessage = freerdp_get_error_info_string(e->code);
Packit 1fb8d4
			message = [[NSString alloc] initWithUTF8String:errorMessage];
Packit 1fb8d4
		}
Packit 1fb8d4
Packit 1fb8d4
		// Making sure this should be invoked on the main UI thread.
Packit 1fb8d4
		[_singleDelegate performSelectorOnMainThread:@selector(rdpConnectError:)
Packit Service 5a9772
		                                  withObject:message
Packit Service 5a9772
		                               waitUntilDone:TRUE];
Packit 1fb8d4
		[message release];
Packit 1fb8d4
	}
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
void AppDelegate_EmbedWindowEventHandler(void *ctx, EmbedWindowEventArgs *e)
Packit 1fb8d4
{
Packit Service 5a9772
	rdpContext *context = (rdpContext *)ctx;
Packit 1fb8d4
Packit 1fb8d4
	if (_singleDelegate)
Packit 1fb8d4
	{
Packit Service 5a9772
		mfContext *mfc = (mfContext *)context;
Packit 1fb8d4
		_singleDelegate->mrdpView = mfc->view;
Packit 1fb8d4
Packit 1fb8d4
		if (_singleDelegate->window)
Packit 1fb8d4
		{
Packit 1fb8d4
			[[_singleDelegate->window contentView] addSubview:mfc->view];
Packit 1fb8d4
		}
Packit 1fb8d4
Packit Service 5a9772
		dispatch_async(dispatch_get_main_queue(), ^{
Packit Service 5a9772
			mac_set_view_size(context, mfc->view);
Packit Service 5a9772
		});
Packit 1fb8d4
	}
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
void AppDelegate_ResizeWindowEventHandler(void *ctx, ResizeWindowEventArgs *e)
Packit 1fb8d4
{
Packit Service 5a9772
	rdpContext *context = (rdpContext *)ctx;
Packit 1fb8d4
	fprintf(stderr, "ResizeWindowEventHandler: %d %d\n", e->width, e->height);
Packit 1fb8d4
Packit 1fb8d4
	if (_singleDelegate)
Packit 1fb8d4
	{
Packit Service 5a9772
		mfContext *mfc = (mfContext *)context;
Packit Service 5a9772
		dispatch_async(dispatch_get_main_queue(), ^{
Packit Service 5a9772
			mac_set_view_size(context, mfc->view);
Packit Service 5a9772
		});
Packit 1fb8d4
	}
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
void mac_set_view_size(rdpContext *context, MRDPView *view)
Packit 1fb8d4
{
Packit 1fb8d4
	// set client area to specified dimensions
Packit 1fb8d4
	NSRect innerRect;
Packit 1fb8d4
	innerRect.origin.x = 0;
Packit 1fb8d4
	innerRect.origin.y = 0;
Packit 1fb8d4
	innerRect.size.width = context->settings->DesktopWidth;
Packit 1fb8d4
	innerRect.size.height = context->settings->DesktopHeight;
Packit 1fb8d4
	[view setFrame:innerRect];
Packit 1fb8d4
	// calculate window of same size, but keep position
Packit 1fb8d4
	NSRect outerRect = [[view window] frame];
Packit 1fb8d4
	outerRect.size = [[view window] frameRectForContentRect:innerRect].size;
Packit 1fb8d4
	// we are not in RemoteApp mode, disable larger than resolution
Packit 1fb8d4
	[[view window] setContentMaxSize:innerRect.size];
Packit 1fb8d4
	// set window to given area
Packit 1fb8d4
	[[view window] setFrame:outerRect display:YES];
Packit 1fb8d4
	// set window to front
Packit 1fb8d4
	[NSApp activateIgnoringOtherApps:YES];
Packit 1fb8d4
Packit 1fb8d4
	if (context->settings->Fullscreen)
Packit 1fb8d4
		[[view window] toggleFullScreen:nil];
Packit 1fb8d4
}