From 6a9fa3dcbd4fcc28611e560963c406daffaf1bf9 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 16 Nov 2018 10:33:29 +0100 Subject: [PATCH] Refactored floatbar, extended command line settings. --- client/Windows/wf_client.c | 14 +- client/Windows/wf_client.h | 3 +- client/Windows/wf_event.c | 27 +- client/Windows/wf_floatbar.c | 685 +++++++++++++++++++++++++++---------------- client/Windows/wf_floatbar.h | 11 +- client/Windows/wf_gdi.c | 13 +- client/common/cmdline.c | 20 +- libfreerdp/core/settings.c | 1 - 8 files changed, 468 insertions(+), 306 deletions(-) diff --git a/client/Windows/wf_client.c b/client/Windows/wf_client.c index f92a8e1..33be84a 100644 --- a/client/Windows/wf_client.c +++ b/client/Windows/wf_client.c @@ -193,10 +193,7 @@ static BOOL wf_pre_connect(freerdp* instance) settings->OsMajorType = OSMAJORTYPE_WINDOWS; settings->OsMinorType = OSMINORTYPE_WINDOWS_NT; wfc->fullscreen = settings->Fullscreen; - wfc->floatbar_active = settings->Floatbar; - wfc->fullscreen_toggle = settings->ToggleFullscreen; - desktopWidth = settings->DesktopWidth; desktopHeight = settings->DesktopHeight; @@ -260,12 +257,12 @@ static void wf_add_system_menu(wfContext* wfc) { HMENU hMenu; MENUITEMINFO item_info; - + if (wfc->fullscreen && !wfc->fullscreen_toggle) { return; } - + hMenu = GetSystemMenu(wfc->hwnd, FALSE); ZeroMemory(&item_info, sizeof(MENUITEMINFO)); item_info.fMask = MIIM_CHECKMARKS | MIIM_FTYPE | MIIM_ID | MIIM_STRING | @@ -312,7 +309,8 @@ static BOOL wf_post_connect(freerdp* instance) } if (settings->WindowTitle != NULL) - _snwprintf_s(wfc->window_title, ARRAYSIZE(wfc->window_title), _TRUNCATE, L"%S", settings->WindowTitle); + _snwprintf_s(wfc->window_title, ARRAYSIZE(wfc->window_title), _TRUNCATE, L"%S", + settings->WindowTitle); else if (settings->ServerPort == 3389) _snwprintf_s(wfc->window_title, ARRAYSIZE(wfc->window_title), _TRUNCATE, L"FreeRDP: %S", settings->ServerHostname); @@ -366,9 +364,7 @@ static BOOL wf_post_connect(freerdp* instance) palette_cache_register_callbacks(instance->update); } - if (wfc->fullscreen) - floatbar_window_create(wfc); - + wfc->floatbar = wf_floatbar_new(wfc, wfc->hInstance, settings->Floatbar); return TRUE; } diff --git a/client/Windows/wf_client.h b/client/Windows/wf_client.h index 61eb95e..e683eb4 100644 --- a/client/Windows/wf_client.h +++ b/client/Windows/wf_client.h @@ -80,7 +80,6 @@ struct wf_context int offset_y; int fullscreen_toggle; int fullscreen; - int floatbar_active; int percentscreen; WCHAR window_title[512]; int client_x; @@ -129,7 +128,7 @@ struct wf_context void* clipboard; CliprdrClientContext* cliprdr; - FloatBar* floatbar; + wfFloatBar* floatbar; RailClientContext* rail; wHashTable* railWindows; diff --git a/client/Windows/wf_event.c b/client/Windows/wf_event.c index bf8ce0f..a4a2063 100644 --- a/client/Windows/wf_event.c +++ b/client/Windows/wf_event.c @@ -212,8 +212,8 @@ static BOOL wf_event_process_WM_MOUSEWHEEL(wfContext* wfc, HWND hWnd, UINT Msg, flags |= PTR_FLAGS_WHEEL_NEGATIVE; delta = -delta; } - flags |= delta; + flags |= delta; return wf_scale_mouse_event(wfc, input, flags, x, y); } @@ -359,16 +359,16 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, y - wfc->offset_y + wfc->yCurrentScroll, SRCCOPY); EndPaint(hWnd, &ps); break; - #if (_WIN32_WINNT >= 0x0500) + case WM_XBUTTONDOWN: wf_scale_mouse_event_ex(wfc, input, PTR_XFLAGS_DOWN, GET_XBUTTON_WPARAM(wParam), - X_POS(lParam) - wfc->offset_x, Y_POS(lParam) - wfc->offset_y); + X_POS(lParam) - wfc->offset_x, Y_POS(lParam) - wfc->offset_y); break; case WM_XBUTTONUP: wf_scale_mouse_event_ex(wfc, input, 0, GET_XBUTTON_WPARAM(wParam), - X_POS(lParam) - wfc->offset_x, Y_POS(lParam) - wfc->offset_y); + X_POS(lParam) - wfc->offset_x, Y_POS(lParam) - wfc->offset_y); break; #endif @@ -406,20 +406,20 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, wf_scale_mouse_event(wfc, input, PTR_FLAGS_MOVE, X_POS(lParam) - wfc->offset_x, Y_POS(lParam) - wfc->offset_y); break; - #if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400) + case WM_MOUSEWHEEL: wf_event_process_WM_MOUSEWHEEL(wfc, hWnd, Msg, wParam, lParam, FALSE, - X_POS(lParam) - wfc->offset_x, - Y_POS(lParam) - wfc->offset_y); + X_POS(lParam) - wfc->offset_x, + Y_POS(lParam) - wfc->offset_y); break; #endif - #if (_WIN32_WINNT >= 0x0600) + case WM_MOUSEHWHEEL: wf_event_process_WM_MOUSEWHEEL(wfc, hWnd, Msg, wParam, lParam, TRUE, - X_POS(lParam) - wfc->offset_x, - Y_POS(lParam) - wfc->offset_y); + X_POS(lParam) - wfc->offset_x, + Y_POS(lParam) - wfc->offset_y); break; #endif @@ -701,11 +701,12 @@ static BOOL wf_scale_mouse_pos(wfContext* wfc, UINT16* x, UINT16* y) int ww, wh, dw, dh; rdpContext* context; rdpSettings* settings; - + if (!wfc || !x || !y) return FALSE; settings = wfc->context.settings; + if (!settings) return FALSE; @@ -753,13 +754,15 @@ static BOOL wf_scale_mouse_event(wfContext* wfc, rdpInput* input, UINT16 flags, } #if(_WIN32_WINNT >= 0x0500) -static BOOL wf_scale_mouse_event_ex(wfContext* wfc, rdpInput* input, UINT16 flags, UINT16 buttonMask, +static BOOL wf_scale_mouse_event_ex(wfContext* wfc, rdpInput* input, UINT16 flags, + UINT16 buttonMask, UINT16 x, UINT16 y) { MouseEventExEventArgs eventArgs; if (buttonMask & XBUTTON1) flags |= PTR_XFLAGS_BUTTON1; + if (buttonMask & XBUTTON2) flags |= PTR_XFLAGS_BUTTON2; diff --git a/client/Windows/wf_floatbar.c b/client/Windows/wf_floatbar.c index 9c8f393..fc1d4ac 100644 --- a/client/Windows/wf_floatbar.c +++ b/client/Windows/wf_floatbar.c @@ -27,6 +27,8 @@ #include "wf_gdi.h" #pragma comment( lib, "Msimg32.lib" ) +#define TAG CLIENT_TAG("windows.floatbar") + typedef struct _Button Button; /* TIMERs */ @@ -44,7 +46,7 @@ typedef struct _Button Button; /* bmp size */ #define BACKGROUND_W 576 #define BACKGROUND_H 27 -#define BUTTON_OFFSET 5 +#define BUTTON_OFFSET 5 #define BUTTON_Y 2 #define BUTTON_WIDTH 23 #define BUTTON_HEIGHT 21 @@ -56,8 +58,9 @@ typedef struct _Button Button; #define MINIMIZE_X ( RESTORE_X - ( BUTTON_WIDTH + BUTTON_SPACING ) ) #define TEXT_X ( BACKGROUND_H + ( ( BUTTON_WIDTH + BUTTON_SPACING ) * 3 ) + 5 ) -struct _Button { - FloatBar* floatbar; +struct _Button +{ + wfFloatBar* floatbar; int type; int x, y, h, w; int active; @@ -71,41 +74,175 @@ struct _Button { HBITMAP unlocked_bmp_act; }; -struct _FloatBar { +struct _FloatBar +{ + HINSTANCE root_window; + DWORD flags; HWND parent; HWND hwnd; RECT rect; LONG width; LONG height; + LONG offset; wfContext* wfc; Button* buttons[BTN_MAX]; BOOL shown; BOOL locked; HDC hdcmem; - RECT textRect; + RECT textRect; + UINT_PTR animating; }; -static int button_hit(Button * const button) +static BOOL floatbar_kill_timers(wfFloatBar* floatbar) +{ + size_t x; + UINT_PTR timers[] = + { + TIMER_HIDE, + TIMER_ANIMAT_HIDE, + TIMER_ANIMAT_SHOW + }; + + if (!floatbar) + return FALSE; + + for (x = 0; x < ARRAYSIZE(timers); x++) + KillTimer(floatbar->hwnd, timers[x]); + + floatbar->animating = 0; + return TRUE; +} + +static BOOL floatbar_animation(wfFloatBar* const floatbar, const BOOL show) +{ + UINT_PTR timer = show ? TIMER_ANIMAT_SHOW : TIMER_ANIMAT_HIDE; + + if (!floatbar) + return FALSE; + + if (floatbar->shown == show) + return TRUE; + + if (floatbar->animating == timer) + return TRUE; + + floatbar->animating = timer; + + if (SetTimer(floatbar->hwnd, timer, 10, NULL) == NULL) + { + DWORD err = GetLastError(); + WLog_ERR(TAG, "SetTimer failed with %08"PRIx32, err); + return FALSE; + } + + return TRUE; +} + +static BOOL floatbar_trigger_hide(wfFloatBar* floatbar) +{ + if (!floatbar_kill_timers(floatbar)) + return FALSE; + + if (!floatbar->locked && floatbar->shown) + { + if (SetTimer(floatbar->hwnd, TIMER_HIDE, 3000, NULL) == NULL) + { + DWORD err = GetLastError(); + WLog_ERR(TAG, "SetTimer failed with %08"PRIx32, err); + return FALSE; + } + } + + return TRUE; +} + +static BOOL floatbar_hide(wfFloatBar* floatbar) +{ + if (!floatbar_kill_timers(floatbar)) + return FALSE; + + floatbar->offset = floatbar->height - 2; + + if (!MoveWindow(floatbar->hwnd, floatbar->rect.left, -floatbar->offset, + floatbar->width, floatbar->height, TRUE)) + { + DWORD err = GetLastError(); + WLog_ERR(TAG, "MoveWindow failed with %08"PRIx32, err); + return FALSE; + } + + floatbar->shown = FALSE; + + if (!floatbar_trigger_hide(floatbar)) + return FALSE; + + return TRUE; +} + +static BOOL floatbar_show(wfFloatBar* floatbar) +{ + if (!floatbar_kill_timers(floatbar)) + return FALSE; + + floatbar->offset = 0; + + if (!MoveWindow(floatbar->hwnd, floatbar->rect.left, -floatbar->offset, + floatbar->width, floatbar->height, TRUE)) + { + DWORD err = GetLastError(); + WLog_ERR(TAG, "MoveWindow failed with %08"PRIx32, err); + return FALSE; + } + + floatbar->shown = TRUE; + + if (!floatbar_trigger_hide(floatbar)) + return FALSE; + + return TRUE; +} + +static BOOL button_set_locked(Button* button, BOOL locked) +{ + if (locked) + { + button->bmp = button->locked_bmp; + button->bmp_act = button->locked_bmp_act; + } + else + { + button->bmp = button->unlocked_bmp; + button->bmp_act = button->unlocked_bmp_act; + } + + InvalidateRect(button->floatbar->hwnd, NULL, FALSE); + UpdateWindow(button->floatbar->hwnd); +} + +static BOOL update_locked_state(wfFloatBar* floatbar) { - FloatBar* const floatbar = button->floatbar; + Button* button; + + if (!floatbar) + return FALSE; + + button = floatbar->buttons[3]; + + if (!button_set_locked(button, floatbar->locked)) + return FALSE; + + return TRUE; +} + +static int button_hit(Button* const button) +{ + wfFloatBar* const floatbar = button->floatbar; switch (button->type) { case BUTTON_LOCKPIN: - if (!floatbar->locked) - { - button->bmp = button->locked_bmp; - button->bmp_act = button->locked_bmp_act; - } - else - { - button->bmp = button->unlocked_bmp; - button->bmp_act = button->unlocked_bmp_act; - } - - floatbar->locked = ~floatbar->locked; - InvalidateRect(button->floatbar->hwnd, NULL, FALSE); - UpdateWindow(button->floatbar->hwnd); + floatbar->locked = !floatbar->locked; + update_locked_state(floatbar); break; case BUTTON_MINIMIZE: @@ -117,7 +254,7 @@ static int button_hit(Button * const button) break; case BUTTON_CLOSE: - SendMessage(floatbar->parent, WM_DESTROY, 0 , 0); + SendMessage(floatbar->parent, WM_DESTROY, 0, 0); break; default: @@ -127,31 +264,28 @@ static int button_hit(Button * const button) return 0; } -static int button_paint( const Button * const button, const HDC hdc) +static int button_paint(const Button* const button, const HDC hdc) { - if (button != NULL) - { - FloatBar* floatbar = button->floatbar; - - SelectObject( floatbar->hdcmem, button->active ? button->bmp_act : button->bmp ); - - BLENDFUNCTION bf; - bf.BlendOp = AC_SRC_OVER; - bf.BlendFlags = 0; - bf.SourceConstantAlpha = 255; - bf.AlphaFormat = AC_SRC_ALPHA; - - AlphaBlend( hdc, button->x, button->y, button->w, button->h, floatbar->hdcmem, 0, 0, button->w, button->h, bf ); - } + if (button != NULL) + { + wfFloatBar* floatbar = button->floatbar; + BLENDFUNCTION bf; + SelectObject(floatbar->hdcmem, button->active ? button->bmp_act : button->bmp); + bf.BlendOp = AC_SRC_OVER; + bf.BlendFlags = 0; + bf.SourceConstantAlpha = 255; + bf.AlphaFormat = AC_SRC_ALPHA; + AlphaBlend(hdc, button->x, button->y, button->w, button->h, floatbar->hdcmem, 0, 0, button->w, + button->h, bf); + } return 0; } -static Button* floatbar_create_button( FloatBar *const floatbar, const int type, const int resid, const int resid_act, const int x, const int y, const int h, const int w) +static Button* floatbar_create_button(wfFloatBar* const floatbar, const int type, const int resid, + const int resid_act, const int x, const int y, const int h, const int w) { - Button *button; - - button = (Button *)malloc(sizeof(Button)); + Button* button = (Button*) calloc(1, sizeof(Button)); if (!button) return NULL; @@ -163,135 +297,124 @@ static Button* floatbar_create_button( FloatBar *const floatbar, const int type, button->w = w; button->h = h; button->active = FALSE; - - button->bmp = (HBITMAP)LoadImage(floatbar->wfc->hInstance, MAKEINTRESOURCE(resid), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); - button->bmp_act = (HBITMAP)LoadImage(floatbar->wfc->hInstance, MAKEINTRESOURCE(resid_act), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); - + button->bmp = (HBITMAP)LoadImage(floatbar->root_window, MAKEINTRESOURCE(resid), IMAGE_BITMAP, 0, + 0, LR_DEFAULTCOLOR); + button->bmp_act = (HBITMAP)LoadImage(floatbar->root_window, MAKEINTRESOURCE(resid_act), + IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); return button; } -static Button* floatbar_create_lock_button( FloatBar * const floatbar, const int unlock_resid, const int unlock_resid_act, const int lock_resid, const int lock_resid_act, const int x, const int y, const int h, const int w) +static Button* floatbar_create_lock_button(wfFloatBar* const floatbar, const int unlock_resid, + const int unlock_resid_act, const int lock_resid, const int lock_resid_act, const int x, + const int y, const int h, const int w) { - Button* button; - - button = floatbar_create_button(floatbar, BUTTON_LOCKPIN, unlock_resid, unlock_resid_act, x, y, h, w); + Button* button = floatbar_create_button(floatbar, BUTTON_LOCKPIN, unlock_resid, unlock_resid_act, x, + y, h, + w); if (!button) return NULL; button->unlocked_bmp = button->bmp; button->unlocked_bmp_act = button->bmp_act; - button->locked_bmp = (HBITMAP)LoadImage(floatbar->wfc->hInstance, MAKEINTRESOURCE(lock_resid), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); - button->locked_bmp_act = (HBITMAP)LoadImage(floatbar->wfc->hInstance, MAKEINTRESOURCE(lock_resid_act), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); - + button->locked_bmp = (HBITMAP)LoadImage(floatbar->wfc->hInstance, MAKEINTRESOURCE(lock_resid), + IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); + button->locked_bmp_act = (HBITMAP)LoadImage(floatbar->wfc->hInstance, + MAKEINTRESOURCE(lock_resid_act), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); return button; } -static Button* floatbar_get_button( const FloatBar * const floatbar, const int x, const int y) +static Button* floatbar_get_button(const wfFloatBar* const floatbar, const int x, const int y) { int i; - if (y > BUTTON_Y && y < BUTTON_Y + BUTTON_HEIGHT) - { + if ((y > BUTTON_Y) && (y < BUTTON_Y + BUTTON_HEIGHT)) + { for (i = 0; i < BTN_MAX; i++) - { - if (floatbar->buttons[i] != NULL && x > floatbar->buttons[i]->x && x < floatbar->buttons[i]->x + floatbar->buttons[i]->w) - { + { + if ((floatbar->buttons[i] != NULL) && (x > floatbar->buttons[i]->x) && + (x < floatbar->buttons[i]->x + floatbar->buttons[i]->w)) + { return floatbar->buttons[i]; - } - } - } + } + } + } return NULL; } -static int floatbar_paint( FloatBar * const floatbar, const HDC hdc) +static BOOL floatbar_paint(wfFloatBar* const floatbar, const HDC hdc) { int i; - + HPEN hpen; + HGDIOBJECT orig; /* paint background */ - - GRADIENT_RECT gradientRect = { 0, 1 }; - COLORREF rgbTop = RGB( 117, 154, 198 ); - COLORREF rgbBottom = RGB( 6, 55, 120 ); - - const int top = 0; - int left = 0; - int bottom = BACKGROUND_H - 1; - int right = BACKGROUND_W - 1; - const int angleOffset = BACKGROUND_H - 1; - - TRIVERTEX triVertext[2] = { - left, - top, - GetRValue( rgbTop ) << 8, - GetGValue( rgbTop ) << 8, - GetBValue( rgbTop ) << 8, - 0x0000, - right, - bottom, - GetRValue( rgbBottom ) << 8, - GetGValue( rgbBottom ) << 8, - GetBValue( rgbBottom ) << 8, - 0x0000 - }; - - GradientFill( hdc, triVertext, 2, &gradientRect, 1, GRADIENT_FILL_RECT_V ); - - /* paint shadow */ - - HPEN hpen = CreatePen( PS_SOLID, 1, RGB( 71, 71, 71 ) ); - HGDIOBJECT orig = SelectObject( hdc, hpen ); - - MoveToEx( hdc, left, top, NULL ); - LineTo( hdc, left + angleOffset, bottom ); - LineTo( hdc, right - angleOffset, bottom ); - LineTo( hdc, right + 1, top - 1 ); - DeleteObject( hpen ); - - hpen = CreatePen( PS_SOLID, 1, RGB( 107, 141, 184 ) ); - SelectObject( hdc, hpen ); - - left += 1; - bottom -= 1; - right -= 1; - - MoveToEx( hdc, left, top, NULL ); - LineTo( hdc, left + ( angleOffset - 1 ), bottom ); - LineTo( hdc, right - ( angleOffset - 1 ), bottom ); - LineTo( hdc, right + 1, top - 1 ); - DeleteObject( hpen ); - - SelectObject( hdc, orig ); - - DrawText( hdc, floatbar->wfc->window_title, wcslen( floatbar->wfc->window_title ), &floatbar->textRect, DT_CENTER | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX | DT_SINGLELINE ); + GRADIENT_RECT gradientRect = { 0, 1 }; + COLORREF rgbTop = RGB(117, 154, 198); + COLORREF rgbBottom = RGB(6, 55, 120); + const int top = 0; + int left = 0; + int bottom = BACKGROUND_H - 1; + int right = BACKGROUND_W - 1; + const int angleOffset = BACKGROUND_H - 1; + TRIVERTEX triVertext[2] = + { + left, + top, + GetRValue(rgbTop) << 8, + GetGValue(rgbTop) << 8, + GetBValue(rgbTop) << 8, + 0x0000, + right, + bottom, + GetRValue(rgbBottom) << 8, + GetGValue(rgbBottom) << 8, + GetBValue(rgbBottom) << 8, + 0x0000 + }; + + if (!floatbar) + return FALSE; + + GradientFill(hdc, triVertext, 2, &gradientRect, 1, GRADIENT_FILL_RECT_V); + /* paint shadow */ + hpen = CreatePen(PS_SOLID, 1, RGB(71, 71, 71)); + orig = SelectObject(hdc, hpen); + MoveToEx(hdc, left, top, NULL); + LineTo(hdc, left + angleOffset, bottom); + LineTo(hdc, right - angleOffset, bottom); + LineTo(hdc, right + 1, top - 1); + DeleteObject(hpen); + hpen = CreatePen(PS_SOLID, 1, RGB(107, 141, 184)); + SelectObject(hdc, hpen); + left += 1; + bottom -= 1; + right -= 1; + MoveToEx(hdc, left, top, NULL); + LineTo(hdc, left + (angleOffset - 1), bottom); + LineTo(hdc, right - (angleOffset - 1), bottom); + LineTo(hdc, right + 1, top - 1); + DeleteObject(hpen); + SelectObject(hdc, orig); + DrawText(hdc, floatbar->wfc->window_title, wcslen(floatbar->wfc->window_title), &floatbar->textRect, + DT_CENTER | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX | DT_SINGLELINE); /* paint buttons */ for (i = 0; i < BTN_MAX; i++) - { button_paint(floatbar->buttons[i], hdc); - } - - return 0; -} -static int floatbar_animation( FloatBar* const floatbar, const BOOL show) -{ - SetTimer(floatbar->hwnd, show ? TIMER_ANIMAT_SHOW : TIMER_ANIMAT_HIDE, 10, NULL); - floatbar->shown = show; - return 0; + return TRUE; } -LRESULT CALLBACK floatbar_proc(const HWND hWnd, const UINT Msg, const WPARAM wParam, const LPARAM lParam) +static LRESULT CALLBACK floatbar_proc(const HWND hWnd, const UINT Msg, const WPARAM wParam, + const LPARAM lParam) { static int dragging = FALSE; static int lbtn_dwn = FALSE; static int btn_dwn_x = 0; - static wfContext * wfc; - static FloatBar* floatbar; + static wfFloatBar* floatbar; static TRACKMOUSEEVENT tme; - PAINTSTRUCT ps; Button* button; HDC hdc; @@ -300,38 +423,30 @@ LRESULT CALLBACK floatbar_proc(const HWND hWnd, const UINT Msg, const WPARAM wPa NONCLIENTMETRICS ncm; int xScreen = GetSystemMetrics(SM_CXSCREEN); - switch(Msg) + switch (Msg) { case WM_CREATE: - wfc = ( (wfContext *) ( (CREATESTRUCT *) lParam )->lpCreateParams ); - floatbar = wfc->floatbar; + floatbar = ((wfFloatBar*)((CREATESTRUCT*) lParam)->lpCreateParams); floatbar->hwnd = hWnd; - floatbar->parent = GetParent(hWnd); - GetWindowRect(floatbar->hwnd, &floatbar->rect); floatbar->width = floatbar->rect.right - floatbar->rect.left; floatbar->height = floatbar->rect.bottom - floatbar->rect.top; - hdc = GetDC(hWnd); floatbar->hdcmem = CreateCompatibleDC(hdc); ReleaseDC(hWnd, hdc); - tme.cbSize = sizeof(TRACKMOUSEEVENT); tme.dwFlags = TME_LEAVE; tme.hwndTrack = hWnd; tme.dwHoverTime = HOVER_DEFAULT; - - // Use caption font, white, draw transparent - GetClientRect( hWnd, &floatbar->textRect ); - InflateRect( &floatbar->textRect, -TEXT_X, 0 ); - SetBkMode( hdc, TRANSPARENT ); - SetTextColor( hdc, RGB( 255, 255, 255 ) ); - - ncm.cbSize = sizeof( NONCLIENTMETRICS ); - SystemParametersInfo( SPI_GETNONCLIENTMETRICS, sizeof( NONCLIENTMETRICS ), &ncm, 0 ); - SelectObject( hdc, CreateFontIndirect( &ncm.lfCaptionFont ) ); - - SetTimer(hWnd, TIMER_HIDE, 3000, NULL); + // Use caption font, white, draw transparent + GetClientRect(hWnd, &floatbar->textRect); + InflateRect(&floatbar->textRect, -TEXT_X, 0); + SetBkMode(hdc, TRANSPARENT); + SetTextColor(hdc, RGB(255, 255, 255)); + ncm.cbSize = sizeof(NONCLIENTMETRICS); + SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0); + SelectObject(hdc, CreateFontIndirect(&ncm.lfCaptionFont)); + floatbar_trigger_hide(floatbar); break; case WM_PAINT: @@ -343,8 +458,8 @@ LRESULT CALLBACK floatbar_proc(const HWND hWnd, const UINT Msg, const WPARAM wPa case WM_LBUTTONDOWN: pos_x = lParam & 0xffff; pos_y = (lParam >> 16) & 0xffff; - button = floatbar_get_button(floatbar, pos_x, pos_y); + if (!button) { SetCapture(hWnd); @@ -359,25 +474,26 @@ LRESULT CALLBACK floatbar_proc(const HWND hWnd, const UINT Msg, const WPARAM wPa case WM_LBUTTONUP: pos_x = lParam & 0xffff; pos_y = (lParam >> 16) & 0xffff; - ReleaseCapture(); dragging = FALSE; if (lbtn_dwn) { button = floatbar_get_button(floatbar, pos_x, pos_y); + if (button) button_hit(button); + lbtn_dwn = FALSE; } + break; case WM_MOUSEMOVE: - KillTimer(hWnd, TIMER_HIDE); pos_x = lParam & 0xffff; pos_y = (lParam >> 16) & 0xffff; - if (!floatbar->shown) + if (!floatbar->locked) floatbar_animation(floatbar, TRUE); if (dragging) @@ -389,21 +505,22 @@ LRESULT CALLBACK floatbar_proc(const HWND hWnd, const UINT Msg, const WPARAM wPa else if (floatbar->rect.left > xScreen - floatbar->width) floatbar->rect.left = xScreen - floatbar->width; - MoveWindow(hWnd, floatbar->rect.left, floatbar->rect.top, floatbar->width, floatbar->height, TRUE); + MoveWindow(hWnd, floatbar->rect.left, 0, floatbar->width, floatbar->height, TRUE); } else { int i; for (i = 0; i < BTN_MAX; i++) - { - if (floatbar->buttons[i] != NULL) - { - floatbar->buttons[i]->active = FALSE; - } - } + { + if (floatbar->buttons[i] != NULL) + { + floatbar->buttons[i]->active = FALSE; + } + } button = floatbar_get_button(floatbar, pos_x, pos_y); + if (button) button->active = TRUE; @@ -419,60 +536,58 @@ LRESULT CALLBACK floatbar_proc(const HWND hWnd, const UINT Msg, const WPARAM wPa break; case WM_MOUSELEAVE: - { - int i; + { + int i; - for (i = 0; i < BTN_MAX; i++) - { - if (floatbar->buttons[i] != NULL) - { - floatbar->buttons[i]->active = FALSE; - } - } + for (i = 0; i < BTN_MAX; i++) + { + if (floatbar->buttons[i] != NULL) + { + floatbar->buttons[i]->active = FALSE; + } + } - InvalidateRect(hWnd, NULL, FALSE); - UpdateWindow(hWnd); + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + floatbar_trigger_hide(floatbar); + break; + } - SetTimer(hWnd, TIMER_HIDE, 3000, NULL); - break; - } case WM_TIMER: switch (wParam) { case TIMER_HIDE: - { - KillTimer(hWnd, TIMER_HIDE); - if (!floatbar->locked) - floatbar_animation(floatbar, FALSE); + floatbar_animation(floatbar, FALSE); break; - } - case TIMER_ANIMAT_SHOW: - { - static int y = 0; - MoveWindow(floatbar->hwnd, floatbar->rect.left, (y++ - floatbar->height), floatbar->width, floatbar->height, TRUE); - if (y == floatbar->height) + case TIMER_ANIMAT_SHOW: { - y = 0; - KillTimer(hWnd, wParam); + floatbar->offset--; + MoveWindow(floatbar->hwnd, floatbar->rect.left, -floatbar->offset, floatbar->width, + floatbar->height, TRUE); + + if (floatbar->offset <= 0) + floatbar_show(floatbar); + + break; } - break; - } - case TIMER_ANIMAT_HIDE: - { - static int y = 0; - MoveWindow(floatbar->hwnd, floatbar->rect.left, -y++, floatbar->width, floatbar->height, TRUE); - if (y == floatbar->height) + case TIMER_ANIMAT_HIDE: { - y = 0; - KillTimer(hWnd, wParam); + floatbar->offset++; + MoveWindow(floatbar->hwnd, floatbar->rect.left, -floatbar->offset, + floatbar->width, floatbar->height, TRUE); + + if (floatbar->offset >= floatbar->height - 2) + floatbar_hide(floatbar); + + break; } - break; - } + default: break; } + break; case WM_DESTROY: @@ -483,88 +598,45 @@ LRESULT CALLBACK floatbar_proc(const HWND hWnd, const UINT Msg, const WPARAM wPa default: return DefWindowProc(hWnd, Msg, wParam, lParam); } - return 0; -} - -static FloatBar* floatbar_create(wfContext* const wfc) -{ - FloatBar* floatbar; - - floatbar = (FloatBar *)calloc(1, sizeof(FloatBar)); - - if (!floatbar) - return NULL; - - floatbar->locked = FALSE; - floatbar->shown = TRUE; - floatbar->hwnd = NULL; - floatbar->parent = wfc->hwnd; - floatbar->wfc = wfc; - floatbar->hdcmem = NULL; - - if (wfc->fullscreen_toggle) - { - floatbar->buttons[0] = floatbar_create_button( floatbar, BUTTON_MINIMIZE, IDB_MINIMIZE, IDB_MINIMIZE_ACT, MINIMIZE_X, BUTTON_Y, BUTTON_HEIGHT, BUTTON_WIDTH ); - floatbar->buttons[1] = floatbar_create_button( floatbar, BUTTON_RESTORE, IDB_RESTORE, IDB_RESTORE_ACT, RESTORE_X, BUTTON_Y, BUTTON_HEIGHT, BUTTON_WIDTH ); - } - else - { - floatbar->buttons[0] = NULL; - floatbar->buttons[1] = NULL; - } - - floatbar->buttons[2] = floatbar_create_button(floatbar, BUTTON_CLOSE, IDB_CLOSE, IDB_CLOSE_ACT, CLOSE_X, BUTTON_Y, BUTTON_HEIGHT, BUTTON_WIDTH); - floatbar->buttons[3] = floatbar_create_lock_button(floatbar, IDB_UNLOCK, IDB_UNLOCK_ACT, IDB_LOCK, IDB_LOCK_ACT, LOCK_X, BUTTON_Y, BUTTON_HEIGHT, BUTTON_WIDTH); - - return floatbar; -} - -int floatbar_hide(const FloatBar* const floatbar) -{ - KillTimer(floatbar->hwnd, TIMER_HIDE); - MoveWindow(floatbar->hwnd, floatbar->rect.left, -floatbar->height, - floatbar->width, floatbar->height, TRUE); - return 0; -} -int floatbar_show(const FloatBar* const floatbar) -{ - SetTimer(floatbar->hwnd, TIMER_HIDE, 3000, NULL); - MoveWindow(floatbar->hwnd, floatbar->rect.left, floatbar->rect.top, - floatbar->width, floatbar->height, TRUE); return 0; } -void floatbar_window_create( wfContext * const wfc ) +static BOOL floatbar_window_create(wfFloatBar* floatbar) { WNDCLASSEX wnd_cls; HWND barWnd; HRGN hRgn; POINT pt[4]; - int x = (GetSystemMetrics(SM_CXSCREEN) - BACKGROUND_W) / 2; + RECT rect; + LONG x; + + if (!floatbar) + return FALSE; + + if (!GetWindowRect(floatbar->parent, &rect)) + return FALSE; + x = (rect.right - rect.left - BACKGROUND_W) / 2; wnd_cls.cbSize = sizeof(WNDCLASSEX); wnd_cls.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wnd_cls.lpfnWndProc = floatbar_proc; wnd_cls.cbClsExtra = 0; wnd_cls.cbWndExtra = 0; wnd_cls.hIcon = LoadIcon(NULL, IDI_APPLICATION); - wnd_cls.hCursor = LoadCursor(wfc->hInstance, IDC_ARROW); + wnd_cls.hCursor = LoadCursor(floatbar->root_window, IDC_ARROW); wnd_cls.hbrBackground = NULL; wnd_cls.lpszMenuName = NULL; wnd_cls.lpszClassName = L"floatbar"; - wnd_cls.hInstance = wfc->hInstance; + wnd_cls.hInstance = floatbar->root_window; wnd_cls.hIconSm = LoadIcon(NULL, IDI_APPLICATION); - RegisterClassEx(&wnd_cls); - - wfc->floatbar = floatbar_create(wfc); - barWnd = CreateWindowEx(WS_EX_TOPMOST, L"floatbar", L"floatbar", WS_CHILD, x, 0, - BACKGROUND_W, BACKGROUND_H, wfc->hwnd, NULL, wfc->hInstance, wfc ); + BACKGROUND_W, BACKGROUND_H, floatbar->parent, NULL, + floatbar->root_window, floatbar); if (barWnd == NULL) - return; + return FALSE; pt[0].x = 0; pt[0].y = 0; @@ -574,9 +646,102 @@ void floatbar_window_create( wfContext * const wfc ) pt[2].y = BACKGROUND_H; pt[3].x = BACKGROUND_H; pt[3].y = BACKGROUND_H; + hRgn = CreatePolygonRgn(pt, 4, ALTERNATE); + SetWindowRgn(barWnd, hRgn, TRUE); + return TRUE; +} + +void wf_floatbar_free(wfFloatBar* floatbar) +{ + if (!floatbar) + return; + + free(floatbar); +} + +wfFloatBar* wf_floatbar_new(wfContext* wfc, HINSTANCE window, DWORD flags) +{ + wfFloatBar* floatbar; + + /* Floatbar not enabled */ + if ((flags & 0x0001) == 0) + return NULL; + + if (!wfc) + return NULL; + + // TODO: Disable for remote app + floatbar = (wfFloatBar*) calloc(1, sizeof(wfFloatBar)); + + if (!floatbar) + return NULL; - hRgn = CreatePolygonRgn( pt, 4, ALTERNATE ); - SetWindowRgn( barWnd, hRgn, TRUE ); + floatbar->root_window = window; + floatbar->flags = flags; + floatbar->wfc = wfc; + floatbar->locked = (flags & 0x0002) != 0; + floatbar->shown = (flags & 0x0006) != 0; /* If it is loked or shown show it */ + floatbar->hwnd = NULL; + floatbar->parent = wfc->hwnd; + floatbar->hdcmem = NULL; + + if (wfc->fullscreen_toggle) + { + floatbar->buttons[0] = floatbar_create_button(floatbar, BUTTON_MINIMIZE, IDB_MINIMIZE, + IDB_MINIMIZE_ACT, MINIMIZE_X, BUTTON_Y, BUTTON_HEIGHT, BUTTON_WIDTH); + floatbar->buttons[1] = floatbar_create_button(floatbar, BUTTON_RESTORE, IDB_RESTORE, + IDB_RESTORE_ACT, RESTORE_X, BUTTON_Y, BUTTON_HEIGHT, BUTTON_WIDTH); + } + else + { + floatbar->buttons[0] = NULL; + floatbar->buttons[1] = NULL; + } + + floatbar->buttons[2] = floatbar_create_button(floatbar, BUTTON_CLOSE, IDB_CLOSE, IDB_CLOSE_ACT, + CLOSE_X, BUTTON_Y, BUTTON_HEIGHT, BUTTON_WIDTH); + floatbar->buttons[3] = floatbar_create_lock_button(floatbar, IDB_UNLOCK, IDB_UNLOCK_ACT, IDB_LOCK, + IDB_LOCK_ACT, LOCK_X, BUTTON_Y, BUTTON_HEIGHT, BUTTON_WIDTH); + + if (!floatbar_window_create(floatbar)) + goto fail; + + if (!update_locked_state(floatbar)) + goto fail; + + if (!wf_floatbar_toggle_fullscreen(floatbar, wfc->context.settings->Fullscreen)) + goto fail; + + return floatbar; +fail: + wf_floatbar_free(floatbar); + return NULL; +} + +BOOL wf_floatbar_toggle_fullscreen(wfFloatBar* floatbar, BOOL fullscreen) +{ + BOOL show_fs, show_wn; + + if (!floatbar) + return FALSE; + + show_fs = (floatbar->flags & 0x0010) != 0; + show_wn = (floatbar->flags & 0x0020) != 0; + + if ((show_fs && fullscreen) || (show_wn && !fullscreen)) + { + ShowWindow(floatbar->hwnd, SW_SHOWNORMAL); + Sleep(10); + + if (floatbar->shown) + floatbar_show(floatbar); + else + floatbar_hide(floatbar); + } + else + { + ShowWindow(floatbar->hwnd, SW_HIDE); + } - ShowWindow(barWnd, SW_SHOWNORMAL); + return TRUE; } diff --git a/client/Windows/wf_floatbar.h b/client/Windows/wf_floatbar.h index d562d2f..2636aba 100644 --- a/client/Windows/wf_floatbar.h +++ b/client/Windows/wf_floatbar.h @@ -20,11 +20,14 @@ #ifndef FREERDP_CLIENT_WIN_FLOATBAR_H #define FREERDP_CLIENT_WIN_FLOATBAR_H -typedef struct _FloatBar FloatBar; +#include + +typedef struct _FloatBar wfFloatBar; typedef struct wf_context wfContext; -void floatbar_window_create(wfContext* const wfc); -int floatbar_show(const FloatBar* const floatbar); -int floatbar_hide(const FloatBar* const floatbar); +wfFloatBar* wf_floatbar_new(wfContext* wfc, HINSTANCE window, DWORD flags); +void wf_floatbar_free(wfFloatBar* floatbar); + +BOOL wf_floatbar_toggle_fullscreen(wfFloatBar* floatbar, BOOL fullscreen); #endif /* FREERDP_CLIENT_WIN_FLOATBAR_H */ diff --git a/client/Windows/wf_gdi.c b/client/Windows/wf_gdi.c index 2306575..96dbd0e 100644 --- a/client/Windows/wf_gdi.c +++ b/client/Windows/wf_gdi.c @@ -103,7 +103,7 @@ static BOOL wf_decode_color(wfContext* wfc, const UINT32 srcColor, } *color = FreeRDPConvertColor(srcColor, SrcFormat, - DstFormat, &gdi->palette); + DstFormat, &gdi->palette); return TRUE; } @@ -351,6 +351,7 @@ void wf_resize_window(wfContext* wfc) else if (!wfc->context.settings->Decorations) { SetWindowLongPtr(wfc->hwnd, GWL_STYLE, WS_CHILD); + if (settings->EmbeddedWindow) { wf_update_canvas_diff(wfc); @@ -359,10 +360,10 @@ void wf_resize_window(wfContext* wfc) { /* Now resize to get full canvas size and room for caption and borders */ SetWindowPos(wfc->hwnd, HWND_TOP, 0, 0, settings->DesktopWidth, - settings->DesktopHeight, SWP_FRAMECHANGED); + settings->DesktopHeight, SWP_FRAMECHANGED); wf_update_canvas_diff(wfc); SetWindowPos(wfc->hwnd, HWND_TOP, -1, -1, settings->DesktopWidth + wfc->diff.x, - settings->DesktopHeight + wfc->diff.y, SWP_NOMOVE | SWP_FRAMECHANGED); + settings->DesktopHeight + wfc->diff.y, SWP_NOMOVE | SWP_FRAMECHANGED); } } else @@ -404,11 +405,7 @@ void wf_toggle_fullscreen(wfContext* wfc) wfc->disablewindowtracking = TRUE; } - if (wfc->fullscreen && wfc->floatbar_active) - floatbar_show(wfc->floatbar); - else - floatbar_hide(wfc->floatbar); - + wf_floatbar_toggle_fullscreen(wfc->floatbar, wfc->fullscreen); SetParent(wfc->hwnd, wfc->fullscreen ? NULL : wfc->hWndParent); wf_resize_window(wfc); ShowWindow(wfc->hwnd, SW_SHOW); diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 7902cd5..263abe4 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -2647,42 +2647,42 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, } /* sticky:[on|off] */ - if (strncasecmp(cur, "sticky:", 7) == 0) + if (_strnicmp(cur, "sticky:", 7) == 0) { const char* val = cur + 7; settings->Floatbar &= ~0x02u; - if (strncasecmp(val, "on", 3) == 0) + if (_strnicmp(val, "on", 3) == 0) settings->Floatbar |= 0x02u; - else if (strncasecmp(val, "off", 4) == 0) + else if (_strnicmp(val, "off", 4) == 0) settings->Floatbar &= ~0x02u; else return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; } /* default:[visible|hidden] */ - else if (strncasecmp(cur, "default:", 8) == 0) + else if (_strnicmp(cur, "default:", 8) == 0) { const char* val = cur + 8; settings->Floatbar &= ~0x04u; - if (strncasecmp(val, "visible", 8) == 0) + if (_strnicmp(val, "visible", 8) == 0) settings->Floatbar |= 0x04u; - else if (strncasecmp(val, "hidden", 7) == 0) + else if (_strnicmp(val, "hidden", 7) == 0) settings->Floatbar &= ~0x04u; else return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; } /* show:[always|fullscreen|window] */ - else if (strncasecmp(cur, "show:", 5) == 0) + else if (_strnicmp(cur, "show:", 5) == 0) { const char* val = cur + 5; settings->Floatbar &= ~0x30u; - if (strncasecmp(val, "always", 7) == 0) + if (_strnicmp(val, "always", 7) == 0) settings->Floatbar |= 0x30u; - else if (strncasecmp(val, "fullscreen", 11) == 0) + else if (_strnicmp(val, "fullscreen", 11) == 0) settings->Floatbar |= 0x10u; - else if (strncasecmp(val, "window", 7) == 0) + else if (_strnicmp(val, "window", 7) == 0) settings->Floatbar |= 0x20u; else return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; diff --git a/libfreerdp/core/settings.c b/libfreerdp/core/settings.c index 932dffe..59bbaa7 100644 --- a/libfreerdp/core/settings.c +++ b/libfreerdp/core/settings.c @@ -352,7 +352,6 @@ rdpSettings* freerdp_settings_new(DWORD flags) settings->GatewayPort = 443; settings->DesktopResize = TRUE; settings->ToggleFullscreen = TRUE; - settings->Floatbar = TRUE; settings->DesktopPosX = UINT32_MAX; settings->DesktopPosY = UINT32_MAX; settings->SoftwareGdi = TRUE; -- 2.7.4