Merge git://github.com/awakecoding/FreeRDP

Latest updates from master branch (PubSub)
This commit is contained in:
Benoît LeBlanc 2013-06-17 09:21:56 -04:00
commit a5c57e1bfb
46 changed files with 1444 additions and 1085 deletions

View File

@ -44,27 +44,53 @@
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
int index;
int status;
wfInfo* wfi;
HANDLE thread;
wfContext* wfc;
DWORD dwExitCode;
rdpContext* context;
rdpSettings* settings;
RDP_CLIENT_ENTRY_POINTS clientEntryPoints;
freerdp_client_global_init();
ZeroMemory(&clientEntryPoints, sizeof(RDP_CLIENT_ENTRY_POINTS));
clientEntryPoints.Size = sizeof(RDP_CLIENT_ENTRY_POINTS);
clientEntryPoints.Version = RDP_CLIENT_INTERFACE_VERSION;
wfi = freerdp_client_new(__argc, __argv);
RdpClientEntry(&clientEntryPoints);
status = freerdp_client_start(wfi);
context = freerdp_client_context_new(&clientEntryPoints);
if (status < 0)
settings = context->settings;
wfc = (wfContext*) context;
context->argc = __argc;
context->argv = (char**) malloc(sizeof(char*) * __argc);
for (index = 0; index < context->argc; index++)
context->argv[index] = _strdup(__argv[index]);
status = freerdp_client_parse_command_line(context, context->argc, context->argv);
status = freerdp_client_command_line_status_print(context->argc, context->argv, settings, status);
if (status)
{
MessageBox(GetConsoleWindow(),
_T("Failed to start wfreerdp.\n\nPlease check the debug output."),
_T("FreeRDP Error"), MB_ICONSTOP);
}
else
{
WaitForSingleObject(wfi->thread, INFINITE);
freerdp_client_context_free(context);
return 0;
}
freerdp_client_free(wfi);
freerdp_client_start(context);
thread = freerdp_client_get_thread(context);
WaitForSingleObject(thread, INFINITE);
GetExitCodeThread(thread, &dwExitCode);
freerdp_client_stop(context);
freerdp_client_context_free(context);
return 0;
}

View File

