diff --git a/client/Mac/MRDPView.h b/client/Mac/MRDPView.h index 289dae5ce..29964ff19 100755 --- a/client/Mac/MRDPView.h +++ b/client/Mac/MRDPView.h @@ -41,21 +41,19 @@ @interface MRDPView : NSView { + mfContext* mfc; NSBitmapImageRep* bmiRep; NSMutableArray* cursors; NSMutableArray* windows; NSTimer* pasteboard_timer; NSCursor* currentCursor; NSRect prevWinPosition; - int titleBarHeight; freerdp* instance; rdpContext* context; CGContextRef bitmap_context; char* pixel_data; - int width; - int height; int argc; - char** argv; + char** argv; NSPoint savedDragLocation; BOOL firstCreateWindow; @@ -75,9 +73,7 @@ int kdrmeta; int kdcapslock; - BOOL initialized; - - NSImageView* imageView; + BOOL initialized; @public NSPasteboard* pasteboard_rd; /* for reading from clipboard */ @@ -89,10 +85,10 @@ - (int) rdpStart :(rdpContext*) rdp_context; - (void) setCursor: (NSCursor*) cursor; +- (void) setScrollOffset:(int)xOffset y:(int)yOffset w:(int)width h:(int)height; - (void) onPasteboardTimerFired :(NSTimer *) timer; - (void) releaseResources; -- (void) setViewSize : (int) w : (int) h; @property (assign) int is_connected; diff --git a/client/Mac/MRDPView.m b/client/Mac/MRDPView.m index b89599246..4a02dbcb1 100644 --- a/client/Mac/MRDPView.m +++ b/client/Mac/MRDPView.m @@ -123,7 +123,6 @@ struct rgba_data - (int) rdpStart:(rdpContext*) rdp_context { - mfContext* mfc; rdpSettings* settings; EmbedWindowEventArgs e; @@ -148,11 +147,8 @@ struct rgba_data instance->settings->DesktopHeight = screenFrame.size.height; } - [self setViewSize :instance->settings->DesktopWidth :instance->settings->DesktopHeight]; - - - if(instance->settings->Fullscreen) - [[self window] toggleFullScreen:nil]; + mfc->client_height = instance->settings->DesktopHeight; + mfc->client_width = instance->settings->DesktopWidth; mfc->thread = CreateThread(NULL, 0, mac_client_thread, (void*) context, 0, &mfc->mainThreadId); @@ -278,14 +274,6 @@ DWORD mac_client_thread(void* param) { if (!initialized) { - // store our window dimensions - width = [self frame].size.width; - height = [self frame].size.height; - titleBarHeight = 22; - - [[self window] becomeFirstResponder]; - [[self window] setAcceptsMouseMovedEvents:YES]; - cursors = [[NSMutableArray alloc] initWithCapacity:10]; // setup a mouse tracking area @@ -304,8 +292,6 @@ DWORD mac_client_thread(void* param) { self->currentCursor = cursor; [[self window] invalidateCursorRectsForView:self]; - - [imageView setImage:[currentCursor image]]; } @@ -347,11 +333,10 @@ DWORD mac_client_thread(void* param) NSPoint loc = [event locationInWindow]; int x = (int) loc.x; int y = (int) loc.y; - - y = height - y; - - // send mouse motion event to RDP server - instance->input->MouseEvent(instance->input, PTR_FLAGS_MOVE, x, y); + + y = [self frame].size.height - y; + + mf_scale_mouse_event(context, instance->input, PTR_FLAGS_MOVE, x, y); } /** ********************************************************************* @@ -369,9 +354,9 @@ DWORD mac_client_thread(void* param) int x = (int) loc.x; int y = (int) loc.y; - y = height - y; + y = [self frame].size.height - y; - instance->input->MouseEvent(instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1, x, y); + mf_scale_mouse_event(context, instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1, x, y); } /** ********************************************************************* @@ -389,9 +374,9 @@ DWORD mac_client_thread(void* param) int x = (int) loc.x; int y = (int) loc.y; - y = height - y; + y = [self frame].size.height - y; - instance->input->MouseEvent(instance->input, PTR_FLAGS_BUTTON1, x, y); + mf_scale_mouse_event(context, instance->input, PTR_FLAGS_BUTTON1, x, y); } /** ********************************************************************* @@ -409,9 +394,9 @@ DWORD mac_client_thread(void* param) int x = (int) loc.x; int y = (int) loc.y; - y = height - y; + y = [self frame].size.height - y; - instance->input->MouseEvent(instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2, x, y); + mf_scale_mouse_event(context, instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2, x, y); } /** ********************************************************************* @@ -429,9 +414,9 @@ DWORD mac_client_thread(void* param) int x = (int) loc.x; int y = (int) loc.y; - y = height - y; + y = [self frame].size.height - y; - instance->input->MouseEvent(instance->input, PTR_FLAGS_BUTTON2, x, y); + mf_scale_mouse_event(context, instance->input, PTR_FLAGS_BUTTON2, x, y); } /** ********************************************************************* @@ -449,9 +434,9 @@ DWORD mac_client_thread(void* param) int x = (int) loc.x; int y = (int) loc.y; - y = height - y; + y = [self frame].size.height - y; - instance->input->MouseEvent(instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON3, x, y); + mf_scale_mouse_event(context, instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON3, x, y); } /** ********************************************************************* @@ -469,9 +454,9 @@ DWORD mac_client_thread(void* param) int x = (int) loc.x; int y = (int) loc.y; - y = height - y; + y = [self frame].size.height - y; - instance->input->MouseEvent(instance->input, PTR_FLAGS_BUTTON3, x, y); + mf_scale_mouse_event(context, instance->input, PTR_FLAGS_BUTTON3, x, y); } - (void) scrollWheel:(NSEvent *)event @@ -487,7 +472,7 @@ DWORD mac_client_thread(void* param) int x = (int) loc.x; int y = (int) loc.y; - y = height - y; + y = [self frame].size.height - y; flags = PTR_FLAGS_WHEEL; @@ -500,7 +485,7 @@ DWORD mac_client_thread(void* param) /* limit to maximum value in WheelRotationMask (9bit signed value) */ int step = MIN(MAX(-256, units), 255); - instance->input->MouseEvent(instance->input, flags | ((UINT16)step & WheelRotationMask), x, y); + mf_scale_mouse_event(context, instance->input, flags | ((UINT16)step & WheelRotationMask), x, y); units -= step; } } @@ -521,10 +506,10 @@ DWORD mac_client_thread(void* param) int x = (int) loc.x; int y = (int) loc.y; - y = height - y; + y = [self frame].size.height - y; // send mouse motion event to RDP server - instance->input->MouseEvent(instance->input, PTR_FLAGS_MOVE, x, y); + mf_scale_mouse_event(context, instance->input, PTR_FLAGS_MOVE, x, y); } /** ********************************************************************* @@ -720,19 +705,20 @@ DWORD mac_client_thread(void* param) return; if (self->bitmap_context) - { + { CGContextRef cgContext = [[NSGraphicsContext currentContext] graphicsPort]; CGImageRef cgImage = CGBitmapContextCreateImage(self->bitmap_context); - 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); + 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); - CGImageRelease(cgImage); - } + CGImageRelease(cgImage); + } else { // just clear the screen with black - [[NSColor redColor] set]; + [[NSColor blackColor] set]; NSRectFill([self bounds]); } } @@ -760,30 +746,12 @@ DWORD mac_client_thread(void* param) } } -- (void) setViewSize : (int) w : (int) h +- (void) setScrollOffset:(int)xOffset y:(int)yOffset w:(int)width h:(int)height { - // store current dimensions - width = w; - height = h; - - - // set client area to specified dimensions - NSRect innerRect; - innerRect.origin.x = 0; - innerRect.origin.y = 0; - innerRect.size.width = w; - innerRect.size.height = h; - [self setFrame:innerRect]; - - // calculate window of same size, but keep position - NSRect outerRect = [[self window] frame]; - outerRect.size = [[self window] frameRectForContentRect:innerRect].size; - - // we are not in RemoteApp mode, disable larger than resolution - [[self window] setContentMaxSize:innerRect.size]; - - // set window to given area - [[self window] setFrame:outerRect display:YES]; + mfc->yCurrentScroll = yOffset; + mfc->xCurrentScroll = xOffset; + mfc->client_height = height; + mfc->client_width = width; } /************************************************************************ @@ -1125,6 +1093,13 @@ void mac_end_paint(rdpContext* context) mfContext* mfc = (mfContext*) context; MRDPView* view = (MRDPView*) mfc->view; + int ww, wh, dw, dh; + + ww = mfc->client_width; + wh = mfc->client_height; + dw = mfc->context.settings->DesktopWidth; + dh = mfc->context.settings->DesktopHeight; + if ((context == 0) || (context->gdi == 0)) return; @@ -1138,12 +1113,32 @@ void mac_end_paint(rdpContext* context) for (i = 0; i < gdi->primary->hdc->hwnd->ninvalid; i++) { - drawRect.origin.x = gdi->primary->hdc->hwnd->cinvalid[i].x - 1; - drawRect.origin.y = gdi->primary->hdc->hwnd->cinvalid[i].y - 1; - drawRect.size.width = gdi->primary->hdc->hwnd->cinvalid[i].w + 1; - drawRect.size.height = gdi->primary->hdc->hwnd->cinvalid[i].h + 1; - windows_to_apple_cords(mfc->view, &drawRect); - [view setNeedsDisplayInRect:drawRect]; + drawRect.origin.x = gdi->primary->hdc->hwnd->cinvalid[i].x; + drawRect.origin.y = gdi->primary->hdc->hwnd->cinvalid[i].y; + drawRect.size.width = gdi->primary->hdc->hwnd->cinvalid[i].w; + drawRect.size.height = gdi->primary->hdc->hwnd->cinvalid[i].h; + + if (mfc->context.settings->SmartSizing && (ww != dw || wh != dh)) + { + drawRect.origin.y = drawRect.origin.y * wh / dh - 1; + drawRect.size.height = drawRect.size.height * wh / dh + 1; + drawRect.origin.x = drawRect.origin.x * ww / dw - 1; + drawRect.size.width = drawRect.size.width * ww / dw + 1; + } + else + { + drawRect.origin.y = drawRect.origin.y - 1; + drawRect.size.height = drawRect.size.height + 1; + drawRect.origin.x = drawRect.origin.x - 1; + drawRect.size.width = drawRect.size.width + 1; + } + + windows_to_apple_cords(mfc->view, &drawRect); + + // Note: The xCurrentScroll and yCurrentScroll values do not need to be taken into account + // because the current frame is always at full size, since the scrolling is handled by the external container. + + [view setNeedsDisplayInRect:drawRect]; } gdi->primary->hdc->hwnd->ninvalid = 0; @@ -1477,7 +1472,8 @@ void cliprdr_send_supported_format_list(freerdp* instance) void windows_to_apple_cords(MRDPView* view, NSRect* r) { - r->origin.y = view->height - (r->origin.y + r->size.height); + r->origin.y = [view frame].size.height - (r->origin.y + r->size.height); } + @end diff --git a/client/Mac/cli/AppDelegate.m b/client/Mac/cli/AppDelegate.m index 7348d5912..c05213240 100644 --- a/client/Mac/cli/AppDelegate.m +++ b/client/Mac/cli/AppDelegate.m @@ -9,12 +9,15 @@ #import "AppDelegate.h" #import "MacFreeRDP/mfreerdp.h" #import "MacFreeRDP/mf_client.h" +#import "MacFreeRDP/MRDPView.h" #import static AppDelegate* _singleDelegate = nil; void AppDelegate_EmbedWindowEventHandler(void* context, EmbedWindowEventArgs* e); void AppDelegate_ConnectionResultEventHandler(void* context, ConnectionResultEventArgs* e); void AppDelegate_ErrorInfoEventHandler(void* ctx, ErrorInfoEventArgs* e); +int mac_client_start(rdpContext* context); +void mac_set_view_size(rdpContext* context, MRDPView* view); @implementation AppDelegate @@ -105,12 +108,24 @@ void AppDelegate_ErrorInfoEventHandler(void* ctx, ErrorInfoEventArgs* e); clientEntryPoints.Version = RDP_CLIENT_INTERFACE_VERSION; RdpClientEntry(&clientEntryPoints); + + clientEntryPoints.ClientStart = mac_client_start; context = freerdp_client_context_new(&clientEntryPoints); } - (void) ReleaseContext { + mfContext* mfc; + MRDPView* view; + + mfc = (mfContext*) context; + view = (MRDPView*) mfc->view; + + [view releaseResources]; + [view release]; + mfc->view = nil; + freerdp_client_context_free(context); context = nil; } @@ -158,6 +173,9 @@ void AppDelegate_EmbedWindowEventHandler(void* ctx, EmbedWindowEventArgs* e) { [[_singleDelegate->window contentView] addSubview:mfc->view]; } + + + mac_set_view_size(context, mfc->view); } } @@ -203,4 +221,45 @@ void AppDelegate_ErrorInfoEventHandler(void* ctx, ErrorInfoEventArgs* e) [_singleDelegate performSelectorOnMainThread:@selector(rdpConnectError:) withObject:message waitUntilDone:TRUE]; [message release]; } -} \ No newline at end of file +} + + +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]; + + + if(context->settings->Fullscreen) + [[view window] toggleFullScreen:nil]; +} + +int mac_client_start(rdpContext* context) +{ + mfContext* mfc; + MRDPView* view; + + mfc = (mfContext*) context; + view = [[MRDPView alloc] initWithFrame : NSMakeRect(0, 0, context->settings->DesktopWidth, context->settings->DesktopHeight)]; + mfc->view = view; + + [view rdpStart:context]; + mac_set_view_size(context, view); + + return 0; +} diff --git a/client/Mac/mf_client.h b/client/Mac/mf_client.h index 711c77b47..341fcacbc 100755 --- a/client/Mac/mf_client.h +++ b/client/Mac/mf_client.h @@ -28,6 +28,8 @@ extern "C" { #endif +FREERDP_API void mf_scale_mouse_event(void* context, rdpInput* input, UINT16 flags, UINT16 x, UINT16 y); + /** * Client Interface */ diff --git a/client/Mac/mf_client.m b/client/Mac/mf_client.m index cf830d3c7..2d75b3a7b 100755 --- a/client/Mac/mf_client.m +++ b/client/Mac/mf_client.m @@ -25,7 +25,6 @@ #include #include #include -#import "MRDPView.h" /** * Client Interface @@ -193,6 +192,36 @@ 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; + + int ww, wh, dw, dh; + + ww = mfc->client_width; + wh = mfc->client_height; + dw = mfc->context.settings->DesktopWidth; + dh = mfc->context.settings->DesktopHeight; + + if (!mfc->context.settings->SmartSizing || ((ww == dw) && (wh == dh))) + { + y = y + mfc->yCurrentScroll; + + if (wh != dh) + { + y -= (dh - wh); + } + + input->MouseEvent(input, flags, x + mfc->xCurrentScroll, y); + } + else + { + y = y * dh / wh + mfc->yCurrentScroll; + input->MouseEvent(input, flags, x * dw / ww + mfc->xCurrentScroll, y); + } +} + int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints) { pEntryPoints->Version = 1; diff --git a/client/Windows/wf_event.c b/client/Windows/wf_event.c index c243d35da..87a0ec17e 100644 --- a/client/Windows/wf_event.c +++ b/client/Windows/wf_event.c @@ -588,7 +588,7 @@ void wf_scale_mouse_event(wfContext* wfc, rdpInput* input, UINT16 flags, UINT16 dw = wfc->instance->settings->DesktopWidth; dh = wfc->instance->settings->DesktopHeight; - if (!wfc->instance->settings->SmartSizing || (ww == dw) && (wh == dh)) + if (!wfc->instance->settings->SmartSizing || ((ww == dw) && (wh == dh))) input->MouseEvent(input, flags, x + wfc->xCurrentScroll, y + wfc->yCurrentScroll); else input->MouseEvent(input, flags, x * dw / ww + wfc->xCurrentScroll, y * dh / wh + wfc->yCurrentScroll); diff --git a/client/Windows/wf_interface.c b/client/Windows/wf_interface.c index 87abe188d..9d09d30a5 100644 --- a/client/Windows/wf_interface.c +++ b/client/Windows/wf_interface.c @@ -49,6 +49,7 @@ #include #include #include +#include #include "wf_gdi.h" #include "wf_graphics.h" @@ -331,6 +332,7 @@ BOOL wf_post_connect(freerdp* instance) rdpContext* context; WCHAR lpWindowName[64]; rdpSettings* settings; + EmbedWindowEventArgs e; settings = instance->settings; context = instance->context; @@ -388,6 +390,9 @@ BOOL wf_post_connect(freerdp* instance) else _snwprintf(lpWindowName, ARRAYSIZE(lpWindowName), L"FreeRDP: %S:%d", settings->ServerHostname, settings->ServerPort); + if (settings->EmbeddedWindow) + settings->Decorations = FALSE; + if (!settings->Decorations) dwStyle = WS_CHILD | WS_BORDER; else @@ -398,7 +403,7 @@ BOOL wf_post_connect(freerdp* instance) wfc->hwnd = CreateWindowEx((DWORD) NULL, wfc->wndClassName, lpWindowName, dwStyle, 0, 0, 0, 0, wfc->hWndParent, NULL, wfc->hInstance, NULL); - SetWindowLongPtr(wfc->hwnd, GWLP_USERDATA, (LONG_PTR) wfc); + SetWindowLongPtr(wfc->hwnd, GWLP_USERDATA, (LONG_PTR) wfc); } wf_resize_window(wfc); @@ -408,6 +413,11 @@ BOOL wf_post_connect(freerdp* instance) BitBlt(wfc->primary->hdc, 0, 0, wfc->width, wfc->height, NULL, 0, 0, BLACKNESS); wfc->drawing = wfc->primary; + EventArgsInit(&e, "wfreerdp"); + e.embed = FALSE; + e.handle = (void*) wfc->hwnd; + PubSub_OnEmbedWindow(context->pubSub, context, &e); + ShowWindow(wfc->hwnd, SW_SHOWNORMAL); UpdateWindow(wfc->hwnd); @@ -764,6 +774,8 @@ int freerdp_client_focus_out(wfContext* wfc) int freerdp_client_set_window_size(wfContext* wfc, int width, int height) { + fprintf(stderr, "freerdp_client_set_window_size %d, %d", width, height); + if ((width != wfc->client_width) || (height != wfc->client_height)) { PostThreadMessage(wfc->mainThreadId, WM_SIZE, SIZE_RESTORED, ((UINT) height << 16) | (UINT) width); diff --git a/client/Windows/wf_interface.h b/client/Windows/wf_interface.h index 028e1a853..de83a55e3 100644 --- a/client/Windows/wf_interface.h +++ b/client/Windows/wf_interface.h @@ -138,6 +138,8 @@ typedef struct wf_context wfContext; */ FREERDP_API int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints); +FREERDP_API int freerdp_client_set_window_size(wfContext* wfc, int width, int height); + #ifdef __cplusplus } diff --git a/client/common/client.c b/client/common/client.c index 14456618c..d43375a10 100644 --- a/client/common/client.c +++ b/client/common/client.c @@ -70,8 +70,8 @@ void freerdp_client_context_free(rdpContext* context) { freerdp* instance = context->instance; - free(instance->pClientEntryPoints); freerdp_context_free(instance); + free(instance->pClientEntryPoints); freerdp_free(instance); } diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index 02697579d..99b188acb 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -1333,7 +1333,7 @@ FREERDP_API UINT64 freerdp_get_param_uint64(rdpSettings* settings, int id); FREERDP_API int freerdp_set_param_uint64(rdpSettings* settings, int id, UINT64 param); FREERDP_API char* freerdp_get_param_string(rdpSettings* settings, int id); -FREERDP_API int freerdp_set_param_string(rdpSettings* settings, int id, char* param); +FREERDP_API int freerdp_set_param_string(rdpSettings* settings, int id, const char* param); FREERDP_API double freerdp_get_param_double(rdpSettings* settings, int id); FREERDP_API int freerdp_set_param_double(rdpSettings* settings, int id, double param); diff --git a/libfreerdp/common/settings.c b/libfreerdp/common/settings.c index ffcf1937f..0b667f640 100644 --- a/libfreerdp/common/settings.c +++ b/libfreerdp/common/settings.c @@ -2167,7 +2167,7 @@ char* freerdp_get_param_string(rdpSettings* settings, int id) return NULL; } -int freerdp_set_param_string(rdpSettings* settings, int id, char* param) +int freerdp_set_param_string(rdpSettings* settings, int id, const char* param) { ParamChangeEventArgs e; rdpContext* context = ((freerdp*) settings->instance)->context;