FreeRDP/client/Mac/cli/AppDelegate.m

316 lines
8.8 KiB
Mathematica
Raw Normal View History

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