@ -29,54 +29,54 @@
#include "wf_cliprdr.h"
void wf_cliprdr_init(wfInfo* wfi, rdpChannels* chanman)
void wf_cliprdr_init(wfContext* wfc, rdpChannels* channels)
{
}
void wf_cliprdr_uninit(wfInfo* wfi)
void wf_cliprdr_uninit(wfContext* wfc)
{
}
static void wf_cliprdr_process_cb_monitor_ready_event(wfInfo* wfi)
static void wf_cliprdr_process_cb_monitor_ready_event(wfContext* wfc)
{
}
static void wf_cliprdr_process_cb_data_request_event(wfInfo* wfi, RDP_CB_DATA_REQUEST_EVENT* event)
static void wf_cliprdr_process_cb_data_request_event(wfContext* wfc, RDP_CB_DATA_REQUEST_EVENT* event)
{
}
static void wf_cliprdr_process_cb_format_list_event(wfInfo* wfi, RDP_CB_FORMAT_LIST_EVENT* event)
static void wf_cliprdr_process_cb_format_list_event(wfContext* wfc, RDP_CB_FORMAT_LIST_EVENT* event)
{
}
static void wf_cliprdr_process_cb_data_response_event(wfInfo* wfi, RDP_CB_DATA_RESPONSE_EVENT* event)
static void wf_cliprdr_process_cb_data_response_event(wfContext* wfc, RDP_CB_DATA_RESPONSE_EVENT* event)
{
}
void wf_process_cliprdr_event(wfInfo* wfi, wMessage* event)
void wf_process_cliprdr_event(wfContext* wfc, wMessage* event)
{
switch (GetMessageType(event->id))
{
case CliprdrChannel_MonitorReady:
wf_cliprdr_process_cb_monitor_ready_event(wfi);
wf_cliprdr_process_cb_monitor_ready_event(wfc);
break;
case CliprdrChannel_FormatList:
wf_cliprdr_process_cb_format_list_event(wfi, (RDP_CB_FORMAT_LIST_EVENT*) event);
wf_cliprdr_process_cb_format_list_event(wfc, (RDP_CB_FORMAT_LIST_EVENT*) event);
break;
case CliprdrChannel_DataRequest:
wf_cliprdr_process_cb_data_request_event(wfi, (RDP_CB_DATA_REQUEST_EVENT*) event);
wf_cliprdr_process_cb_data_request_event(wfc, (RDP_CB_DATA_REQUEST_EVENT*) event);
break;
case CliprdrChannel_DataResponse:
wf_cliprdr_process_cb_data_response_event(wfi, (RDP_CB_DATA_RESPONSE_EVENT*) event);
wf_cliprdr_process_cb_data_response_event(wfc, (RDP_CB_DATA_RESPONSE_EVENT*) event);
break;
default:
@ -84,27 +84,27 @@ void wf_process_cliprdr_event(wfInfo* wfi, wMessage* event)
}
}
BOOL wf_cliprdr_process_selection_notify(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
BOOL wf_cliprdr_process_selection_notify(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
return TRUE;
}
BOOL wf_cliprdr_process_selection_request(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
BOOL wf_cliprdr_process_selection_request(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
return TRUE;
}
BOOL wf_cliprdr_process_selection_clear(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
BOOL wf_cliprdr_process_selection_clear(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
return TRUE;
}
BOOL wf_cliprdr_process_property_notify(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
BOOL wf_cliprdr_process_property_notify(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
return TRUE;
}
void wf_cliprdr_check_owner(wfInfo* wfi)
void wf_cliprdr_check_owner(wfContext* wfc)
{
}

View File

@ -21,13 +21,13 @@
#include "wf_interface.h"
void wf_cliprdr_init(wfInfo* wfi, rdpChannels* chanman);
void wf_cliprdr_uninit(wfInfo* wfi);
void wf_process_cliprdr_event(wfInfo* wfi, wMessage* event);
BOOL wf_cliprdr_process_selection_notify(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
BOOL wf_cliprdr_process_selection_request(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
BOOL wf_cliprdr_process_selection_clear(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
BOOL wf_cliprdr_process_property_notify(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
void wf_cliprdr_check_owner(wfInfo* wfi);
void wf_cliprdr_init(wfContext* wfc, rdpChannels* channels);
void wf_cliprdr_uninit(wfContext* wfc);
void wf_process_cliprdr_event(wfContext* wfc, wMessage* event);
BOOL wf_cliprdr_process_selection_notify(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
BOOL wf_cliprdr_process_selection_request(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
BOOL wf_cliprdr_process_selection_clear(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
BOOL wf_cliprdr_process_property_notify(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
void wf_cliprdr_check_owner(wfContext* wfc);
#endif /* __WF_CLIPRDR_H */

View File

@ -37,12 +37,12 @@ static HWND g_focus_hWnd;
#define X_POS(lParam) (lParam & 0xFFFF)
#define Y_POS(lParam) ((lParam >> 16) & 0xFFFF)
BOOL wf_scale_blt(wfInfo* wfi, HDC hdc, int x, int y, int w, int h, HDC hdcSrc, int x1, int y1, DWORD rop);
void wf_scale_mouse_event(wfInfo* wfi, rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
BOOL wf_scale_blt(wfContext* wfc, HDC hdc, int x, int y, int w, int h, HDC hdcSrc, int x1, int y1, DWORD rop);
void wf_scale_mouse_event(wfContext* wfc, rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam)
{
wfInfo* wfi;
wfContext* wfc;
DWORD rdp_scancode;
rdpInput* input;
PKBDLLHOOKSTRUCT p;
@ -57,26 +57,26 @@ LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam)
case WM_SYSKEYDOWN:
case WM_KEYUP:
case WM_SYSKEYUP:
wfi = (wfInfo*) GetWindowLongPtr(g_focus_hWnd, GWLP_USERDATA);
wfc = (wfContext*) GetWindowLongPtr(g_focus_hWnd, GWLP_USERDATA);
p = (PKBDLLHOOKSTRUCT) lParam;
if (!wfi || !p)
if (!wfc || !p)
return 1;
input = wfi->instance->input;
input = wfc->instance->input;
rdp_scancode = MAKE_RDP_SCANCODE((BYTE) p->scanCode, p->flags & LLKHF_EXTENDED);
DEBUG_KBD("keydown %d scanCode %04X flags %02X vkCode %02X",
(wParam == WM_KEYDOWN), (BYTE) p->scanCode, p->flags, p->vkCode);
if (wfi->fs_toggle &&
if (wfc->fs_toggle &&
((p->vkCode == VK_RETURN) || (p->vkCode == VK_CANCEL)) &&
(GetAsyncKeyState(VK_CONTROL) & 0x8000) &&
(GetAsyncKeyState(VK_MENU) & 0x8000)) /* could also use flags & LLKHF_ALTDOWN */
{
if (wParam == WM_KEYDOWN)
{
wf_toggle_fullscreen(wfi);
wf_toggle_fullscreen(wfc);
return 1;
}
}
@ -126,14 +126,14 @@ LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam)
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
static int wf_event_process_WM_MOUSEWHEEL(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
static int wf_event_process_WM_MOUSEWHEEL(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
int delta;
int flags;
rdpInput* input;
DefWindowProc(hWnd, Msg, wParam, lParam);
input = wfi->instance->input;
input = wfc->instance->input;
delta = ((signed short) HIWORD(wParam)); /* GET_WHEEL_DELTA_WPARAM(wParam); */
if (delta > 0)
@ -150,11 +150,12 @@ 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)
void wf_sizing(wfContext* wfc, 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))
if (wfc->instance->settings->SmartSizing && (GetAsyncKeyState(VK_CONTROL) & 0x8000))
{
rect = (LPRECT) wParam;
@ -164,20 +165,20 @@ void wf_sizing(wfInfo* wfi, WPARAM wParam, LPARAM lParam)
case WMSZ_RIGHT:
case WMSZ_BOTTOMRIGHT:
// Adjust height
rect->bottom = rect->top + wfi->height * (rect->right - rect->left) / wfi->instance->settings->DesktopWidth;
rect->bottom = rect->top + wfc->height * (rect->right - rect->left) / wfc->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;
rect->right = rect->left + wfc->width * (rect->bottom - rect->top) / wfc->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);
rect->left = rect->right - (wfc->width * (rect->bottom - rect->top) / wfc->instance->settings->DesktopHeight);
break;
}
@ -189,38 +190,38 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
{
HDC hdc;
LONG ptr;
wfInfo* wfi;
wfContext* wfc;
int x, y, w, h;
PAINTSTRUCT ps;
rdpInput* input;
BOOL processed;
RECT windowRect, clientRect;
MINMAXINFO *minmax;
RECT windowRect;
RECT clientRect;
MINMAXINFO* minmax;
SCROLLINFO si;
processed = TRUE;
ptr = GetWindowLongPtr(hWnd, GWLP_USERDATA);
wfi = (wfInfo*) ptr;
wfc = (wfContext*) ptr;
if (wfi != NULL)
if (wfc != NULL)
{
input = wfi->instance->input;
input = wfc->instance->input;
switch (Msg)
{
case WM_MOVE:
if (!wfi->disablewindowtracking)
if (!wfc->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;
wfc->client_x = x;
wfc->client_y = y;
}
break;
case WM_GETMINMAXINFO:
if (wfi->instance->settings->SmartSizing)
if (wfc->instance->settings->SmartSizing)
{
processed = FALSE;
}
@ -229,41 +230,42 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
// Set maximum window size for resizing
minmax = (MINMAXINFO*) lParam;
wf_update_canvas_diff(wfi);
if (!wfi->fullscreen)
wf_update_canvas_diff(wfc);
if (!wfc->fullscreen)
{
// add window decoration
minmax->ptMaxTrackSize.x = wfi->width + wfi->diff.x;
minmax->ptMaxTrackSize.y = wfi->height + wfi->diff.y;
minmax->ptMaxTrackSize.x = wfc->width + wfc->diff.x;
minmax->ptMaxTrackSize.y = wfc->height + wfc->diff.y;
}
}
break;
case WM_SIZING:
wf_sizing(wfi, lParam, wParam);
wf_sizing(wfc, lParam, wParam);
break;
case WM_SIZE:
GetWindowRect(wfi->hwnd, &windowRect);
GetWindowRect(wfc->hwnd, &windowRect);
if (!wfi->fullscreen)
if (!wfc->fullscreen)
{
wfi->client_width = LOWORD(lParam);
wfi->client_height = HIWORD(lParam);
wfi->client_x = windowRect.left;
wfi->client_y = windowRect.top;
wfc->client_width = LOWORD(lParam);
wfc->client_height = HIWORD(lParam);
wfc->client_x = windowRect.left;
wfc->client_y = windowRect.top;
}
wf_size_scrollbars(wfi, LOWORD(lParam), HIWORD(lParam));
wf_size_scrollbars(wfc, 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);
if (wParam == SIZE_MAXIMIZED && !wfc->fullscreen)
SetWindowPos(wfc->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);
wf_size_scrollbars(wfc, wfc->client_width, wfc->client_height);
break;
case WM_ERASEBKGND:
@ -278,38 +280,38 @@ 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 + wfi->xCurrentScroll, y - wfi->offset_y + wfi->yCurrentScroll, SRCCOPY);
wf_scale_blt(wfc, hdc, x, y, w, h, wfc->primary->hdc, x - wfc->offset_x + wfc->xCurrentScroll, y - wfc->offset_y + wfc->yCurrentScroll, SRCCOPY);
EndPaint(hWnd, &ps);
break;
case WM_LBUTTONDOWN:
wf_scale_mouse_event(wfi, input,PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y);
wf_scale_mouse_event(wfc, input,PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1, X_POS(lParam) - wfc->offset_x, Y_POS(lParam) - wfc->offset_y);
break;
case WM_LBUTTONUP:
wf_scale_mouse_event(wfi, input, PTR_FLAGS_BUTTON1, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y);
wf_scale_mouse_event(wfc, input, PTR_FLAGS_BUTTON1, X_POS(lParam) - wfc->offset_x, Y_POS(lParam) - wfc->offset_y);
break;
case WM_RBUTTONDOWN:
wf_scale_mouse_event(wfi, input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y);
wf_scale_mouse_event(wfc, input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2, X_POS(lParam) - wfc->offset_x, Y_POS(lParam) - wfc->offset_y);
break;
case WM_RBUTTONUP:
wf_scale_mouse_event(wfi, input, PTR_FLAGS_BUTTON2, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y);
wf_scale_mouse_event(wfc, input, PTR_FLAGS_BUTTON2, X_POS(lParam) - wfc->offset_x, Y_POS(lParam) - wfc->offset_y);
break;
case WM_MOUSEMOVE:
wf_scale_mouse_event(wfi, input, PTR_FLAGS_MOVE, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y);
wf_scale_mouse_event(wfc, input, PTR_FLAGS_MOVE, X_POS(lParam) - wfc->offset_x, Y_POS(lParam) - wfc->offset_y);
break;
case WM_MOUSEWHEEL:
wf_event_process_WM_MOUSEWHEEL(wfi, hWnd, Msg, wParam, lParam);
wf_event_process_WM_MOUSEWHEEL(wfc, hWnd, Msg, wParam, lParam);
break;
case WM_SETCURSOR:
if (LOWORD(lParam) == HTCLIENT)
SetCursor(wfi->cursor);
SetCursor(wfc->cursor);
else
DefWindowProc(hWnd, Msg, wParam, lParam);
break;
@ -324,22 +326,22 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
{
// User clicked the scroll bar shaft left of the scroll box.
case SB_PAGEUP:
xNewPos = wfi->xCurrentScroll - 50;
xNewPos = wfc->xCurrentScroll - 50;
break;
// User clicked the scroll bar shaft right of the scroll box.
case SB_PAGEDOWN:
xNewPos = wfi->xCurrentScroll + 50;
xNewPos = wfc->xCurrentScroll + 50;
break;
// User clicked the left arrow.
case SB_LINEUP:
xNewPos = wfi->xCurrentScroll - 5;
xNewPos = wfc->xCurrentScroll - 5;
break;
// User clicked the right arrow.
case SB_LINEDOWN:
xNewPos = wfi->xCurrentScroll + 5;
xNewPos = wfc->xCurrentScroll + 5;
break;
// User dragged the scroll box.
@ -352,37 +354,37 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
break;
default:
xNewPos = wfi->xCurrentScroll;
xNewPos = wfc->xCurrentScroll;
}
// New position must be between 0 and the screen width.
xNewPos = MAX(0, xNewPos);
xNewPos = MIN(wfi->xMaxScroll, xNewPos);
xNewPos = MIN(wfc->xMaxScroll, xNewPos);
// If the current position does not change, do not scroll.
if (xNewPos == wfi->xCurrentScroll)
if (xNewPos == wfc->xCurrentScroll)
break;
// Determine the amount scrolled (in pixels).
xDelta = xNewPos - wfi->xCurrentScroll;
xDelta = xNewPos - wfc->xCurrentScroll;
// Reset the current scroll position.
wfi->xCurrentScroll = xNewPos;
wfc->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,
ScrollWindowEx(wfc->hwnd, -xDelta, -yDelta, (CONST RECT *) NULL,
(CONST RECT *) NULL, (HRGN) NULL, (PRECT) NULL,
SW_INVALIDATE);
UpdateWindow(wfi->hwnd);
UpdateWindow(wfc->hwnd);
// Reset the scroll bar.
si.cbSize = sizeof(si);
si.fMask = SIF_POS;
si.nPos = wfi->xCurrentScroll;
SetScrollInfo(wfi->hwnd, SB_HORZ, &si, TRUE);
si.nPos = wfc->xCurrentScroll;
SetScrollInfo(wfc->hwnd, SB_HORZ, &si, TRUE);
}
break;
@ -396,22 +398,22 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
{
// User clicked the scroll bar shaft above the scroll box.
case SB_PAGEUP:
yNewPos = wfi->yCurrentScroll - 50;
yNewPos = wfc->yCurrentScroll - 50;
break;
// User clicked the scroll bar shaft below the scroll box.
case SB_PAGEDOWN:
yNewPos = wfi->yCurrentScroll + 50;
yNewPos = wfc->yCurrentScroll + 50;
break;
// User clicked the top arrow.
case SB_LINEUP:
yNewPos = wfi->yCurrentScroll - 5;
yNewPos = wfc->yCurrentScroll - 5;
break;
// User clicked the bottom arrow.
case SB_LINEDOWN:
yNewPos = wfi->yCurrentScroll + 5;
yNewPos = wfc->yCurrentScroll + 5;
break;
// User dragged the scroll box.
@ -425,37 +427,37 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
break;
default:
yNewPos = wfi->yCurrentScroll;
yNewPos = wfc->yCurrentScroll;
}
// New position must be between 0 and the screen height.
yNewPos = MAX(0, yNewPos);
yNewPos = MIN(wfi->yMaxScroll, yNewPos);
yNewPos = MIN(wfc->yMaxScroll, yNewPos);
// If the current position does not change, do not scroll.
if (yNewPos == wfi->yCurrentScroll)
if (yNewPos == wfc->yCurrentScroll)
break;
// Determine the amount scrolled (in pixels).
yDelta = yNewPos - wfi->yCurrentScroll;
yDelta = yNewPos - wfc->yCurrentScroll;
// Reset the current scroll position.
wfi->yCurrentScroll = yNewPos;
wfc->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,
ScrollWindowEx(wfc->hwnd, -xDelta, -yDelta, (CONST RECT *) NULL,
(CONST RECT *) NULL, (HRGN) NULL, (PRECT) NULL,
SW_INVALIDATE);
UpdateWindow(wfi->hwnd);
UpdateWindow(wfc->hwnd);
// Reset the scroll bar.
si.cbSize = sizeof(si);
si.fMask = SIF_POS;
si.nPos = wfi->yCurrentScroll;
SetScrollInfo(wfi->hwnd, SB_VERT, &si, TRUE);
si.nPos = wfc->yCurrentScroll;
SetScrollInfo(wfc->hwnd, SB_VERT, &si, TRUE);
}
break;
@ -463,9 +465,9 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
{
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);
HMENU hMenu = GetSystemMenu(wfc->hwnd, FALSE);
freerdp_set_param_bool(wfc->instance->settings, FreeRDP_SmartSizing, !wfc->instance->settings->SmartSizing);
CheckMenuItem(hMenu, SYSCOMMAND_ID_SMARTSIZING, wfc->instance->settings->SmartSizing ? MF_CHECKED : MF_UNCHECKED);
}
else
@ -496,7 +498,7 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
case WM_SETCURSOR:
if (LOWORD(lParam) == HTCLIENT)
SetCursor(wfi->hDefaultCursor);
SetCursor(wfc->hDefaultCursor);
else
DefWindowProc(hWnd, Msg, wParam, lParam);
break;
@ -507,7 +509,7 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
break;
case WM_KILLFOCUS:
if (g_focus_hWnd == hWnd && wfi && !wfi->fullscreen)
if (g_focus_hWnd == hWnd && wfc && !wfc->fullscreen)
{
DEBUG_KBD("loosing focus %X", hWnd);
g_focus_hWnd = NULL;
@ -535,20 +537,20 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
return 0;
}
BOOL wf_scale_blt(wfInfo* wfi, HDC hdc, int x, int y, int w, int h, HDC hdcSrc, int x1, int y1, DWORD rop)
BOOL wf_scale_blt(wfContext* wfc, HDC hdc, int x, int y, int w, int h, HDC hdcSrc, int x1, int y1, DWORD rop)
{
int ww, wh, dw, dh;
if (!wfi->client_width)
wfi->client_width = wfi->width;
if (!wfc->client_width)
wfc->client_width = wfc->width;
if (!wfi->client_height)
wfi->client_height = wfi->height;
if (!wfc->client_height)
wfc->client_height = wfc->height;
ww = wfi->client_width;
wh = wfi->client_height;
dw = wfi->instance->settings->DesktopWidth;
dh = wfi->instance->settings->DesktopHeight;
ww = wfc->client_width;
wh = wfc->client_height;
dw = wfc->instance->settings->DesktopWidth;
dh = wfc->instance->settings->DesktopHeight;
if (!ww)
ww = dw;
@ -556,38 +558,38 @@ BOOL wf_scale_blt(wfInfo* wfi, HDC hdc, int x, int y, int w, int h, HDC hdcSrc,
if (!wh)
wh = dh;
if (wfi->fullscreen || !wfi->instance->settings->SmartSizing || (ww == dw && wh == dh))
if (wfc->fullscreen || !wfc->instance->settings->SmartSizing || (ww == dw && wh == dh))
{
return BitBlt(hdc, x, y, w, h, wfi->primary->hdc, x1, y1, SRCCOPY);
return BitBlt(hdc, x, y, w, h, wfc->primary->hdc, x1, y1, SRCCOPY);
}
else
{
SetStretchBltMode(hdc, HALFTONE);
SetBrushOrgEx(hdc, 0, 0, NULL);
return StretchBlt(hdc, 0, 0, ww, wh, wfi->primary->hdc, 0, 0, dw, dh, SRCCOPY);
return StretchBlt(hdc, 0, 0, ww, wh, wfc->primary->hdc, 0, 0, dw, dh, SRCCOPY);
}
return TRUE;
}
void wf_scale_mouse_event(wfInfo* wfi, rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
void wf_scale_mouse_event(wfContext* wfc, rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
{
int ww, wh, dw, dh;
if (!wfi->client_width)
wfi->client_width = wfi->width;
if (!wfc->client_width)
wfc->client_width = wfc->width;
if (!wfi->client_height)
wfi->client_height = wfi->height;
if (!wfc->client_height)
wfc->client_height = wfc->height;
ww = wfi->client_width;
wh = wfi->client_height;
dw = wfi->instance->settings->DesktopWidth;
dh = wfi->instance->settings->DesktopHeight;
ww = wfc->client_width;
wh = wfc->client_height;
dw = wfc->instance->settings->DesktopWidth;
dh = wfc->instance->settings->DesktopHeight;
if (!wfi->instance->settings->SmartSizing || (ww == dw) && (wh == dh))
input->MouseEvent(input, flags, x + wfi->xCurrentScroll, y + wfi->yCurrentScroll);
if (!wfc->instance->settings->SmartSizing || (ww == dw) && (wh == dh))
input->MouseEvent(input, flags, x + wfc->xCurrentScroll, y + wfc->yCurrentScroll);
else
input->MouseEvent(input, flags, x * dw / ww + wfi->xCurrentScroll, y * dh / wh + wfi->yCurrentScroll);
input->MouseEvent(input, flags, x * dw / ww + wfc->xCurrentScroll, y * dh / wh + wfc->yCurrentScroll);
}

View File

@ -72,10 +72,10 @@ BOOL wf_set_rop2(HDC hdc, int rop2)
return TRUE;
}
wfBitmap* wf_glyph_new(wfInfo* wfi, GLYPH_DATA* glyph)
wfBitmap* wf_glyph_new(wfContext* wfc, GLYPH_DATA* glyph)
{
wfBitmap* glyph_bmp;
glyph_bmp = wf_image_new(wfi, glyph->cx, glyph->cy, 1, glyph->aj);
glyph_bmp = wf_image_new(wfc, glyph->cx, glyph->cy, 1, glyph->aj);
return glyph_bmp;
}
@ -84,7 +84,7 @@ void wf_glyph_free(wfBitmap* glyph)
wf_image_free(glyph);
}
BYTE* wf_glyph_convert(wfInfo* wfi, int width, int height, BYTE* data)
BYTE* wf_glyph_convert(wfContext* wfc, int width, int height, BYTE* data)
{
int indexx;
int indexy;
@ -115,7 +115,7 @@ BYTE* wf_glyph_convert(wfInfo* wfi, int width, int height, BYTE* data)
return cdata;
}
HBRUSH wf_create_brush(wfInfo * wfi, rdpBrush* brush, UINT32 color, int bpp)
HBRUSH wf_create_brush(wfContext* wfc, rdpBrush* brush, UINT32 color, int bpp)
{
int i;
HBRUSH br;
@ -135,7 +135,7 @@ HBRUSH wf_create_brush(wfInfo * wfi, rdpBrush* brush, UINT32 color, int bpp)
{
if (brush->bpp > 1)
{
pattern = wf_create_dib(wfi, 8, 8, bpp, brush->data, NULL);
pattern = wf_create_dib(wfc, 8, 8, bpp, brush->data, NULL);
lbr.lbHatch = (ULONG_PTR) pattern;
}
else
@ -143,7 +143,7 @@ HBRUSH wf_create_brush(wfInfo * wfi, rdpBrush* brush, UINT32 color, int bpp)
for (i = 0; i != 8; i++)
ipattern[7 - i] = brush->data[i];
cdata = wf_glyph_convert(wfi, 8, 8, ipattern);
cdata = wf_glyph_convert(wfc, 8, 8, ipattern);
pattern = CreateBitmap(8, 8, 1, 1, cdata);
lbr.lbHatch = (ULONG_PTR) pattern;
free(cdata);
@ -159,7 +159,7 @@ HBRUSH wf_create_brush(wfInfo * wfi, rdpBrush* brush, UINT32 color, int bpp)
}
br = CreateBrushIndirect(&lbr);
SetBrushOrgEx(wfi->drawing->hdc, brush->x, brush->y, NULL);
SetBrushOrgEx(wfc->drawing->hdc, brush->x, brush->y, NULL);
if (pattern != NULL)
DeleteObject(pattern);
@ -167,20 +167,20 @@ HBRUSH wf_create_brush(wfInfo * wfi, rdpBrush* brush, UINT32 color, int bpp)
return br;
}
void wf_scale_rect(wfInfo* wfi, RECT* source)
void wf_scale_rect(wfContext* wfc, RECT* source)
{
int ww, wh, dw, dh;
if (!wfi->client_width)
wfi->client_width = wfi->width;
if (!wfc->client_width)
wfc->client_width = wfc->width;
if (!wfi->client_height)
wfi->client_height = wfi->height;
if (!wfc->client_height)
wfc->client_height = wfc->height;
ww = wfi->client_width;
wh = wfi->client_height;
dw = wfi->instance->settings->DesktopWidth;
dh = wfi->instance->settings->DesktopHeight;
ww = wfc->client_width;
wh = wfc->client_height;
dw = wfc->instance->settings->DesktopWidth;
dh = wfc->instance->settings->DesktopHeight;
if (!ww)
ww = dw;
@ -188,7 +188,7 @@ void wf_scale_rect(wfInfo* wfi, RECT* source)
if (!wh)
wh = dh;
if (wfi->instance->settings->SmartSizing && (ww != dw || wh != dh))
if (wfc->instance->settings->SmartSizing && (ww != dw || wh != dh))
{
source->bottom = source->bottom * wh / dh + 20;
source->top = source->top * wh / dh - 20;
@ -196,197 +196,194 @@ void wf_scale_rect(wfInfo* wfi, RECT* source)
source->right = source->right * ww / dw + 20;
}
source->bottom -= wfi->yCurrentScroll;
source->top -= wfi->yCurrentScroll;
source->left -= wfi->xCurrentScroll;
source->right -= wfi->xCurrentScroll;
source->bottom -= wfc->yCurrentScroll;
source->top -= wfc->yCurrentScroll;
source->left -= wfc->xCurrentScroll;
source->right -= wfc->xCurrentScroll;
}
void wf_invalidate_region(wfInfo* wfi, int x, int y, int width, int height)
void wf_invalidate_region(wfContext* wfc, int x, int y, int width, int height)
{
RECT rect;
wfi->update_rect.left = x + wfi->offset_x;
wfi->update_rect.top = y + wfi->offset_y;
wfi->update_rect.right = wfi->update_rect.left + width;
wfi->update_rect.bottom = wfi->update_rect.top + height;
wfc->update_rect.left = x + wfc->offset_x;
wfc->update_rect.top = y + wfc->offset_y;
wfc->update_rect.right = wfc->update_rect.left + width;
wfc->update_rect.bottom = wfc->update_rect.top + height;
wf_scale_rect(wfi, &(wfi->update_rect));
InvalidateRect(wfi->hwnd, &(wfi->update_rect), FALSE);
wf_scale_rect(wfc, &(wfc->update_rect));
InvalidateRect(wfc->hwnd, &(wfc->update_rect), FALSE);
rect.left = x;
rect.right = width;
rect.top = y;
rect.bottom = height;
wf_scale_rect(wfi, &rect);
gdi_InvalidateRegion(wfi->hdc, rect.left, rect.top, rect.right, rect.bottom);
wf_scale_rect(wfc, &rect);
gdi_InvalidateRegion(wfc->hdc, rect.left, rect.top, rect.right, rect.bottom);
}
void wf_update_offset(wfInfo* wfi)
void wf_update_offset(wfContext* wfc)
{
if (wfi->fullscreen)
if (wfc->fullscreen)
{
if (wfi->instance->settings->UseMultimon)
if (wfc->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;
wfc->offset_x = (w - wfc->width) / 2;
if (wfc->offset_x < x)
wfc->offset_x = x;
wfc->offset_y = (h - wfc->height) / 2;
if (wfc->offset_y < y)
wfc->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;
wfc->offset_x = (GetSystemMetrics(SM_CXSCREEN) - wfc->width) / 2;
if (wfc->offset_x < 0)
wfc->offset_x = 0;
wfc->offset_y = (GetSystemMetrics(SM_CYSCREEN) - wfc->height) / 2;
if (wfc->offset_y < 0)
wfc->offset_y = 0;
}
}
else
{
wfi->offset_x = 0;
wfi->offset_y = 0;
wfc->offset_x = 0;
wfc->offset_y = 0;
}
}
void wf_resize_window(wfInfo* wfi)
void wf_resize_window(wfContext* wfc)
{
if (wfi->fullscreen)
if (wfc->fullscreen)
{
if(wfi->instance->settings->UseMultimon)
if(wfc->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);
SetWindowLongPtr(wfc->hwnd, GWL_STYLE, WS_POPUP);
SetWindowPos(wfc->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);
SetWindowLongPtr(wfc->hwnd, GWL_STYLE, WS_POPUP);
SetWindowPos(wfc->hwnd, HWND_TOP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), SWP_FRAMECHANGED);
}
}
else if (!wfi->instance->settings->Decorations)
else if (!wfc->instance->settings->Decorations)
{
RECT rc_wnd;
RECT rc_client;
SetWindowLongPtr(wfi->hwnd, GWL_STYLE, WS_CHILD);
SetWindowLongPtr(wfc->hwnd, GWL_STYLE, WS_CHILD);
/* 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);
SetWindowPos(wfc->hwnd, HWND_TOP, 0, 0, wfc->width, wfc->height, SWP_FRAMECHANGED);
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);
wf_update_canvas_diff(wfc);
SetWindowPos(wfc->hwnd, HWND_TOP, -1, -1, wfc->width + wfc->diff.x, wfc->height + wfc->diff.y, SWP_NOMOVE | SWP_FRAMECHANGED);
}
else
{
RECT rc_wnd;
RECT rc_client;
SetWindowLongPtr(wfi->hwnd, GWL_STYLE, WS_CAPTION | WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX | WS_SIZEBOX | WS_MAXIMIZEBOX);
SetWindowLongPtr(wfc->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 (!wfc->client_height)
wfc->client_height = wfc->height;
if (!wfi->client_width)
wfi->client_width = wfi->width;
if (!wfc->client_width)
wfc->client_width = wfc->width;
if (!wfi->client_x)
wfi->client_x = 10;
if (!wfc->client_x)
wfc->client_x = 10;
if (!wfi->client_y)
wfi->client_y = 10;
if (!wfc->client_y)
wfc->client_y = 10;
wf_update_canvas_diff(wfi);
wf_update_canvas_diff(wfc);
/* 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, 0 /*SWP_FRAMECHANGED*/);
//wf_size_scrollbars(wfi, wfi->client_width, wfi->client_height);
SetWindowPos(wfc->hwnd, HWND_TOP, wfc->client_x, wfc->client_y, wfc->client_width + wfc->diff.x, wfc->client_height + wfc->diff.y, 0 /*SWP_FRAMECHANGED*/);
//wf_size_scrollbars(wfc, wfc->client_width, wfc->client_height);
}
wf_update_offset(wfi);
wf_update_offset(wfc);
}
void wf_toggle_fullscreen(wfInfo* wfi)
void wf_toggle_fullscreen(wfContext* wfc)
{
ShowWindow(wfi->hwnd, SW_HIDE);
wfi->fullscreen = !wfi->fullscreen;
ShowWindow(wfc->hwnd, SW_HIDE);
wfc->fullscreen = !wfc->fullscreen;
if (wfi->fullscreen)
if (wfc->fullscreen)
{
wfi->disablewindowtracking = TRUE;
wfc->disablewindowtracking = TRUE;
}
SetParent(wfi->hwnd, wfi->fullscreen ? NULL : wfi->hWndParent);
wf_resize_window(wfi);
ShowWindow(wfi->hwnd, SW_SHOW);
SetForegroundWindow(wfi->hwnd);
SetParent(wfc->hwnd, wfc->fullscreen ? NULL : wfc->hWndParent);
wf_resize_window(wfc);
ShowWindow(wfc->hwnd, SW_SHOW);
SetForegroundWindow(wfc->hwnd);
if (!wfi->fullscreen)
if (!wfc->fullscreen)
{
// Reenable window tracking AFTER resizing it back, otherwise it can lean to repositioning errors.
wfi->disablewindowtracking = FALSE;
wfc->disablewindowtracking = FALSE;
}
}
void wf_gdi_palette_update(rdpContext* context, PALETTE_UPDATE* palette)
void wf_gdi_palette_update(wfContext* wfc, PALETTE_UPDATE* palette)
{
}
void wf_set_null_clip_rgn(wfInfo* wfi)
void wf_set_null_clip_rgn(wfContext* wfc)
{
SelectClipRgn(wfi->drawing->hdc, NULL);
SelectClipRgn(wfc->drawing->hdc, NULL);
}
void wf_set_clip_rgn(wfInfo* wfi, int x, int y, int width, int height)
void wf_set_clip_rgn(wfContext* wfc, int x, int y, int width, int height)
{
HRGN clip;
clip = CreateRectRgn(x, y, x + width, y + height);
SelectClipRgn(wfi->drawing->hdc, clip);
SelectClipRgn(wfc->drawing->hdc, clip);
DeleteObject(clip);
}
void wf_gdi_set_bounds(rdpContext* context, rdpBounds* bounds)
void wf_gdi_set_bounds(wfContext* wfc, rdpBounds* bounds)
{
HRGN hrgn;
wfInfo* wfi = ((wfContext*) context)->wfi;
if (bounds != NULL)
{
hrgn = CreateRectRgn(bounds->left, bounds->top, bounds->right + 1, bounds->bottom + 1);
SelectClipRgn(wfi->drawing->hdc, hrgn);
SelectClipRgn(wfc->drawing->hdc, hrgn);
DeleteObject(hrgn);
}
else
{
SelectClipRgn(wfi->drawing->hdc, NULL);
SelectClipRgn(wfc->drawing->hdc, NULL);
}
}
void wf_gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt)
void wf_gdi_dstblt(wfContext* wfc, DSTBLT_ORDER* dstblt)
{
wfInfo* wfi = ((wfContext*) context)->wfi;
BitBlt(wfi->drawing->hdc, dstblt->nLeftRect, dstblt->nTopRect,
BitBlt(wfc->drawing->hdc, dstblt->nLeftRect, dstblt->nTopRect,
dstblt->nWidth, dstblt->nHeight, NULL, 0, 0, gdi_rop3_code(dstblt->bRop));
wf_invalidate_region(wfi, dstblt->nLeftRect, dstblt->nTopRect,
wf_invalidate_region(wfc, dstblt->nLeftRect, dstblt->nTopRect,
dstblt->nWidth, dstblt->nHeight);
}
void wf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
void wf_gdi_patblt(wfContext* wfc, PATBLT_ORDER* patblt)
{
HBRUSH brush;
HBRUSH org_brush;
@ -395,78 +392,73 @@ void wf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
UINT32 bgcolor;
COLORREF org_bkcolor;
COLORREF org_textcolor;
wfInfo* wfi = ((wfContext*) context)->wfi;
fgcolor = freerdp_color_convert_bgr(patblt->foreColor, wfi->srcBpp, wfi->dstBpp, wfi->clrconv);
bgcolor = freerdp_color_convert_bgr(patblt->backColor, wfi->srcBpp, wfi->dstBpp, wfi->clrconv);
fgcolor = freerdp_color_convert_bgr(patblt->foreColor, wfc->srcBpp, wfc->dstBpp, wfc->clrconv);
bgcolor = freerdp_color_convert_bgr(patblt->backColor, wfc->srcBpp, wfc->dstBpp, wfc->clrconv);
brush = wf_create_brush(wfi, &patblt->brush, fgcolor, wfi->srcBpp);
org_bkmode = SetBkMode(wfi->drawing->hdc, OPAQUE);
org_bkcolor = SetBkColor(wfi->drawing->hdc, bgcolor);
org_textcolor = SetTextColor(wfi->drawing->hdc, fgcolor);
org_brush = (HBRUSH)SelectObject(wfi->drawing->hdc, brush);
brush = wf_create_brush(wfc, &patblt->brush, fgcolor, wfc->srcBpp);
org_bkmode = SetBkMode(wfc->drawing->hdc, OPAQUE);
org_bkcolor = SetBkColor(wfc->drawing->hdc, bgcolor);
org_textcolor = SetTextColor(wfc->drawing->hdc, fgcolor);
org_brush = (HBRUSH)SelectObject(wfc->drawing->hdc, brush);
PatBlt(wfi->drawing->hdc, patblt->nLeftRect, patblt->nTopRect,
PatBlt(wfc->drawing->hdc, patblt->nLeftRect, patblt->nTopRect,
patblt->nWidth, patblt->nHeight, gdi_rop3_code(patblt->bRop));
SelectObject(wfi->drawing->hdc, org_brush);
SelectObject(wfc->drawing->hdc, org_brush);
DeleteObject(brush);
SetBkMode(wfi->drawing->hdc, org_bkmode);
SetBkColor(wfi->drawing->hdc, org_bkcolor);
SetTextColor(wfi->drawing->hdc, org_textcolor);
SetBkMode(wfc->drawing->hdc, org_bkmode);
SetBkColor(wfc->drawing->hdc, org_bkcolor);
SetTextColor(wfc->drawing->hdc, org_textcolor);
if (wfi->drawing == wfi->primary)
wf_invalidate_region(wfi, patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight);
if (wfc->drawing == wfc->primary)
wf_invalidate_region(wfc, patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight);
}
void wf_gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt)
void wf_gdi_scrblt(wfContext* wfc, SCRBLT_ORDER* scrblt)
{
wfInfo* wfi = ((wfContext*) context)->wfi;
BitBlt(wfi->drawing->hdc, scrblt->nLeftRect, scrblt->nTopRect,
scrblt->nWidth, scrblt->nHeight, wfi->primary->hdc,
BitBlt(wfc->drawing->hdc, scrblt->nLeftRect, scrblt->nTopRect,
scrblt->nWidth, scrblt->nHeight, wfc->primary->hdc,
scrblt->nXSrc, scrblt->nYSrc, gdi_rop3_code(scrblt->bRop));
wf_invalidate_region(wfi, scrblt->nLeftRect, scrblt->nTopRect,
wf_invalidate_region(wfc, scrblt->nLeftRect, scrblt->nTopRect,
scrblt->nWidth, scrblt->nHeight);
}
void wf_gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect)
void wf_gdi_opaque_rect(wfContext* wfc, OPAQUE_RECT_ORDER* opaque_rect)
{
RECT rect;
HBRUSH brush;
UINT32 brush_color;
wfInfo* wfi = ((wfContext*) context)->wfi;
brush_color = freerdp_color_convert_var_bgr(opaque_rect->color, wfi->srcBpp, wfi->dstBpp, wfi->clrconv);
brush_color = freerdp_color_convert_var_bgr(opaque_rect->color, wfc->srcBpp, wfc->dstBpp, wfc->clrconv);
rect.left = opaque_rect->nLeftRect;
rect.top = opaque_rect->nTopRect;
rect.right = opaque_rect->nLeftRect + opaque_rect->nWidth;
rect.bottom = opaque_rect->nTopRect + opaque_rect->nHeight;
brush = CreateSolidBrush(brush_color);
FillRect(wfi->drawing->hdc, &rect, brush);
FillRect(wfc->drawing->hdc, &rect, brush);
DeleteObject(brush);
if (wfi->drawing == wfi->primary)
wf_invalidate_region(wfi, rect.left, rect.top, rect.right - rect.left + 1, rect.bottom - rect.top + 1);
if (wfc->drawing == wfc->primary)
wf_invalidate_region(wfc, rect.left, rect.top, rect.right - rect.left + 1, rect.bottom - rect.top + 1);
}
void wf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect)
void wf_gdi_multi_opaque_rect(wfContext* wfc, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect)
{
int i;
RECT rect;
HBRUSH brush;
UINT32 brush_color;
DELTA_RECT* rectangle;
wfInfo* wfi = ((wfContext*) context)->wfi;
for (i = 1; i < (int) multi_opaque_rect->numRectangles + 1; i++)
{
rectangle = &multi_opaque_rect->rectangles[i];
brush_color = freerdp_color_convert_var_bgr(multi_opaque_rect->color, wfi->srcBpp, wfi->dstBpp, wfi->clrconv);
brush_color = freerdp_color_convert_var_bgr(multi_opaque_rect->color, wfc->srcBpp, wfc->dstBpp, wfc->clrconv);
rect.left = rectangle->left;
rect.top = rectangle->top;
@ -475,46 +467,45 @@ void wf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* mult
brush = CreateSolidBrush(brush_color);
brush = CreateSolidBrush(brush_color);
FillRect(wfi->drawing->hdc, &rect, brush);
FillRect(wfc->drawing->hdc, &rect, brush);
if (wfi->drawing == wfi->primary)
wf_invalidate_region(wfi, rect.left, rect.top, rect.right - rect.left + 1, rect.bottom - rect.top + 1);
if (wfc->drawing == wfc->primary)
wf_invalidate_region(wfc, rect.left, rect.top, rect.right - rect.left + 1, rect.bottom - rect.top + 1);
DeleteObject(brush);
}
}
void wf_gdi_line_to(rdpContext* context, LINE_TO_ORDER* line_to)
void wf_gdi_line_to(wfContext* wfc, LINE_TO_ORDER* line_to)
{
HPEN pen;
HPEN org_pen;
int x, y, w, h;
UINT32 pen_color;
wfInfo* wfi = ((wfContext*) context)->wfi;
pen_color = freerdp_color_convert_bgr(line_to->penColor, wfi->srcBpp, wfi->dstBpp, wfi->clrconv);
pen_color = freerdp_color_convert_bgr(line_to->penColor, wfc->srcBpp, wfc->dstBpp, wfc->clrconv);
pen = CreatePen(line_to->penStyle, line_to->penWidth, pen_color);
wf_set_rop2(wfi->drawing->hdc, line_to->bRop2);
org_pen = (HPEN) SelectObject(wfi->drawing->hdc, pen);
wf_set_rop2(wfc->drawing->hdc, line_to->bRop2);
org_pen = (HPEN) SelectObject(wfc->drawing->hdc, pen);
MoveToEx(wfi->drawing->hdc, line_to->nXStart, line_to->nYStart, NULL);
LineTo(wfi->drawing->hdc, line_to->nXEnd, line_to->nYEnd);
MoveToEx(wfc->drawing->hdc, line_to->nXStart, line_to->nYStart, NULL);
LineTo(wfc->drawing->hdc, line_to->nXEnd, line_to->nYEnd);
x = (line_to->nXStart < line_to->nXEnd) ? line_to->nXStart : line_to->nXEnd;
y = (line_to->nYStart < line_to->nYEnd) ? line_to->nYStart : line_to->nYEnd;
w = (line_to->nXStart < line_to->nXEnd) ? (line_to->nXEnd - line_to->nXStart) : (line_to->nXStart - line_to->nXEnd);
h = (line_to->nYStart < line_to->nYEnd) ? (line_to->nYEnd - line_to->nYStart) : (line_to->nYStart - line_to->nYEnd);
if (wfi->drawing == wfi->primary)
wf_invalidate_region(wfi, x, y, w, h);
if (wfc->drawing == wfc->primary)
wf_invalidate_region(wfc, x, y, w, h);
SelectObject(wfi->drawing->hdc, org_pen);
SelectObject(wfc->drawing->hdc, org_pen);
DeleteObject(pen);
}
void wf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline)
void wf_gdi_polyline(wfContext* wfc, POLYLINE_ORDER* polyline)
{
int i;
POINT* pts;
@ -522,13 +513,12 @@ void wf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline)
HPEN hpen;
HPEN org_hpen;
UINT32 pen_color;
wfInfo* wfi = ((wfContext*) context)->wfi;
pen_color = freerdp_color_convert_bgr(polyline->penColor, wfi->srcBpp, wfi->dstBpp, wfi->clrconv);
pen_color = freerdp_color_convert_bgr(polyline->penColor, wfc->srcBpp, wfc->dstBpp, wfc->clrconv);
hpen = CreatePen(0, 1, pen_color);
org_rop2 = wf_set_rop2(wfi->drawing->hdc, polyline->bRop2);
org_hpen = (HPEN) SelectObject(wfi->drawing->hdc, hpen);
org_rop2 = wf_set_rop2(wfc->drawing->hdc, polyline->bRop2);
org_hpen = (HPEN) SelectObject(wfc->drawing->hdc, hpen);
if (polyline->numPoints > 0)
{
@ -539,45 +529,43 @@ void wf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline)
pts[i].x = polyline->points[i].x;
pts[i].y = polyline->points[i].y;
if (wfi->drawing == wfi->primary)
wf_invalidate_region(wfi, pts[i].x, pts[i].y, pts[i].x + 1, pts[i].y + 1);
if (wfc->drawing == wfc->primary)
wf_invalidate_region(wfc, pts[i].x, pts[i].y, pts[i].x + 1, pts[i].y + 1);
}
Polyline(wfi->drawing->hdc, pts, polyline->numPoints);
Polyline(wfc->drawing->hdc, pts, polyline->numPoints);
free(pts);
}
SelectObject(wfi->drawing->hdc, org_hpen);
wf_set_rop2(wfi->drawing->hdc, org_rop2);
SelectObject(wfc->drawing->hdc, org_hpen);
wf_set_rop2(wfc->drawing->hdc, org_rop2);
DeleteObject(hpen);
}
void wf_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt)
void wf_gdi_memblt(wfContext* wfc, MEMBLT_ORDER* memblt)
{
wfBitmap* bitmap;
wfInfo* wfi = ((wfContext*) context)->wfi;
bitmap = (wfBitmap*) memblt->bitmap;
BitBlt(wfi->drawing->hdc, memblt->nLeftRect, memblt->nTopRect,
BitBlt(wfc->drawing->hdc, memblt->nLeftRect, memblt->nTopRect,
memblt->nWidth, memblt->nHeight, bitmap->hdc,
memblt->nXSrc, memblt->nYSrc, gdi_rop3_code(memblt->bRop));
if (wfi->drawing == wfi->primary)
wf_invalidate_region(wfi, memblt->nLeftRect, memblt->nTopRect, memblt->nWidth, memblt->nHeight);
if (wfc->drawing == wfc->primary)
wf_invalidate_region(wfc, memblt->nLeftRect, memblt->nTopRect, memblt->nWidth, memblt->nHeight);
}
void wf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_command)
void wf_gdi_surface_bits(wfContext* wfc, SURFACE_BITS_COMMAND* surface_bits_command)
{
int i, j;
int tx, ty;
char* tile_bitmap;
RFX_MESSAGE* message;
BITMAPINFO bitmap_info;
wfInfo* wfi = ((wfContext*) context)->wfi;
RFX_CONTEXT* rfx_context = (RFX_CONTEXT*) wfi->rfx_context;
NSC_CONTEXT* nsc_context = (NSC_CONTEXT*) wfi->nsc_context;
RFX_CONTEXT* rfx_context = (RFX_CONTEXT*) wfc->rfx_context;
NSC_CONTEXT* nsc_context = (NSC_CONTEXT*) wfc->nsc_context;
tile_bitmap = (char*) malloc(32);
ZeroMemory(tile_bitmap, 32);
@ -592,27 +580,27 @@ void wf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
tx = message->tiles[i]->x + surface_bits_command->destLeft;
ty = message->tiles[i]->y + surface_bits_command->destTop;
freerdp_image_convert(message->tiles[i]->data, wfi->tile->pdata, 64, 64, 32, 32, wfi->clrconv);
freerdp_image_convert(message->tiles[i]->data, wfc->tile->pdata, 64, 64, 32, 32, wfc->clrconv);
for (j = 0; j < message->num_rects; j++)
{
wf_set_clip_rgn(wfi,
wf_set_clip_rgn(wfc,
surface_bits_command->destLeft + message->rects[j].x,
surface_bits_command->destTop + message->rects[j].y,
message->rects[j].width, message->rects[j].height);
BitBlt(wfi->primary->hdc, tx, ty, 64, 64, wfi->tile->hdc, 0, 0, SRCCOPY);
BitBlt(wfc->primary->hdc, tx, ty, 64, 64, wfc->tile->hdc, 0, 0, SRCCOPY);
}
}
wf_set_null_clip_rgn(wfi);
wf_set_null_clip_rgn(wfc);
/* invalidate regions */
for (i = 0; i < message->num_rects; i++)
{
tx = surface_bits_command->destLeft + message->rects[i].x;
ty = surface_bits_command->destTop + message->rects[i].y;
wf_invalidate_region(wfi, tx, ty, message->rects[i].width, message->rects[i].height);
wf_invalidate_region(wfc, tx, ty, message->rects[i].width, message->rects[i].height);
}
rfx_message_free(rfx_context, message);
@ -628,10 +616,10 @@ void wf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
bitmap_info.bmiHeader.biPlanes = 1;
bitmap_info.bmiHeader.biBitCount = surface_bits_command->bpp;
bitmap_info.bmiHeader.biCompression = BI_RGB;
SetDIBitsToDevice(wfi->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop,
SetDIBitsToDevice(wfc->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop,
surface_bits_command->width, surface_bits_command->height, 0, 0, 0, surface_bits_command->height,
nsc_context->bmpdata, &bitmap_info, DIB_RGB_COLORS);
wf_invalidate_region(wfi, surface_bits_command->destLeft, surface_bits_command->destTop,
wf_invalidate_region(wfc, surface_bits_command->destLeft, surface_bits_command->destTop,
surface_bits_command->width, surface_bits_command->height);
}
else if (surface_bits_command->codecID == RDP_CODEC_ID_NONE)
@ -643,10 +631,10 @@ void wf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
bitmap_info.bmiHeader.biPlanes = 1;
bitmap_info.bmiHeader.biBitCount = surface_bits_command->bpp;
bitmap_info.bmiHeader.biCompression = BI_RGB;
SetDIBitsToDevice(wfi->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop,
SetDIBitsToDevice(wfc->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop,
surface_bits_command->width, surface_bits_command->height, 0, 0, 0, surface_bits_command->height,
surface_bits_command->bitmapData, &bitmap_info, DIB_RGB_COLORS);
wf_invalidate_region(wfi, surface_bits_command->destLeft, surface_bits_command->destTop,
wf_invalidate_region(wfc, surface_bits_command->destLeft, surface_bits_command->destTop,
surface_bits_command->width, surface_bits_command->height);
}
else
@ -658,16 +646,17 @@ void wf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
free(tile_bitmap);
}
void wf_gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker)
void wf_gdi_surface_frame_marker(wfContext* wfc, SURFACE_FRAME_MARKER* surface_frame_marker)
{
wfInfo* wfi;
rdpContext* context;
rdpSettings* settings;
wfi = ((wfContext*) context)->wfi;
settings = wfi->instance->settings;
context = (rdpContext*) wfc;
settings = wfc->instance->settings;
if (surface_frame_marker->frameAction == SURFACECMD_FRAMEACTION_END && settings->FrameAcknowledge > 0)
{
IFCALL(wfi->instance->update->SurfaceFrameAcknowledge, context, surface_frame_marker->frameId);
IFCALL(context->instance->update->SurfaceFrameAcknowledge, context, surface_frame_marker->frameId);
}
}
@ -678,19 +667,19 @@ void wf_gdi_register_update_callbacks(rdpUpdate* update)
update->Palette = wf_gdi_palette_update;
update->SetBounds = wf_gdi_set_bounds;
primary->DstBlt = wf_gdi_dstblt;
primary->PatBlt = wf_gdi_patblt;
primary->ScrBlt = wf_gdi_scrblt;
primary->OpaqueRect = wf_gdi_opaque_rect;
primary->DstBlt = (pDstBlt) wf_gdi_dstblt;
primary->PatBlt = (pPatBlt) wf_gdi_patblt;
primary->ScrBlt = (pScrBlt) wf_gdi_scrblt;
primary->OpaqueRect = (pOpaqueRect) wf_gdi_opaque_rect;
primary->DrawNineGrid = NULL;
primary->MultiDstBlt = NULL;
primary->MultiPatBlt = NULL;
primary->MultiScrBlt = NULL;
primary->MultiOpaqueRect = wf_gdi_multi_opaque_rect;
primary->MultiOpaqueRect = (pMultiOpaqueRect) wf_gdi_multi_opaque_rect;
primary->MultiDrawNineGrid = NULL;
primary->LineTo = wf_gdi_line_to;
primary->Polyline = wf_gdi_polyline;
primary->MemBlt = wf_gdi_memblt;
primary->LineTo = (pLineTo) wf_gdi_line_to;
primary->Polyline = (pPolyline) wf_gdi_polyline;
primary->MemBlt = (pMemBlt) wf_gdi_memblt;
primary->Mem3Blt = NULL;
primary->SaveBitmap = NULL;
primary->GlyphIndex = NULL;
@ -705,20 +694,20 @@ void wf_gdi_register_update_callbacks(rdpUpdate* update)
update->SurfaceFrameMarker = wf_gdi_surface_frame_marker;
}
void wf_update_canvas_diff(wfInfo* wfi)
void wf_update_canvas_diff(wfContext* wfc)
{
RECT rc_client, rc_wnd;
int dx, dy;
GetClientRect(wfi->hwnd, &rc_client);
GetWindowRect(wfi->hwnd, &rc_wnd);
GetClientRect(wfc->hwnd, &rc_client);
GetWindowRect(wfc->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)
if (!wfc->disablewindowtracking)
{
wfi->diff.x = dx;
wfi->diff.y = dy;
wfc->diff.x = dx;
wfc->diff.y = dy;
}
}
}

View File

@ -24,15 +24,15 @@
#include "wf_interface.h"
void wf_invalidate_region(wfInfo* wfi, int x, int y, int width, int height);
wfBitmap* wf_image_new(wfInfo* wfi, int width, int height, int bpp, BYTE* data);
void wf_invalidate_region(wfContext* wfc, int x, int y, int width, int height);
wfBitmap* wf_image_new(wfContext* wfc, int width, int height, int bpp, BYTE* data);
void wf_image_free(wfBitmap* image);
void wf_update_offset(wfInfo* wfi);
void wf_resize_window(wfInfo* wfi);
void wf_toggle_fullscreen(wfInfo* wfi);
void wf_update_offset(wfContext* wfc);
void wf_resize_window(wfContext* wfc);
void wf_toggle_fullscreen(wfContext* wfc);
void wf_gdi_register_update_callbacks(rdpUpdate* update);
void wf_update_canvas_diff(wfInfo* wfi);
void wf_update_canvas_diff(wfContext* wfc);
#endif /* __WF_GDI_H */

View File

@ -21,12 +21,14 @@
#include "config.h"
#endif
#include <winpr/crt.h>
#include <freerdp/codec/bitmap.h>
#include "wf_gdi.h"
#include "wf_graphics.h"
HBITMAP wf_create_dib(wfInfo* wfi, int width, int height, int bpp, BYTE* data, BYTE** pdata)
HBITMAP wf_create_dib(wfContext* wfc, int width, int height, int bpp, BYTE* data, BYTE** pdata)
{
HDC hdc;
int negHeight;
@ -48,12 +50,12 @@ HBITMAP wf_create_dib(wfInfo* wfi, int width, int height, int bpp, BYTE* data, B
bmi.bmiHeader.biWidth = width;
bmi.bmiHeader.biHeight = negHeight;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = wfi->dstBpp;
bmi.bmiHeader.biBitCount = wfc->dstBpp;
bmi.bmiHeader.biCompression = BI_RGB;
bitmap = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, (void**) &cdata, NULL, 0);
if (data != NULL)
freerdp_image_convert(data, cdata, width, height, bpp, wfi->dstBpp, wfi->clrconv);
freerdp_image_convert(data, cdata, width, height, bpp, wfc->dstBpp, wfc->clrconv);
if (pdata != NULL)
*pdata = cdata;
@ -64,7 +66,7 @@ HBITMAP wf_create_dib(wfInfo* wfi, int width, int height, int bpp, BYTE* data, B
return bitmap;
}
wfBitmap* wf_image_new(wfInfo* wfi, int width, int height, int bpp, BYTE* data)
wfBitmap* wf_image_new(wfContext* wfc, int width, int height, int bpp, BYTE* data)
{
HDC hdc;
wfBitmap* image;
@ -73,7 +75,7 @@ wfBitmap* wf_image_new(wfInfo* wfi, int width, int height, int bpp, BYTE* data)
image = (wfBitmap*) malloc(sizeof(wfBitmap));
image->hdc = CreateCompatibleDC(hdc);
image->bitmap = wf_create_dib(wfi, width, height, bpp, data, &(image->pdata));
image->bitmap = wf_create_dib(wfc, width, height, bpp, data, &(image->pdata));
image->org_bitmap = (HBITMAP) SelectObject(image->hdc, image->bitmap);
ReleaseDC(NULL, hdc);
@ -94,27 +96,26 @@ void wf_image_free(wfBitmap* image)
/* Bitmap Class */
void wf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap)
void wf_Bitmap_New(wfContext* wfc, rdpBitmap* bitmap)
{
HDC hdc;
wfBitmap* wf_bitmap = (wfBitmap*) bitmap;
wfInfo* wfi = ((wfContext*) context)->wfi;
wf_bitmap = (wfBitmap*) bitmap;
hdc = GetDC(NULL);
wf_bitmap->hdc = CreateCompatibleDC(hdc);
if (bitmap->data == NULL)
if (!bitmap->data)
wf_bitmap->bitmap = CreateCompatibleBitmap(hdc, bitmap->width, bitmap->height);
else
wf_bitmap->bitmap = wf_create_dib(wfi, bitmap->width, bitmap->height, bitmap->bpp, bitmap->data, NULL);
wf_bitmap->bitmap = wf_create_dib(wfc, bitmap->width, bitmap->height, bitmap->bpp, bitmap->data, NULL);
wf_bitmap->org_bitmap = (HBITMAP) SelectObject(wf_bitmap->hdc, wf_bitmap->bitmap);
ReleaseDC(NULL, hdc);
}
void wf_Bitmap_Free(rdpContext* context, rdpBitmap* bitmap)
void wf_Bitmap_Free(wfContext* wfc, rdpBitmap* bitmap)
{
wfBitmap* wf_bitmap = (wfBitmap*) bitmap;
@ -126,22 +127,21 @@ void wf_Bitmap_Free(rdpContext* context, rdpBitmap* bitmap)
}
}
void wf_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap)
void wf_Bitmap_Paint(wfContext* wfc, rdpBitmap* bitmap)
{
int width, height;
wfBitmap* wf_bitmap = (wfBitmap*) bitmap;
wfInfo* wfi = ((wfContext*) context)->wfi;
width = bitmap->right - bitmap->left + 1;
height = bitmap->bottom - bitmap->top + 1;
BitBlt(wfi->primary->hdc, bitmap->left, bitmap->top,
BitBlt(wfc->primary->hdc, bitmap->left, bitmap->top,
width, height, wf_bitmap->hdc, 0, 0, SRCCOPY);
wf_invalidate_region(wfi, bitmap->left, bitmap->top, width, height);
wf_invalidate_region(wfc, bitmap->left, bitmap->top, width, height);
}
void wf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
void wf_Bitmap_Decompress(wfContext* wfc, rdpBitmap* bitmap,
BYTE* data, int width, int height, int bpp, int length, BOOL compressed, int codec_id)
{
UINT16 size;
@ -174,19 +174,17 @@ void wf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
bitmap->bpp = bpp;
}
void wf_Bitmap_SetSurface(rdpContext* context, rdpBitmap* bitmap, BOOL primary)
void wf_Bitmap_SetSurface(wfContext* wfc, rdpBitmap* bitmap, BOOL primary)
{
wfInfo* wfi = ((wfContext*) context)->wfi;
if (primary)
wfi->drawing = wfi->primary;
wfc->drawing = wfc->primary;
else
wfi->drawing = (wfBitmap*) bitmap;
wfc->drawing = (wfBitmap*) bitmap;
}
/* Pointer Class */
void wf_Pointer_New(rdpContext* context, rdpPointer* pointer)
void wf_Pointer_New(wfContext* wfc, rdpPointer* pointer)
{
HCURSOR hCur;
ICONINFO info;
@ -223,35 +221,35 @@ void wf_Pointer_New(rdpContext* context, rdpPointer* pointer)
DeleteObject(info.hbmColor);
}
void wf_Pointer_Free(rdpContext* context, rdpPointer* pointer)
void wf_Pointer_Free(wfContext* wfc, rdpPointer* pointer)
{
HCURSOR hCur;
hCur = ((wfPointer*) pointer)->cursor;
if (hCur != 0)
DestroyIcon(hCur);
}
void wf_Pointer_Set(rdpContext* context, rdpPointer* pointer)
void wf_Pointer_Set(wfContext* wfc, rdpPointer* pointer)
{
wfInfo* wfi;
HCURSOR hCur;
wfi = ((wfContext*) context)->wfi;
hCur = ((wfPointer*) pointer)->cursor;
if (hCur != NULL)
{
SetCursor(hCur);
wfi->cursor = hCur;
wfc->cursor = hCur;
}
}
void wf_Pointer_SetNull(rdpContext* context)
void wf_Pointer_SetNull(wfContext* wfc)
{
}
void wf_Pointer_SetDefault(rdpContext* context)
void wf_Pointer_SetDefault(wfContext* wfc)
{
}
@ -263,21 +261,21 @@ void wf_register_graphics(rdpGraphics* graphics)
rdpBitmap bitmap;
rdpPointer pointer;
memset(&bitmap, 0, sizeof(rdpBitmap));
ZeroMemory(&bitmap, sizeof(rdpBitmap));
bitmap.size = sizeof(wfBitmap);
bitmap.New = wf_Bitmap_New;
bitmap.Free = wf_Bitmap_Free;
bitmap.Paint = wf_Bitmap_Paint;
bitmap.Decompress = wf_Bitmap_Decompress;
bitmap.SetSurface = wf_Bitmap_SetSurface;
bitmap.New = (pBitmap_New) wf_Bitmap_New;
bitmap.Free = (pBitmap_Free) wf_Bitmap_Free;
bitmap.Paint = (pBitmap_Paint) wf_Bitmap_Paint;
bitmap.Decompress = (pBitmap_Decompress) wf_Bitmap_Decompress;
bitmap.SetSurface = (pBitmap_SetSurface) wf_Bitmap_SetSurface;
memset(&pointer, 0, sizeof(rdpPointer));
ZeroMemory(&pointer, sizeof(rdpPointer));
pointer.size = sizeof(wfPointer);
pointer.New = wf_Pointer_New;
pointer.Free = wf_Pointer_Free;
pointer.Set = wf_Pointer_Set;
pointer.SetNull = wf_Pointer_SetNull;
pointer.SetDefault = wf_Pointer_SetDefault;
pointer.New = (pPointer_New) wf_Pointer_New;
pointer.Free = (pPointer_Free) wf_Pointer_Free;
pointer.Set = (pPointer_Set) wf_Pointer_Set;
pointer.SetNull = (pPointer_SetNull) wf_Pointer_SetNull;
pointer.SetDefault = (pPointer_SetDefault) wf_Pointer_SetDefault;
graphics_register_bitmap(graphics, &bitmap);
graphics_register_pointer(graphics, &pointer);

View File

@ -22,8 +22,8 @@
#include "wf_interface.h"
HBITMAP wf_create_dib(wfInfo* wfi, int width, int height, int bpp, BYTE* data, BYTE** pdata);
wfBitmap* wf_image_new(wfInfo* wfi, int width, int height, int bpp, BYTE* data);
HBITMAP wf_create_dib(wfContext* wfc, int width, int height, int bpp, BYTE* data, BYTE** pdata);
wfBitmap* wf_image_new(wfContext* wfc, int width, int height, int bpp, BYTE* data);
void wf_image_free(wfBitmap* image);
void wf_register_graphics(rdpGraphics* graphics);

File diff suppressed because it is too large Load Diff

View File

@ -43,11 +43,6 @@
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
@ -68,21 +63,10 @@ struct wf_pointer
};
typedef struct wf_pointer wfPointer;
typedef struct wf_info wfInfo;
struct wf_context
{
rdpContext _p;
wfInfo* wfi;
};
typedef struct wf_context wfContext;
typedef void (CALLBACK * callbackFunc)(wfInfo* wfi, int callback_type, DWORD param1, DWORD param2);
struct wf_info
{
rdpClient* client;
rdpContext context;
DEFINE_RDP_CLIENT_COMMON();
int width;
int height;
@ -97,7 +81,6 @@ struct wf_info
int client_width;
int client_height;
HANDLE thread;
HANDLE keyboardThread;
HICON icon;
@ -129,61 +112,33 @@ struct wf_info
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;
BOOL disablewindowtracking;
// These variables are required for horizontal scrolling.
// 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.
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
int yMinScroll; // minimum vertical scroll value
int yCurrentScroll; // current vertical scroll value
int yMaxScroll; // maximum vertical scroll value
};
typedef struct wf_context wfContext;
/**
* Client Interface
*/
#define cfInfo wfInfo
FREERDP_API int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints);
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();
FREERDP_API int freerdp_client_start(wfInfo* cfi);
FREERDP_API int freerdp_client_stop(wfInfo* cfi);
FREERDP_API HANDLE freerdp_client_get_thread(wfInfo* cfi);
FREERDP_API freerdp* freerdp_client_get_instance(wfInfo* cfi);
FREERDP_API rdpClient* freerdp_client_get_interface(wfInfo* cfi);
FREERDP_API int freerdp_client_focus_in(wfInfo* cfi);
FREERDP_API int freerdp_client_focus_out(wfInfo* cfi);
FREERDP_API int freerdp_client_set_window_size(wfInfo* cfi, int width, int height);
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

@ -29,30 +29,30 @@
#include "wf_window.h"
#include "wf_rail.h"
void wf_rail_paint(wfInfo* wfi, rdpRail* rail, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom)
void wf_rail_paint(wfContext* wfc, rdpRail* rail, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom)
{
}
void wf_rail_register_callbacks(wfInfo* wfi, rdpRail* rail)
void wf_rail_register_callbacks(wfContext* wfc, rdpRail* rail)
{
}
void wf_rail_send_client_system_command(wfInfo* wfi, UINT32 windowId, UINT16 command)
void wf_rail_send_client_system_command(wfContext* wfc, UINT32 windowId, UINT16 command)
{
}
void wf_rail_send_activate(wfInfo* wfi, HWND window, BOOL enabled)
void wf_rail_send_activate(wfContext* wfc, HWND window, BOOL enabled)
{
}
void wf_process_rail_event(wfInfo* wfi, rdpChannels* chanman, wMessage* event)
void wf_process_rail_event(wfContext* wfc, rdpChannels* channels, wMessage* event)
{
}
void wf_rail_adjust_position(wfInfo* wfi, rdpWindow *window)
void wf_rail_adjust_position(wfContext* wfc, rdpWindow* window)
{
}
void wf_rail_end_local_move(wfInfo* wfi, rdpWindow *window)
void wf_rail_end_local_move(wfContext* wfc, rdpWindow* window)
{
}

View File

@ -21,12 +21,12 @@
#include "wf_interface.h"
void wf_rail_paint(wfInfo* wfi, rdpRail* rail, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom);
void wf_rail_register_callbacks(wfInfo* wfi, rdpRail* rail);
void wf_rail_send_client_system_command(wfInfo* wfi, UINT32 windowId, UINT16 command);
void wf_rail_send_activate(wfInfo* wfi, HWND window, BOOL enabled);
void wf_process_rail_event(wfInfo* wfi, rdpChannels* chanman, wMessage* event);
void wf_rail_adjust_position(wfInfo* wfi, rdpWindow *window);
void wf_rail_end_local_move(wfInfo* wfi, rdpWindow *window);
void wf_rail_paint(wfContext* wfc, rdpRail* rail, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom);
void wf_rail_register_callbacks(wfContext* wfc, rdpRail* rail);
void wf_rail_send_client_system_command(wfContext* wfc, UINT32 windowId, UINT16 command);
void wf_rail_send_activate(wfContext* wfc, HWND window, BOOL enabled);
void wf_process_rail_event(wfContext* wfc, rdpChannels* channels, wMessage* event);
void wf_rail_adjust_position(wfContext* wfc, rdpWindow* window);
void wf_rail_end_local_move(wfContext* wfc, rdpWindow* window);
#endif

View File

@ -44,8 +44,8 @@ set(${MODULE_PREFIX}_SRCS
xf_keyboard.h
xf_window.c
xf_window.h
xf_interface.c
xf_interface.h)
xf_client.c
xf_client.h)
if(WITH_CLIENT_INTERFACE)
if(CLIENT_INTERFACE_SHARED)

