11 #include <winpr/assert.h>
12 #import <winpr/clipboard.h>
14 #import <freerdp/gdi/gdi.h>
15 #import <freerdp/channels/channels.h>
16 #import <freerdp/client/channels.h>
17 #import <freerdp/client/cmdline.h>
18 #import <freerdp/freerdp.h>
19 #import <freerdp/gdi/gfx.h>
20 #import <freerdp/client/cliprdr.h>
22 #import "ios_freerdp.h"
23 #import "ios_freerdp_ui.h"
24 #import "ios_freerdp_events.h"
25 #import "ios_cliprdr.h"
27 #import "RDPSession.h"
32 #define TAG FREERDP_TAG("iOS")
34 #pragma mark Connection helpers
36 static void ios_OnChannelConnectedEventHandler(
void *context,
const ChannelConnectedEventArgs *e)
38 WLog_INFO(TAG,
"ios_OnChannelConnectedEventHandler, channel %s", e->name);
39 rdpSettings *settings;
44 WLog_FATAL(TAG,
"(context=%p, EventArgs=%p", context, (
void *)e);
49 settings = afc->_p.settings;
51 if (strcmp(e->name, RDPGFX_DVC_CHANNEL_NAME) == 0)
55 gdi_graphics_pipeline_init(afc->_p.gdi, (RdpgfxClientContext *)e->pInterface);
59 WLog_WARN(TAG,
"GFX without software GDI requested. "
60 " This is not supported, add /gdi:sw");
63 else if (strcmp(e->name, CLIPRDR_SVC_CHANNEL_NAME) == 0)
65 ios_cliprdr_init(afc, (CliprdrClientContext *)e->pInterface);
69 static void ios_OnChannelDisconnectedEventHandler(
void *context,
70 const ChannelDisconnectedEventArgs *e)
72 WLog_INFO(TAG,
"ios_OnChannelConnectedEventHandler, channel %s", e->name);
73 rdpSettings *settings;
78 WLog_FATAL(TAG,
"(context=%p, EventArgs=%p", context, (
void *)e);
83 settings = afc->_p.settings;
85 if (strcmp(e->name, RDPGFX_DVC_CHANNEL_NAME) == 0)
89 gdi_graphics_pipeline_uninit(afc->_p.gdi, (RdpgfxClientContext *)e->pInterface);
93 WLog_WARN(TAG,
"GFX without software GDI requested. "
94 " This is not supported, add /gdi:sw");
97 else if (strcmp(e->name, CLIPRDR_SVC_CHANNEL_NAME) == 0)
99 ios_cliprdr_uninit(afc, (CliprdrClientContext *)e->pInterface);
103 static BOOL ios_pre_connect(freerdp *instance)
106 rdpSettings *settings;
108 if (!instance || !instance->context)
111 settings = instance->context->settings;
112 WINPR_ASSERT(settings);
116 Password && (Password && (strlen(Password) > 0))))
125 NSLog(
@"%s: invalid dimensions %d %d", __func__,
131 rc = PubSub_SubscribeChannelConnected(instance->context->pubSub,
132 ios_OnChannelConnectedEventHandler);
134 if (rc != CHANNEL_RC_OK)
136 WLog_ERR(TAG,
"Could not subscribe to connect event handler [%l08X]", rc);
140 rc = PubSub_SubscribeChannelDisconnected(instance->context->pubSub,
141 ios_OnChannelDisconnectedEventHandler);
143 if (rc != CHANNEL_RC_OK)
145 WLog_ERR(TAG,
"Could not subscribe to disconnect event handler [%l08X]", rc);
149 if (!freerdp_client_load_addins(instance->context->channels, settings))
151 WLog_ERR(TAG,
"Failed to load addins [%l08X]", GetLastError());
158 static BOOL ios_Pointer_New(rdpContext *context, rdpPointer *pointer)
160 if (!context || !pointer || !context->gdi)
166 static void ios_Pointer_Free(rdpContext *context, rdpPointer *pointer)
168 if (!context || !pointer)
172 static BOOL ios_Pointer_Set(rdpContext *context, rdpPointer *pointer)
180 static BOOL ios_Pointer_SetPosition(rdpContext *context, UINT32 x, UINT32 y)
188 static BOOL ios_Pointer_SetNull(rdpContext *context)
196 static BOOL ios_Pointer_SetDefault(rdpContext *context)
204 static BOOL ios_register_pointer(rdpGraphics *graphics)
206 rdpPointer pointer = { 0 };
211 pointer.size =
sizeof(pointer);
212 pointer.New = ios_Pointer_New;
213 pointer.Free = ios_Pointer_Free;
214 pointer.Set = ios_Pointer_Set;
215 pointer.SetNull = ios_Pointer_SetNull;
216 pointer.SetDefault = ios_Pointer_SetDefault;
217 pointer.SetPosition = ios_Pointer_SetPosition;
218 graphics_register_pointer(graphics, &pointer);
222 static BOOL ios_post_connect(freerdp *instance)
229 mfi = MFI_FROM_INSTANCE(instance);
234 if (!gdi_init(instance, PIXEL_FORMAT_BGRA32))
237 if (!ios_register_pointer(instance->context->graphics))
240 ios_allocate_display_buffer(mfi);
241 instance->context->update->BeginPaint = ios_ui_begin_paint;
242 instance->context->update->EndPaint = ios_ui_end_paint;
243 instance->context->update->DesktopResize = ios_ui_resize_window;
244 [mfi->session performSelectorOnMainThread:@selector(sessionDidConnect)
250 static void ios_post_disconnect(freerdp *instance)
256 #pragma mark Running the connection
258 int ios_run_freerdp(freerdp *instance)
261 mfInfo *mfi = context->mfi;
262 rdpChannels *channels = instance->context->channels;
263 mfi->connection_state = TSXConnectionConnecting;
265 if (!freerdp_connect(instance))
267 NSLog(
@"%s: inst->rdp_connect failed", __func__);
268 return mfi->unwanted ? MF_EXIT_CONN_CANCELED : MF_EXIT_CONN_FAILED;
272 return MF_EXIT_CONN_CANCELED;
274 mfi->connection_state = TSXConnectionConnected;
276 NSAutoreleasePool *pool;
278 while (!freerdp_shall_disconnect_context(instance->context))
282 HANDLE handles[MAXIMUM_WAIT_OBJECTS] = { 0 };
283 pool = [[NSAutoreleasePool alloc] init];
285 nCount = freerdp_get_event_handles(instance->context, handles, ARRAYSIZE(handles));
288 NSLog(
@"%s: freerdp_get_event_handles failed", __func__);
292 handles[nCount++] = ios_events_get_handle(mfi);
294 status = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE);
296 if (WAIT_FAILED == status)
298 NSLog(
@"%s: WaitForMultipleObjects failed!", __func__);
303 if (!freerdp_check_event_handles(instance->context))
305 NSLog(
@"%s: freerdp_check_event_handles failed.", __func__);
310 if (ios_events_check_handle(mfi) != TRUE)
321 CGContextRelease(mfi->bitmap_context);
322 mfi->bitmap_context = NULL;
323 mfi->connection_state = TSXConnectionDisconnected;
325 freerdp_disconnect(instance);
327 cache_free(instance->context->cache);
330 return MF_EXIT_SUCCESS;
334 #pragma mark Context callbacks
336 static BOOL ios_client_new(freerdp *instance, rdpContext *context)
340 if (!instance || !context)
343 if ((ctx->mfi = calloc(1,
sizeof(mfInfo))) == NULL)
346 ctx->mfi->context = (
mfContext *)context;
347 ctx->mfi->_context = context;
348 ctx->mfi->instance = instance;
350 if (!ios_events_create_pipe(ctx->mfi))
353 instance->PreConnect = ios_pre_connect;
354 instance->PostConnect = ios_post_connect;
355 instance->PostDisconnect = ios_post_disconnect;
356 instance->Authenticate = ios_ui_authenticate;
357 instance->GatewayAuthenticate = ios_ui_gw_authenticate;
358 instance->VerifyCertificateEx = ios_ui_verify_certificate_ex;
359 instance->VerifyChangedCertificateEx = ios_ui_verify_changed_certificate_ex;
360 instance->LogonErrorInfo = NULL;
364 static void ios_client_free(freerdp *instance, rdpContext *context)
372 ios_events_free_pipe(mfi);
376 static int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS *pEntryPoints)
378 WINPR_ASSERT(pEntryPoints);
380 ZeroMemory(pEntryPoints,
sizeof(RDP_CLIENT_ENTRY_POINTS));
381 pEntryPoints->Version = RDP_CLIENT_INTERFACE_VERSION;
382 pEntryPoints->Size =
sizeof(RDP_CLIENT_ENTRY_POINTS_V1);
383 pEntryPoints->GlobalInit = NULL;
384 pEntryPoints->GlobalUninit = NULL;
385 pEntryPoints->ContextSize =
sizeof(
mfContext);
386 pEntryPoints->ClientNew = ios_client_new;
387 pEntryPoints->ClientFree = ios_client_free;
388 pEntryPoints->ClientStart = NULL;
389 pEntryPoints->ClientStop = NULL;
394 #pragma mark Initialization and cleanup
396 freerdp *ios_freerdp_new()
399 RDP_CLIENT_ENTRY_POINTS clientEntryPoints;
400 RdpClientEntry(&clientEntryPoints);
401 context = freerdp_client_context_new(&clientEntryPoints);
406 return context->instance;
409 void ios_freerdp_free(freerdp *instance)
411 if (!instance || !instance->context)
414 freerdp_client_context_free(instance->context);
417 void ios_init_freerdp()
419 signal(SIGPIPE, SIG_IGN);
422 void ios_uninit_freerdp()
427 size_t fwrite$UNIX2003(
const void *ptr,
size_t size,
size_t nmemb, FILE *stream)
429 return fwrite(ptr, size, nmemb, stream);
432 void ios_send_clipboard_data(
void *context,
const void *data, UINT32 size)
435 ClipboardLock(afc->clipboard);
436 UINT32 formatId = ClipboardRegisterFormat(afc->clipboard,
"UTF8_STRING");
438 ClipboardSetData(afc->clipboard, formatId, data, size);
440 ClipboardEmpty(afc->clipboard);
441 ClipboardUnlock(afc->clipboard);
442 ios_cliprdr_send_client_format_list(afc->cliprdr);
FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.
FREERDP_API const char * freerdp_settings_get_string(const rdpSettings *settings, FreeRDP_Settings_Keys_String id)
Returns a immutable string settings value.
FREERDP_API BOOL freerdp_settings_set_bool(rdpSettings *settings, FreeRDP_Settings_Keys_Bool id, BOOL param)
Sets a BOOL settings value.