|
Packit |
1fb8d4 |
/*
|
|
Packit |
1fb8d4 |
RDP run-loop
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
Copyright 2013 Thincast Technologies GmbH, Authors: Martin Fleisz, Dorian Johnson
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
|
Packit |
1fb8d4 |
If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
Packit |
1fb8d4 |
*/
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#import <freerdp/gdi/gdi.h>
|
|
Packit |
1fb8d4 |
#import <freerdp/channels/channels.h>
|
|
Packit |
1fb8d4 |
#import <freerdp/client/channels.h>
|
|
Packit |
1fb8d4 |
#import <freerdp/client/cmdline.h>
|
|
Packit |
1fb8d4 |
#import <freerdp/freerdp.h>
|
|
Packit |
1fb8d4 |
#import <freerdp/gdi/gfx.h>
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#import "ios_freerdp.h"
|
|
Packit |
1fb8d4 |
#import "ios_freerdp_ui.h"
|
|
Packit |
1fb8d4 |
#import "ios_freerdp_events.h"
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#import "RDPSession.h"
|
|
Packit |
1fb8d4 |
#import "Utils.h"
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#include <errno.h>
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#define TAG FREERDP_TAG("iOS")
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#pragma mark Connection helpers
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static void ios_OnChannelConnectedEventHandler(
|
|
Packit |
1fb8d4 |
void* context,
|
|
Packit |
1fb8d4 |
ChannelConnectedEventArgs* e)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
rdpSettings* settings;
|
|
Packit |
1fb8d4 |
mfContext* afc;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!context || !e)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_FATAL(TAG, "%s(context=%p, EventArgs=%p",
|
|
Packit |
1fb8d4 |
__FUNCTION__, context, (void*) e);
|
|
Packit |
1fb8d4 |
return;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
afc = (mfContext*) context;
|
|
Packit |
1fb8d4 |
settings = afc->_p.settings;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (strcmp(e->name, RDPGFX_DVC_CHANNEL_NAME) == 0)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (settings->SoftwareGdi)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
gdi_graphics_pipeline_init(afc->_p.gdi,
|
|
Packit |
1fb8d4 |
(RdpgfxClientContext*) e->pInterface);
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
else
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_WARN(TAG, "GFX without software GDI requested. "
|
|
Packit |
1fb8d4 |
" This is not supported, add /gdi:sw");
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static void ios_OnChannelDisconnectedEventHandler(
|
|
Packit |
1fb8d4 |
void* context, ChannelDisconnectedEventArgs* e)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
rdpSettings* settings;
|
|
Packit |
1fb8d4 |
mfContext* afc;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!context || !e)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_FATAL(TAG, "%s(context=%p, EventArgs=%p",
|
|
Packit |
1fb8d4 |
__FUNCTION__, context, (void*) e);
|
|
Packit |
1fb8d4 |
return;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
afc = (mfContext*) context;
|
|
Packit |
1fb8d4 |
settings = afc->_p.settings;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (strcmp(e->name, RDPGFX_DVC_CHANNEL_NAME) == 0)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (settings->SoftwareGdi)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
gdi_graphics_pipeline_uninit(afc->_p.gdi,
|
|
Packit |
1fb8d4 |
(RdpgfxClientContext*) e->pInterface);
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
else
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_WARN(TAG, "GFX without software GDI requested. "
|
|
Packit |
1fb8d4 |
" This is not supported, add /gdi:sw");
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static BOOL ios_pre_connect(freerdp* instance)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
int rc;
|
|
Packit |
1fb8d4 |
rdpSettings* settings;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!instance || !instance->settings)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
settings = instance->settings;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!settings->OrderSupport)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
settings->AutoLogonEnabled = settings->Password
|
|
Packit |
1fb8d4 |
&& (strlen(settings->Password) > 0);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
// Verify screen width/height are sane
|
|
Packit |
1fb8d4 |
if ((settings->DesktopWidth < 64) || (settings->DesktopHeight < 64)
|
|
Packit |
1fb8d4 |
|| (settings->DesktopWidth > 4096) || (settings->DesktopHeight > 4096))
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
NSLog(@"%s: invalid dimensions %d %d", __func__, settings->DesktopWidth,
|
|
Packit |
1fb8d4 |
settings->DesktopHeight);
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
BOOL bitmap_cache = settings->BitmapCacheEnabled;
|
|
Packit |
1fb8d4 |
settings->OrderSupport[NEG_DSTBLT_INDEX] = TRUE;
|
|
Packit |
1fb8d4 |
settings->OrderSupport[NEG_PATBLT_INDEX] = TRUE;
|
|
Packit |
1fb8d4 |
settings->OrderSupport[NEG_SCRBLT_INDEX] = TRUE;
|
|
Packit |
1fb8d4 |
settings->OrderSupport[NEG_OPAQUE_RECT_INDEX] = TRUE;
|
|
Packit |
1fb8d4 |
settings->OrderSupport[NEG_DRAWNINEGRID_INDEX] = FALSE;
|
|
Packit |
1fb8d4 |
settings->OrderSupport[NEG_MULTIDSTBLT_INDEX] = FALSE;
|
|
Packit |
1fb8d4 |
settings->OrderSupport[NEG_MULTIPATBLT_INDEX] = FALSE;
|
|
Packit |
1fb8d4 |
settings->OrderSupport[NEG_MULTISCRBLT_INDEX] = FALSE;
|
|
Packit |
1fb8d4 |
settings->OrderSupport[NEG_MULTIOPAQUERECT_INDEX] = TRUE;
|
|
Packit |
1fb8d4 |
settings->OrderSupport[NEG_MULTI_DRAWNINEGRID_INDEX] = FALSE;
|
|
Packit |
1fb8d4 |
settings->OrderSupport[NEG_LINETO_INDEX] = TRUE;
|
|
Packit |
1fb8d4 |
settings->OrderSupport[NEG_POLYLINE_INDEX] = TRUE;
|
|
Packit |
1fb8d4 |
settings->OrderSupport[NEG_MEMBLT_INDEX] = bitmap_cache;
|
|
Packit |
1fb8d4 |
settings->OrderSupport[NEG_MEM3BLT_INDEX] = TRUE;
|
|
Packit |
1fb8d4 |
settings->OrderSupport[NEG_MEMBLT_V2_INDEX] = bitmap_cache;
|
|
Packit |
1fb8d4 |
settings->OrderSupport[NEG_MEM3BLT_V2_INDEX] = FALSE;
|
|
Packit |
1fb8d4 |
settings->OrderSupport[NEG_SAVEBITMAP_INDEX] = FALSE;
|
|
Packit |
1fb8d4 |
settings->OrderSupport[NEG_GLYPH_INDEX_INDEX] = TRUE;
|
|
Packit |
1fb8d4 |
settings->OrderSupport[NEG_FAST_INDEX_INDEX] = TRUE;
|
|
Packit |
1fb8d4 |
settings->OrderSupport[NEG_FAST_GLYPH_INDEX] = TRUE;
|
|
Packit |
1fb8d4 |
settings->OrderSupport[NEG_POLYGON_SC_INDEX] = FALSE;
|
|
Packit |
1fb8d4 |
settings->OrderSupport[NEG_POLYGON_CB_INDEX] = FALSE;
|
|
Packit |
1fb8d4 |
settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = FALSE;
|
|
Packit |
1fb8d4 |
settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE;
|
|
Packit |
1fb8d4 |
rc = PubSub_SubscribeChannelConnected(
|
|
Packit |
1fb8d4 |
instance->context->pubSub,
|
|
Packit |
1fb8d4 |
ios_OnChannelConnectedEventHandler);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (rc != CHANNEL_RC_OK)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_ERR(TAG, "Could not subscribe to connect event handler [%l08X]", rc);
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
rc = PubSub_SubscribeChannelDisconnected(
|
|
Packit |
1fb8d4 |
instance->context->pubSub,
|
|
Packit |
1fb8d4 |
ios_OnChannelDisconnectedEventHandler);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (rc != CHANNEL_RC_OK)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_ERR(TAG, "Could not subscribe to disconnect event handler [%l08X]", rc);
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!freerdp_client_load_addins(instance->context->channels,
|
|
Packit |
1fb8d4 |
instance->settings))
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_ERR(TAG, "Failed to load addins [%l08X]", GetLastError());
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static BOOL ios_Pointer_New(rdpContext* context, rdpPointer* pointer)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (!context || !pointer || !context->gdi)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static void ios_Pointer_Free(rdpContext* context, rdpPointer* pointer)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (!context || !pointer)
|
|
Packit |
1fb8d4 |
return;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static BOOL ios_Pointer_Set(rdpContext* context,
|
|
Packit |
1fb8d4 |
const rdpPointer* pointer)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (!context)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static BOOL ios_Pointer_SetPosition(rdpContext* context,
|
|
Packit |
1fb8d4 |
UINT32 x, UINT32 y)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (!context)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static BOOL ios_Pointer_SetNull(rdpContext* context)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (!context)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static BOOL ios_Pointer_SetDefault(rdpContext* context)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (!context)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static BOOL ios_register_pointer(rdpGraphics* graphics)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
rdpPointer pointer;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!graphics)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
pointer.size = sizeof(pointer);
|
|
Packit |
1fb8d4 |
pointer.New = ios_Pointer_New;
|
|
Packit |
1fb8d4 |
pointer.Free = ios_Pointer_Free;
|
|
Packit |
1fb8d4 |
pointer.Set = ios_Pointer_Set;
|
|
Packit |
1fb8d4 |
pointer.SetNull = ios_Pointer_SetNull;
|
|
Packit |
1fb8d4 |
pointer.SetDefault = ios_Pointer_SetDefault;
|
|
Packit |
1fb8d4 |
pointer.SetPosition = ios_Pointer_SetPosition;
|
|
Packit |
1fb8d4 |
graphics_register_pointer(graphics, &pointer);
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static BOOL ios_post_connect(freerdp* instance)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
mfInfo* mfi;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!instance)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
mfi = MFI_FROM_INSTANCE(instance);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!mfi)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!gdi_init(instance, PIXEL_FORMAT_BGRA32))
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!ios_register_pointer(instance->context->graphics))
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
ios_allocate_display_buffer(mfi);
|
|
Packit |
1fb8d4 |
instance->update->BeginPaint = ios_ui_begin_paint;
|
|
Packit |
1fb8d4 |
instance->update->EndPaint = ios_ui_end_paint;
|
|
Packit |
1fb8d4 |
instance->update->DesktopResize = ios_ui_resize_window;
|
|
Packit |
1fb8d4 |
[mfi->session performSelectorOnMainThread:@selector(sessionDidConnect)
|
|
Packit |
1fb8d4 |
withObject:nil waitUntilDone:YES];
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static void ios_post_disconnect(freerdp* instance)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
gdi_free(instance);
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#pragma mark -
|
|
Packit |
1fb8d4 |
#pragma mark Running the connection
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
int ios_run_freerdp(freerdp* instance)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
mfContext* context = (mfContext*)instance->context;
|
|
Packit |
1fb8d4 |
mfInfo* mfi = context->mfi;
|
|
Packit |
1fb8d4 |
rdpChannels* channels = instance->context->channels;
|
|
Packit |
1fb8d4 |
mfi->connection_state = TSXConnectionConnecting;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!freerdp_connect(instance))
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
NSLog(@"%s: inst->rdp_connect failed", __func__);
|
|
Packit |
1fb8d4 |
return mfi->unwanted ? MF_EXIT_CONN_CANCELED : MF_EXIT_CONN_FAILED;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (mfi->unwanted)
|
|
Packit |
1fb8d4 |
return MF_EXIT_CONN_CANCELED;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
mfi->connection_state = TSXConnectionConnected;
|
|
Packit |
1fb8d4 |
// Connection main loop
|
|
Packit |
1fb8d4 |
NSAutoreleasePool* pool;
|
|
Packit |
1fb8d4 |
int i;
|
|
Packit |
1fb8d4 |
int fds;
|
|
Packit |
1fb8d4 |
int max_fds;
|
|
Packit |
1fb8d4 |
int rcount;
|
|
Packit |
1fb8d4 |
int wcount;
|
|
Packit |
1fb8d4 |
void* rfds[32];
|
|
Packit |
1fb8d4 |
void* wfds[32];
|
|
Packit |
1fb8d4 |
fd_set rfds_set;
|
|
Packit |
1fb8d4 |
fd_set wfds_set;
|
|
Packit |
1fb8d4 |
struct timeval timeout;
|
|
Packit |
1fb8d4 |
int select_status;
|
|
Packit |
1fb8d4 |
memset(rfds, 0, sizeof(rfds));
|
|
Packit |
1fb8d4 |
memset(wfds, 0, sizeof(wfds));
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
while (!freerdp_shall_disconnect(instance))
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
rcount = wcount = 0;
|
|
Packit |
1fb8d4 |
pool = [[NSAutoreleasePool alloc] init];
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
NSLog(@"%s: inst->rdp_get_fds failed", __func__);
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds,
|
|
Packit |
1fb8d4 |
&wcount) != TRUE)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
NSLog(@"%s: freerdp_chanman_get_fds failed", __func__);
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (ios_events_get_fds(mfi, rfds, &rcount, wfds, &wcount) != TRUE)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
NSLog(@"%s: ios_events_get_fds", __func__);
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
max_fds = 0;
|
|
Packit |
1fb8d4 |
FD_ZERO(&rfds_set);
|
|
Packit |
1fb8d4 |
FD_ZERO(&wfds_set);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (i = 0; i < rcount; i++)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
fds = (int)(long)(rfds[i]);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (fds > max_fds)
|
|
Packit |
1fb8d4 |
max_fds = fds;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
FD_SET(fds, &rfds_set);
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (max_fds == 0)
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
timeout.tv_sec = 1;
|
|
Packit |
1fb8d4 |
timeout.tv_usec = 0;
|
|
Packit |
1fb8d4 |
select_status = select(max_fds + 1, &rfds_set, NULL, NULL, &timeout);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
// timeout?
|
|
Packit |
1fb8d4 |
if (select_status == 0)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
continue;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
else if (select_status == -1)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
/* these are not really errors */
|
|
Packit |
1fb8d4 |
if (!((errno == EAGAIN) ||
|
|
Packit |
1fb8d4 |
(errno == EWOULDBLOCK) ||
|
|
Packit |
1fb8d4 |
(errno == EINPROGRESS) ||
|
|
Packit |
1fb8d4 |
(errno == EINTR))) /* signal occurred */
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
NSLog(@"%s: select failed!", __func__);
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
// Check the libfreerdp fds
|
|
Packit |
1fb8d4 |
if (freerdp_check_fds(instance) != true)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
NSLog(@"%s: inst->rdp_check_fds failed.", __func__);
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
// Check input event fds
|
|
Packit |
1fb8d4 |
if (ios_events_check_fds(mfi, &rfds_set) != TRUE)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
// This event will fail when the app asks for a disconnect.
|
|
Packit |
1fb8d4 |
//NSLog(@"%s: ios_events_check_fds failed: terminating connection.", __func__);
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
// Check channel fds
|
|
Packit |
1fb8d4 |
if (freerdp_channels_check_fds(channels, instance) != TRUE)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
NSLog(@"%s: freerdp_chanman_check_fds failed", __func__);
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
[pool release];
|
|
Packit |
1fb8d4 |
pool = nil;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
CGContextRelease(mfi->bitmap_context);
|
|
Packit |
1fb8d4 |
mfi->bitmap_context = NULL;
|
|
Packit |
1fb8d4 |
mfi->connection_state = TSXConnectionDisconnected;
|
|
Packit |
1fb8d4 |
// Cleanup
|
|
Packit |
1fb8d4 |
freerdp_disconnect(instance);
|
|
Packit |
1fb8d4 |
gdi_free(instance);
|
|
Packit |
1fb8d4 |
cache_free(instance->context->cache);
|
|
Packit |
1fb8d4 |
[pool release];
|
|
Packit |
1fb8d4 |
pool = nil;
|
|
Packit |
1fb8d4 |
return MF_EXIT_SUCCESS;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#pragma mark -
|
|
Packit |
1fb8d4 |
#pragma mark Context callbacks
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static BOOL ios_client_new(freerdp* instance, rdpContext* context)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
mfContext* ctx = (mfContext*)context;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!instance || !context)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if ((ctx->mfi = calloc(1, sizeof(mfInfo))) == NULL)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
ctx->mfi->context = (mfContext*)context;
|
|
Packit |
1fb8d4 |
ctx->mfi->_context = context;
|
|
Packit |
1fb8d4 |
ctx->mfi->context->settings = instance->settings;
|
|
Packit |
1fb8d4 |
ctx->mfi->instance = instance;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!ios_events_create_pipe(ctx->mfi))
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
instance->PreConnect = ios_pre_connect;
|
|
Packit |
1fb8d4 |
instance->PostConnect = ios_post_connect;
|
|
Packit |
1fb8d4 |
instance->PostDisconnect = ios_post_disconnect;
|
|
Packit |
1fb8d4 |
instance->Authenticate = ios_ui_authenticate;
|
|
Packit |
1fb8d4 |
instance->GatewayAuthenticate = ios_ui_gw_authenticate;
|
|
Packit |
1fb8d4 |
instance->VerifyCertificate = ios_ui_verify_certificate;
|
|
Packit |
1fb8d4 |
instance->VerifyChangedCertificate = ios_ui_verify_changed_certificate;
|
|
Packit |
1fb8d4 |
instance->LogonErrorInfo = NULL;
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static void ios_client_free(freerdp* instance, rdpContext* context)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
mfInfo* mfi;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!context)
|
|
Packit |
1fb8d4 |
return;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
mfi = ((mfContext*) context)->mfi;
|
|
Packit |
1fb8d4 |
ios_events_free_pipe(mfi);
|
|
Packit |
1fb8d4 |
free(mfi);
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
ZeroMemory(pEntryPoints, sizeof(RDP_CLIENT_ENTRY_POINTS));
|
|
Packit |
1fb8d4 |
pEntryPoints->Version = RDP_CLIENT_INTERFACE_VERSION;
|
|
Packit |
1fb8d4 |
pEntryPoints->Size = sizeof(RDP_CLIENT_ENTRY_POINTS_V1);
|
|
Packit |
1fb8d4 |
pEntryPoints->GlobalInit = NULL;
|
|
Packit |
1fb8d4 |
pEntryPoints->GlobalUninit = NULL;
|
|
Packit |
1fb8d4 |
pEntryPoints->ContextSize = sizeof(mfContext);
|
|
Packit |
1fb8d4 |
pEntryPoints->ClientNew = ios_client_new;
|
|
Packit |
1fb8d4 |
pEntryPoints->ClientFree = ios_client_free;
|
|
Packit |
1fb8d4 |
pEntryPoints->ClientStart = NULL;
|
|
Packit |
1fb8d4 |
pEntryPoints->ClientStop = NULL;
|
|
Packit |
1fb8d4 |
return 0;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#pragma mark -
|
|
Packit |
1fb8d4 |
#pragma mark Initialization and cleanup
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
freerdp* ios_freerdp_new()
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
rdpContext* context;
|
|
Packit |
1fb8d4 |
RDP_CLIENT_ENTRY_POINTS clientEntryPoints;
|
|
Packit |
1fb8d4 |
RdpClientEntry(&clientEntryPoints);
|
|
Packit |
1fb8d4 |
context = freerdp_client_context_new(&clientEntryPoints);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!context)
|
|
Packit |
1fb8d4 |
return NULL;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return context->instance;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
void ios_freerdp_free(freerdp* instance)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (!instance || !instance->context)
|
|
Packit |
1fb8d4 |
return;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
freerdp_client_context_free(instance->context);
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
void ios_init_freerdp()
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
signal(SIGPIPE, SIG_IGN);
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
void ios_uninit_freerdp()
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
/* compatibilty functions */
|
|
Packit |
1fb8d4 |
size_t fwrite$UNIX2003(const void* ptr, size_t size, size_t nmemb, FILE* stream)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
return fwrite(ptr, size, nmemb, stream);
|
|
Packit |
1fb8d4 |
}
|