View File

@ -27,13 +27,14 @@
#include <winpr/thread.h>
#include <freerdp/freerdp.h>
#include <freerdp/client/cmdline.h>
#include "xf_interface.h"
#include "xf_client.h"
#include "xfreerdp.h"
int main(int argc, char* argv[])
{
int status;
HANDLE thread;
xfContext* xfc;
DWORD dwExitCode;
@ -52,20 +53,17 @@ int main(int argc, char* argv[])
settings = context->settings;
xfc = (xfContext*) context;
if (freerdp_client_parse_command_line(context, argc, argv) < 0)
{
if (settings->ConnectionFile)
{
freerdp_client_parse_connection_file(context, settings->ConnectionFile);
}
else
{
if (settings->ListMonitors)
xf_list_monitors(xfc);
status = freerdp_client_parse_command_line(context, argc, argv);
freerdp_client_context_free(context);
return 0;
}
status = freerdp_client_command_line_status_print(argc, argv, settings, status);
if (status)
{
if (settings->ListMonitors)
xf_list_monitors(xfc);
freerdp_client_context_free(context);
return 0;
}
freerdp_client_start(context);

View File

@ -23,7 +23,7 @@
#include "xf_channels.h"
#include "xf_interface.h"
#include "xf_client.h"
#include "xfreerdp.h"
int xf_on_channel_connected(freerdp* instance, const char* name, void* pInterface)

View File

@ -480,6 +480,7 @@ void xf_create_window(xfContext* xfc)
void xf_toggle_fullscreen(xfContext* xfc)
{
Pixmap contents = 0;
WindowStateChangeEventArgs e;
xf_lock_x11(xfc, TRUE);
@ -495,8 +496,9 @@ void xf_toggle_fullscreen(xfContext* xfc)
xf_unlock_x11(xfc, TRUE);
IFCALL(xfc->client->OnWindowStateChange, xfc->instance,
xfc->fullscreen ? FREERDP_WINDOW_STATE_FULLSCREEN : 0);
e.state = xfc->fullscreen ? FREERDP_WINDOW_STATE_FULLSCREEN : 0;
PubSub_OnEvent(((rdpContext*) xfc)->pubSub, "WindowStateChange", xfc, (wEventArgs*) &e);
}
void xf_lock_x11(xfContext* xfc, BOOL display)
@ -667,9 +669,6 @@ BOOL xf_pre_connect(freerdp* instance)
instance->OnChannelConnected = xf_on_channel_connected;
instance->OnChannelDisconnected = xf_on_channel_disconnected;
//if (status < 0)
// exit(XF_EXIT_PARSE_ARGUMENTS);
freerdp_client_load_addins(channels, instance->settings);
freerdp_channels_pre_connect(channels, instance);
@ -774,6 +773,7 @@ BOOL xf_post_connect(freerdp* instance)
rdpCache* cache;
rdpChannels* channels;
rdpSettings* settings;
ResizeWindowEventArgs e;
RFX_CONTEXT* rfx_context = NULL;
NSC_CONTEXT* nsc_context = NULL;
xfContext* xfc = (xfContext*) instance->context;
@ -894,7 +894,10 @@ BOOL xf_post_connect(freerdp* instance)
xf_cliprdr_init(xfc, channels);
IFCALL(xfc->client->OnResizeWindow, instance, settings->DesktopWidth, settings->DesktopHeight);
e.width = settings->DesktopWidth;
e.height = settings->DesktopHeight;
PubSub_OnEvent(((rdpContext*) xfc)->pubSub, "ResizeWindow", xfc, (wEventArgs*) &e);
return TRUE;
}
@ -1550,11 +1553,6 @@ int xfreerdp_client_stop(rdpContext* context)
return 0;
}
rdpClient* freerdp_client_get_interface(rdpContext* context)
{
return context->client;
}
double freerdp_client_get_scale(rdpContext* context)
{
xfContext* xfc = (xfContext*) context;
@ -1563,11 +1561,16 @@ double freerdp_client_get_scale(rdpContext* context)
void freerdp_client_reset_scale(rdpContext* context)
{
ResizeWindowEventArgs e;
xfContext* xfc = (xfContext*) context;
xfc->scale = 1.0;
XResizeWindow(xfc->display, xfc->window->handle, xfc->originalWidth * xfc->scale, xfc->originalHeight * xfc->scale);
IFCALL(xfc->client->OnResizeWindow, xfc->instance, xfc->originalWidth * xfc->scale, xfc->originalHeight * xfc->scale);
e.width = (int) xfc->originalWidth * xfc->scale;
e.height = (int) xfc->originalHeight * xfc->scale;
PubSub_OnEvent(((rdpContext*) xfc)->pubSub, "ResizeWindow", xfc, (wEventArgs*) &e);
xf_draw_screen_scaled(xfc);
}
@ -1588,7 +1591,6 @@ int xfreerdp_client_new(freerdp* instance, rdpContext* context)
context->channels = freerdp_channels_new();
settings = instance->settings;
xfc->client = instance->context->client;
xfc->settings = instance->context->settings;
settings->OsMajorType = OSMAJORTYPE_UNIX;

View File

@ -17,11 +17,12 @@
* limitations under the License.
*/
#ifndef __XF_INTERFACE_H
#define __XF_INTERFACE_H
#ifndef __XF_CLIENT_H
#define __XF_CLIENT_H
#include <freerdp/api.h>
#include <freerdp/freerdp.h>
#include <freerdp/client.h>
#include <freerdp/gdi/gdi.h>
#include <freerdp/gdi/dc.h>
@ -33,6 +34,7 @@
#include <winpr/crt.h>
#include <winpr/synch.h>
#include <winpr/thread.h>
#include <winpr/collections.h>
#ifdef __cplusplus
extern "C" {
@ -48,4 +50,4 @@ FREERDP_API int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints);
}
#endif
#endif /* __XF_INTERFACE_H */
#endif /* __XF_CLIENT_H */

