Merge branch 'master' of git://github.com/mrthebunny/FreeRDP

This commit is contained in:
Marc-André Moreau 2013-05-31 14:58:10 -04:00
commit fd1b5a448f
14 changed files with 1024 additions and 96 deletions

View File

@ -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;
@ -160,6 +195,10 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
rdpInput* input;
BOOL processed;
RECT windowRect, clientRect;
MINMAXINFO *minmax;
SCROLLINFO si;
processed = TRUE;
ptr = GetWindowLongPtr(hWnd, GWLP_USERDATA);
wfi = (wfInfo*) ptr;
@ -170,6 +209,63 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
switch (Msg)
{
case WM_MOVE:
if (!wfi->disablewindowtracking)
{
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:
if (wfi->instance->settings->SmartSizing)
{
processed = FALSE;
}
else
{
// Set maximum window size for resizing
minmax = (MINMAXINFO*) lParam;
wf_update_canvas_diff(wfi);
if (!wfi->fullscreen)
{
// 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:
GetWindowRect(wfi->hwnd, &windowRect);
if (!wfi->fullscreen)
{
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));
// Workaround: when the window is maximized, the call to "ShowScrollBars" returns TRUE but has no effect.
if (wParam == SIZE_MAXIMIZED && !wfi->fullscreen)
SetWindowPos(wfi->hwnd, HWND_TOP, 0, 0, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, SWP_NOMOVE | SWP_FRAMECHANGED);
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;
@ -182,7 +278,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;
@ -218,6 +314,167 @@ 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;
case WM_SYSCOMMAND:
{
if (wParam == SYSCOMMAND_ID_SMARTSIZING)
{
HMENU hMenu = GetSystemMenu(wfi->hwnd, FALSE);
freerdp_set_param_bool(wfi->instance->settings, FreeRDP_SmartSizing, !wfi->instance->settings->SmartSizing);
CheckMenuItem(hMenu, SYSCOMMAND_ID_SMARTSIZING, wfi->instance->settings->SmartSizing ? MF_CHECKED : MF_UNCHECKED);
}
else
{
processed = FALSE;
}
}
break;
default:
processed = FALSE;
break;
@ -250,11 +507,26 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
break;
case WM_KILLFOCUS:
DEBUG_KBD("loosing focus %X", hWnd);
if (g_focus_hWnd == hWnd)
if (g_focus_hWnd == hWnd && wfi && !wfi->fullscreen)
{
DEBUG_KBD("loosing focus %X", hWnd);
g_focus_hWnd = NULL;
}
break;
case WM_ACTIVATE:
{
int activate = (int)(short) LOWORD(lParam);
if (activate != WA_INACTIVE)
{
g_focus_hWnd = hWnd;
}
else
{
g_focus_hWnd = NULL;
}
}
default:
return DefWindowProc(hWnd, Msg, wParam, lParam);
break;
@ -284,7 +556,7 @@ BOOL wf_scale_blt(wfInfo* wfi, HDC hdc, int x, int y, int w, int h, HDC hdcSrc,
if (!wh)
wh = dh;
if (!wfi->instance->settings->SmartSizing || (ww == dw && wh == dh))
if (wfi->fullscreen || !wfi->instance->settings->SmartSizing || (ww == dw && wh == dh))
{
return BitBlt(hdc, x, y, w, h, wfi->primary->hdc, x1, y1, SRCCOPY);
}
@ -293,7 +565,7 @@ BOOL wf_scale_blt(wfInfo* wfi, HDC hdc, int x, int y, int w, int h, HDC hdcSrc,
SetStretchBltMode(hdc, HALFTONE);
SetBrushOrgEx(hdc, 0, 0, NULL);
return StretchBlt(hdc, x * ww / dw, y * wh / dh, ww, wh, wfi->primary->hdc, x1, y1, dw, dh, SRCCOPY);
return StretchBlt(hdc, 0, 0, ww, wh, wfi->primary->hdc, 0, 0, dw, dh, SRCCOPY);
}
return TRUE;
@ -314,8 +586,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, x * dw / ww, y * dh / wh);
input->MouseEvent(input, flags, x * dw / ww + wfi->xCurrentScroll, y * dh / wh + wfi->yCurrentScroll);
}

View File

@ -37,6 +37,7 @@
#include "wf_interface.h"
#include "wf_graphics.h"
#include "wf_gdi.h"
const BYTE wf_rop2_table[] =
{
@ -189,11 +190,16 @@ void wf_scale_rect(wfInfo* wfi, RECT* source)
if (wfi->instance->settings->SmartSizing && (ww != dw || wh != dh))
{
source->bottom = MIN(dh, MAX(0, source->bottom * wh / dh + 2));
source->top = MIN(dh, MAX(0, source->top * wh / dh - 2));
source->left = MIN(dw, MAX(0, source->left * ww / dw - 2));
source->right = MIN(dw, MAX(0, source->right * ww / dw + 2));
source->bottom = source->bottom * wh / dh + 20;
source->top = source->top * wh / dh - 20;
source->left = source->left * ww / dw - 20;
source->right = source->right * ww / dw + 20;
}
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)
@ -220,12 +226,29 @@ 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;
if (wfi->instance->settings->UseMultimon)
{
int x = GetSystemMetrics(SM_XVIRTUALSCREEN);
int y = GetSystemMetrics(SM_YVIRTUALSCREEN);
int w = GetSystemMetrics(SM_CXVIRTUALSCREEN);
int h = GetSystemMetrics(SM_CYVIRTUALSCREEN);
wfi->offset_x = (w - wfi->width) / 2;
if (wfi->offset_x < x)
wfi->offset_x = x;
wfi->offset_y = (h - wfi->height) / 2;
if (wfi->offset_y < y)
wfi->offset_y = y;
}
else
{
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
{
@ -238,8 +261,21 @@ 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);
if(wfi->instance->settings->UseMultimon)
{
int x = GetSystemMetrics(SM_XVIRTUALSCREEN);
int y = GetSystemMetrics(SM_YVIRTUALSCREEN);
int w = GetSystemMetrics(SM_CXVIRTUALSCREEN);
int h = GetSystemMetrics(SM_CYVIRTUALSCREEN);
SetWindowLongPtr(wfi->hwnd, GWL_STYLE, WS_POPUP);
SetWindowPos(wfi->hwnd, HWND_TOP, x, y, w, h, SWP_FRAMECHANGED);
}
else
{
SetWindowLongPtr(wfi->hwnd, GWL_STYLE, WS_POPUP);
SetWindowPos(wfi->hwnd, HWND_TOP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), SWP_FRAMECHANGED);
}
}
else if (!wfi->instance->settings->Decorations)
{
@ -250,12 +286,8 @@ void wf_resize_window(wfInfo* wfi)
/* Now resize to get full canvas size and room for caption and borders */
SetWindowPos(wfi->hwnd, HWND_TOP, 0, 0, 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;
wf_update_canvas_diff(wfi);
SetWindowPos(wfi->hwnd, HWND_TOP, -1, -1, wfi->width + wfi->diff.x, wfi->height + wfi->diff.y, SWP_NOMOVE | SWP_FRAMECHANGED);
}
else
@ -263,17 +295,25 @@ void wf_resize_window(wfInfo* wfi)
RECT rc_wnd;
RECT rc_client;
SetWindowLongPtr(wfi->hwnd, GWL_STYLE, WS_CAPTION | WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX);
SetWindowLongPtr(wfi->hwnd, GWL_STYLE, WS_CAPTION | WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX | WS_SIZEBOX | WS_MAXIMIZEBOX);
if (!wfi->client_height)
wfi->client_height = wfi->height;
if (!wfi->client_width)
wfi->client_width = wfi->width;
if (!wfi->client_x)
wfi->client_x = 10;
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, 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);
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);
}
@ -282,9 +322,22 @@ void wf_toggle_fullscreen(wfInfo* wfi)
{
ShowWindow(wfi->hwnd, SW_HIDE);
wfi->fullscreen = !wfi->fullscreen;
if (wfi->fullscreen)
{
wfi->disablewindowtracking = TRUE;
}
SetParent(wfi->hwnd, wfi->fullscreen ? NULL : wfi->hWndParent);
wf_resize_window(wfi);
ShowWindow(wfi->hwnd, SW_SHOW);
SetForegroundWindow(wfi->hwnd);
if (!wfi->fullscreen)
{
// Reenable window tracking AFTER resizing it back, otherwise it can lean to repositioning errors.
wfi->disablewindowtracking = FALSE;
}
}
void wf_gdi_palette_update(rdpContext* context, PALETTE_UPDATE* palette)
@ -651,3 +704,21 @@ void wf_gdi_register_update_callbacks(rdpUpdate* update)
update->SurfaceBits = wf_gdi_surface_bits;
update->SurfaceFrameMarker = wf_gdi_surface_frame_marker;
}
void wf_update_canvas_diff(wfInfo* wfi)
{
RECT rc_client, rc_wnd;
int dx, dy;
GetClientRect(wfi->hwnd, &rc_client);
GetWindowRect(wfi->hwnd, &rc_wnd);
dx = (rc_wnd.right - rc_wnd.left) - rc_client.right;
dy = (rc_wnd.bottom - rc_wnd.top) - rc_client.bottom;
if (!wfi->disablewindowtracking)
{
wfi->diff.x = dx;
wfi->diff.y = dy;
}
}

View File

@ -33,4 +33,6 @@ void wf_toggle_fullscreen(wfInfo* wfi);
void wf_gdi_register_update_callbacks(rdpUpdate* update);
void wf_update_canvas_diff(wfInfo* wfi);
#endif /* __WF_GDI_H */

View File

@ -44,7 +44,7 @@
#include <freerdp/utils/event.h>
#include <freerdp/utils/svc_plugin.h>
#include <freerdp/client/file.h>
//#include <freerdp/client/file.h>
#include <freerdp/client/cmdline.h>
#include <freerdp/client/channels.h>
#include <freerdp/channels/channels.h>
@ -57,17 +57,34 @@
#include "resource.h"
wfInfo* wf_wfi_new()
{
wfInfo* wfi;
wfi = (wfInfo*) malloc(sizeof(wfInfo));
ZeroMemory(wfi, sizeof(wfInfo));
return wfi;
}
void wf_wfi_free(wfInfo* wfi)
{
free(wfi);
}
void wf_context_new(freerdp* instance, rdpContext* context)
{
wfInfo* wfi;
context->channels = freerdp_channels_new();
wfi = (wfInfo*) malloc(sizeof(wfInfo));
ZeroMemory(wfi, sizeof(wfInfo));
wfi = wf_wfi_new();
((wfContext*) context)->wfi = wfi;
wfi->instance = instance;
// Register callbacks
instance->context->client->OnParamChange = wf_on_param_change;
}
void wf_context_free(freerdp* instance, rdpContext* context)
@ -76,6 +93,9 @@ void wf_context_free(freerdp* instance, rdpContext* context)
cache_free(context->cache);
freerdp_channels_free(context->channels);
wf_wfi_free(((wfContext*) context)->wfi);
((wfContext*) context)->wfi = NULL;
}
int wf_create_console(void)
@ -205,9 +225,8 @@ void wf_hw_desktop_resize(rdpContext* context)
BOOL wf_pre_connect(freerdp* instance)
{
int i1;
int desktopWidth, desktopHeight;
wfInfo* wfi;
rdpFile* file;
wfContext* context;
rdpSettings* settings;
@ -220,14 +239,17 @@ BOOL wf_pre_connect(freerdp* instance)
if (settings->ConnectionFile)
{
file = freerdp_client_rdp_file_new();
if (wfi->connectionRdpFile)
{
freerdp_client_rdp_file_free(wfi->connectionRdpFile);
}
wfi->connectionRdpFile = freerdp_client_rdp_file_new();
fprintf(stderr, "Using connection file: %s\n", settings->ConnectionFile);
freerdp_client_parse_rdp_file(file, settings->ConnectionFile);
freerdp_client_populate_settings_from_rdp_file(file, settings);
freerdp_client_rdp_file_free(file);
freerdp_client_parse_rdp_file(wfi->connectionRdpFile, settings->ConnectionFile);
freerdp_client_populate_settings_from_rdp_file(wfi->connectionRdpFile, settings);
}
settings->OsMajorType = OSMAJORTYPE_WINDOWS;
@ -269,24 +291,43 @@ BOOL wf_pre_connect(freerdp* instance)
instance->context->cache = cache_new(settings);
desktopWidth = settings->DesktopWidth;
desktopHeight = settings->DesktopHeight;
if (wfi->percentscreen > 0)
{
i1 = (GetSystemMetrics(SM_CXSCREEN) * wfi->percentscreen) / 100;
settings->DesktopWidth = i1;
desktopWidth = (GetSystemMetrics(SM_CXSCREEN) * wfi->percentscreen) / 100;
settings->DesktopWidth = desktopWidth;
i1 = (GetSystemMetrics(SM_CYSCREEN) * wfi->percentscreen) / 100;
settings->DesktopHeight = i1;
desktopHeight = (GetSystemMetrics(SM_CYSCREEN) * wfi->percentscreen) / 100;
settings->DesktopHeight = desktopHeight;
}
if (wfi->fullscreen)
{
settings->DesktopWidth = GetSystemMetrics(SM_CXSCREEN);
settings->DesktopHeight = GetSystemMetrics(SM_CYSCREEN);
if (settings->UseMultimon)
{
settings->DesktopWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
settings->DesktopHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
}
else
{
settings->DesktopWidth = GetSystemMetrics(SM_CXSCREEN);
settings->DesktopHeight = GetSystemMetrics(SM_CYSCREEN);
}
}
i1 = settings->DesktopWidth;
i1 = (i1 + 3) & (~3);
settings->DesktopWidth = i1;
desktopWidth = (desktopWidth + 3) & (~3);
if (desktopWidth != settings->DesktopWidth)
{
freerdp_set_param_uint32(settings, FreeRDP_DesktopWidth, desktopWidth);
}
if (desktopHeight != settings->DesktopHeight)
{
freerdp_set_param_uint32(settings, FreeRDP_DesktopHeight, desktopHeight);
}
if ((settings->DesktopWidth < 64) || (settings->DesktopHeight < 64) ||
(settings->DesktopWidth > 4096) || (settings->DesktopHeight > 4096))
@ -295,12 +336,35 @@ BOOL wf_pre_connect(freerdp* instance)
return 1;
}
settings->KeyboardLayout = (int) GetKeyboardLayout(0) & 0x0000FFFF;
freerdp_set_param_uint32(settings, FreeRDP_KeyboardLayout, (int) GetKeyboardLayout(0) & 0x0000FFFF);
freerdp_channels_pre_connect(instance->context->channels, instance);
return TRUE;
}
void wf_add_system_menu(wfInfo* wfi)
{
HMENU hMenu = GetSystemMenu(wfi->hwnd, FALSE);
MENUITEMINFO item_info;
ZeroMemory(&item_info, sizeof(MENUITEMINFO));
item_info.fMask = MIIM_CHECKMARKS | MIIM_FTYPE | MIIM_ID | MIIM_STRING | MIIM_DATA;
item_info.cbSize = sizeof(MENUITEMINFO);
item_info.wID = SYSCOMMAND_ID_SMARTSIZING;
item_info.fType = MFT_STRING;
item_info.dwTypeData = _wcsdup(_T("Smart sizing"));
item_info.cch = _wcslen(_T("Smart sizing"));
item_info.dwItemData = (ULONG_PTR) wfi;
InsertMenuItem(hMenu, 6, TRUE, &item_info);
if (wfi->instance->settings->SmartSizing)
{
CheckMenuItem(hMenu, SYSCOMMAND_ID_SMARTSIZING, MF_CHECKED);
}
}
BOOL wf_post_connect(freerdp* instance)
{
rdpGdi* gdi;
@ -382,6 +446,8 @@ BOOL wf_post_connect(freerdp* instance)
wf_resize_window(wfi);
wf_add_system_menu(wfi);
BitBlt(wfi->primary->hdc, 0, 0, wfi->width, wfi->height, NULL, 0, 0, BLACKNESS);
wfi->drawing = wfi->primary;
@ -389,7 +455,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;
@ -416,6 +482,12 @@ BOOL wf_post_connect(freerdp* instance)
wf_cliprdr_init(wfi, instance->context->channels);
// Callback
if (wfi->client_callback_func != NULL)
{
wfi->client_callback_func(wfi, CALLBACK_TYPE_CONNECTED, 0, 0);
}
return TRUE;
}
@ -645,8 +717,8 @@ DWORD WINAPI wf_thread(LPVOID lpParam)
width = LOWORD(msg.lParam);
height = HIWORD(msg.lParam);
((wfContext*) instance->context)->wfi->client_width = width;
((wfContext*) instance->context)->wfi->client_height = height;
//((wfContext*) instance->context)->wfi->client_width = width;
//((wfContext*) instance->context)->wfi->client_height = height;
SetWindowPos(((wfContext*) instance->context)->wfi->hwnd, HWND_TOP, 0, 0, width, height, SWP_FRAMECHANGED);
}
@ -666,10 +738,17 @@ DWORD WINAPI wf_thread(LPVOID lpParam)
}
/* cleanup */
((wfContext*) instance->context)->wfi->mainThreadId = 0;
freerdp_channels_close(channels, instance);
freerdp_disconnect(instance);
freerdp_disconnect(instance);
// Callback
if (((wfContext*) instance->context)->wfi->client_callback_func != NULL)
{
((wfContext*) instance->context)->wfi->client_callback_func(((wfContext*) instance->context)->wfi, CALLBACK_TYPE_DISCONNECTED, 12, 34);
}
return 0;
}
@ -707,6 +786,8 @@ DWORD WINAPI wf_keyboard_thread(LPVOID lpParam)
fprintf(stderr, "failed to install keyboard hook\n");
}
wfi->keyboardThreadId = 0;
printf("Keyboard thread exited.\n");
return (DWORD) NULL;
}
@ -778,6 +859,11 @@ wfInfo* freerdp_client_new(int argc, char** argv)
return wfi;
}
rdpSettings* freerdp_client_get_settings(wfInfo* wfi)
{
return wfi->instance->settings;
}
int freerdp_client_start(wfInfo* wfi)
{
HWND hWndParent;
@ -808,7 +894,7 @@ int freerdp_client_start(wfInfo* wfi)
wfi->wndClass.hIconSm = wfi->icon;
RegisterClassEx(&(wfi->wndClass));
wfi->keyboardThread = CreateThread(NULL, 0, wf_keyboard_thread, (void*) wfi, 0, NULL);
wfi->keyboardThread = CreateThread(NULL, 0, wf_keyboard_thread, (void*) wfi, 0, &wfi->keyboardThreadId);
if (!wfi->keyboardThread)
return -1;
@ -820,12 +906,17 @@ int freerdp_client_start(wfInfo* wfi)
if (!wfi->thread)
return -1;
printf("Main thread exited.\n");
return 0;
}
int freerdp_client_stop(wfInfo* wfi)
{
PostThreadMessage(wfi->mainThreadId, WM_QUIT, 0, 0);
if (wfi->mainThreadId)
PostThreadMessage(wfi->mainThreadId, WM_QUIT, 0, 0);
if (wfi->keyboardThreadId)
PostThreadMessage(wfi->keyboardThreadId, WM_QUIT, 0, 0);
return 0;
}
@ -856,7 +947,7 @@ int freerdp_client_focus_out(wfInfo* wfi)
return 0;
}
int wf_set_window_size(wfInfo* wfi, int width, int height)
int freerdp_client_set_window_size(wfInfo* wfi, int width, int height)
{
if ((width != wfi->client_width) || (height != wfi->client_height))
{
@ -875,3 +966,225 @@ int freerdp_client_free(wfInfo* wfi)
return 0;
}
void wf_on_param_change(freerdp* instance, int id)
{
wfInfo* cfi = ((wfContext*) instance->context)->wfi;
RECT rect;
HMENU hMenu;
// specific processing here
switch(id)
{
case FreeRDP_SmartSizing:
fprintf(stderr, "SmartSizing changed.\n");
if (!instance->settings->SmartSizing && (cfi->client_width > instance->settings->DesktopWidth || cfi->client_height > instance->settings->DesktopHeight))
{
GetWindowRect(cfi->hwnd, &rect);
SetWindowPos(cfi->hwnd, HWND_TOP, 0, 0, MIN(cfi->client_width + cfi->offset_x, rect.right - rect.left), MIN(cfi->client_height + cfi->offset_y, rect.bottom - rect.top), SWP_NOMOVE | SWP_FRAMECHANGED);
wf_update_canvas_diff(cfi);
}
hMenu = GetSystemMenu(cfi->hwnd, FALSE);
CheckMenuItem(hMenu, SYSCOMMAND_ID_SMARTSIZING, instance->settings->SmartSizing);
wf_size_scrollbars(cfi, cfi->client_width, cfi->client_height);
GetClientRect(cfi->hwnd, &rect);
InvalidateRect(cfi->hwnd, &rect, TRUE);
break;
case FreeRDP_ConnectionType:
fprintf(stderr, "ConnectionType changed.\n");
freerdp_set_connection_type(cfi->instance->settings, cfi->instance->settings->ConnectionType);
break;
}
// trigger callback to client
if (cfi->client_callback_func != NULL)
{
fprintf(stderr, "Notifying client...");
cfi->client_callback_func(cfi, CALLBACK_TYPE_PARAM_CHANGE, id, 0);
}
}
int freerdp_client_set_client_callback_function(wfInfo* cfi, callbackFunc callbackFunc)
{
cfi->client_callback_func = callbackFunc;
return 0;
}
// TODO: Some of that code is a duplicate of wf_pre_connect. Refactor?
int freerdp_client_load_settings_from_rdp_file(wfInfo* cfi, char* filename)
{
rdpSettings* settings;
settings = cfi->instance->settings;
if (filename)
{
settings->ConnectionFile = _strdup(filename);
// free old settings file
freerdp_client_rdp_file_free(cfi->connectionRdpFile);
cfi->connectionRdpFile = freerdp_client_rdp_file_new();
fprintf(stderr, "Using connection file: %s\n", settings->ConnectionFile);
if (!freerdp_client_parse_rdp_file(cfi->connectionRdpFile, settings->ConnectionFile))
{
return 1;
}
if (!freerdp_client_populate_settings_from_rdp_file(cfi->connectionRdpFile, settings))
{
return 2;
}
}
return 0;
}
int freerdp_client_save_settings_to_rdp_file(wfInfo* cfi, char* filename)
{
if (filename == NULL)
return 1;
if (cfi->instance->settings->ConnectionFile)
{
free(cfi->instance->settings->ConnectionFile);
}
cfi->instance->settings->ConnectionFile = _strdup(filename);
// Reuse existing rdpFile structure if available, to preserve unsupported settings when saving to disk.
if (cfi->connectionRdpFile == NULL)
{
cfi->connectionRdpFile = freerdp_client_rdp_file_new();
}
if (!freerdp_client_populate_rdp_file_from_settings(cfi->connectionRdpFile, cfi->instance->settings))
{
return 1;
}
if (!freerdp_client_write_rdp_file(cfi->connectionRdpFile, filename, UNICODE));
{
return 2;
}
return 0;
}
void wf_size_scrollbars(wfInfo* wfi, int client_width, int client_height)
{
BOOL rc;
if (wfi->disablewindowtracking == TRUE)
{
return;
}
// prevent infinite message loop
wfi->disablewindowtracking = TRUE;
if (wfi->instance->settings->SmartSizing)
{
wfi->xCurrentScroll = 0;
wfi->yCurrentScroll = 0;
if (wfi->xScrollVisible || wfi->yScrollVisible)
{
if (ShowScrollBar(wfi->hwnd, SB_BOTH, FALSE))
{
wfi->xScrollVisible = FALSE;
wfi->yScrollVisible = 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))
{
if (ShowScrollBar(wfi->hwnd, SB_BOTH, horiz))
{
wfi->xScrollVisible = horiz;
wfi->yScrollVisible = vert;
}
}
if (horiz != wfi->xScrollVisible)
{
if (ShowScrollBar(wfi->hwnd, SB_HORZ, horiz))
{
wfi->xScrollVisible = horiz;
}
}
if (vert != wfi->yScrollVisible)
{
if (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);
}

View File

@ -35,6 +35,7 @@
#include <freerdp/channels/channels.h>
#include <freerdp/codec/rfx.h>
#include <freerdp/codec/nsc.h>
#include <freerdp/client/file.h>
#include "wf_event.h"
@ -42,6 +43,14 @@
extern "C" {
#endif
// Callback type codes. Move elsewhere?
#define CALLBACK_TYPE_PARAM_CHANGE 0x01
#define CALLBACK_TYPE_CONNECTED 0x02
#define CALLBACK_TYPE_DISCONNECTED 0x03
// System menu constants
#define SYSCOMMAND_ID_SMARTSIZING 1000
struct wf_bitmap
{
rdpBitmap _bitmap;
@ -69,6 +78,8 @@ struct wf_context
};
typedef struct wf_context wfContext;
typedef void (CALLBACK * callbackFunc)(wfInfo* wfi, int callback_type, DWORD param1, DWORD param2);
struct wf_info
{
rdpClient* client;
@ -81,6 +92,8 @@ struct wf_info
int fullscreen;
int percentscreen;
char window_title[64];
int client_x;
int client_y;
int client_width;
int client_height;
@ -111,10 +124,30 @@ struct wf_info
wfBitmap* tile;
DWORD mainThreadId;
DWORD keyboardThreadId;
RFX_CONTEXT* rfx_context;
NSC_CONTEXT* nsc_context;
BOOL sw_gdi;
callbackFunc client_callback_func;
rdpFile* connectionRdpFile;
// 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
};
/**
@ -123,6 +156,9 @@ 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();
@ -141,6 +177,13 @@ FREERDP_API int freerdp_client_set_window_size(wfInfo* cfi, int width, int heigh
FREERDP_API cfInfo* freerdp_client_new(int argc, char** argv);
FREERDP_API int freerdp_client_free(wfInfo* cfi);
FREERDP_API int freerdp_client_set_client_callback_function(wfInfo* cfi, callbackFunc callbackFunc);
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

View File

@ -724,6 +724,7 @@ int freerdp_parse_username(char* username, char** user, char** domain)
int freerdp_set_connection_type(rdpSettings* settings, int type)
{
settings->ConnectionType = type;
if (type == CONNECTION_TYPE_MODEM)
{
settings->DisableWallpaper = TRUE;
@ -1106,6 +1107,11 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin
CommandLineSwitchCase(arg, "multimon")
{
settings->UseMultimon = TRUE;
settings->Fullscreen = TRUE;
// force?
settings->DesktopWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
settings->DesktopHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
if (arg->Flags & COMMAND_LINE_VALUE_PRESENT)
{

View File

@ -480,10 +480,192 @@ BOOL freerdp_client_parse_rdp_file(rdpFile* file, char* name)
return freerdp_client_parse_rdp_file_buffer(file, buffer, file_size);
}
#define SETTING_MODIFIED(_settings, _field) (_settings->settings_modified[FreeRDP_##_field])
#define SETTING_MODIFIED_SET(_target, _settings, _field) if SETTING_MODIFIED(_settings, _field) _target = _settings->_field
BOOL freerdp_client_populate_rdp_file_from_settings(rdpFile* file, rdpSettings* settings)
{
SETTING_MODIFIED_SET(file->Domain, settings, Domain);
SETTING_MODIFIED_SET(file->Username, settings, Username);
SETTING_MODIFIED_SET(file->ServerPort, settings, ServerPort);
SETTING_MODIFIED_SET(file->FullAddress, settings, ServerHostname);
SETTING_MODIFIED_SET(file->DesktopWidth, settings, DesktopWidth);
SETTING_MODIFIED_SET(file->DesktopHeight, settings, DesktopHeight);
SETTING_MODIFIED_SET(file->SessionBpp, settings, ColorDepth);
SETTING_MODIFIED_SET(file->ConnectToConsole, settings, ConsoleSession);
SETTING_MODIFIED_SET(file->AdministrativeSession, settings, ConsoleSession);
SETTING_MODIFIED_SET(file->NegotiateSecurityLayer, settings, NegotiateSecurityLayer);
SETTING_MODIFIED_SET(file->EnableCredSSPSupport, settings, NlaSecurity);
SETTING_MODIFIED_SET(file->AlternateShell, settings, AlternateShell);
SETTING_MODIFIED_SET(file->ShellWorkingDirectory, settings, ShellWorkingDirectory);
SETTING_MODIFIED_SET(file->ConnectionType, settings, ConnectionType);
if (SETTING_MODIFIED(settings, AudioPlayback) || SETTING_MODIFIED(settings, RemoteConsoleAudio))
{
if (settings->AudioPlayback)
file->AudioMode = AUDIO_MODE_REDIRECT;
else if (settings->RemoteConsoleAudio)
file->AudioMode = AUDIO_MODE_PLAY_ON_SERVER;
else
file->AudioMode = AUDIO_MODE_NONE;
}
SETTING_MODIFIED_SET(file->GatewayHostname, settings, GatewayHostname);
SETTING_MODIFIED_SET(file->GatewayUsageMethod, settings, GatewayUsageMethod);
SETTING_MODIFIED_SET(file->PromptCredentialOnce, settings, GatewayUseSameCredentials);
SETTING_MODIFIED_SET(file->RemoteApplicationMode, settings, RemoteApplicationMode);
SETTING_MODIFIED_SET(file->RemoteApplicationProgram, settings, RemoteApplicationProgram);
SETTING_MODIFIED_SET(file->RemoteApplicationName, settings, RemoteApplicationName);
SETTING_MODIFIED_SET(file->RemoteApplicationIcon, settings, RemoteApplicationIcon);
SETTING_MODIFIED_SET(file->RemoteApplicationFile, settings, RemoteApplicationFile);
SETTING_MODIFIED_SET(file->RemoteApplicationGuid, settings, RemoteApplicationGuid);
SETTING_MODIFIED_SET(file->RemoteApplicationCmdLine, settings, RemoteApplicationCmdLine);
SETTING_MODIFIED_SET(file->SpanMonitors, settings, SpanMonitors);
SETTING_MODIFIED_SET(file->UseMultiMon, settings, UseMultimon);
return TRUE;
}
BOOL freerdp_client_write_rdp_file(rdpFile* file, char* name, BOOL unicode)
{
BOOL success = FALSE;
char* buffer;
int len, len2;
FILE* fp = NULL;
WCHAR* unicodestr = NULL;
len = freerdp_client_write_rdp_file_buffer(file, NULL, 0);
if (len <= 0)
{
fprintf(stderr, "freerdp_client_write_rdp_file: Error determining buffer size.\n");
return FALSE;
}
buffer = (char*) malloc((len + 1) * sizeof(char));
len2 = freerdp_client_write_rdp_file_buffer(file, buffer, len + 1);
if (len2 == len)
{
fp = fopen(name, "w+b");
if (fp != NULL)
{
if (unicode)
{
ConvertToUnicode(CP_UTF8, 0, buffer, len, &unicodestr, 0);
// Write multi-byte header
fwrite(BOM_UTF16_LE, sizeof(BYTE), 2, fp);
fwrite(unicodestr, 2, len, fp);
free(unicodestr);
}
else
{
fwrite(buffer, 1, len, fp);
}
fflush(fp);
fclose(fp);
}
}
if (buffer != NULL)
free(buffer);
return success;
}
#define WRITE_RDP_FILE_DECLARE(_file, _buffer, _size) \
rdpFile* __rdpFile = file; \
char* __buffer = _buffer; \
size_t __size = _size; \
size_t __required_size = 0; \
int __current = 0; \
int __count = 0;
#define WRITE_RDP_FILE_VALUE(_format, _field) \
if (~__rdpFile->_field) \
{ \
__count = _snprintf(__buffer == NULL ? NULL : __buffer + __current, __buffer == NULL ? 0 : __size - __required_size, _format, __rdpFile->_field); \
__required_size += __count; \
__current += __count; \
}
#define WRITE_RDP_FILE_VALUE_STRING(_format, _field) \
if (~((size_t) __rdpFile->_field) && __rdpFile->_field != NULL) \
{ \
__count = _snprintf(__buffer == NULL ? NULL : __buffer + __current, __buffer == NULL ? 0 : __size - __required_size, _format, __rdpFile->_field); \
__required_size += __count; \
__current += __count; \
}
#define WRITE_RDP_FILE_VALUE_RETURN \
return __required_size;
// TODO: Optimize by only writing the fields that have a value i.e ~((size_t) file->FieldName) != 0
size_t freerdp_client_write_rdp_file_buffer(rdpFile* file, char* buffer, size_t size)
{
WRITE_RDP_FILE_DECLARE(file, buffer, size)
WRITE_RDP_FILE_VALUE("screen mode id:i:%d\n", ScreenModeId);
WRITE_RDP_FILE_VALUE("use multimon:i:%d\n", UseMultiMon);
WRITE_RDP_FILE_VALUE("desktopwidth:i:%d\n", DesktopWidth);
WRITE_RDP_FILE_VALUE("desktopheight:i:%d\n", DesktopHeight);
WRITE_RDP_FILE_VALUE("session bpp:i:%d\n", SessionBpp);
WRITE_RDP_FILE_VALUE_STRING("winposstr:s:%s\n", WinPosStr);
WRITE_RDP_FILE_VALUE("compression:i:%d\n", Compression);
WRITE_RDP_FILE_VALUE("keyboardhook:i:%d\n", KeyboardHook);
WRITE_RDP_FILE_VALUE("audiocapturemode:i:%d\n", AudioCaptureMode);
WRITE_RDP_FILE_VALUE("videoplaybackmode:i:%d\n", VideoPlaybackMode);
WRITE_RDP_FILE_VALUE("connection type:i:%d\n", ConnectionType);
WRITE_RDP_FILE_VALUE("networkautodetect:i:%d\n", NetworkAutoDetect);
WRITE_RDP_FILE_VALUE("bandwidthautodetect:i:%d\n", BandwidthAutoDetect);
WRITE_RDP_FILE_VALUE("displayconnectionbar:i:%d\n", DisplayConnectionBar);
WRITE_RDP_FILE_VALUE("enableworkspacereconnect:i:%d\n", EnableWorkspaceReconnect);
WRITE_RDP_FILE_VALUE("disable wallpaper:i:%d\n", DisableWallpaper);
WRITE_RDP_FILE_VALUE("allow font smoothing:i:%d\n", AllowFontSmoothing);
WRITE_RDP_FILE_VALUE("allow desktop composition:i:%d\n", AllowDesktopComposition);
WRITE_RDP_FILE_VALUE("disable full window drag:i:%d\n", DisableFullWindowDrag);
WRITE_RDP_FILE_VALUE("disable menu anims:i:%d\n", DisableMenuAnims);
WRITE_RDP_FILE_VALUE("disable themes:i:%d\n", DisableThemes);
WRITE_RDP_FILE_VALUE("disable cursor setting:i:%d\n", DisableCursorSetting);
WRITE_RDP_FILE_VALUE("bitmapcachepersistenable:i:%d\n", BitmapCachePersistEnable);
WRITE_RDP_FILE_VALUE_STRING("full address:s:%s\n", FullAddress);
WRITE_RDP_FILE_VALUE("audiomode:i:%d\n", AudioMode);
WRITE_RDP_FILE_VALUE("redirectprinters:i:%d\n", RedirectPrinters);
WRITE_RDP_FILE_VALUE("redirectcomports:i:%d\n", RedirectComPorts);
WRITE_RDP_FILE_VALUE("redirectsmartcards:i:%d\n", RedirectSmartCards);
WRITE_RDP_FILE_VALUE("redirectclipboard:i:%d\n", RedirectClipboard);
WRITE_RDP_FILE_VALUE("redirectposdevices:i:%d\n", RedirectPosDevices);
WRITE_RDP_FILE_VALUE("autoreconnection enabled:i:%d\n", AutoReconnectionEnabled);
WRITE_RDP_FILE_VALUE("authentication level:i:%d\n", AuthenticationLevel);
WRITE_RDP_FILE_VALUE("prompt for credentials:i:%d\n", PromptForCredentials);
WRITE_RDP_FILE_VALUE("negotiate security layer:i:%d\n", NegotiateSecurityLayer);
WRITE_RDP_FILE_VALUE("remoteapplicationmode:i:%d\n", RemoteApplicationMode);
WRITE_RDP_FILE_VALUE_STRING("alternate shell:s:%s\n", AlternateShell);
WRITE_RDP_FILE_VALUE_STRING("shell working directory:s:%s\n", ShellWorkingDirectory);
WRITE_RDP_FILE_VALUE_STRING("gatewayhostname:s:%s\n", GatewayHostname);
WRITE_RDP_FILE_VALUE("gatewayusagemethod:i:%d\n", GatewayUsageMethod);
WRITE_RDP_FILE_VALUE("gatewaycredentialssource:i:%d\n", GatewayCredentialsSource);
WRITE_RDP_FILE_VALUE("gatewayprofileusagemethod:i:%d\n", GatewayProfileUsageMethod);
WRITE_RDP_FILE_VALUE("promptcredentialonce:i:%d\n", PromptCredentialOnce);
WRITE_RDP_FILE_VALUE("use redirection server name:i:%d\n", UseRedirectionServerName);
WRITE_RDP_FILE_VALUE("rdgiskdcproxy:i:%d\n", RdgIsKdcProxy);
WRITE_RDP_FILE_VALUE_STRING("kdcproxyname:s:%s\n", KdcProxyName);
WRITE_RDP_FILE_VALUE_STRING("drivestoredirect:s:%s\n", DrivesToRedirect);
WRITE_RDP_FILE_VALUE_STRING("username:s:%s\n", Username);
WRITE_RDP_FILE_VALUE_STRING("domain:s:%s\n", Domain);
WRITE_RDP_FILE_VALUE_RETURN
}
BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings* settings)
{
if (~((size_t) file->Domain))
settings->Domain = file->Domain;
freerdp_set_param_string(settings, FreeRDP_Domain, file->Domain);
if (~((size_t) file->Username))
{
@ -491,33 +673,35 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings*
char* domain;
freerdp_parse_username(file->Username, &user, &domain);
freerdp_set_param_string(settings, FreeRDP_Username, user);
settings->Username = user;
settings->Domain = domain;
if (domain != NULL)
freerdp_set_param_string(settings, FreeRDP_Domain, domain);
}
if (~file->ServerPort)
settings->ServerPort = file->ServerPort;
freerdp_set_param_uint32(settings, FreeRDP_ServerPort, file->ServerPort);
if (~((size_t) file->FullAddress))
settings->ServerHostname = _strdup(file->FullAddress);
freerdp_set_param_string(settings, FreeRDP_ServerHostname, file->FullAddress);
if (~file->DesktopWidth)
settings->DesktopWidth = file->DesktopWidth;
freerdp_set_param_uint32(settings, FreeRDP_DesktopWidth, file->DesktopWidth);
if (~file->DesktopHeight)
settings->DesktopHeight = file->DesktopHeight;
freerdp_set_param_uint32(settings, FreeRDP_DesktopHeight, file->DesktopHeight);
if (~file->SessionBpp)
settings->ColorDepth = file->SessionBpp;
freerdp_set_param_uint32(settings, FreeRDP_ColorDepth, file->SessionBpp);
if (~file->ConnectToConsole)
settings->ConsoleSession = file->ConnectToConsole;
freerdp_set_param_uint32(settings, FreeRDP_ConsoleSession, file->ConnectToConsole);
if (~file->AdministrativeSession)
settings->ConsoleSession = file->AdministrativeSession;
freerdp_set_param_uint32(settings, FreeRDP_ConsoleSession, file->AdministrativeSession);
if (~file->NegotiateSecurityLayer)
settings->NegotiateSecurityLayer = file->NegotiateSecurityLayer;
freerdp_set_param_uint32(settings, FreeRDP_NegotiateSecurityLayer, file->NegotiateSecurityLayer);
if (~file->EnableCredSSPSupport)
settings->NlaSecurity = file->EnableCredSSPSupport;
freerdp_set_param_uint32(settings, FreeRDP_NlaSecurity, file->EnableCredSSPSupport);
if (~((size_t) file->AlternateShell))
settings->AlternateShell = _strdup(file->AlternateShell);
freerdp_set_param_string(settings, FreeRDP_AlternateShell, file->AlternateShell);
if (~((size_t) file->ShellWorkingDirectory))
settings->ShellWorkingDirectory = _strdup(file->ShellWorkingDirectory);
freerdp_set_param_string(settings, FreeRDP_ShellWorkingDirectory, file->ShellWorkingDirectory);
if (~((size_t) file->LoadBalanceInfo))
{
@ -526,53 +710,52 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings*
}
if (~file->ConnectionType)
{
freerdp_set_connection_type(settings, file->ConnectionType);
}
freerdp_set_param_uint32(settings, FreeRDP_ConnectionType, file->ConnectionType);
if (~file->AudioMode)
{
if (file->AudioMode == AUDIO_MODE_REDIRECT)
{
settings->AudioPlayback = TRUE;
freerdp_set_param_bool(settings, FreeRDP_AudioPlayback, TRUE);
}
else if (file->AudioMode == AUDIO_MODE_PLAY_ON_SERVER)
{
settings->RemoteConsoleAudio = TRUE;
freerdp_set_param_bool(settings, FreeRDP_RemoteConsoleAudio, TRUE);
}
else if (file->AudioMode == AUDIO_MODE_NONE)
{
settings->AudioPlayback = FALSE;
settings->RemoteConsoleAudio = FALSE;
freerdp_set_param_bool(settings, FreeRDP_AudioPlayback, FALSE);
freerdp_set_param_bool(settings, FreeRDP_RemoteConsoleAudio, FALSE);
}
}
if (~((size_t) file->GatewayHostname))
settings->GatewayHostname = _strdup(file->GatewayHostname);
freerdp_set_param_string(settings, FreeRDP_GatewayHostname, file->GatewayHostname);
if (~file->GatewayUsageMethod)
settings->GatewayUsageMethod = TRUE;
freerdp_set_param_bool(settings, FreeRDP_GatewayUsageMethod, file->GatewayUsageMethod);
if (~file->PromptCredentialOnce)
freerdp_set_param_bool(settings, FreeRDP_GatewayUsageMethod, file->GatewayUsageMethod);
settings->GatewayUseSameCredentials = TRUE;
if (~file->RemoteApplicationMode)
settings->RemoteApplicationMode = file->RemoteApplicationMode;
freerdp_set_param_bool(settings, FreeRDP_RemoteApplicationMode, file->RemoteApplicationMode);
if (~((size_t) file->RemoteApplicationProgram))
settings->RemoteApplicationProgram = _strdup(file->RemoteApplicationProgram);
freerdp_set_param_string(settings, FreeRDP_RemoteApplicationProgram, file->RemoteApplicationProgram);
if (~((size_t) file->RemoteApplicationName))
settings->RemoteApplicationName = _strdup(file->RemoteApplicationName);
freerdp_set_param_string(settings, FreeRDP_RemoteApplicationName, file->RemoteApplicationName);
if (~((size_t) file->RemoteApplicationIcon))
settings->RemoteApplicationIcon = _strdup(file->RemoteApplicationIcon);
freerdp_set_param_string(settings, FreeRDP_RemoteApplicationIcon, file->RemoteApplicationIcon);
if (~((size_t) file->RemoteApplicationFile))
settings->RemoteApplicationFile = _strdup(file->RemoteApplicationFile);
freerdp_set_param_string(settings, FreeRDP_RemoteApplicationGuid, file->RemoteApplicationGuid);
if (~((size_t) file->RemoteApplicationGuid))
settings->RemoteApplicationGuid = _strdup(file->RemoteApplicationGuid);
freerdp_set_param_string(settings, FreeRDP_RemoteApplicationGuid, file->RemoteApplicationGuid);
if (~((size_t) file->RemoteApplicationCmdLine))
settings->RemoteApplicationCmdLine = _strdup(file->RemoteApplicationCmdLine);
freerdp_set_param_string(settings, FreeRDP_RemoteApplicationCmdLine, file->RemoteApplicationCmdLine);
if (~file->SpanMonitors)
settings->SpanMonitors = file->SpanMonitors;
freerdp_set_param_bool(settings, FreeRDP_SpanMonitors, file->SpanMonitors);
if (~file->UseMultiMon)
settings->UseMultimon = file->UseMultiMon;
freerdp_set_param_bool(settings, FreeRDP_UseMultimon, file->UseMultiMon);
return TRUE;
}

View File

@ -38,12 +38,14 @@ extern "C" {
typedef void (*pOnResizeWindow)(freerdp* instance, int width, int height);
typedef void (*pOnWindowStateChange)(freerdp* instance, int state);
typedef void (*pOnErrorInfo)(freerdp* instance, UINT32 code);
typedef void (*pOnParamChange)(freerdp* instance, int id);
struct rdp_client
{
pOnResizeWindow OnResizeWindow;
pOnWindowStateChange OnWindowStateChange;
pOnErrorInfo OnErrorInfo;
pOnParamChange OnParamChange;
};
/**

View File

@ -141,6 +141,10 @@ FREERDP_API BOOL freerdp_client_parse_rdp_file(rdpFile* file, char* name);
FREERDP_API BOOL freerdp_client_parse_rdp_file_buffer(rdpFile* file, BYTE* buffer, size_t size);
FREERDP_API BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings* settings);
FREERDP_API BOOL freerdp_client_populate_rdp_file_from_settings(rdpFile* file, rdpSettings* settings);
FREERDP_API BOOL freerdp_client_write_rdp_file(rdpFile* file, char* name, BOOL unicode);
FREERDP_API size_t freerdp_client_write_rdp_file_buffer(rdpFile* file, char* buffer, size_t size);
FREERDP_API rdpFile* freerdp_client_rdp_file_new(void);
FREERDP_API void freerdp_client_rdp_file_free(rdpFile* file);

View File

@ -1276,6 +1276,8 @@ struct rdp_settings
/* Extensions */
ALIGN64 int num_extensions; /* */
ALIGN64 struct rdp_ext_set extensions[16]; /* */
ALIGN64 BYTE* settings_modified; /* byte array marking fields that have been modified from their default value */
};
typedef struct rdp_settings rdpSettings;

View File

@ -28,6 +28,7 @@
#include <winpr/crt.h>
#include <freerdp/settings.h>
#include <freerdp/freerdp.h>
int freerdp_addin_set_argument(ADDIN_ARGV* args, char* argument)
{
@ -513,6 +514,10 @@ BOOL freerdp_get_param_bool(rdpSettings* settings, int id)
return settings->Decorations;
break;
case FreeRDP_SmartSizing:
return settings->SmartSizing;
break;
case FreeRDP_MouseMotion:
return settings->MouseMotion;
break;
@ -953,6 +958,10 @@ int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param)
settings->Decorations = param;
break;
case FreeRDP_SmartSizing:
settings->SmartSizing = param;
break;
case FreeRDP_MouseMotion:
settings->MouseMotion = param;
break;
@ -1174,6 +1183,10 @@ int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param)
break;
}
// Mark field as modified
settings->settings_modified[id] = 1;
IFCALL(((freerdp*) settings->instance)->context->client->OnParamChange, ((freerdp*) settings->instance), id);
return -1;
}
@ -1806,6 +1819,10 @@ int freerdp_set_param_uint32(rdpSettings* settings, int id, UINT32 param)
break;
}
// Mark field as modified
settings->settings_modified[id] = 1;
IFCALL(((freerdp*) settings->instance)->context->client->OnParamChange, ((freerdp*) settings->instance), id);
return 0;
}
@ -1838,6 +1855,10 @@ int freerdp_set_param_uint64(rdpSettings* settings, int id, UINT64 param)
break;
}
// Mark field as modified
settings->settings_modified[id] = 1;
IFCALL(((freerdp*) settings->instance)->context->client->OnParamChange, ((freerdp*) settings->instance), id);
return 0;
}
@ -2166,5 +2187,9 @@ int freerdp_set_param_string(rdpSettings* settings, int id, char* param)
break;
}
// Mark field as modified
settings->settings_modified[id] = 1;
IFCALL(((freerdp*) settings->instance)->context->client->OnParamChange, ((freerdp*) settings->instance), id);
return 0;
}

