11#import "ios_freerdp.h"
12#import "ios_freerdp_ui.h"
13#import "ios_freerdp_events.h"
19#import "ConnectionParams.h"
21NSString *TSXSessionDidDisconnectNotification =
@"TSXSessionDidDisconnect";
22NSString *TSXSessionDidFailToConnectNotification =
@"TSXSessionDidFailToConnect";
24@interface RDPSession (Private)
26- (void)runSessionFinished:(NSNumber *)result;
30- (void)sessionWillConnect;
31- (void)sessionDidConnect;
32- (void)sessionDidDisconnect;
33- (void)sessionDidFailToConnect:(
int)reason;
34- (void)sessionBitmapContextWillChange;
35- (void)sessionBitmapContextDidChange;
40@synthesize delegate = _delegate, params = _params, toolbarVisible = _toolbar_visible,
41 uiRequestCompleted = _ui_request_completed, bookmark = _bookmark;
48static BOOL addArgument(
int *argc,
char ***argv,
const char *fmt, ...)
50 va_list ap = WINPR_C_ARRAY_INIT;
52 char **tmp = realloc(*argv, (*argc + 1) *
sizeof(
char *));
60 const BOOL rc = vasprintf(&arg, fmt, ap) >= 0;
62 (*argv)[*argc - 1] = arg;
66static BOOL addFlag(
int *argc,
char ***argv,
const char *str, BOOL flag)
68 return addArgument(argc, argv,
"%s%s", flag ?
"+" :
"-", str);
71static void freeArguments(
int argc,
char **argv)
73 for (
int i = 0; i < argc; i++)
83 char **argv =
nullptr;
86 if (!(
self = [super init]))
90 [NSException raise:NSInvalidArgumentException
91 format:@"%s: params may not be nil.", __func__];
93 _bookmark = [bookmark retain];
94 _params = [[bookmark params] copy];
95 _name = [[bookmark label] retain];
97 _toolbar_visible = YES;
98 _freerdp = ios_freerdp_new();
99 _ui_request_completed = [[NSCondition alloc] init];
100 BOOL connected_via_3g = ![bookmark conntectedViaWLAN];
102 if (!addArgument(&argc, &argv,
"iFreeRDP"))
105 if (!addArgument(&argc, &argv,
"/gdi:sw"))
108 if (!addArgument(&argc, &argv,
"/relax-order-checks"))
114 if ([_params hasValueForKey:
@"colors"])
115 if (!addArgument(&argc, &argv,
"/bpp:%d",
116 [_params intForKey:
@"colors" with3GEnabled:connected_via_3g]))
119 if ([_params hasValueForKey:
@"port"])
120 if (!addArgument(&argc, &argv,
"/port:%d", [_params intForKey:
@"port"]))
123 if ([_params boolForKey:
@"console"])
124 if (!addArgument(&argc, &argv,
"/admin"))
127 if (!addArgument(&argc, &argv,
"/v:%s", [_params UTF8StringForKey:
@"hostname"]))
131 if ([[_params StringForKey:
@"username"] length])
133 if (!addArgument(&argc, &argv,
"/u:%s", [_params UTF8StringForKey:
@"username"]))
137 if ([[_params StringForKey:
@"password"] length])
139 if (!addArgument(&argc, &argv,
"/p:%s", [_params UTF8StringForKey:
@"password"]))
143 if ([[_params StringForKey:
@"domain"] length])
145 if (!addArgument(&argc, &argv,
"/d:%s", [_params UTF8StringForKey:
@"domain"]))
149 if ([[_params StringForKey:
@"working_directory"] length])
151 if (!addArgument(&argc, &argv,
"/shell-dir:%s",
152 [_params UTF8StringForKey:
@"working_directory"]))
156 if ([[_params StringForKey:
@"remote_program"] length])
158 if (!addArgument(&argc, &argv,
"/shell:%s", [_params UTF8StringForKey:
@"remote_program"]))
163 if ([_params boolForKey:
@"perf_remotefx" with3GEnabled:connected_via_3g])
164 if (!addArgument(&argc, &argv,
"/rfx"))
167 if ([_params boolForKey:
@"perf_gfx" with3GEnabled:connected_via_3g])
168 if (!addArgument(&argc, &argv,
"/gfx"))
171 if ([_params boolForKey:
@"perf_h264" with3GEnabled:connected_via_3g])
172 if (!addArgument(&argc, &argv,
"/gfx:AVC444"))
175 if (![_params boolForKey:
@"perf_remotefx" with3GEnabled:connected_via_3g] &&
176 ![_params boolForKey:
@"perf_gfx" with3GEnabled:connected_via_3g] &&
177 ![_params boolForKey:
@"perf_h264" with3GEnabled:connected_via_3g])
178 if (!addArgument(&argc, &argv,
"/nsc"))
181 if (!addArgument(&argc, &argv,
"/cache:bitmap:on,glyph:on"))
184 if (!addFlag(&argc, &argv,
"wallpaper",
185 [_params boolForKey:
@"perf_show_desktop" with3GEnabled:connected_via_3g]))
188 if (!addFlag(&argc, &argv,
"window-drag",
189 [_params boolForKey:
@"perf_window_dragging" with3GEnabled:connected_via_3g]))
192 if (!addFlag(&argc, &argv,
"menu-anims",
193 [_params boolForKey:
@"perf_menu_animation" with3GEnabled:connected_via_3g]))
196 if (!addFlag(&argc, &argv,
"themes",
197 [_params boolForKey:
@"perf_windows_themes" with3GEnabled:connected_via_3g]))
200 if (!addFlag(&argc, &argv,
"fonts",
201 [_params boolForKey:
@"perf_font_smoothing" with3GEnabled:connected_via_3g]))
204 if (!addFlag(&argc, &argv,
"aero",
205 [_params boolForKey:
@"perf_desktop_composition" with3GEnabled:connected_via_3g]))
208 if ([_params hasValueForKey:
@"width"])
209 if (!addArgument(&argc, &argv,
"/w:%d", [_params intForKey:
@"width"]))
212 if ([_params hasValueForKey:
@"height"])
213 if (!addArgument(&argc, &argv,
"/h:%d", [_params intForKey:
@"height"]))
217 switch ([_params intForKey:
@"security"])
219 case TSXProtocolSecurityNLA:
220 if (!addArgument(&argc, &argv,
"/sec:NLA"))
225 case TSXProtocolSecurityTLS:
226 if (!addArgument(&argc, &argv,
"/sec:TLS"))
231 case TSXProtocolSecurityRDP:
232 if (!addArgument(&argc, &argv,
"/sec:RDP"))
242 if ([_params boolForKey:
@"enable_tsg_settings"])
244 if (!addArgument(&argc, &argv,
"/gateway:g:%s:%d,u:%s,d:%s,p:%s",
245 [_params UTF8StringForKey:
@"tsg_hostname"],
246 [_params intForKey:
@"tsg_port"],
247 [_params UTF8StringForKey:
@"tsg_username"],
248 [_params UTF8StringForKey:
@"tsg_domain"],
249 [_params UTF8StringForKey:
@"tsg_password"]))
254 if (!addArgument(&argc, &argv,
"/kbd:layout:%d", 0x409))
258 if (!addArgument(&argc, &argv,
"/kbd:unicode:on"))
262 freerdp_client_settings_parse_command_line(_freerdp->context->settings, argc, argv, FALSE);
267 freeArguments(argc, argv);
268 [
self mfi]->session =
self;
271 freeArguments(argc, argv);
278 [
self setDelegate:nil];
282 [_ui_request_completed release];
283 ios_freerdp_free(_freerdp);
287- (CGContextRef)bitmapContext
289 return [
self mfi]->bitmap_context;
293#pragma mark Connecting and disconnecting
298 rdpSettings *settings = _freerdp->context->settings;
303 CGSize size = CGSizeZero;
305 if ([[
self delegate] respondsToSelector:@selector(sizeForFitScreenForSession:)])
306 size = [[self delegate] sizeForFitScreenForSession:self];
308 if (!CGSizeEqualToSize(CGSizeZero, size))
310 [_params setInt:size.width forKey:@"width"];
311 [_params setInt:size.height forKey:@"height"];
326 [
self performSelectorInBackground:@selector(runSession) withObject:nil];
331 mfInfo *mfi = [
self mfi];
332 ios_events_send(mfi, [NSDictionary dictionaryWithObject:
@"disconnect" forKey:
@"type"]);
334 if (mfi->connection_state == TSXConnectionConnecting)
337 [
self sessionDidDisconnect];
342- (TSXConnectionState)connectionState
344 return [
self mfi]->connection_state;
381#pragma mark Input events
383- (void)sendInputEvent:(NSDictionary *)eventDescriptor
385 if ([
self mfi]->connection_state == TSXConnectionConnected)
386 ios_events_send([
self mfi], eventDescriptor);
390#pragma mark Server events (main thread)
392- (void)setNeedsDisplayInRectAsValue:(NSValue *)rect_value
394 if ([[
self delegate] respondsToSelector:@selector(session:needsRedrawInRect:)])
395 [[self delegate] session:self needsRedrawInRect:[rect_value CGRectValue]];
398- (void)setRemoteCursor:(
RDPCursor *)cursor
400 if ([[
self delegate] respondsToSelector:@selector(session:didSetRemoteCursor:)])
401 [[self delegate] session:self didSetRemoteCursor:cursor];
404- (void)setRemoteCursorPositionValue:(NSValue *)positionValue
406 if ([[
self delegate] respondsToSelector:@selector(session:didMoveRemoteCursor:)])
407 [[self delegate] session:self didMoveRemoteCursor:[positionValue CGPointValue]];
410- (void)hideRemoteCursor
412 if ([[
self delegate] respondsToSelector:@selector(sessionDidHideRemoteCursor:)])
413 [[self delegate] sessionDidHideRemoteCursor:self];
416- (void)setDefaultRemoteCursor
418 if ([[
self delegate] respondsToSelector:@selector(sessionDidSetDefaultRemoteCursor:)])
419 [[self delegate] sessionDidSetDefaultRemoteCursor:self];
423#pragma mark interface functions
425- (UIImage *)getScreenshotWithSize:(CGSize)size
427 NSAssert([
self mfi]->bitmap_context != nil,
428 @"Screenshot requested while having no valid RDP drawing context");
429 CGImageRef cgImage = CGBitmapContextCreateImage([
self mfi]->bitmap_context);
430 UIGraphicsBeginImageContext(size);
431 CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0, size.height);
432 CGContextScaleCTM(UIGraphicsGetCurrentContext(), 1.0, -1.0);
433 CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, size.width, size.height),
435 UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
436 UIGraphicsEndImageContext();
437 CGImageRelease(cgImage);
441- (rdpSettings *)getSessionParams
443 return _freerdp->context->settings;
446- (NSString *)sessionName
454@implementation RDPSession (Private)
458 return MFI_FROM_INSTANCE(_freerdp);
464 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
466 [
self performSelectorOnMainThread:@selector(sessionWillConnect)
469 int result_code = ios_run_freerdp(_freerdp);
470 [
self mfi]->connection_state = TSXConnectionDisconnected;
471 [
self performSelectorOnMainThread:@selector(runSessionFinished:)
472 withObject:[NSNumber numberWithInt:result_code]
478- (void)runSessionFinished:(NSNumber *)result
480 int result_code = [result intValue];
484 case MF_EXIT_CONN_CANCELED:
485 [
self sessionDidDisconnect];
488 case MF_EXIT_LOGON_TIMEOUT:
489 case MF_EXIT_CONN_FAILED:
490 [
self sessionDidFailToConnect:result_code];
493 case MF_EXIT_SUCCESS:
495 [
self sessionDidDisconnect];
501#pragma mark Session management (main thread)
503- (void)sessionWillConnect
505 if ([[
self delegate] respondsToSelector:@selector(sessionWillConnect:)])
506 [[self delegate] sessionWillConnect:self];
509- (void)sessionDidConnect
511 if ([[
self delegate] respondsToSelector:@selector(sessionDidConnect:)])
512 [[self delegate] sessionDidConnect:self];
515- (void)sessionDidFailToConnect:(
int)reason
517 [[NSNotificationCenter defaultCenter]
518 postNotificationName:TSXSessionDidFailToConnectNotification
521 if ([[
self delegate] respondsToSelector:@selector(session:didFailToConnect:)])
522 [[self delegate] session:self didFailToConnect:reason];
525- (void)sessionDidDisconnect
527 [[NSNotificationCenter defaultCenter] postNotificationName:TSXSessionDidDisconnectNotification
530 if ([[
self delegate] respondsToSelector:@selector(sessionDidDisconnect:)])
531 [[self delegate] sessionDidDisconnect:self];
534- (void)sessionBitmapContextWillChange
536 if ([[
self delegate] respondsToSelector:@selector(sessionBitmapContextWillChange:)])
537 [[self delegate] sessionBitmapContextWillChange:self];
540- (void)sessionBitmapContextDidChange
542 if ([[
self delegate] respondsToSelector:@selector(sessionBitmapContextDidChange:)])
543 [[self delegate] sessionBitmapContextDidChange:self];
546- (void)sessionRequestsAuthenticationWithParams:(NSMutableDictionary *)params
548 if ([[
self delegate] respondsToSelector:@selector(session:requestsAuthenticationWithParams:)])
549 [[self delegate] session:self requestsAuthenticationWithParams:params];
552- (void)sessionVerifyCertificateWithParams:(NSMutableDictionary *)params
554 if ([[
self delegate] respondsToSelector:@selector(session:verifyCertificateWithParams:)])
555 [[self delegate] session:self verifyCertificateWithParams:params];
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_set_uint32(rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id, UINT32 val)
Sets a UINT32 settings value.
WINPR_ATTR_NODISCARD FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.