View File

@ -20,7 +20,7 @@
#ifndef __XF_CLIPRDR_H
#define __XF_CLIPRDR_H
#include "xf_interface.h"
#include "xf_client.h"
#include "xfreerdp.h"
void xf_cliprdr_init(xfContext* xfc, rdpChannels* channels);

View File

@ -22,7 +22,7 @@
#include "xf_keyboard.h"
#include "xf_interface.h"
#include "xf_client.h"
#include "xfreerdp.h"
BOOL xf_event_process(freerdp* instance, XEvent* event);

View File

@ -22,7 +22,7 @@
#include <freerdp/gdi/gdi.h>
#include "xf_interface.h"
#include "xf_client.h"
#include "xfreerdp.h"
void xf_gdi_register_update_callbacks(rdpUpdate* update);

View File

@ -20,7 +20,7 @@
#ifndef __XF_GRAPHICS_H
#define __XF_GRAPHICS_H
#include "xf_interface.h"
#include "xf_client.h"
#include "xfreerdp.h"
void xf_register_graphics(rdpGraphics* graphics);

View File

@ -156,6 +156,7 @@ void xf_input_detect_pinch(xfContext* xfc)
double dist;
double zoom;
double delta;
ResizeWindowEventArgs e;
if (active_contacts != 2)
{
@ -195,7 +196,10 @@ void xf_input_detect_pinch(xfContext* xfc)
xfc->scale = 0.5;
XResizeWindow(xfc->display, xfc->window->handle, xfc->originalWidth * xfc->scale, xfc->originalHeight * xfc->scale);
IFCALL(xfc->client->OnResizeWindow, xfc->instance, xfc->originalWidth * xfc->scale, xfc->originalHeight * xfc->scale);
e.width = (int) xfc->originalWidth * xfc->scale;
e.height = (int) xfc->originalHeight * xfc->scale;
PubSub_OnEvent(((rdpContext*) xfc)->pubSub, "ResizeWindow", xfc, (wEventArgs*) &e);
z_vector = 0;
}
@ -208,7 +212,10 @@ void xf_input_detect_pinch(xfContext* xfc)
xfc->scale = 1.5;
XResizeWindow(xfc->display, xfc->window->handle, xfc->originalWidth * xfc->scale, xfc->originalHeight * xfc->scale);
IFCALL(xfc->client->OnResizeWindow, xfc->instance, xfc->originalWidth * xfc->scale, xfc->originalHeight * xfc->scale);
e.width = (int) xfc->originalWidth * xfc->scale;
e.height = (int) xfc->originalHeight * xfc->scale;
PubSub_OnEvent(((rdpContext*) xfc)->pubSub, "ResizeWindow", xfc, (wEventArgs*) &e);
z_vector = 0;
}

