mirror of https://github.com/FreeRDP/FreeRDP
wfreerdp: scrollbars, aspect ratio smartsizing
This commit is contained in:
parent
b91a7cd3a8
commit
391d238f1a
|
@ -150,6 +150,41 @@ static int wf_event_process_WM_MOUSEWHEEL(wfInfo* wfi, HWND hWnd, UINT Msg, WPAR
|
|||
return 0;
|
||||
}
|
||||
|
||||
void wf_sizing(wfInfo* wfi, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
// Holding the CTRL key down while resizing the window will force the desktop aspect ratio.
|
||||
LPRECT rect;
|
||||
if (wfi->instance->settings->SmartSizing && (GetAsyncKeyState(VK_CONTROL) & 0x8000))
|
||||
{
|
||||
rect = (LPRECT) wParam;
|
||||
|
||||
switch(lParam)
|
||||
{
|
||||
case WMSZ_LEFT:
|
||||
case WMSZ_RIGHT:
|
||||
case WMSZ_BOTTOMRIGHT:
|
||||
// Adjust height
|
||||
rect->bottom = rect->top + wfi->height * (rect->right - rect->left) / wfi->instance->settings->DesktopWidth;
|
||||
break;
|
||||
|
||||
case WMSZ_TOP:
|
||||
case WMSZ_BOTTOM:
|
||||
case WMSZ_TOPRIGHT:
|
||||
// Adjust width
|
||||
rect->right = rect->left + wfi->width * (rect->bottom - rect->top) / wfi->instance->settings->DesktopHeight;
|
||||
break;
|
||||
|
||||
case WMSZ_BOTTOMLEFT:
|
||||
case WMSZ_TOPLEFT:
|
||||
// adjust width
|
||||
rect->left = rect->right - (wfi->width * (rect->bottom - rect->top) / wfi->instance->settings->DesktopHeight);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
HDC hdc;
|
||||
|
@ -162,6 +197,7 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
|
|||
|
||||
RECT windowRect, clientRect;
|
||||
MINMAXINFO *minmax;
|
||||
SCROLLINFO si;
|
||||
|
||||
processed = TRUE;
|
||||
ptr = GetWindowLongPtr(hWnd, GWLP_USERDATA);
|
||||
|
@ -176,42 +212,54 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
|
|||
case WM_MOVE:
|
||||
if (!wfi->disablewindowtracking)
|
||||
{
|
||||
int x = LOWORD(lParam);
|
||||
int y = HIWORD(lParam);
|
||||
int x = (int)(short) LOWORD(lParam);
|
||||
int y = (int)(short) HIWORD(lParam);
|
||||
((wfContext*) wfi->instance->context)->wfi->client_x = x;
|
||||
((wfContext*) wfi->instance->context)->wfi->client_y = y;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_GETMINMAXINFO:
|
||||
// Set maximum window size for resizing
|
||||
|
||||
minmax = (MINMAXINFO*) lParam;
|
||||
wf_update_canvas_diff(wfi);
|
||||
if (!wfi->fullscreen)
|
||||
if (wfi->instance->settings->SmartSizing)
|
||||
{
|
||||
// add window decoration
|
||||
minmax->ptMaxTrackSize.x = wfi->width + wfi->diff.x;
|
||||
minmax->ptMaxTrackSize.y = wfi->height + wfi->diff.y;
|
||||
processed = FALSE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case WM_SIZE:
|
||||
else
|
||||
{
|
||||
int dwStyle = GetWindowLongPtr(wfi->hwnd, GWL_STYLE);
|
||||
|
||||
int width = LOWORD(lParam);
|
||||
int height = HIWORD(lParam);
|
||||
// Set maximum window size for resizing
|
||||
|
||||
minmax = (MINMAXINFO*) lParam;
|
||||
wf_update_canvas_diff(wfi);
|
||||
if (!wfi->fullscreen)
|
||||
{
|
||||
((wfContext*) wfi->instance->context)->wfi->client_width = width;
|
||||
((wfContext*) wfi->instance->context)->wfi->client_height = height;
|
||||
// add window decoration
|
||||
minmax->ptMaxTrackSize.x = wfi->width + wfi->diff.x;
|
||||
minmax->ptMaxTrackSize.y = wfi->height + wfi->diff.y;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_SIZING:
|
||||
wf_sizing(wfi, lParam, wParam);
|
||||
break;
|
||||
|
||||
case WM_SIZE:
|
||||
if (!wfi->fullscreen)
|
||||
{
|
||||
GetWindowRect(wfi->hwnd, &windowRect);
|
||||
wfi->client_width = LOWORD(lParam);
|
||||
wfi->client_height = HIWORD(lParam);
|
||||
wfi->client_x = windowRect.left;
|
||||
wfi->client_y = windowRect.top;
|
||||
}
|
||||
|
||||
wf_size_scrollbars(wfi, LOWORD(lParam), HIWORD(lParam));
|
||||
break;
|
||||
|
||||
case WM_EXITSIZEMOVE:
|
||||
wf_size_scrollbars(wfi, wfi->client_width, wfi->client_height);
|
||||
break;
|
||||
|
||||
case WM_ERASEBKGND:
|
||||
/* Say we handled it - prevents flickering */
|
||||
return (LRESULT) 1;
|
||||
|
@ -224,7 +272,7 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
|
|||
w = ps.rcPaint.right - ps.rcPaint.left + 1;
|
||||
h = ps.rcPaint.bottom - ps.rcPaint.top + 1;
|
||||
|
||||
wf_scale_blt(wfi, hdc, x, y, w, h, wfi->primary->hdc, x - wfi->offset_x, y - wfi->offset_y, SRCCOPY);
|
||||
wf_scale_blt(wfi, hdc, x, y, w, h, wfi->primary->hdc, x - wfi->offset_x + wfi->xCurrentScroll, y - wfi->offset_y + wfi->yCurrentScroll, SRCCOPY);
|
||||
|
||||
EndPaint(hWnd, &ps);
|
||||
break;
|
||||
|
@ -260,6 +308,151 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
|
|||
DefWindowProc(hWnd, Msg, wParam, lParam);
|
||||
break;
|
||||
|
||||
case WM_HSCROLL:
|
||||
{
|
||||
int xDelta; // xDelta = new_pos - current_pos
|
||||
int xNewPos; // new position
|
||||
int yDelta = 0;
|
||||
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
// User clicked the scroll bar shaft left of the scroll box.
|
||||
case SB_PAGEUP:
|
||||
xNewPos = wfi->xCurrentScroll - 50;
|
||||
break;
|
||||
|
||||
// User clicked the scroll bar shaft right of the scroll box.
|
||||
case SB_PAGEDOWN:
|
||||
xNewPos = wfi->xCurrentScroll + 50;
|
||||
break;
|
||||
|
||||
// User clicked the left arrow.
|
||||
case SB_LINEUP:
|
||||
xNewPos = wfi->xCurrentScroll - 5;
|
||||
break;
|
||||
|
||||
// User clicked the right arrow.
|
||||
case SB_LINEDOWN:
|
||||
xNewPos = wfi->xCurrentScroll + 5;
|
||||
break;
|
||||
|
||||
// User dragged the scroll box.
|
||||
case SB_THUMBPOSITION:
|
||||
xNewPos = HIWORD(wParam);
|
||||
|
||||
// user is dragging the scrollbar
|
||||
case SB_THUMBTRACK :
|
||||
xNewPos = HIWORD(wParam);
|
||||
break;
|
||||
|
||||
default:
|
||||
xNewPos = wfi->xCurrentScroll;
|
||||
}
|
||||
|
||||
// New position must be between 0 and the screen width.
|
||||
xNewPos = MAX(0, xNewPos);
|
||||
xNewPos = MIN(wfi->xMaxScroll, xNewPos);
|
||||
|
||||
// If the current position does not change, do not scroll.
|
||||
if (xNewPos == wfi->xCurrentScroll)
|
||||
break;
|
||||
|
||||
// Determine the amount scrolled (in pixels).
|
||||
xDelta = xNewPos - wfi->xCurrentScroll;
|
||||
|
||||
// Reset the current scroll position.
|
||||
wfi->xCurrentScroll = xNewPos;
|
||||
|
||||
// Scroll the window. (The system repaints most of the
|
||||
// client area when ScrollWindowEx is called; however, it is
|
||||
// necessary to call UpdateWindow in order to repaint the
|
||||
// rectangle of pixels that were invalidated.)
|
||||
ScrollWindowEx(wfi->hwnd, -xDelta, -yDelta, (CONST RECT *) NULL,
|
||||
(CONST RECT *) NULL, (HRGN) NULL, (PRECT) NULL,
|
||||
SW_INVALIDATE);
|
||||
UpdateWindow(wfi->hwnd);
|
||||
|
||||
// Reset the scroll bar.
|
||||
si.cbSize = sizeof(si);
|
||||
si.fMask = SIF_POS;
|
||||
si.nPos = wfi->xCurrentScroll;
|
||||
SetScrollInfo(wfi->hwnd, SB_HORZ, &si, TRUE);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_VSCROLL:
|
||||
{
|
||||
int xDelta = 0;
|
||||
int yDelta; // yDelta = new_pos - current_pos
|
||||
int yNewPos; // new position
|
||||
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
// User clicked the scroll bar shaft above the scroll box.
|
||||
case SB_PAGEUP:
|
||||
yNewPos = wfi->yCurrentScroll - 50;
|
||||
break;
|
||||
|
||||
// User clicked the scroll bar shaft below the scroll box.
|
||||
case SB_PAGEDOWN:
|
||||
yNewPos = wfi->yCurrentScroll + 50;
|
||||
break;
|
||||
|
||||
// User clicked the top arrow.
|
||||
case SB_LINEUP:
|
||||
yNewPos = wfi->yCurrentScroll - 5;
|
||||
break;
|
||||
|
||||
// User clicked the bottom arrow.
|
||||
case SB_LINEDOWN:
|
||||
yNewPos = wfi->yCurrentScroll + 5;
|
||||
break;
|
||||
|
||||
// User dragged the scroll box.
|
||||
case SB_THUMBPOSITION:
|
||||
yNewPos = HIWORD(wParam);
|
||||
break;
|
||||
|
||||
// user is dragging the scrollbar
|
||||
case SB_THUMBTRACK :
|
||||
yNewPos = HIWORD(wParam);
|
||||
break;
|
||||
|
||||
default:
|
||||
yNewPos = wfi->yCurrentScroll;
|
||||
}
|
||||
|
||||
// New position must be between 0 and the screen height.
|
||||
yNewPos = MAX(0, yNewPos);
|
||||
yNewPos = MIN(wfi->yMaxScroll, yNewPos);
|
||||
|
||||
// If the current position does not change, do not scroll.
|
||||
if (yNewPos == wfi->yCurrentScroll)
|
||||
break;
|
||||
|
||||
// Determine the amount scrolled (in pixels).
|
||||
yDelta = yNewPos - wfi->yCurrentScroll;
|
||||
|
||||
// Reset the current scroll position.
|
||||
wfi->yCurrentScroll = yNewPos;
|
||||
|
||||
// Scroll the window. (The system repaints most of the
|
||||
// client area when ScrollWindowEx is called; however, it is
|
||||
// necessary to call UpdateWindow in order to repaint the
|
||||
// rectangle of pixels that were invalidated.)
|
||||
ScrollWindowEx(wfi->hwnd, -xDelta, -yDelta, (CONST RECT *) NULL,
|
||||
(CONST RECT *) NULL, (HRGN) NULL, (PRECT) NULL,
|
||||
SW_INVALIDATE);
|
||||
UpdateWindow(wfi->hwnd);
|
||||
|
||||
// Reset the scroll bar.
|
||||
si.cbSize = sizeof(si);
|
||||
si.fMask = SIF_POS;
|
||||
si.nPos = wfi->yCurrentScroll;
|
||||
SetScrollInfo(wfi->hwnd, SB_VERT, &si, TRUE);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
processed = FALSE;
|
||||
break;
|
||||
|
@ -358,8 +551,8 @@ void wf_scale_mouse_event(wfInfo* wfi, rdpInput* input, UINT16 flags, UINT16 x,
|
|||
dw = wfi->instance->settings->DesktopWidth;
|
||||
dh = wfi->instance->settings->DesktopHeight;
|
||||
|
||||
if ((ww >= dw) && (wh >= dh))
|
||||
input->MouseEvent(input, flags, x, y);
|
||||
if (!wfi->instance->settings->SmartSizing || (ww >= dw) && (wh >= dh))
|
||||
input->MouseEvent(input, flags, x + wfi->xCurrentScroll, y + wfi->yCurrentScroll);
|
||||
else
|
||||
input->MouseEvent(input, flags, MAX(x, x * dw / ww), MAX(y, y * dh / wh));
|
||||
input->MouseEvent(input, flags, MAX(x, x * dw / ww) + wfi->xCurrentScroll, MAX(y, y * dh / wh) + wfi->yCurrentScroll);
|
||||
}
|
||||
|
|
|
@ -195,6 +195,11 @@ void wf_scale_rect(wfInfo* wfi, RECT* source)
|
|||
source->left = MIN(source->left - 2, MAX(0, source->left * ww / dw - 2));
|
||||
source->right = MIN(source->right + 2, MAX(0, source->right * ww / dw + 2));
|
||||
}
|
||||
|
||||
source->bottom -= wfi->yCurrentScroll;
|
||||
source->top -= wfi->yCurrentScroll;
|
||||
source->left -= wfi->xCurrentScroll;
|
||||
source->right -= wfi->xCurrentScroll;
|
||||
}
|
||||
|
||||
void wf_invalidate_region(wfInfo* wfi, int x, int y, int width, int height)
|
||||
|
@ -303,11 +308,12 @@ void wf_resize_window(wfInfo* wfi)
|
|||
|
||||
if (!wfi->client_y)
|
||||
wfi->client_y = 10;
|
||||
|
||||
|
||||
wf_update_canvas_diff(wfi);
|
||||
|
||||
/* Now resize to get full canvas size and room for caption and borders */
|
||||
SetWindowPos(wfi->hwnd, HWND_TOP, wfi->client_x, wfi->client_y, wfi->client_width + wfi->diff.x, wfi->client_height + wfi->diff.y, SWP_FRAMECHANGED);
|
||||
SetWindowPos(wfi->hwnd, HWND_TOP, wfi->client_x, wfi->client_y, wfi->client_width + wfi->diff.x, wfi->client_height + wfi->diff.y, 0 /*SWP_FRAMECHANGED*/);
|
||||
//wf_size_scrollbars(wfi, wfi->client_width, wfi->client_height);
|
||||
}
|
||||
wf_update_offset(wfi);
|
||||
}
|
||||
|
|
|
@ -430,7 +430,7 @@ BOOL wf_post_connect(freerdp* instance)
|
|||
UpdateWindow(wfi->hwnd);
|
||||
|
||||
if (wfi->sw_gdi)
|
||||
{
|
||||
{
|
||||
instance->update->BeginPaint = wf_sw_begin_paint;
|
||||
instance->update->EndPaint = wf_sw_end_paint;
|
||||
instance->update->DesktopResize = wf_sw_desktop_resize;
|
||||
|
@ -1023,4 +1023,103 @@ int freerdp_client_save_settings_to_rdp_file(wfInfo* cfi, char* filename)
|
|||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void wf_size_scrollbars(wfInfo* wfi, int client_width, int client_height)
|
||||
{
|
||||
if (wfi->disablewindowtracking == TRUE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// prevent infinite message loop
|
||||
wfi->disablewindowtracking = TRUE;
|
||||
|
||||
if (wfi->instance->settings->SmartSizing && (wfi->xScrollVisible || wfi->yScrollVisible))
|
||||
{
|
||||
wfi->xScrollVisible = FALSE;
|
||||
wfi->yScrollVisible = FALSE;
|
||||
ShowScrollBar(wfi->hwnd, SB_BOTH, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
SCROLLINFO si;
|
||||
BOOL horiz = wfi->xScrollVisible;
|
||||
BOOL vert = wfi->yScrollVisible;;
|
||||
|
||||
if (!horiz && client_width < wfi->instance->settings->DesktopWidth)
|
||||
{
|
||||
horiz = TRUE;
|
||||
}
|
||||
else if (horiz && client_width >= wfi->instance->settings->DesktopWidth/* - GetSystemMetrics(SM_CXVSCROLL)*/)
|
||||
{
|
||||
horiz = FALSE;
|
||||
}
|
||||
|
||||
if (!vert && client_height < wfi->instance->settings->DesktopHeight)
|
||||
{
|
||||
vert = TRUE;
|
||||
}
|
||||
else if (vert && client_height >= wfi->instance->settings->DesktopHeight/* - GetSystemMetrics(SM_CYHSCROLL)*/)
|
||||
{
|
||||
vert = FALSE;
|
||||
}
|
||||
|
||||
if (horiz == vert && (horiz != wfi->xScrollVisible && vert != wfi->yScrollVisible))
|
||||
{
|
||||
ShowScrollBar(wfi->hwnd, SB_BOTH, horiz);
|
||||
wfi->xScrollVisible = horiz;
|
||||
wfi->yScrollVisible = vert;
|
||||
}
|
||||
|
||||
if (horiz != wfi->xScrollVisible)
|
||||
{
|
||||
ShowScrollBar(wfi->hwnd, SB_HORZ, horiz);
|
||||
wfi->xScrollVisible = horiz;
|
||||
}
|
||||
|
||||
if (vert != wfi->yScrollVisible)
|
||||
{
|
||||
ShowScrollBar(wfi->hwnd, SB_VERT, vert);
|
||||
wfi->yScrollVisible = vert;
|
||||
}
|
||||
|
||||
if (horiz)
|
||||
{
|
||||
// The horizontal scrolling range is defined by
|
||||
// (bitmap_width) - (client_width). The current horizontal
|
||||
// scroll value remains within the horizontal scrolling range.
|
||||
wfi->xMaxScroll = MAX(wfi->instance->settings->DesktopWidth - client_width, 0);
|
||||
wfi->xCurrentScroll = MIN(wfi->xCurrentScroll, wfi->xMaxScroll);
|
||||
si.cbSize = sizeof(si);
|
||||
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
|
||||
si.nMin = wfi->xMinScroll;
|
||||
si.nMax = wfi->instance->settings->DesktopWidth;
|
||||
si.nPage = client_width;
|
||||
si.nPos = wfi->xCurrentScroll;
|
||||
SetScrollInfo(wfi->hwnd, SB_HORZ, &si, TRUE);
|
||||
}
|
||||
|
||||
if (vert)
|
||||
{
|
||||
// The vertical scrolling range is defined by
|
||||
// (bitmap_height) - (client_height). The current vertical
|
||||
// scroll value remains within the vertical scrolling range.
|
||||
wfi->yMaxScroll = MAX(wfi->instance->settings->DesktopHeight - client_height, 0);
|
||||
wfi->yCurrentScroll = MIN(wfi->yCurrentScroll, wfi->yMaxScroll);
|
||||
si.cbSize = sizeof(si);
|
||||
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
|
||||
si.nMin = wfi->yMinScroll;
|
||||
si.nMax = wfi->instance->settings->DesktopHeight;
|
||||
si.nPage = client_height;
|
||||
si.nPos = wfi->yCurrentScroll;
|
||||
SetScrollInfo(wfi->hwnd, SB_VERT, &si, TRUE);
|
||||
}
|
||||
|
||||
wfi->disablewindowtracking = FALSE;
|
||||
wf_update_canvas_diff(wfi);
|
||||
}
|
||||
|
||||
}
|
|
@ -48,6 +48,9 @@ extern "C" {
|
|||
#define CALLBACK_TYPE_CONNECTED 0x02
|
||||
#define CALLBACK_TYPE_DISCONNECTED 0x03
|
||||
|
||||
// System menu constants
|
||||
#define SMARTSIZING_SYS_MENU_ID 1000
|
||||
|
||||
struct wf_bitmap
|
||||
{
|
||||
rdpBitmap _bitmap;
|
||||
|
@ -132,6 +135,19 @@ struct wf_info
|
|||
|
||||
// Keep track of window size and position, disable when in fullscreen mode.
|
||||
BOOL disablewindowtracking;
|
||||
|
||||
// These variables are required for horizontal scrolling.
|
||||
BOOL updating_scrollbars;
|
||||
BOOL xScrollVisible;
|
||||
int xMinScroll; // minimum horizontal scroll value
|
||||
int xCurrentScroll; // current horizontal scroll value
|
||||
int xMaxScroll; // maximum horizontal scroll value
|
||||
|
||||
// These variables are required for vertical scrolling.
|
||||
BOOL yScrollVisible;
|
||||
int yMinScroll; // minimum vertical scroll value
|
||||
int yCurrentScroll; // current vertical scroll value
|
||||
int yMaxScroll; // maximum vertical scroll value
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -141,6 +157,7 @@ struct wf_info
|
|||
#define cfInfo wfInfo
|
||||
|
||||
void wf_on_param_change(freerdp* instance, int id);
|
||||
void wf_size_scrollbars(wfInfo* wfi, int client_width, int client_height);
|
||||
|
||||
FREERDP_API int freerdp_client_global_init();
|
||||
FREERDP_API int freerdp_client_global_uninit();
|
||||
|
@ -162,7 +179,7 @@ FREERDP_API rdpSettings* freerdp_client_get_settings(wfInfo* wfi);
|
|||
|
||||
FREERDP_API int freerdp_client_load_settings_from_rdp_file(wfInfo* cfi, char* filename);
|
||||
FREERDP_API int freerdp_client_save_settings_to_rdp_file(wfInfo* cfi, char* filename);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue