diff --git a/client/Windows/wf_event.c b/client/Windows/wf_event.c index d12b972c3..b837d19c0 100644 --- a/client/Windows/wf_event.c +++ b/client/Windows/wf_event.c @@ -29,6 +29,7 @@ #include "wfreerdp.h" +#include "wf_gdi.h" #include "wf_event.h" static HWND g_focus_hWnd; @@ -70,8 +71,10 @@ LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam) (GetAsyncKeyState(VK_MENU) & 0x8000)) /* could also use flags & LLKHF_ALTDOWN */ { if (wParam == WM_KEYDOWN) - //wf_toggle_fullscreen(wfi); - return 1; + { + wf_toggle_fullscreen(wfi); + return 1; + } } if (rdp_scancode == RDP_SCANCODE_NUMLOCK_EXTENDED) @@ -173,29 +176,29 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam //printf("WM_PAINT: x:%d y:%d w:%d h:%d\n", x, y, w, h); - BitBlt(hdc, x, y, w, h, wfi->primary->hdc, x, y, SRCCOPY); + BitBlt(hdc, x, y, w, h, wfi->primary->hdc, x - wfi->offset_x, y - wfi->offset_y, SRCCOPY); EndPaint(hWnd, &ps); break; case WM_LBUTTONDOWN: - input->MouseEvent(input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1, X_POS(lParam), Y_POS(lParam)); + input->MouseEvent(input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y); break; case WM_LBUTTONUP: - input->MouseEvent(input, PTR_FLAGS_BUTTON1, X_POS(lParam), Y_POS(lParam)); + input->MouseEvent(input, PTR_FLAGS_BUTTON1, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y); break; case WM_RBUTTONDOWN: - input->MouseEvent(input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2, X_POS(lParam), Y_POS(lParam)); + input->MouseEvent(input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y); break; case WM_RBUTTONUP: - input->MouseEvent(input, PTR_FLAGS_BUTTON2, X_POS(lParam), Y_POS(lParam)); + input->MouseEvent(input, PTR_FLAGS_BUTTON2, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y); break; case WM_MOUSEMOVE: - input->MouseEvent(input, PTR_FLAGS_MOVE, X_POS(lParam), Y_POS(lParam)); + input->MouseEvent(input, PTR_FLAGS_MOVE, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y); break; case WM_MOUSEWHEEL: diff --git a/client/Windows/wf_gdi.c b/client/Windows/wf_gdi.c index c702ffddf..7c1d988ca 100644 --- a/client/Windows/wf_gdi.c +++ b/client/Windows/wf_gdi.c @@ -168,18 +168,61 @@ HBRUSH wf_create_brush(wfInfo * wfi, rdpBrush* brush, UINT32 color, int bpp) void wf_invalidate_region(wfInfo* wfi, int x, int y, int width, int height) { - wfi->update_rect.left = x; - wfi->update_rect.top = y; - wfi->update_rect.right = x + width; - wfi->update_rect.bottom = y + height; + wfi->update_rect.left = x + wfi->offset_x; + wfi->update_rect.top = y + wfi->offset_y; + wfi->update_rect.right = wfi->update_rect.left + width; + wfi->update_rect.bottom = wfi->update_rect.top + height; InvalidateRect(wfi->hwnd, &(wfi->update_rect), FALSE); gdi_InvalidateRegion(wfi->hdc, x, y, width, height); } +void wf_update_offset(wfInfo* wfi) +{ + if (wfi->fullscreen) + { + wfi->offset_x = (GetSystemMetrics(SM_CXSCREEN) - wfi->width) / 2; + if (wfi->offset_x < 0) + wfi->offset_x = 0; + wfi->offset_y = (GetSystemMetrics(SM_CYSCREEN) - wfi->height) / 2; + if (wfi->offset_y < 0) + wfi->offset_y = 0; + } + else + { + wfi->offset_x = 0; + wfi->offset_y = 0; + } +} + +void wf_resize_window(wfInfo* wfi) +{ + if (wfi->fullscreen) + { + SetWindowLongPtr(wfi->hwnd, GWL_STYLE, WS_POPUP); + SetWindowPos(wfi->hwnd, HWND_TOP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), SWP_FRAMECHANGED); + } + else + { + RECT rc_client, rc_wnd; + + SetWindowLongPtr(wfi->hwnd, GWL_STYLE, WS_CAPTION | WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX); + /* Now resize to get full canvas size and room for caption and borders */ + SetWindowPos(wfi->hwnd, HWND_TOP, 10, 10, wfi->width, wfi->height, SWP_FRAMECHANGED); + GetClientRect(wfi->hwnd, &rc_client); + GetWindowRect(wfi->hwnd, &rc_wnd); + wfi->diff.x = (rc_wnd.right - rc_wnd.left) - rc_client.right; + wfi->diff.y = (rc_wnd.bottom - rc_wnd.top) - rc_client.bottom; + SetWindowPos(wfi->hwnd, HWND_TOP, -1, -1, wfi->width + wfi->diff.x, wfi->height + wfi->diff.y, SWP_NOMOVE | SWP_FRAMECHANGED); + } + wf_update_offset(wfi); +} + void wf_toggle_fullscreen(wfInfo* wfi) { ShowWindow(wfi->hwnd, SW_HIDE); wfi->fullscreen = !wfi->fullscreen; + wf_resize_window(wfi); + ShowWindow(wfi->hwnd, SW_SHOW); SetForegroundWindow(wfi->hwnd); } diff --git a/client/Windows/wf_gdi.h b/client/Windows/wf_gdi.h index 470f66193..6aaa27f64 100644 --- a/client/Windows/wf_gdi.h +++ b/client/Windows/wf_gdi.h @@ -27,6 +27,8 @@ void wf_invalidate_region(wfInfo* wfi, int x, int y, int width, int height); wfBitmap* wf_image_new(wfInfo* wfi, int width, int height, int bpp, BYTE* data); void wf_image_free(wfBitmap* image); +void wf_update_offset(wfInfo* wfi); +void wf_resize_window(wfInfo* wfi); void wf_toggle_fullscreen(wfInfo* wfi); void wf_gdi_register_update_callbacks(rdpUpdate* update); diff --git a/client/Windows/wfreerdp.c b/client/Windows/wfreerdp.c index 5e1655518..0c4c839af 100644 --- a/client/Windows/wfreerdp.c +++ b/client/Windows/wfreerdp.c @@ -131,6 +131,27 @@ void wf_sw_end_paint(rdpContext* context) } } +void wf_sw_desktop_resize(rdpContext* context) +{ + wfInfo* wfi; + rdpGdi* gdi; + rdpSettings* settings; + + wfi = ((wfContext*) context)->wfi; + settings = wfi->instance->settings; + gdi = context->gdi; + + wfi->width = settings->DesktopWidth; + wfi->height = settings->DesktopHeight; + gdi_resize(gdi, wfi->width, wfi->height); + + if (wfi->primary) + { + wf_image_free(wfi->primary); + wfi->primary = wf_image_new(wfi, wfi->width, wfi->height, wfi->dstBpp, gdi->primary_buffer); + } +} + void wf_hw_begin_paint(rdpContext* context) { wfInfo* wfi = ((wfContext*) context)->wfi; @@ -143,6 +164,42 @@ void wf_hw_end_paint(rdpContext* context) } +void wf_hw_desktop_resize(rdpContext* context) +{ + wfInfo* wfi; + BOOL same; + RECT rect; + rdpSettings* settings; + + wfi = ((wfContext*) context)->wfi; + settings = wfi->instance->settings; + + wfi->width = settings->DesktopWidth; + wfi->height = settings->DesktopHeight; + if (wfi->primary) + { + same = (wfi->primary == wfi->drawing) ? TRUE : FALSE; + + wf_image_free(wfi->primary); + + wfi->primary = wf_image_new(wfi, wfi->width, wfi->height, wfi->dstBpp, NULL); + + if (same) + wfi->drawing = wfi->primary; + } + if (wfi->fullscreen != TRUE) + { + if (wfi->hwnd) + SetWindowPos(wfi->hwnd, HWND_TOP, -1, -1, wfi->width + wfi->diff.x, wfi->height + wfi->diff.y, SWP_NOMOVE); + } + else + { + wf_update_offset(wfi); + GetWindowRect(wfi->hwnd, &rect); + InvalidateRect(wfi->hwnd, &rect, TRUE); + } +} + BOOL wf_pre_connect(freerdp* instance) { int i1; @@ -289,7 +346,6 @@ BOOL wf_post_connect(freerdp* instance) wfInfo* wfi; rdpCache* cache; wfContext* context; - int width, height; wchar_t win_title[64]; rdpSettings* settings; @@ -299,15 +355,15 @@ BOOL wf_post_connect(freerdp* instance) wfi = context->wfi; wfi->dstBpp = 32; - width = settings->DesktopWidth; - height = settings->DesktopHeight; + wfi->width = settings->DesktopWidth; + wfi->height = settings->DesktopHeight; if (wfi->sw_gdi) { gdi_init(instance, CLRCONV_ALPHA | CLRCONV_INVERT | CLRBUF_32BPP, NULL); gdi = instance->context->gdi; wfi->hdc = gdi->primary->hdc; - wfi->primary = wf_image_new(wfi, width, height, wfi->dstBpp, gdi->primary_buffer); + wfi->primary = wf_image_new(wfi, wfi->width, wfi->height, wfi->dstBpp, gdi->primary_buffer); rfx_context_set_cpu_opt((RFX_CONTEXT*) gdi->rfx_context, wfi_detect_cpu()); } @@ -315,7 +371,7 @@ BOOL wf_post_connect(freerdp* instance) { wf_gdi_register_update_callbacks(instance->update); wfi->srcBpp = instance->settings->ColorDepth; - wfi->primary = wf_image_new(wfi, width, height, wfi->dstBpp, NULL); + wfi->primary = wf_image_new(wfi, wfi->width, wfi->height, wfi->dstBpp, NULL); wfi->hdc = gdi_GetDC(); wfi->hdc->bitsPerPixel = wfi->dstBpp; @@ -358,27 +414,9 @@ BOOL wf_post_connect(freerdp* instance) SetWindowLongPtr(wfi->hwnd, GWLP_USERDATA, (LONG_PTR) wfi); } - if (wfi->fullscreen) - { - SetWindowLongPtr(wfi->hwnd, GWL_STYLE, WS_POPUP); - SetWindowPos(wfi->hwnd, HWND_TOP, 0, 0, width, height, SWP_FRAMECHANGED); - } - else - { - POINT diff; - RECT rc_client, rc_wnd; + wf_resize_window(wfi); - SetWindowLongPtr(wfi->hwnd, GWL_STYLE, WS_CAPTION | WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX); - /* Now resize to get full canvas size and room for caption and borders */ - SetWindowPos(wfi->hwnd, HWND_TOP, 10, 10, width, height, SWP_FRAMECHANGED); - GetClientRect(wfi->hwnd, &rc_client); - GetWindowRect(wfi->hwnd, &rc_wnd); - diff.x = (rc_wnd.right - rc_wnd.left) - rc_client.right; - diff.y = (rc_wnd.bottom - rc_wnd.top) - rc_client.bottom; - SetWindowPos(wfi->hwnd, HWND_TOP, -1, -1, width + diff.x, height + diff.y, SWP_NOMOVE | SWP_FRAMECHANGED); - } - - BitBlt(wfi->primary->hdc, 0, 0, width, height, NULL, 0, 0, BLACKNESS); + BitBlt(wfi->primary->hdc, 0, 0, wfi->width, wfi->height, NULL, 0, 0, BLACKNESS); wfi->drawing = wfi->primary; ShowWindow(wfi->hwnd, SW_SHOWNORMAL); @@ -388,11 +426,13 @@ BOOL wf_post_connect(freerdp* instance) { instance->update->BeginPaint = wf_sw_begin_paint; instance->update->EndPaint = wf_sw_end_paint; + instance->update->DesktopResize = wf_sw_desktop_resize; } else { instance->update->BeginPaint = wf_hw_begin_paint; instance->update->EndPaint = wf_hw_end_paint; + instance->update->DesktopResize = wf_hw_desktop_resize; } pointer_cache_register_callbacks(instance->update); @@ -729,7 +769,7 @@ INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine wnd_cls.cbWndExtra = 0; wnd_cls.hIcon = LoadIcon(NULL, IDI_APPLICATION); wnd_cls.hCursor = g_default_cursor; - wnd_cls.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); + wnd_cls.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH); wnd_cls.lpszMenuName = NULL; wnd_cls.lpszClassName = g_wnd_class_name; wnd_cls.hInstance = hInstance; diff --git a/client/Windows/wfreerdp.h b/client/Windows/wfreerdp.h index 170eab97b..8ff88ba49 100644 --- a/client/Windows/wfreerdp.h +++ b/client/Windows/wfreerdp.h @@ -66,12 +66,17 @@ typedef struct wf_context wfContext; struct wf_info { + int width; + int height; + int offset_x; + int offset_y; int fs_toggle; int fullscreen; int percentscreen; char window_title[64]; HWND hwnd; + POINT diff; HGDI_DC hdc; UINT16 srcBpp; UINT16 dstBpp;