wfreerdp: add RAIL window update, partial input support

This commit is contained in:
Marc-André Moreau 2014-10-24 19:46:02 -04:00
parent 55ea4caf11
commit 8942631947
3 changed files with 174 additions and 20 deletions

View File

@ -41,11 +41,13 @@
#include <freerdp/freerdp.h>
#include <freerdp/constants.h>
#include <freerdp/codec/region.h>
#include <freerdp/client/cmdline.h>
#include <freerdp/client/channels.h>
#include <freerdp/channels/channels.h>
#include "wf_gdi.h"
#include "wf_rail.h"
#include "wf_channels.h"
#include "wf_graphics.h"
#include "wf_cliprdr.h"
@ -78,34 +80,50 @@ void wf_sw_end_paint(wfContext* wfc)
{
int i;
rdpGdi* gdi;
INT32 x, y;
UINT32 w, h;
int ninvalid;
RECT update_rect;
RECT updateRect;
HGDI_RGN cinvalid;
REGION16 invalidRegion;
RECTANGLE_16 invalidRect;
const RECTANGLE_16* extents;
rdpContext* context = (rdpContext*) wfc;
gdi = ((rdpContext*) wfc)->gdi;
if (gdi->primary->hdc->hwnd->ninvalid < 1)
return;
gdi = context->gdi;
ninvalid = gdi->primary->hdc->hwnd->ninvalid;
cinvalid = gdi->primary->hdc->hwnd->cinvalid;
if (ninvalid < 1)
return;
region16_init(&invalidRegion);
for (i = 0; i < ninvalid; i++)
{
x = cinvalid[i].x;
y = cinvalid[i].y;
w = cinvalid[i].w;
h = cinvalid[i].h;
invalidRect.left = cinvalid[i].x;
invalidRect.top = cinvalid[i].y;
invalidRect.right = cinvalid[i].x + cinvalid[i].w;
invalidRect.bottom = cinvalid[i].y + cinvalid[i].h;
update_rect.left = x;
update_rect.top = y;
update_rect.right = x + w;
update_rect.bottom = y + h;
InvalidateRect(wfc->hwnd, &update_rect, FALSE);
region16_union_rect(&invalidRegion, &invalidRegion, &invalidRect);
}
if (!region16_is_empty(&invalidRegion))
{
extents = region16_extents(&invalidRegion);
updateRect.left = extents->left;
updateRect.top = extents->top;
updateRect.right = extents->right;
updateRect.bottom = extents->bottom;
InvalidateRect(wfc->hwnd, &updateRect, FALSE);
if (wfc->rail)
wf_rail_invalidate_region(wfc, &invalidRegion);
}
region16_uninit(&invalidRegion);
}
void wf_sw_desktop_resize(wfContext* wfc)
@ -1110,7 +1128,7 @@ int wfreerdp_client_new(freerdp* instance, rdpContext* context)
wfc->instance = instance;
wfc->settings = instance->settings;
context->channels = freerdp_channels_new();
return 0;
}

View File