View File

@ -20,7 +20,7 @@
#ifndef __XF_INPUT_H
#define __XF_INPUT_H
#include "xf_interface.h"
#include "xf_client.h"
#include "xfreerdp.h"
#ifdef WITH_XI

View File

@ -22,7 +22,7 @@
#include <freerdp/locale/keyboard.h>
#include "xf_interface.h"
#include "xf_client.h"
#include "xfreerdp.h"
void xf_kbd_init(xfContext* xfc);

View File

@ -40,7 +40,7 @@ struct _VIRTUAL_SCREEN
};
typedef struct _VIRTUAL_SCREEN VIRTUAL_SCREEN;
#include "xf_interface.h"
#include "xf_client.h"
#include "xfreerdp.h"
int xf_list_monitors(xfContext* xfc);

View File

@ -20,7 +20,7 @@
#ifndef __XF_RAIL_H
#define __XF_RAIL_H
#include "xf_interface.h"
#include "xf_client.h"
#include "xfreerdp.h"
void xf_rail_paint(xfContext* xfc, rdpRail* rail, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom);

View File

@ -20,7 +20,7 @@
#ifndef __XF_TSMF_H
#define __XF_TSMF_H
#include "xf_interface.h"
#include "xf_client.h"
#include "xfreerdp.h"
void xf_tsmf_init(xfContext* xfc, long xv_port);

