mfreerdp: apply fixes from mac-audio branch

This commit is contained in:
Marc-André Moreau 2014-03-03 16:57:43 -05:00
parent bb5c5dcaf0
commit fb2428309c
6 changed files with 298 additions and 315 deletions

View File

@ -22,23 +22,6 @@
#import <Cocoa/Cocoa.h>
/*
#import "freerdp/freerdp.h"
#import "freerdp/types.h"
#import "freerdp/channels/channels.h"
#import "freerdp/gdi/gdi.h"
#import "freerdp/graphics.h"
#import "freerdp/utils/event.h"
#import "freerdp/client/cliprdr.h"
#import "freerdp/client/file.h"
#import "freerdp/client/cmdline.h"
#import "freerdp/rail/rail.h"
#import "freerdp/rail.h"
#import "freerdp/utils/rail.h"
#import "mf_interface.h"
*/
#import "mfreerdp.h"
#import "mf_client.h"

View File

@ -17,31 +17,6 @@
* limitations under the License.
*/
/*
* TODO
* + provide a UI for configuring optional parameters, but keep cmd line args
* + audio redirection is delayed considerably
* + caps lock key needs to be sent in func flagsChanged()
* + libfreerdp-utils.1.0.dylib needs to be installed to /usr/local/lib
*
* - MRDPView implementation is incomplete
* - all variables should have consistent nameing scheme - camel case
* - all funcs same as above
* - PolygonSc seems to create a transparent rect
* - ensure mouse cursor changes are working ok after moving to NSTracking area
* - RAIL:
* -
* -
* - tool tips to be correctly positioned
* - dragging is slightly of
* - resize after dragging not working
* - dragging app from macbook to monitor gives exec/access err
* - unable to drag rect out of monitor boundaries
* -
* -
* -
*/
#include <winpr/windows.h>
#include "mf_client.h"
@ -52,6 +27,8 @@
#include <winpr/crt.h>
#include <winpr/input.h>
#include <winpr/synch.h>
#include <winpr/sysinfo.h>
#include <freerdp/constants.h>
@ -67,26 +44,20 @@
#import "freerdp/client/file.h"
#import "freerdp/client/cmdline.h"
/******************************************
Forward declarations
******************************************/
void mf_Pointer_New(rdpContext* context, rdpPointer* pointer);
void mf_Pointer_Free(rdpContext* context, rdpPointer* pointer);
void mf_Pointer_Set(rdpContext* context, rdpPointer* pointer);
void mf_Pointer_SetNull(rdpContext* context);
void mf_Pointer_SetDefault(rdpContext* context);
// int rdp_connect(void);
void mac_set_bounds(rdpContext* context, rdpBounds* bounds);
void mac_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmap);
void mac_begin_paint(rdpContext* context);
void mac_end_paint(rdpContext* context);
void mac_save_state_info(freerdp* instance, rdpContext* context);
void mac_desktop_resize(rdpContext* context);
static void update_activity_cb(freerdp* instance);
static void input_activity_cb(freerdp* instance);
static void channel_activity_cb(freerdp* instance);
int invoke_draw_rect(rdpContext* context);
int process_plugin_args(rdpSettings* settings, const char* name, RDP_PLUGIN_DATA* plugin_data, void* user_data);
int receive_channel_data(freerdp* instance, int chan_id, BYTE* data, int size, int flags, int total_size);
@ -99,7 +70,6 @@ void cliprdr_process_text(freerdp* instance, BYTE* data, int len);
void cliprdr_send_supported_format_list(freerdp* instance);
int register_channel_fds(int* fds, int count, freerdp* instance);
DWORD mac_client_thread(void* param);
struct cursor
@ -140,10 +110,10 @@ struct rgba_data
e.handle = (void*) self;
PubSub_OnEmbedWindow(context->pubSub, context, &e);
NSScreen *screen = [[NSScreen screens] objectAtIndex:0];
NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
NSRect screenFrame = [screen frame];
if(instance->settings->Fullscreen)
if (instance->settings->Fullscreen)
{
instance->settings->DesktopWidth = screenFrame.size.width;
instance->settings->DesktopHeight = screenFrame.size.height;
@ -157,15 +127,108 @@ struct rgba_data
return 0;
}
DWORD mac_client_update_thread(void* param)
{
int status;
wMessage message;
wMessageQueue* queue;
rdpContext* context = (rdpContext*) param;
status = 1;
queue = freerdp_get_message_queue(context->instance, FREERDP_UPDATE_MESSAGE_QUEUE);
while (MessageQueue_Wait(queue))
{
while (MessageQueue_Peek(queue, &message, TRUE))
{
status = freerdp_message_queue_process_message(context->instance, FREERDP_UPDATE_MESSAGE_QUEUE, &message);
if (!status)
break;
}
if (!status)
break;
}
ExitThread(0);
return NULL;
}
DWORD mac_client_input_thread(void* param)
{
int status;
wMessage message;
wMessageQueue* queue;
rdpContext* context = (rdpContext*) param;
status = 1;
queue = freerdp_get_message_queue(context->instance, FREERDP_INPUT_MESSAGE_QUEUE);
while (MessageQueue_Wait(queue))
{
while (MessageQueue_Peek(queue, &message, TRUE))
{
status = freerdp_message_queue_process_message(context->instance, FREERDP_INPUT_MESSAGE_QUEUE, &message);
if (!status)
break;
}
}
ExitThread(0);
return NULL;
}
DWORD mac_client_channels_thread(void* param)
{
int status;
wMessage* event;
HANDLE channelsEvent;
rdpChannels* channels;
rdpContext* context = (rdpContext*) param;
channels = context->channels;
channelsEvent = freerdp_channels_get_event_handle(context->instance);
while (WaitForSingleObject(channelsEvent, INFINITE) == WAIT_OBJECT_0)
{
status = freerdp_channels_process_pending_messages(context->instance);
if (!status)
break;
event = freerdp_channels_pop_event(context->channels);
if (event)
{
switch (GetMessageClass(event->id))
{
case CliprdrChannel_Class:
process_cliprdr_event(context->instance, event);
break;
}
freerdp_event_free(event);
}
}
ExitThread(0);
return NULL;
}
DWORD mac_client_thread(void* param)
{
@autoreleasepool
{
int status;
HANDLE events[4];
HANDLE input_event;
HANDLE update_event;
HANDLE channels_event;
HANDLE inputEvent;
HANDLE inputThread;
HANDLE updateEvent;
HANDLE updateThread;
HANDLE channelsEvent;
HANDLE channelsThread;
DWORD nCount;
rdpContext* context = (rdpContext*) param;
@ -190,17 +253,29 @@ DWORD mac_client_thread(void* param)
if (settings->AsyncUpdate)
{
events[nCount++] = update_event = freerdp_get_message_queue_event_handle(instance, FREERDP_UPDATE_MESSAGE_QUEUE);
updateThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) mac_client_update_thread, context, 0, NULL);
}
else
{
events[nCount++] = updateEvent = freerdp_get_message_queue_event_handle(instance, FREERDP_UPDATE_MESSAGE_QUEUE);
}
if (settings->AsyncInput)
{
events[nCount++] = input_event = freerdp_get_message_queue_event_handle(instance, FREERDP_INPUT_MESSAGE_QUEUE);
inputThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) mac_client_input_thread, context, 0, NULL);
}
else
{
events[nCount++] = inputEvent = freerdp_get_message_queue_event_handle(instance, FREERDP_INPUT_MESSAGE_QUEUE);
}
if (settings->AsyncChannels)
{
events[nCount++] = channels_event = freerdp_channels_get_event_handle(instance);
channelsThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) mac_client_channels_thread, context, 0, NULL);
}
else
{
events[nCount++] = channelsEvent = freerdp_channels_get_event_handle(instance);
}
while (1)
@ -213,44 +288,58 @@ DWORD mac_client_thread(void* param)
break;
}
if (settings->AsyncUpdate)
if (!settings->AsyncUpdate)
{
if (WaitForSingleObject(update_event, 0) == WAIT_OBJECT_0)
if (WaitForSingleObject(updateEvent, 0) == WAIT_OBJECT_0)
{
update_activity_cb(instance);
}
}
if (settings->AsyncInput)
if (!settings->AsyncInput)
{
if (WaitForSingleObject(input_event, 0) == WAIT_OBJECT_0)
if (WaitForSingleObject(inputEvent, 0) == WAIT_OBJECT_0)
{
input_activity_cb(instance);
}
}
if (settings->AsyncChannels)
if (!settings->AsyncChannels)
{
if (WaitForSingleObject(channels_event, 0) == WAIT_OBJECT_0)
if (WaitForSingleObject(channelsEvent, 0) == WAIT_OBJECT_0)
{
channel_activity_cb(instance);
}
}
}
if (settings->AsyncUpdate)
{
wMessageQueue* updateQueue = freerdp_get_message_queue(instance, FREERDP_UPDATE_MESSAGE_QUEUE);
MessageQueue_PostQuit(updateQueue, 0);
WaitForSingleObject(updateThread, INFINITE);
CloseHandle(updateThread);
}
if (settings->AsyncInput)
{
wMessageQueue* inputQueue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE);
MessageQueue_PostQuit(inputQueue, 0);
WaitForSingleObject(inputThread, INFINITE);
CloseHandle(inputThread);
}
if (settings->AsyncChannels)
{
WaitForSingleObject(channelsThread, INFINITE);
CloseHandle(channelsThread);
}
ExitThread(0);
return 0;
}
}
/************************************************************************
methods we override
************************************************************************/
/** *********************************************************************
* create MRDPView with specified rectangle
***********************************************************************/
- (id)initWithFrame:(NSRect)frame
{
self = [super initWithFrame:frame];
@ -263,12 +352,6 @@ DWORD mac_client_thread(void* param)
return self;
}
/** *********************************************************************
* called when MRDPView has been successfully created from the NIB
***********************************************************************/
//TODO - Expose this code as a public method, because awakeFromNib
// won't be called if the view is created dynamically
- (void) viewDidLoad
{
[self initializeView];
@ -298,35 +381,16 @@ DWORD mac_client_thread(void* param)
[[self window] invalidateCursorRectsForView:self];
}
// Set the current cursor
- (void) resetCursorRects
{
[self addCursorRect:[self visibleRect] cursor:currentCursor];
}
/** *********************************************************************
* become first responder so we can get keyboard and mouse events
***********************************************************************/
- (BOOL)acceptsFirstResponder
{
return YES;
}
/** *********************************************************************
* called when a mouse move event occurrs
*
* ideally we want to be called when the mouse moves over NSView client area,
* but in reality we get called any time the mouse moves anywhere on the screen;
* we could use NSTrackingArea class to handle this but this class is available
* on Mac OS X v10.5 and higher; since we want to be compatible with older
* versions, we do this manually.
*
* TODO: here is how it can be done using legacy methods
* http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/EventOverview/MouseTrackingEvents/MouseTrackingEvents.html#//apple_ref/doc/uid/10000060i-CH11-SW1
***********************************************************************/
- (void) mouseMoved:(NSEvent *)event
{
[super mouseMoved:event];
@ -341,10 +405,6 @@ DWORD mac_client_thread(void* param)
mf_scale_mouse_event(context, instance->input, PTR_FLAGS_MOVE, x, y);
}
/** *********************************************************************
* called when left mouse button is pressed down
***********************************************************************/
- (void)mouseDown:(NSEvent *) event
{
[super mouseDown:event];
@ -359,10 +419,6 @@ DWORD mac_client_thread(void* param)
mf_scale_mouse_event(context, instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1, x, y);
}
/** *********************************************************************
* called when left mouse button is released
***********************************************************************/
- (void) mouseUp:(NSEvent *) event
{
[super mouseUp:event];
@ -377,10 +433,6 @@ DWORD mac_client_thread(void* param)
mf_scale_mouse_event(context, instance->input, PTR_FLAGS_BUTTON1, x, y);
}
/** *********************************************************************
* called when right mouse button is pressed down
***********************************************************************/
- (void) rightMouseDown:(NSEvent *)event
{
[super rightMouseDown:event];
@ -395,10 +447,6 @@ DWORD mac_client_thread(void* param)
mf_scale_mouse_event(context, instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2, x, y);
}
/** *********************************************************************
* called when right mouse button is released
***********************************************************************/
- (void) rightMouseUp:(NSEvent *)event
{
[super rightMouseUp:event];
@ -413,10 +461,6 @@ DWORD mac_client_thread(void* param)
mf_scale_mouse_event(context, instance->input, PTR_FLAGS_BUTTON2, x, y);
}
/** *********************************************************************
* called when middle mouse button is pressed
***********************************************************************/
- (void) otherMouseDown:(NSEvent *)event
{
[super otherMouseDown:event];
@ -431,10 +475,6 @@ DWORD mac_client_thread(void* param)
mf_scale_mouse_event(context, instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON3, x, y);
}
/** *********************************************************************
* called when middle mouse button is released
***********************************************************************/
- (void) otherMouseUp:(NSEvent *)event
{
[super otherMouseUp:event];
@ -478,11 +518,6 @@ DWORD mac_client_thread(void* param)
}
}
/** *********************************************************************
* called when mouse is moved with left button pressed
* note: invocation order is: mouseDown, mouseDragged, mouseUp
***********************************************************************/
- (void) mouseDragged:(NSEvent *)event
{
[super mouseDragged:event];
@ -540,10 +575,6 @@ DWORD fixKeyCode(DWORD keyCode, unichar keyChar)
return keyCode;
}
/** *********************************************************************
* called when a key is pressed
***********************************************************************/
- (void) keyDown:(NSEvent *) event
{
DWORD keyCode;
@ -581,10 +612,6 @@ DWORD fixKeyCode(DWORD keyCode, unichar keyChar)
freerdp_input_send_keyboard_event(instance->input, keyFlags, scancode);
}
/** *********************************************************************
* called when a key is released
***********************************************************************/
- (void) keyUp:(NSEvent *) event
{
DWORD keyCode;
@ -622,10 +649,6 @@ DWORD fixKeyCode(DWORD keyCode, unichar keyChar)
freerdp_input_send_keyboard_event(instance->input, keyFlags, scancode);
}
/** *********************************************************************
* called when shift, control, alt and meta keys are pressed/released
***********************************************************************/
- (void) flagsChanged:(NSEvent*) event
{
int key;
@ -732,38 +755,34 @@ DWORD fixKeyCode(DWORD keyCode, unichar keyChar)
free(pixel_data);
}
/** *********************************************************************
* called when our view needs refreshing
***********************************************************************/
- (void) drawRect:(NSRect)rect
{
if (!context)
return;
if (self->bitmap_context)
{
CGContextRef cgContext = [[NSGraphicsContext currentContext] graphicsPort];
CGImageRef cgImage = CGBitmapContextCreateImage(self->bitmap_context);
CGContextSaveGState(cgContext);
CGContextClipToRect(cgContext, CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height));
CGContextDrawImage(cgContext, CGRectMake(0,
0, [self bounds].size.width, [self bounds].size.height), cgImage);
CGContextDrawImage(cgContext, CGRectMake(0, 0, [self bounds].size.width, [self bounds].size.height), cgImage);
CGContextRestoreGState(cgContext);
CGImageRelease(cgImage);
}
else
{
// just clear the screen with black
/* Fill the screen with black */
[[NSColor blackColor] set];
NSRectFill([self bounds]);
}
}
/************************************************************************
instance methods
************************************************************************/
- (void) onPasteboardTimerFired :(NSTimer*) timer
{
int i;
@ -791,30 +810,13 @@ DWORD fixKeyCode(DWORD keyCode, unichar keyChar)
mfc->client_width = width;
}
/************************************************************************
* *
* C functions *
* *
***********************************************************************/
/** *********************************************************************
* a callback given to freerdp_connect() to process the pre-connect operations.
*
* @param inst - pointer to a rdp_freerdp struct that contains the connection's parameters, and
* will be filled with the appropriate informations.
*
* @return true if successful. false otherwise.
************************************************************************/
BOOL mac_pre_connect(freerdp* instance)
{
rdpSettings* settings;
// setup callbacks
instance->update->BeginPaint = mac_begin_paint;
instance->update->EndPaint = mac_end_paint;
instance->update->SetBounds = mac_set_bounds;
//instance->update->BitmapUpdate = mac_bitmap_update;
instance->update->DesktopResize = mac_desktop_resize;
settings = instance->settings;
@ -825,7 +827,6 @@ BOOL mac_pre_connect(freerdp* instance)
return -1;
}
settings->ColorDepth = 32;
settings->SoftwareGdi = TRUE;
settings->OsMajorType = OSMAJORTYPE_MACINTOSH;
@ -852,8 +853,8 @@ BOOL mac_pre_connect(freerdp* instance)
settings->OrderSupport[NEG_GLYPH_INDEX_INDEX] = TRUE;
settings->OrderSupport[NEG_FAST_INDEX_INDEX] = TRUE;
settings->OrderSupport[NEG_FAST_GLYPH_INDEX] = TRUE;
settings->OrderSupport[NEG_POLYGON_SC_INDEX] = (settings->SoftwareGdi) ? FALSE : TRUE;
settings->OrderSupport[NEG_POLYGON_CB_INDEX] = (settings->SoftwareGdi) ? FALSE : TRUE;
settings->OrderSupport[NEG_POLYGON_SC_INDEX] = FALSE;
settings->OrderSupport[NEG_POLYGON_CB_INDEX] = FALSE;
settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = FALSE;
settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE;
@ -864,22 +865,13 @@ BOOL mac_pre_connect(freerdp* instance)
return TRUE;
}
/** *********************************************************************
* a callback registered with freerdp_connect() to perform post-connection operations.
* we get called only if the connection was initialized properly, and will continue
* the initialization based on the newly created connection.
*
* @param inst - pointer to a rdp_freerdp struct
*
* @return true on success, false on failure
*
************************************************************************/
BOOL mac_post_connect(freerdp* instance)
{
rdpGdi* gdi;
UINT32 flags;
rdpSettings* settings;
rdpPointer rdp_pointer;
mfContext *mfc = (mfContext*) instance->context;
mfContext* mfc = (mfContext*) instance->context;
MRDPView* view = (MRDPView*) mfc->view;
@ -891,13 +883,20 @@ BOOL mac_post_connect(freerdp* instance)
rdp_pointer.SetNull = mf_Pointer_SetNull;
rdp_pointer.SetDefault = mf_Pointer_SetDefault;
flags = CLRBUF_32BPP | CLRCONV_ALPHA;
settings = instance->settings;
flags = CLRCONV_ALPHA | CLRCONV_RGB555;
if (settings->ColorDepth > 16)
flags |= CLRBUF_32BPP;
else
flags |= CLRBUF_16BPP;
gdi_init(instance, flags, NULL);
rdpGdi* gdi = instance->context->gdi;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
view->bitmap_context = CGBitmapContextCreate(gdi->primary_buffer, gdi->width, gdi->height, 8, gdi->width * 4, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst);
gdi = instance->context->gdi;
view->bitmap_context = mac_create_bitmap_context(instance->context);
pointer_cache_register_callbacks(instance->update);
graphics_register_pointer(instance->context->graphics, &rdp_pointer);
@ -942,14 +941,6 @@ BOOL mac_authenticate(freerdp* instance, char** username, char** password, char*
return ok;
}
/** *********************************************************************
* create a new mouse cursor
*
* @param context our context state
* @param pointer information about the cursor to create
*
************************************************************************/
void mf_Pointer_New(rdpContext* context, rdpPointer* pointer)
{
NSRect rect;
@ -978,7 +969,7 @@ void mf_Pointer_New(rdpContext* context, rdpPointer* pointer)
freerdp_alpha_cursor_convert(cursor_data, pointer->xorMaskData, pointer->andMaskData,
pointer->width, pointer->height, pointer->xorBpp, context->gdi->clrconv);
/* store cursor bitmap image in representation - required by NSImage */
bmiRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:(unsigned char **) &cursor_data
pixelsWide:rect.size.width
@ -1012,10 +1003,6 @@ void mf_Pointer_New(rdpContext* context, rdpPointer* pointer)
[ma addObject:mrdpCursor];
}
/** *********************************************************************
* release resources on specified cursor
************************************************************************/
void mf_Pointer_Free(rdpContext* context, rdpPointer* pointer)
{
mfContext* mfc = (mfContext*) context;
@ -1036,10 +1023,6 @@ void mf_Pointer_Free(rdpContext* context, rdpPointer* pointer)
}
}
/** *********************************************************************
* set specified cursor as the current cursor
************************************************************************/
void mf_Pointer_Set(rdpContext* context, rdpPointer* pointer)
{
mfContext* mfc = (mfContext*) context;
@ -1059,19 +1042,11 @@ void mf_Pointer_Set(rdpContext* context, rdpPointer* pointer)
NSLog(@"Cursor not found");
}
/** *********************************************************************
* do not display any mouse cursor
***********************************************************************/
void mf_Pointer_SetNull(rdpContext* context)
{
}
/** *********************************************************************
* display default mouse cursor
***********************************************************************/
void mf_Pointer_SetDefault(rdpContext* context)
{
mfContext* mfc = (mfContext*) context;
@ -1079,28 +1054,31 @@ void mf_Pointer_SetDefault(rdpContext* context)
[view setCursor:[NSCursor arrowCursor]];
}
/** *********************************************************************
* clip drawing surface so nothing is drawn outside specified bounds
***********************************************************************/
void mac_set_bounds(rdpContext* context, rdpBounds* bounds)
CGContextRef mac_create_bitmap_context(rdpContext* context)
{
CGContextRef bitmap_context;
rdpGdi* gdi = context->gdi;
}
/** *********************************************************************
* we don't do much over here
***********************************************************************/
void mac_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmap)
{
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
if (gdi->dstBpp == 16)
{
bitmap_context = CGBitmapContextCreate(gdi->primary_buffer,
gdi->width, gdi->height, 5, gdi->width * 2, colorSpace,
kCGBitmapByteOrder16Little | kCGImageAlphaNoneSkipFirst);
}
else
{
bitmap_context = CGBitmapContextCreate(gdi->primary_buffer,
gdi->width, gdi->height, 8, gdi->width * 4, colorSpace,
kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst);
}
CGColorSpaceRelease(colorSpace);
return bitmap_context;
}
/** *********************************************************************
* we don't do much over here
***********************************************************************/
void mac_begin_paint(rdpContext* context)
{
rdpGdi* gdi = context->gdi;
@ -1111,10 +1089,6 @@ void mac_begin_paint(rdpContext* context)
gdi->primary->hdc->hwnd->invalid->null = 1;
}
/** *********************************************************************
* RDP server wants us to draw new data in the view
***********************************************************************/
void mac_end_paint(rdpContext* context)
{
rdpGdi* gdi;
@ -1139,9 +1113,6 @@ void mac_end_paint(rdpContext* context)
if (context->gdi->primary->hdc->hwnd->invalid->null)
return;
if (context->gdi->drawing != context->gdi->primary)
return;
invalid = gdi->primary->hdc->hwnd->invalid;
@ -1172,17 +1143,36 @@ void mac_end_paint(rdpContext* context)
gdi->primary->hdc->hwnd->ninvalid = 0;
}
/** *********************************************************************
* called when update data is available
***********************************************************************/
void mac_desktop_resize(rdpContext* context)
{
mfContext* mfc = (mfContext*) context;
MRDPView* view = (MRDPView*) mfc->view;
rdpSettings* settings = context->settings;
/**
* TODO: Fix resizing race condition. We should probably implement a message to be
* put on the update message queue to be able to properly flush pending updates,
* resize, and then continue with post-resizing graphical updates.
*/
CGContextRef old_context = view->bitmap_context;
view->bitmap_context = NULL;
CGContextRelease(old_context);
mfc->width = settings->DesktopWidth;
mfc->height = settings->DesktopHeight;
gdi_resize(context->gdi, mfc->width, mfc->height);
view->bitmap_context = mac_create_bitmap_context(context);
}
static void update_activity_cb(freerdp* instance)
{
int status;
wMessage message;
wMessageQueue* queue;
status = 1;
queue = freerdp_get_message_queue(instance, FREERDP_UPDATE_MESSAGE_QUEUE);
@ -1191,7 +1181,7 @@ static void update_activity_cb(freerdp* instance)
while (MessageQueue_Peek(queue, &message, TRUE))
{
status = freerdp_message_queue_process_message(instance, FREERDP_UPDATE_MESSAGE_QUEUE, &message);
if (!status)
break;
}
@ -1202,10 +1192,6 @@ static void update_activity_cb(freerdp* instance)
}
}
/** *********************************************************************
* called when input data is available
***********************************************************************/
static void input_activity_cb(freerdp* instance)
{
int status;
@ -1231,10 +1217,6 @@ static void input_activity_cb(freerdp* instance)
}
}
/** *********************************************************************
* called when data is available on a virtual channel
***********************************************************************/
static void channel_activity_cb(freerdp* instance)
{
wMessage* event;
@ -1257,20 +1239,6 @@ static void channel_activity_cb(freerdp* instance)
}
}
/**
* Used to load plugins based on the commandline parameters.
* This function is provided as a parameter to freerdp_parse_args(), that will call it
* each time a plugin name is found on the command line.
* This function just calls freerdp_channels_load_plugin() for the given plugin, and always returns 1.
*
* @param settings
* @param name
* @param plugin_data
* @param user_data
*
* @return 1
*/
int process_plugin_args(rdpSettings* settings, const char* name, RDP_PLUGIN_DATA* plugin_data, void* user_data)
{
rdpChannels* channels = (rdpChannels*) user_data;
@ -1284,10 +1252,6 @@ int process_plugin_args(rdpSettings* settings, const char* name, RDP_PLUGIN_DATA
* stuff related to clipboard redirection
*/
/**
* remote system has requested clipboard data from local system
*/
void cliprdr_process_cb_data_request_event(freerdp* instance)
{
int len;

View File

@ -71,35 +71,38 @@ void mac_set_view_size(rdpContext* context, MRDPView* view);
- (int) ParseCommandLineArguments
{
int i;
int len;
int length;
int status;
char* cptr;
int argc;
char** argv = nil;
NSArray* args = [[NSProcessInfo processInfo] arguments];
argc = (int) [args count];
argv = malloc(sizeof(char*) * argc);
context->argc = (int) [args count];
context->argv = malloc(sizeof(char*) * context->argc);
i = 0;
for (NSString* str in args)
{
len = (int) ([str length] + 1);
cptr = (char*) malloc(len);
/* filter out some arguments added by XCode */
if ([str isEqualToString:@"YES"])
continue;
if ([str isEqualToString:@"-NSDocumentRevisionsDebugMode"])
continue;
length = (int) ([str length] + 1);
cptr = (char*) malloc(length);
strcpy(cptr, [str UTF8String]);
argv[i++] = cptr;
context->argv[i++] = cptr;
}
status = freerdp_client_settings_parse_command_line(context->settings, argc, argv);
if (context->argc && context->argv)
status = freerdp_client_settings_command_line_status_print(context->settings, status, context->argc, context->argv);
else
{
freerdp_client_print_command_line_help(argc, argv);
}
context->argc = i;
status = freerdp_client_settings_parse_command_line(context->settings, context->argc, context->argv);
status = freerdp_client_settings_command_line_status_print(context->settings, status, context->argc, context->argv);
return status;
}

View File

@ -99,10 +99,11 @@ int mfreerdp_client_new(freerdp* instance, rdpContext* context)
settings = instance->settings;
settings->AsyncTransport = TRUE;
settings->AsyncUpdate = TRUE;
settings->AsyncInput = TRUE;
settings->AsyncChannels = TRUE;
settings->AsyncTransport = TRUE;
return 0;
}
@ -135,7 +136,6 @@ void freerdp_client_mouse_event(rdpContext* cfc, DWORD flags, int x, int y)
input->MouseEvent(input, flags, x, y);
}
void mf_scale_mouse_event(void* context, rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
{
mfContext* mfc = (mfContext*) context;

View File

@ -28,7 +28,7 @@ struct mf_context
DEFINE_RDP_CLIENT_COMMON();
void* view;
BOOL view_ownership; // TRUE indicates that the window was created and should be freed by the API.
BOOL view_ownership;
int width;
int height;
@ -44,8 +44,8 @@ struct mf_context
int client_height;
HANDLE keyboardThread;
HANDLE stopEvent;
HANDLE stopEvent;
HGDI_DC hdc;
UINT16 srcBpp;
UINT16 dstBpp;

View File

@ -335,6 +335,14 @@ static void timespec_add_ms(struct timespec* tspec, UINT32 ms)
tspec->tv_nsec = (ns % 1000000000);
}
static UINT64 timespec_to_ms(struct timespec* tspec)
{
UINT64 ms;
ms = tspec->tv_sec * 1000;
ms += tspec->tv_nsec / 1000000;
return ms;
}
static void timespec_gettimeofday(struct timespec* tspec)
{
struct timeval tval;
@ -345,13 +353,10 @@ static void timespec_gettimeofday(struct timespec* tspec)
static int timespec_compare(const struct timespec* tspec1, const struct timespec* tspec2)
{
if (tspec1->tv_sec < tspec2->tv_sec)
return -1;
if (tspec1->tv_sec > tspec2->tv_sec)
return 1;
return tspec1->tv_nsec - tspec2->tv_nsec;
if (tspec1->tv_sec == tspec2->tv_sec)
return (tspec1->tv_nsec - tspec2->tv_nsec);
else
return (tspec1->tv_sec - tspec2->tv_sec);
}
static void timespec_copy(struct timespec* dst, struct timespec* src)
@ -363,37 +368,49 @@ static void timespec_copy(struct timespec* dst, struct timespec* src)
void InsertTimerQueueTimer(WINPR_TIMER_QUEUE_TIMER** pHead, WINPR_TIMER_QUEUE_TIMER* timer)
{
WINPR_TIMER_QUEUE_TIMER* node;
if (!(*pHead))
{
*pHead = timer;
timer->next = NULL;
return;
}
node = *pHead;
while (node->next)
{
if (timespec_compare(&(timer->ExpirationTime), &(node->ExpirationTime)) < 0)
break;
if (timespec_compare(&(timer->ExpirationTime), &(node->ExpirationTime)) > 0)
{
if (timespec_compare(&(timer->ExpirationTime), &(node->next->ExpirationTime)) < 0)
break;
}
node = node->next;
}
if (node->next)
{
timer->next = node->next->next;
node->next = timer;
node->next = timer;
}
else
{
node->next = timer;
timer->next = NULL;
}
}
void RemoveTimerQueueTimer(WINPR_TIMER_QUEUE_TIMER** pHead, WINPR_TIMER_QUEUE_TIMER* timer)
{
BOOL found = FALSE;
WINPR_TIMER_QUEUE_TIMER* node;
WINPR_TIMER_QUEUE_TIMER* prevNode;
if (timer == *pHead)
{
*pHead = timer->next;
timer->next = NULL;
return;
}
@ -403,14 +420,24 @@ void RemoveTimerQueueTimer(WINPR_TIMER_QUEUE_TIMER** pHead, WINPR_TIMER_QUEUE_TI
while (node)
{
if (node == timer)
{
found = TRUE;
break;
}
prevNode = node;
node = node->next;
}
prevNode->next = timer->next;
timer->next = NULL;
if (found)
{
if (prevNode)
{
prevNode->next = timer->next;
}
timer->next = NULL;
}
}
int FireExpiredTimerQueueTimers(WINPR_TIMER_QUEUE* timerQueue)
@ -438,14 +465,14 @@ int FireExpiredTimerQueueTimers(WINPR_TIMER_QUEUE* timerQueue)
if (node->Period)
{
timespec_add_ms(&(node->ExpirationTime), node->Period);
InsertTimerQueueTimer(&(timerQueue->activeHead), node);
node = timerQueue->activeHead;
}
else
{
InsertTimerQueueTimer(&(timerQueue->inactiveHead), node);
}
node = timerQueue->activeHead;
}
else
{
@ -470,7 +497,7 @@ static void* TimerQueueThread(void* arg)
if (!timerQueue->activeHead)
{
timespec_add_ms(&timeout, 100);
timespec_add_ms(&timeout, 50);
}
else
{
@ -518,12 +545,15 @@ HANDLE CreateTimerQueue(void)
if (timerQueue)
{
ZeroMemory(timerQueue, sizeof(WINPR_TIMER_QUEUE));
WINPR_HANDLE_SET_TYPE(timerQueue, HANDLE_TYPE_TIMER_QUEUE);
handle = (HANDLE) timerQueue;
timerQueue->activeHead = NULL;
timerQueue->inactiveHead = NULL;
timerQueue->bCancelled = FALSE;
StartTimerQueueThread(timerQueue);
}
@ -642,6 +672,7 @@ BOOL CreateTimerQueueTimer(PHANDLE phNewTimer, HANDLE TimerQueue,
timer->timerQueue = (WINPR_TIMER_QUEUE*) TimerQueue;
timer->FireCount = 0;
timer->next = NULL;
pthread_mutex_lock(&(timerQueue->cond_mutex));
@ -670,9 +701,11 @@ BOOL ChangeTimerQueueTimer(HANDLE TimerQueue, HANDLE Timer, ULONG DueTime, ULONG
pthread_mutex_lock(&(timerQueue->cond_mutex));
RemoveTimerQueueTimer(&(timerQueue->activeHead), timer);
RemoveTimerQueueTimer(&(timerQueue->inactiveHead), timer);
timer->DueTime = DueTime;
timer->Period = Period;
timer->next = NULL;
timespec_copy(&(timer->StartTime), &CurrentTime);
timespec_add_ms(&(timer->StartTime), DueTime);