wfreerdp: support DesktopResize and fullscreen toggling.
authorVic Lee <llyzs@163.com>
Tue, 25 Dec 2012 04:10:24 +0000 (12:10 +0800)
committerVic Lee <llyzs@163.com>
Tue, 25 Dec 2012 04:10:24 +0000 (12:10 +0800)
client/Windows/wf_event.c
client/Windows/wf_gdi.c
client/Windows/wf_gdi.h
client/Windows/wfreerdp.c
client/Windows/wfreerdp.h

index d12b972..b837d19 100644 (file)
@@ -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, xy, 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:
index c702ffd..7c1d988 100644 (file)
@@ -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);
 }
 
index 470f661..6aaa27f 100644 (file)
@@ -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);
index 5e16555..0c4c839 100644 (file)
@@ -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;
-
-               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);
-       }
+       wf_resize_window(wfi);
 
-       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;
index 170eab9..8ff88ba 100644 (file)
@@ -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;