@ -25,6 +25,9 @@
#include "wf_rail.h"
#define GET_X_LPARAM(lParam) ((UINT16) (lParam & 0xFFFF))
#define GET_Y_LPARAM(lParam) ((UINT16) ((lParam >> 16) & 0xFFFF))
/* RemoteApp Core Protocol Extension */
struct _WINDOW_STYLE
@ -283,8 +286,13 @@ LRESULT CALLBACK wf_RailWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPara
int x, y;
int width;
int height;
UINT32 xPos;
UINT32 yPos;
PAINTSTRUCT ps;
UINT32 inputFlags;
wfContext* wfc = NULL;
rdpInput* input = NULL;
rdpContext* context = NULL;
wfRailWindow* railWindow;
railWindow = (wfRailWindow*) GetWindowLongPtr(hWnd, GWLP_USERDATA);
@ -292,6 +300,12 @@ LRESULT CALLBACK wf_RailWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPara
if (railWindow)
wfc = railWindow->wfc;
if (wfc)
context = (rdpContext*) wfc;
if (context)
input = context->input;
switch (msg)
{
case WM_PAINT:
@ -313,6 +327,79 @@ LRESULT CALLBACK wf_RailWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPara
}
break;
case WM_LBUTTONDOWN:
{
if (!railWindow || !input)
return 0;
xPos = GET_X_LPARAM(lParam) + railWindow->x;
yPos = GET_Y_LPARAM(lParam) + railWindow->y;
inputFlags = PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1;
if (input)
input->MouseEvent(input, inputFlags, xPos, yPos);
}
break;
case WM_LBUTTONUP:
{
if (!railWindow || !input)
return 0;
xPos = GET_X_LPARAM(lParam) + railWindow->x;
yPos = GET_Y_LPARAM(lParam) + railWindow->y;
inputFlags = PTR_FLAGS_BUTTON1;
if (input)
input->MouseEvent(input, inputFlags, xPos, yPos);
}
break;
case WM_RBUTTONDOWN:
{
if (!railWindow || !input)
return 0;
xPos = GET_X_LPARAM(lParam) + railWindow->x;
yPos = GET_Y_LPARAM(lParam) + railWindow->y;
inputFlags = PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2;
if (input)
input->MouseEvent(input, inputFlags, xPos, yPos);
}
break;
case WM_RBUTTONUP:
{
if (!railWindow || !input)
return 0;
xPos = GET_X_LPARAM(lParam) + railWindow->x;
yPos = GET_Y_LPARAM(lParam) + railWindow->y;
inputFlags = PTR_FLAGS_BUTTON2;
if (input)
input->MouseEvent(input, inputFlags, xPos, yPos);
}
break;
case WM_MOUSEMOVE:
{
if (!railWindow || !input)
return 0;
xPos = GET_X_LPARAM(lParam) + railWindow->x;
yPos = GET_Y_LPARAM(lParam) + railWindow->y;
inputFlags = PTR_FLAGS_MOVE;
if (input)
input->MouseEvent(input, inputFlags, xPos, yPos);
}
break;
case WM_MOUSEWHEEL:
break;
case WM_CLOSE:
DestroyWindow(hWnd);
break;
@ -328,8 +415,9 @@ LRESULT CALLBACK wf_RailWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPara
return 0;
}
#define RAIL_DISABLED_WINDOW_STYLES (WS_BORDER | WS_THICKFRAME | WS_DLGFRAME | WS_CAPTION | WS_OVERLAPPED)
#define RAIL_DISABLED_EXTENDED_WINDOW_STYLES (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE)
#define RAIL_DISABLED_WINDOW_STYLES (WS_BORDER | WS_THICKFRAME | WS_DLGFRAME | WS_CAPTION | \
WS_OVERLAPPED | WS_VSCROLL | WS_HSCROLL | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX)
#define RAIL_DISABLED_EXTENDED_WINDOW_STYLES (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE | WS_EX_WINDOWEDGE)
static void wf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* windowState)
{
@ -863,6 +951,52 @@ static int wf_rail_server_get_appid_response(RailClientContext* context, RAIL_GE
return 1;
}
void wf_rail_invalidate_region(wfContext* wfc, REGION16* invalidRegion)
{
int index;
int count;
RECT updateRect;
RECTANGLE_16 windowRect;
ULONG_PTR* pKeys = NULL;
wfRailWindow* railWindow;
const RECTANGLE_16* extents;
REGION16 windowInvalidRegion;
region16_init(&windowInvalidRegion);
count = HashTable_GetKeys(wfc->railWindows, &pKeys);
for (index = 0; index < count; index++)
{
railWindow = (wfRailWindow*) HashTable_GetItemValue(wfc->railWindows, (void*) pKeys[index]);
if (railWindow)
{
windowRect.left = railWindow->x;
windowRect.top = railWindow->y;
windowRect.right = railWindow->x + railWindow->width;
windowRect.bottom = railWindow->y + railWindow->height;
region16_clear(&windowInvalidRegion);
region16_intersect_rect(&windowInvalidRegion, invalidRegion, &windowRect);
if (!region16_is_empty(&windowInvalidRegion))
{
extents = region16_extents(&windowInvalidRegion);
updateRect.left = extents->left - railWindow->x;
updateRect.top = extents->top - railWindow->y;
updateRect.right = extents->right - railWindow->x;
updateRect.bottom = extents->bottom - railWindow->y;
InvalidateRect(railWindow->hWnd, &updateRect, FALSE);
}
}
}
region16_uninit(&windowInvalidRegion);
}
void wf_rail_init(wfContext* wfc, RailClientContext* rail)
{
rdpContext* context = (rdpContext*) wfc;

View File

@ -44,4 +44,6 @@ struct wf_rail_window
void wf_rail_init(wfContext* wfc, RailClientContext* rail);
void wf_rail_uninit(wfContext* wfc, RailClientContext* rail);
void wf_rail_invalidate_region(wfContext* wfc, REGION16* invalidRegion);
#endif