View File

@ -27,7 +27,7 @@
typedef struct xf_localmove xfLocalMove;
typedef struct xf_window xfWindow;
#include "xf_interface.h"
#include "xf_client.h"
#include "xfreerdp.h"
// Extended ICCM flags http://standards.freedesktop.org/wm-spec/wm-spec-latest.html

View File

@ -62,7 +62,6 @@ struct xf_context
DEFINE_RDP_CLIENT_COMMON();
freerdp* instance;
rdpClient* client;
rdpSettings* settings;
GC gc;

View File

@ -26,6 +26,18 @@
#include <freerdp/client/file.h>
#include <freerdp/client/cmdline.h>
int freerdp_client_common_new(freerdp* instance, rdpContext* context)
{
RDP_CLIENT_ENTRY_POINTS* pEntryPoints = instance->pClientEntryPoints;
return pEntryPoints->ClientNew(instance, context);
}
void freerdp_client_common_free(freerdp* instance, rdpContext* context)
{
RDP_CLIENT_ENTRY_POINTS* pEntryPoints = instance->pClientEntryPoints;
pEntryPoints->ClientFree(instance, context);
}
/* Common API */
rdpContext* freerdp_client_context_new(RDP_CLIENT_ENTRY_POINTS* pEntryPoints)
@ -37,15 +49,14 @@ rdpContext* freerdp_client_context_new(RDP_CLIENT_ENTRY_POINTS* pEntryPoints)
instance = freerdp_new();
instance->ContextSize = pEntryPoints->ContextSize;
instance->ContextNew = pEntryPoints->ClientNew;
instance->ContextFree = pEntryPoints->ClientFree;
instance->ContextNew = freerdp_client_common_new;
instance->ContextFree = freerdp_client_common_free;
instance->pClientEntryPoints = (RDP_CLIENT_ENTRY_POINTS*) malloc(pEntryPoints->Size);
CopyMemory(instance->pClientEntryPoints, pEntryPoints, pEntryPoints->Size);
freerdp_context_new(instance);
context = instance->context;
context->client->pEntryPoints = (RDP_CLIENT_ENTRY_POINTS*) malloc(pEntryPoints->Size);
CopyMemory(context->client->pEntryPoints, pEntryPoints, pEntryPoints->Size);
return context;
}
@ -59,14 +70,14 @@ void freerdp_client_context_free(rdpContext* context)
int freerdp_client_start(rdpContext* context)
{
rdpClient* client = context->client;
return client->pEntryPoints->ClientStart(context);
RDP_CLIENT_ENTRY_POINTS* pEntryPoints = context->instance->pClientEntryPoints;
return pEntryPoints->ClientStart(context);
}
int freerdp_client_stop(rdpContext* context)
{
rdpClient* client = context->client;
return client->pEntryPoints->ClientStop(context);
RDP_CLIENT_ENTRY_POINTS* pEntryPoints = context->instance->pClientEntryPoints;
return pEntryPoints->ClientStop(context);
}
freerdp* freerdp_client_get_instance(rdpContext* context)

