wfreerdp: support DesktopResize and fullscreen toggling.

This commit is contained in:
Vic Lee 2012-12-25 12:10:24 +08:00
parent 48c0c4b090
commit ccdcd8b604
5 changed files with 131 additions and 38 deletions

View File

@ -29,6 +29,7 @@
#include "wfreerdp.h" #include "wfreerdp.h"
#include "wf_gdi.h"
#include "wf_event.h" #include "wf_event.h"
static HWND g_focus_hWnd; 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 */ (GetAsyncKeyState(VK_MENU) & 0x8000)) /* could also use flags & LLKHF_ALTDOWN */
{ {
if (wParam == WM_KEYDOWN) if (wParam == WM_KEYDOWN)
//wf_toggle_fullscreen(wfi); {
return 1; wf_toggle_fullscreen(wfi);
return 1;
}
} }
if (rdp_scancode == RDP_SCANCODE_NUMLOCK_EXTENDED) 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); //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); EndPaint(hWnd, &ps);
break; break;
case WM_LBUTTONDOWN: 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; break;
case WM_LBUTTONUP: 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; break;
case WM_RBUTTONDOWN: 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; break;
case WM_RBUTTONUP: 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; break;
case WM_MOUSEMOVE: 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; break;
case WM_MOUSEWHEEL: case WM_MOUSEWHEEL:

View 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) void wf_invalidate_region(wfInfo* wfi, int x, int y, int width, int height)
{ {
wfi->update_rect.left = x; wfi->update_rect.left = x + wfi->offset_x;
wfi->update_rect.top = y; wfi->update_rect.top = y + wfi->offset_y;
wfi->update_rect.right = x + width; wfi->update_rect.right = wfi->update_rect.left + width;
wfi->update_rect.bottom = y + height; wfi->update_rect.bottom = wfi->update_rect.top + height;
InvalidateRect(wfi->hwnd, &(wfi->update_rect), FALSE); InvalidateRect(wfi->hwnd, &(wfi->update_rect), FALSE);
gdi_InvalidateRegion(wfi->hdc, x, y, width, height); 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) void wf_toggle_fullscreen(wfInfo* wfi)
{ {
ShowWindow(wfi->hwnd, SW_HIDE); ShowWindow(wfi->hwnd, SW_HIDE);
wfi->fullscreen = !wfi->fullscreen; wfi->fullscreen = !wfi->fullscreen;
wf_resize_window(wfi);
ShowWindow(wfi->hwnd, SW_SHOW);
SetForegroundWindow(wfi->hwnd); SetForegroundWindow(wfi->hwnd);
} }

View File

@ -27,6 +27,8 @@
void wf_invalidate_region(wfInfo* wfi, int x, int y, int width, int height); 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); wfBitmap* wf_image_new(wfInfo* wfi, int width, int height, int bpp, BYTE* data);
void wf_image_free(wfBitmap* image); 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_toggle_fullscreen(wfInfo* wfi);
void wf_gdi_register_update_callbacks(rdpUpdate* update); void wf_gdi_register_update_callbacks(rdpUpdate* update);

View 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) void wf_hw_begin_paint(rdpContext* context)
{ {
wfInfo* wfi = ((wfContext*) context)->wfi; 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) BOOL wf_pre_connect(freerdp* instance)
{ {
int i1; int i1;
@ -289,7 +346,6 @@ BOOL wf_post_connect(freerdp* instance)
wfInfo* wfi; wfInfo* wfi;
rdpCache* cache; rdpCache* cache;
wfContext* context; wfContext* context;
int width, height;
wchar_t win_title[64]; wchar_t win_title[64];
rdpSettings* settings; rdpSettings* settings;
@ -299,15 +355,15 @@ BOOL wf_post_connect(freerdp* instance)
wfi = context->wfi; wfi = context->wfi;
wfi->dstBpp = 32; wfi->dstBpp = 32;
width = settings->DesktopWidth; wfi->width = settings->DesktopWidth;
height = settings->DesktopHeight; wfi->height = settings->DesktopHeight;
if (wfi->sw_gdi) if (wfi->sw_gdi)
{ {
gdi_init(instance, CLRCONV_ALPHA | CLRCONV_INVERT | CLRBUF_32BPP, NULL); gdi_init(instance, CLRCONV_ALPHA | CLRCONV_INVERT | CLRBUF_32BPP, NULL);
gdi = instance->context->gdi; gdi = instance->context->gdi;
wfi->hdc = gdi->primary->hdc; 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()); 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); wf_gdi_register_update_callbacks(instance->update);
wfi->srcBpp = instance->settings->ColorDepth; 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 = gdi_GetDC();
wfi->hdc->bitsPerPixel = wfi->dstBpp; wfi->hdc->bitsPerPixel = wfi->dstBpp;
@ -358,27 +414,9 @@ BOOL wf_post_connect(freerdp* instance)
SetWindowLongPtr(wfi->hwnd, GWLP_USERDATA, (LONG_PTR) wfi); SetWindowLongPtr(wfi->hwnd, GWLP_USERDATA, (LONG_PTR) wfi);
} }
if (wfi->fullscreen) wf_resize_window(wfi);
{
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); BitBlt(wfi->primary->hdc, 0, 0, wfi->width, wfi->height, NULL, 0, 0, BLACKNESS);
/* 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);
wfi->drawing = wfi->primary; wfi->drawing = wfi->primary;
ShowWindow(wfi->hwnd, SW_SHOWNORMAL); ShowWindow(wfi->hwnd, SW_SHOWNORMAL);
@ -388,11 +426,13 @@ BOOL wf_post_connect(freerdp* instance)
{ {
instance->update->BeginPaint = wf_sw_begin_paint; instance->update->BeginPaint = wf_sw_begin_paint;
instance->update->EndPaint = wf_sw_end_paint; instance->update->EndPaint = wf_sw_end_paint;
instance->update->DesktopResize = wf_sw_desktop_resize;
} }
else else
{ {
instance->update->BeginPaint = wf_hw_begin_paint; instance->update->BeginPaint = wf_hw_begin_paint;
instance->update->EndPaint = wf_hw_end_paint; instance->update->EndPaint = wf_hw_end_paint;
instance->update->DesktopResize = wf_hw_desktop_resize;
} }
pointer_cache_register_callbacks(instance->update); 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.cbWndExtra = 0;
wnd_cls.hIcon = LoadIcon(NULL, IDI_APPLICATION); wnd_cls.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wnd_cls.hCursor = g_default_cursor; 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.lpszMenuName = NULL;
wnd_cls.lpszClassName = g_wnd_class_name; wnd_cls.lpszClassName = g_wnd_class_name;
wnd_cls.hInstance = hInstance; wnd_cls.hInstance = hInstance;

View File

@ -66,12 +66,17 @@ typedef struct wf_context wfContext;
struct wf_info struct wf_info
{ {
int width;
int height;
int offset_x;
int offset_y;
int fs_toggle; int fs_toggle;
int fullscreen; int fullscreen;
int percentscreen; int percentscreen;
char window_title[64]; char window_title[64];
HWND hwnd; HWND hwnd;
POINT diff;
HGDI_DC hdc; HGDI_DC hdc;
UINT16 srcBpp; UINT16 srcBpp;
UINT16 dstBpp; UINT16 dstBpp;