shadow: initial working support for WDS+RDP backend

This commit is contained in:
Marc-André Moreau 2014-08-15 14:57:09 -04:00
parent 0457a29f57
commit 09ae1ac9ca
5 changed files with 90 additions and 56 deletions

View File

@ -23,11 +23,6 @@
#include <winpr/crt.h>
#include <winpr/print.h>
#include <freerdp/addin.h>
#include <freerdp/gdi/gdi.h>
#include <freerdp/client/cmdline.h>
#include <freerdp/channels/channels.h>
#include "win_rdp.h"
void shw_OnChannelConnectedEventHandler(rdpContext* context, ChannelConnectedEventArgs* e)
@ -57,58 +52,30 @@ void shw_begin_paint(rdpContext* context)
void shw_end_paint(rdpContext* context)
{
INT32 x, y;
UINT32 w, h;
shwContext* shw;
HGDI_RGN invalid;
int index;
int ninvalid;
HGDI_RGN cinvalid;
rdpSettings* settings;
RECTANGLE_16 invalidRect;
rdpGdi* gdi = context->gdi;
shwContext* shw = (shwContext*) context;
winShadowSubsystem* subsystem = shw->subsystem;
shw = (shwContext*) context;
settings = context->settings;
invalid = gdi->primary->hdc->hwnd->invalid;
ninvalid = gdi->primary->hdc->hwnd->ninvalid;
cinvalid = gdi->primary->hdc->hwnd->cinvalid;
x = invalid->x;
y = invalid->y;
w = invalid->w;
h = invalid->h;
for (index = 0; index < ninvalid; index++)
{
invalidRect.left = cinvalid[index].x;
invalidRect.top = cinvalid[index].y;
invalidRect.right = cinvalid[index].x + cinvalid[index].w;
invalidRect.bottom = cinvalid[index].y + cinvalid[index].h;
if (x < 0)
x = 0;
region16_union_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &invalidRect);
}
if (x > settings->DesktopWidth - 1)
x = settings->DesktopWidth - 1;
w += x % 16;
x -= x % 16;
w += w % 16;
if (x + w > settings->DesktopWidth)
w = settings->DesktopWidth - x;
if (y < 0)
y = 0;
if (y > settings->DesktopHeight - 1)
y = settings->DesktopHeight - 1;
h += y % 16;
y -= y % 16;
h += h % 16;
if (h > settings->DesktopHeight)
h = settings->DesktopHeight;
if (y + h > settings->DesktopHeight)
h = settings->DesktopHeight - y;
if (w * h < 1)
return;
SetEvent(subsystem->RdpUpdateEnterEvent);
WaitForSingleObject(subsystem->RdpUpdateLeaveEvent, INFINITE);
ResetEvent(subsystem->RdpUpdateLeaveEvent);
}
void shw_desktop_resize(rdpContext* context)
@ -402,6 +369,10 @@ int win_shadow_rdp_init(winShadowSubsystem* subsystem)
subsystem->shw = (shwContext*) context;
subsystem->shw->settings = context->settings;
subsystem->shw->subsystem = subsystem;
subsystem->RdpUpdateEnterEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
subsystem->RdpUpdateLeaveEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
return 1;
}

View File

@ -19,6 +19,11 @@
#ifndef FREERDP_SHADOW_SERVER_WIN_RDP_H
#define FREERDP_SHADOW_SERVER_WIN_RDP_H
#include <freerdp/addin.h>
#include <freerdp/gdi/gdi.h>
#include <freerdp/client/cmdline.h>
#include <freerdp/channels/channels.h>
typedef struct shw_context shwContext;
#include "win_shadow.h"
@ -31,6 +36,7 @@ struct shw_context
HANDLE StopEvent;
freerdp* instance;
rdpSettings* settings;
winShadowSubsystem* subsystem;
};
#ifdef __cplusplus

View File