View File

@ -949,32 +949,10 @@ BOOL freerdp_client_detect_command_line(int argc, char** argv, DWORD* flags)
return compatibility;
}
int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettings* settings)
int freerdp_client_command_line_status_print(int argc, char** argv, rdpSettings* settings, int status)
{
char* p;
char* str;
int length;
int status;
DWORD flags;
BOOL compatibility;
COMMAND_LINE_ARGUMENT_A* arg;
freerdp_register_addin_provider(freerdp_channels_load_static_addin_entry, 0);
compatibility = freerdp_client_detect_command_line(argc, argv, &flags);
if (compatibility)
{
fprintf(stderr, "WARNING: Using deprecated command-line interface!\n");
return freerdp_client_parse_old_command_line_arguments(argc, argv, settings);
}
else
{
CommandLineClearArgumentsA(args);
status = CommandLineParseArgumentsA(argc, (const char**) argv, args, flags, settings,
freerdp_client_command_line_pre_filter, freerdp_client_command_line_post_filter);
}
if (status == COMMAND_LINE_STATUS_PRINT_HELP)
{
freerdp_client_print_command_line_help(argc, argv);
@ -1025,13 +1003,36 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin
return COMMAND_LINE_STATUS_PRINT;
}
arg = CommandLineFindArgumentA(args, "v");
return 0;
}
if (!settings->ConnectionFile && !(arg->Flags & COMMAND_LINE_VALUE_PRESENT))
int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettings* settings)
{
char* p;
char* str;
int length;
int status;
DWORD flags;
BOOL compatibility;
COMMAND_LINE_ARGUMENT_A* arg;
freerdp_register_addin_provider(freerdp_channels_load_static_addin_entry, 0);
compatibility = freerdp_client_detect_command_line(argc, argv, &flags);
if (compatibility)
{
//fprintf(stderr, "error: server hostname was not specified with /v:<server>[:port]\n");
//return COMMAND_LINE_ERROR_MISSING_ARGUMENT;
fprintf(stderr, "WARNING: Using deprecated command-line interface!\n");
return freerdp_client_parse_old_command_line_arguments(argc, argv, settings);
}
else
{
CommandLineClearArgumentsA(args);
status = CommandLineParseArgumentsA(argc, (const char**) argv, args, flags, settings,
freerdp_client_command_line_pre_filter, freerdp_client_command_line_post_filter);
}
arg = CommandLineFindArgumentA(args, "v");
arg = args;

View File

@ -55,37 +55,14 @@ struct rdp_client_entry_points_v1
pRdpClientStart ClientStart;
pRdpClientStop ClientStop;
};
typedef struct rdp_client_entry_points_v1 RDP_CLIENT_ENTRY_POINTS_V1;
#define RDP_CLIENT_INTERFACE_VERSION 1
#define RDP_CLIENT_ENTRY_POINT_NAME "RdpClientEntry"
typedef RDP_CLIENT_ENTRY_POINTS_V1 RDP_CLIENT_ENTRY_POINTS;
typedef int (*pRdpClientEntry)(RDP_CLIENT_ENTRY_POINTS* pEntryPoints);
/* Common Client Interface */
#define FREERDP_WINDOW_STATE_NORMAL 0
#define FREERDP_WINDOW_STATE_MINIMIZED 1
#define FREERDP_WINDOW_STATE_MAXIMIZED 2
#define FREERDP_WINDOW_STATE_FULLSCREEN 3
#define FREERDP_WINDOW_STATE_ACTIVE 4
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
{
RDP_CLIENT_ENTRY_POINTS* pEntryPoints;
pOnResizeWindow OnResizeWindow;
pOnWindowStateChange OnWindowStateChange;
pOnErrorInfo OnErrorInfo;
pOnParamChange OnParamChange;
};
#define DEFINE_RDP_CLIENT_COMMON() \
HANDLE thread

View File

@ -28,6 +28,7 @@ extern "C" {
#endif
FREERDP_API int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettings* settings);
FREERDP_API int freerdp_client_command_line_status_print(int argc, char** argv, rdpSettings* settings, int status);
FREERDP_API int freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings);
FREERDP_API int freerdp_client_print_version(void);

57
include/freerdp/event.h Normal file
View File

@ -0,0 +1,57 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Event Definitions
*
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FREERDP_EVENT_H
#define FREERDP_EVENT_H
#include <freerdp/api.h>
#include <freerdp/freerdp.h>
#ifdef __cplusplus
extern "C" {
#endif
#define FREERDP_WINDOW_STATE_NORMAL 0
#define FREERDP_WINDOW_STATE_MINIMIZED 1
#define FREERDP_WINDOW_STATE_MAXIMIZED 2
#define FREERDP_WINDOW_STATE_FULLSCREEN 3
#define FREERDP_WINDOW_STATE_ACTIVE 4
DEFINE_EVENT_BEGIN(WindowStateChange)
int state;
DEFINE_EVENT_END(WindowStateChange)
DEFINE_EVENT_BEGIN(ResizeWindow)
int width;
int height;
DEFINE_EVENT_END(ResizeWindow)
DEFINE_EVENT_BEGIN(ErrorInfo)
UINT32 code;
DEFINE_EVENT_END(ErrorInfo)
DEFINE_EVENT_BEGIN(ParamChange)
int id;
DEFINE_EVENT_END(ParamChange)
#ifdef __cplusplus
}
#endif
#endif /* FREERDP_EVENT_H */

View File

@ -26,16 +26,19 @@ typedef struct rdp_rail rdpRail;
typedef struct rdp_cache rdpCache;
typedef struct rdp_channels rdpChannels;
typedef struct rdp_graphics rdpGraphics;
typedef struct rdp_client rdpClient;
typedef struct rdp_freerdp freerdp;
typedef struct rdp_context rdpContext;
typedef struct rdp_freerdp_peer freerdp_peer;
typedef struct rdp_client_context rdpClientContext;
typedef struct rdp_client_entry_points_v1 RDP_CLIENT_ENTRY_POINTS_V1;
typedef RDP_CLIENT_ENTRY_POINTS_V1 RDP_CLIENT_ENTRY_POINTS;
#include <freerdp/api.h>
#include <freerdp/types.h>
#include <freerdp/error.h>
#include <freerdp/event.h>
#include <freerdp/settings.h>
#include <freerdp/extension.h>
@ -92,7 +95,9 @@ struct rdp_context
Used to keep this data available and used later on, typically just before connection initialization.
@see freerdp_parse_args() */
UINT64 paddingB[32 - 18]; /* 18 */
ALIGN64 wPubSub* pubSub; /* (offset 18) */
UINT64 paddingB[32 - 19]; /* 19 */
ALIGN64 rdpRdp* rdp; /**< (offset 32)
Pointer to a rdp_rdp structure used to keep the connection's parameters.
@ -109,8 +114,7 @@ struct rdp_context
ALIGN64 rdpInput* input; /* 38 */
ALIGN64 rdpUpdate* update; /* 39 */
ALIGN64 rdpSettings* settings; /* 40 */
ALIGN64 rdpClient* client; /* 41 */
UINT64 paddingC[64 - 42]; /* 42 */
UINT64 paddingC[64 - 41]; /* 41 */
UINT64 paddingD[96 - 64]; /* 64 */
UINT64 paddingE[128 - 96]; /* 96 */
@ -135,7 +139,9 @@ struct rdp_freerdp
Can be allocated by a call to freerdp_context_new().
Must be deallocated by a call to freerdp_context_free() before deallocating the current instance. */
UINT64 paddingA[16 - 1]; /* 1 */
ALIGN64 RDP_CLIENT_ENTRY_POINTS* pClientEntryPoints;
UINT64 paddingA[16 - 2]; /* 2 */
ALIGN64 rdpInput* input; /* (offset 16)
Input handle for the connection.

View File

@ -744,6 +744,9 @@ BOOL freerdp_get_param_bool(rdpSettings* settings, int id)
int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param)
{
ParamChangeEventArgs e;
rdpContext* context = ((freerdp*) settings->instance)->context;
switch (id)
{
case FreeRDP_ServerMode:
@ -1185,7 +1188,9 @@ int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param)
// Mark field as modified
settings->settings_modified[id] = 1;
IFCALL(((freerdp*) settings->instance)->context->client->OnParamChange, ((freerdp*) settings->instance), id);
e.id = id;
PubSub_OnEvent(context->pubSub, "ParamChange", context->instance, (wEventArgs*) &e);
return -1;
}
@ -1508,6 +1513,9 @@ UINT32 freerdp_get_param_uint32(rdpSettings* settings, int id)
int freerdp_set_param_uint32(rdpSettings* settings, int id, UINT32 param)
{
ParamChangeEventArgs e;
rdpContext* context = ((freerdp*) settings->instance)->context;
switch (id)
{
case FreeRDP_ShareId:
@ -1821,7 +1829,9 @@ int freerdp_set_param_uint32(rdpSettings* settings, int id, UINT32 param)
// Mark field as modified
settings->settings_modified[id] = 1;
IFCALL(((freerdp*) settings->instance)->context->client->OnParamChange, ((freerdp*) settings->instance), id);
e.id = id;
PubSub_OnEvent(context->pubSub, "ParamChange", context->instance, (wEventArgs*) &e);
return 0;
}
@ -1844,6 +1854,9 @@ UINT64 freerdp_get_param_uint64(rdpSettings* settings, int id)
int freerdp_set_param_uint64(rdpSettings* settings, int id, UINT64 param)
{
ParamChangeEventArgs e;
rdpContext* context = ((freerdp*) settings->instance)->context;
switch (id)
{
case FreeRDP_ParentWindowId:
@ -1857,7 +1870,9 @@ int freerdp_set_param_uint64(rdpSettings* settings, int id, UINT64 param)
// Mark field as modified
settings->settings_modified[id] = 1;
IFCALL(((freerdp*) settings->instance)->context->client->OnParamChange, ((freerdp*) settings->instance), id);
e.id = id;
PubSub_OnEvent(context->pubSub, "ParamChange", context->instance, (wEventArgs*) &e);
return 0;
}
@ -2028,6 +2043,9 @@ char* freerdp_get_param_string(rdpSettings* settings, int id)
int freerdp_set_param_string(rdpSettings* settings, int id, char* param)
{
ParamChangeEventArgs e;
rdpContext* context = ((freerdp*) settings->instance)->context;
switch (id)
{
case FreeRDP_ServerHostname:
@ -2189,7 +2207,9 @@ int freerdp_set_param_string(rdpSettings* settings, int id, char* param)
// Mark field as modified
settings->settings_modified[id] = 1;
IFCALL(((freerdp*) settings->instance)->context->client->OnParamChange, ((freerdp*) settings->instance), id);
e.id = id;
PubSub_OnEvent(context->pubSub, "ParamChange", context->instance, (wEventArgs*) &e);
return 0;
}

View File

@ -308,6 +308,14 @@ void freerdp_get_version(int* major, int* minor, int* revision)
*revision = FREERDP_VERSION_REVISION;
}
static wEvent FreeRDP_Events[] =
{
DEFINE_EVENT_ENTRY(WindowStateChange)
DEFINE_EVENT_ENTRY(ResizeWindow)
DEFINE_EVENT_ENTRY(ErrorInfo)
DEFINE_EVENT_ENTRY(ParamChange)
};
/** Allocator function for a rdp context.
* The function will allocate a rdpRdp structure using rdp_new(), then copy
* its contents to the appropriate fields in the rdp_freerdp structure given in parameters.
@ -339,8 +347,8 @@ int freerdp_context_new(freerdp* instance)
context->update = instance->update;
context->settings = instance->settings;
context->client = (rdpClient*) malloc(sizeof(rdpClient));
ZeroMemory(context->client, sizeof(rdpClient));
context->pubSub = PubSub_New(TRUE);
PubSub_Publish(context->pubSub, FreeRDP_Events, sizeof(FreeRDP_Events) / sizeof(wEvent));
instance->update->context = instance->context;
instance->update->pointer->context = instance->context;
@ -375,11 +383,7 @@ void freerdp_context_free(freerdp* instance)
rdp_free(instance->context->rdp);
graphics_free(instance->context->graphics);
if (instance->context->client)
{
free(instance->context->client->pEntryPoints);
free(instance->context->client);
}
PubSub_Free(instance->context->pubSub);
free(instance->context);
instance->context = NULL;

View File

@ -502,11 +502,13 @@ BOOL rdp_recv_set_error_info_data_pdu(rdpRdp* rdp, wStream* s)
if (rdp->errorInfo != ERRINFO_SUCCESS)
{
rdpClient* client = rdp->instance->context->client;
ErrorInfoEventArgs e;
rdpContext* context = rdp->instance->context;
rdp_print_errinfo(rdp->errorInfo);
IFCALL(client->OnErrorInfo, rdp->instance, rdp->errorInfo);
e.code = rdp->errorInfo;
PubSub_OnEvent(context->pubSub, "ErrorInfo", context, (wEventArgs*) &e);
}
return TRUE;

View File

@ -339,6 +339,72 @@ WINPR_API void MessagePipe_PostQuit(wMessagePipe* pipe, int nExitCode);
WINPR_API wMessagePipe* MessagePipe_New(void);
WINPR_API void MessagePipe_Free(wMessagePipe* pipe);
/* Publisher/Subscriber Pattern */
struct _wEventArgs
{
DWORD size;
};
typedef struct _wEventArgs wEventArgs;
typedef void (*pEventHandler)(void* context, wEventArgs* e);
#define MAX_EVENT_HANDLERS 32
struct _wEvent
{
const char* EventName;
wEventArgs EventArgs;
int EventHandlerCount;
pEventHandler EventHandlers[MAX_EVENT_HANDLERS];
};
typedef struct _wEvent wEvent;
#define DEFINE_EVENT_HANDLER(_name) \
typedef void (*p ## _name ## EventHandler)(void* context, _name ## EventArgs* e)
#define DEFINE_EVENT_BEGIN(_name) \
typedef struct _ ## _name ## EventArgs { \
wEventArgs e;
#define DEFINE_EVENT_END(_name) \
} _name ## EventArgs; \
DEFINE_EVENT_HANDLER(_name);
#define DEFINE_EVENT_ENTRY(_name) \
{ #_name, { sizeof( _name ## EventArgs) }, 0, { \
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, \
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, \
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, \
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } },
struct _wPubSub
{
HANDLE mutex;
BOOL synchronized;
int size;
int count;
wEvent* events;
};
typedef struct _wPubSub wPubSub;
WINPR_API BOOL PubSub_Lock(wPubSub* pubSub);
WINPR_API BOOL PubSub_Unlock(wPubSub* pubSub);
WINPR_API wEvent* PubSub_Events(wPubSub* pubSub, int* count);
WINPR_API wEvent* PubSub_FindEvent(wPubSub* pubSub, const char* EventName);
WINPR_API void PubSub_Publish(wPubSub* pubSub, wEvent* events, int count);
WINPR_API int PubSub_Subscribe(wPubSub* pubSub, const char* EventName, pEventHandler EventHandler);
WINPR_API int PubSub_Unsubscribe(wPubSub* pubSub, const char* EventName, pEventHandler EventHandler);
WINPR_API int PubSub_OnEvent(wPubSub* pubSub, const char* EventName, void* context, wEventArgs* e);
WINPR_API wPubSub* PubSub_New(BOOL synchronized);
WINPR_API void PubSub_Free(wPubSub* pubSub);
#ifdef __cplusplus
}
#endif