View File

@ -127,7 +127,7 @@ BOOL ntlm_client_make_spn(rdpNtlm* ntlm, LPCTSTR ServiceClass, char* hostname)
#ifdef UNICODE
length = strlen(hostname);
hostnameX = (LPWSTR) malloc(length * sizeof(TCHAR));
hostnameX = (LPWSTR) malloc((length + 1)* sizeof(TCHAR));
MultiByteToWideChar(CP_UTF8, 0, hostname, length, hostnameX, length);
hostnameX[length] = 0;
#else

View File

@ -416,6 +416,9 @@ rdpSettings* freerdp_settings_new(void* instance)
settings->ConfigPath = GetKnownSubPath(KNOWN_PATH_XDG_CONFIG_HOME, "freerdp");
settings_load_hkey_local_machine(settings);
settings->settings_modified = (BYTE*) malloc(sizeof(rdpSettings) / 8 );
ZeroMemory(settings->settings_modified, sizeof(rdpSettings) / 8);
}
return settings;
@ -460,6 +463,7 @@ void freerdp_settings_free(rdpSettings* settings)
freerdp_device_collection_free(settings);
freerdp_static_channel_collection_free(settings);
freerdp_dynamic_channel_collection_free(settings);
free(settings->settings_modified);
free(settings);
}
}

View File

@ -782,6 +782,7 @@ void gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_co
freerdp_bitmap_write(tile_bitmap, gdi->tile->bitmap->data, 64, 64, 32);
#endif
for (j = 0; j < message->num_rects; j++)
{
gdi_SetClipRgn(gdi->primary->hdc,