@ -249,7 +249,20 @@ int win_shadow_surface_copy(winShadowSubsystem* subsystem)
printf("SurfaceCopy x: %d y: %d width: %d height: %d right: %d bottom: %d\n",
x, y, width, height, x + width, y + height);
#ifdef WITH_DXGI_1_2
#if defined(WITH_WDS_API)
{
rdpGdi* gdi;
shwContext* shw;
rdpContext* context;
shw = subsystem->shw;
context = (rdpContext*) shw;
gdi = context->gdi;
pDstData = gdi->primary_buffer;
nDstStep = gdi->width * 4;
}
#elif defined(WITH_DXGI_1_2)
status = win_shadow_dxgi_fetch_frame_data(subsystem, &pDstData, &nDstStep, x, y, width, height);
#endif
@ -277,6 +290,44 @@ int win_shadow_surface_copy(winShadowSubsystem* subsystem)
return 1;
}
#if defined(WITH_WDS_API)
void* win_shadow_subsystem_thread(winShadowSubsystem* subsystem)
{
DWORD status;
DWORD nCount;
HANDLE events[32];
HANDLE StopEvent;
StopEvent = subsystem->server->StopEvent;
nCount = 0;
events[nCount++] = StopEvent;
events[nCount++] = subsystem->RdpUpdateEnterEvent;
while (1)
{
status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
if (WaitForSingleObject(StopEvent, 0) == WAIT_OBJECT_0)
{
break;
}
if (WaitForSingleObject(subsystem->RdpUpdateEnterEvent, 0) == WAIT_OBJECT_0)
{
win_shadow_surface_copy(subsystem);
ResetEvent(subsystem->RdpUpdateEnterEvent);
SetEvent(subsystem->RdpUpdateLeaveEvent);
}
}
ExitThread(0);
return NULL;
}
#elif defined(WITH_DXGI_1_2)
void* win_shadow_subsystem_thread(winShadowSubsystem* subsystem)
{
int fps;
@ -314,7 +365,6 @@ void* win_shadow_subsystem_thread(winShadowSubsystem* subsystem)
if ((status == WAIT_TIMEOUT) || (GetTickCount64() > frameTime))
{
#ifdef WITH_DXGI_1_2
int dxgi_status;
dxgi_status = win_shadow_dxgi_get_next_frame(subsystem);
@ -324,7 +374,6 @@ void* win_shadow_subsystem_thread(winShadowSubsystem* subsystem)
if (dxgi_status > 0)
win_shadow_surface_copy(subsystem);
#endif
dwInterval = 1000 / fps;
frameTime += dwInterval;
@ -335,6 +384,8 @@ void* win_shadow_subsystem_thread(winShadowSubsystem* subsystem)
return NULL;
}
#endif
int win_shadow_subsystem_init(winShadowSubsystem* subsystem)
{
HDC hdc;

View File

@ -46,6 +46,8 @@ struct win_shadow_subsystem
#ifdef WITH_WDS_API
HWND hWnd;
shwContext* shw;
HANDLE RdpUpdateEnterEvent;
HANDLE RdpUpdateLeaveEvent;
rdpAssistanceFile* pAssistanceFile;
_IRDPSessionEvents* pSessionEvents;
IRDPSRAPISharingSession* pSharingSession;

View File

@ -747,7 +747,7 @@ int win_shadow_wds_init(winShadowSubsystem* subsystem)
printf("ConnectionString: %s\n", file->ConnectionString2);
if (1)
if (0)
{
FILE* fp;
size_t size;
@ -803,8 +803,6 @@ int win_shadow_wds_init(winShadowSubsystem* subsystem)
int win_shadow_wds_uninit(winShadowSubsystem* subsystem)
{
printf("win_shadow_wds_uninit\n");
if (subsystem->pSharingSession)
{
subsystem->pSharingSession->lpVtbl->Close(subsystem->pSharingSession);
@ -860,5 +858,11 @@ int win_shadow_wds_uninit(winShadowSubsystem* subsystem)
subsystem->hWnd = NULL;
}
if (subsystem->shw)
{
win_shadow_rdp_uninit(subsystem);
subsystem->shw = NULL;
}
return 1;
}