View File

@ -32,7 +32,7 @@
#define HANDLE_TYPE_ANONYMOUS_PIPE 7
#define WINPR_HANDLE_DEF() \
ULONG Type;
ULONG Type
struct winpr_handle
{

View File

@ -38,8 +38,6 @@
BOOL CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpPipeAttributes, DWORD nSize)
{
void* ptr;
HANDLE handle;
int pipe_fd[2];
WINPR_PIPE* pReadPipe;
WINPR_PIPE* pWritePipe;

View File

@ -21,6 +21,7 @@ set(MODULE_PREFIX "WINPR_UTILS")
set(${MODULE_PREFIX}_COLLECTIONS_SRCS
collections/Queue.c
collections/Stack.c
collections/PubSub.c
collections/Reference.c
collections/ArrayList.c
collections/Dictionary.c

View File

@ -49,6 +49,7 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
void* context, COMMAND_LINE_PRE_FILTER_FN_A preFilter, COMMAND_LINE_POST_FILTER_FN_A postFilter)
{
int i, j;
int status;
int count;
int length;
int index;
@ -67,11 +68,16 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
int value_index;
int toggle;
status = 0;
if (!argv)
return 0;
return status;
if (argc == 1)
return COMMAND_LINE_STATUS_PRINT_HELP;
{
status = COMMAND_LINE_STATUS_PRINT_HELP;
return status;
}
for (i = 1; i < argc; i++)
{
@ -82,7 +88,10 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
count = preFilter(context, i, argc, argv);
if (count < 0)
return COMMAND_LINE_ERROR;
{
status = COMMAND_LINE_ERROR;
return status;
}
if (count > 0)
{
@ -257,7 +266,10 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
}
if (!value && (options[j].Flags & COMMAND_LINE_VALUE_REQUIRED))
return COMMAND_LINE_ERROR_MISSING_VALUE;
{
status = COMMAND_LINE_ERROR_MISSING_VALUE;
return status;
}
options[j].Flags |= COMMAND_LINE_ARGUMENT_PRESENT;
@ -311,7 +323,7 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
}
}
return 0;
return status;
}
int CommandLineParseArgumentsW(int argc, LPCWSTR* argv, COMMAND_LINE_ARGUMENT_W* options, DWORD flags,

View File

@ -0,0 +1,224 @@
/**
* WinPR: Windows Portable Runtime
* Publisher/Subscriber Pattern
*
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <winpr/crt.h>
#include <winpr/collections.h>
/**
* Properties
*/
wEvent* PubSub_Events(wPubSub* pubSub, int* count)
{
if (count)
*count = pubSub->count;
return pubSub->events;
}
/**
* Methods
*/
BOOL PubSub_Lock(wPubSub* pubSub)
{
return (WaitForSingleObject(pubSub->mutex, INFINITE) == WAIT_OBJECT_0) ? TRUE : FALSE;
}
BOOL PubSub_Unlock(wPubSub* pubSub)
{
return ReleaseMutex(pubSub->mutex);
}
wEvent* PubSub_FindEvent(wPubSub* pubSub, const char* EventName)
{
int index;
wEvent* event = NULL;
for (index = 0; pubSub->count; index++)
{
if (strcmp(pubSub->events[index].EventName, EventName) == 0)
{
event = &(pubSub->events[index]);
break;
}
}
return event;
}
void PubSub_Publish(wPubSub* pubSub, wEvent* events, int count)
{
if (pubSub->synchronized)
PubSub_Lock(pubSub);
while (pubSub->count + count >= pubSub->size)
{
pubSub->size *= 2;
pubSub->events = (wEvent*) realloc(pubSub->events, pubSub->size);
}
CopyMemory(&pubSub->events[pubSub->count], events, count * sizeof(wEvent));
pubSub->count += count;
if (pubSub->synchronized)
PubSub_Unlock(pubSub);
}
int PubSub_Subscribe(wPubSub* pubSub, const char* EventName, pEventHandler EventHandler)
{
wEvent* event;
int status = -1;
if (pubSub->synchronized)
PubSub_Lock(pubSub);
event = PubSub_FindEvent(pubSub, EventName);
if (event)
{
status = 0;
if (event->EventHandlerCount <= MAX_EVENT_HANDLERS)
{
event->EventHandlers[event->EventHandlerCount] = EventHandler;
event->EventHandlerCount++;
}
else
{
status = -1;
}
}
if (pubSub->synchronized)
PubSub_Unlock(pubSub);
return status;
}
int PubSub_Unsubscribe(wPubSub* pubSub, const char* EventName, pEventHandler EventHandler)
{
int index;
wEvent* event;
int status = -1;
if (pubSub->synchronized)
PubSub_Lock(pubSub);
event = PubSub_FindEvent(pubSub, EventName);
if (event)
{
status = 0;
for (index = 0; index < event->EventHandlerCount; index++)
{
if (event->EventHandlers[index] == EventHandler)
{
event->EventHandlers[index] = NULL;
event->EventHandlerCount--;
MoveMemory(&event->EventHandlers[index], &event->EventHandlers[index + 1],
(MAX_EVENT_HANDLERS - index - 1) * sizeof(wEvent));
status = 1;
}
}
}
if (pubSub->synchronized)
PubSub_Unlock(pubSub);
return status;
}
int PubSub_OnEvent(wPubSub* pubSub, const char* EventName, void* context, wEventArgs* e)
{
int index;
wEvent* event;
int status = -1;
if (pubSub->synchronized)
PubSub_Lock(pubSub);
event = PubSub_FindEvent(pubSub, EventName);
if (event)
{
status = 0;
for (index = 0; index < event->EventHandlerCount; index++)
{
if (event->EventHandlers[index])
{
event->EventHandlers[index](context, e);
status = 1;
}
}
}
if (pubSub->synchronized)
PubSub_Unlock(pubSub);
return status;
}
/**
* Construction, Destruction
*/
wPubSub* PubSub_New(BOOL synchronized)
{
wPubSub* pubSub = NULL;
pubSub = (wPubSub*) malloc(sizeof(wPubSub));
if (pubSub)
{
pubSub->synchronized = synchronized;
if (pubSub->synchronized)
pubSub->mutex = CreateMutex(NULL, FALSE, NULL);
pubSub->count = 0;
pubSub->size = 64;
pubSub->events = (wEvent*) malloc(sizeof(wEvent) * pubSub->size);
ZeroMemory(pubSub->events, sizeof(wEvent) * pubSub->size);
}
return pubSub;
}
void PubSub_Free(wPubSub* pubSub)
{
if (pubSub)
{
if (pubSub->synchronized)
CloseHandle(pubSub->mutex);
if (pubSub->events)
free(pubSub->events);
free(pubSub);
}
}

View File

@ -7,6 +7,7 @@ set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c)
set(${MODULE_PREFIX}_TESTS
TestQueue.c
TestPrint.c
TestPubSub.c
TestArrayList.c
TestCmdLine.c
TestStreamPool.c

View File

@ -0,0 +1,86 @@
#include <winpr/crt.h>
#include <winpr/thread.h>
#include <winpr/collections.h>
DEFINE_EVENT_BEGIN(MouseMotion)
int x;
int y;
DEFINE_EVENT_END(MouseMotion)
DEFINE_EVENT_BEGIN(MouseButton)
int x;
int y;
int flags;
int button;
DEFINE_EVENT_END(MouseButton)
void MouseMotionEventHandler(void* context, MouseMotionEventArgs* e)
{
printf("MouseMotionEvent: x: %d y: %d\n", e->x, e->y);
}
void MouseButtonEventHandler(void* context, MouseButtonEventArgs* e)
{
printf("MouseButtonEvent: x: %d y: %d flags: %d button: %d\n", e->x, e->y, e->flags, e->button);
}
static wEvent Node_Events[] =
{
DEFINE_EVENT_ENTRY(MouseMotion)
DEFINE_EVENT_ENTRY(MouseButton)
};
#define NODE_EVENT_COUNT (sizeof(Node_Events) / sizeof(wEvent))
/* strongly-typed wrappers could be automatically defined using a macro */
static INLINE int PubSub_SubscribeMouseMotion(wPubSub* pubSub, pMouseMotionEventHandler MouseMotionEventHandler)
{
return PubSub_Subscribe(pubSub, "MouseMotion", (pEventHandler) MouseMotionEventHandler);
}
static INLINE int PubSub_OnMouseMotion(wPubSub* pubSub, void* context, MouseMotionEventArgs* e)
{
return PubSub_OnEvent(pubSub, "MouseMotion", context, (wEventArgs*) e);
}
int TestPubSub(int argc, char* argv[])
{
wPubSub* node;
node = PubSub_New(TRUE);
PubSub_Publish(node, Node_Events, NODE_EVENT_COUNT);
/* Register Event Handler */
PubSub_SubscribeMouseMotion(node, MouseMotionEventHandler);
PubSub_Subscribe(node, "MouseButton", (pEventHandler) MouseButtonEventHandler);
/* Call Event Handler */
{
MouseMotionEventArgs e;
e.x = 64;
e.y = 128;
PubSub_OnMouseMotion(node, NULL, &e);
}
{
MouseButtonEventArgs e;
e.x = 23;
e.y = 56;
e.flags = 7;
e.button = 1;
PubSub_OnEvent(node, "MouseButton", NULL, (wEventArgs*) &e);
}
PubSub_Free(node);
return 0;
}