shadow: start hooking X11 subsystem with shadow server core

This commit is contained in:
Marc-André Moreau
2014-07-12 00:01:29 -04:00
parent 3d57659efb
commit c865fed299
10 changed files with 189 additions and 32 deletions

View File

@@ -23,6 +23,7 @@
#include <freerdp/api.h>
#include <freerdp/types.h>
#include <freerdp/settings.h>
#include <freerdp/listener.h>
typedef struct rdp_shadow_client rdpShadowClient;
@@ -36,8 +37,8 @@ struct rdp_shadow_client
{
rdpContext context;
void* ext;
HANDLE thread;
BOOL activated;
rdpShadowServer* server;
};
@@ -55,7 +56,9 @@ struct rdp_shadow_server
};
#define RDP_SHADOW_SUBSYSTEM_COMMON() \
rdpShadowServer* server
rdpShadowServer* server; \
int monitorCount; \
MONITOR_DEF monitors[16]
struct rdp_shadow_subsystem
{

View File

@@ -276,7 +276,12 @@ int x11_shadow_subsystem_init(x11ShadowSubsystem* subsystem)
x11_shadow_cursor_init(subsystem);
subsystem->bytesPerPixel = 4;
subsystem->monitorCount = 1;
subsystem->monitors[0].left = 0;
subsystem->monitors[0].top = 0;
subsystem->monitors[0].right = subsystem->width;
subsystem->monitors[0].bottom = subsystem->height;
subsystem->monitors[0].flags = 1;
return 1;
}

View File

@@ -29,12 +29,7 @@ typedef struct x11_shadow_subsystem x11ShadowSubsystem;
#include <winpr/stream.h>
#include <winpr/collections.h>
#include <freerdp/gdi/gdi.h>
#include <freerdp/gdi/dc.h>
#include <freerdp/gdi/region.h>
#include <freerdp/codec/rfx.h>
#include <freerdp/listener.h>
#include <freerdp/utils/stopwatch.h>
#include <X11/Xlib.h>
@@ -71,7 +66,6 @@ struct x11_shadow_subsystem
Visual* visual;
Display* display;
int scanline_pad;
int bytesPerPixel;
BOOL use_xshm;
XImage* fb_image;

View File

@@ -115,6 +115,11 @@ rdpShadowServer* shadow_server_new(int argc, char** argv)
server->listener->info = (void*) server;
server->listener->PeerAccepted = shadow_client_accepted;
server->subsystem = x11_shadow_subsystem_new(server);
if (!server->subsystem)
return NULL;
server->screen = shadow_screen_new(server);
if (!server->screen)
@@ -125,11 +130,6 @@ rdpShadowServer* shadow_server_new(int argc, char** argv)
if (!server->encoder)
return NULL;
server->subsystem = x11_shadow_subsystem_new(server);
if (!server->subsystem)
return NULL;
return server;
}

View File

@@ -43,16 +43,6 @@ void shadow_client_context_free(freerdp_peer* peer, rdpShadowClient* client)
}
BOOL shadow_client_get_fds(freerdp_peer* peer, void** rfds, int* rcount)
{
return TRUE;
}
BOOL shadow_client_check_fds(freerdp_peer* peer)
{
return TRUE;
}
BOOL shadow_client_capabilities(freerdp_peer* peer)
{
return TRUE;
@@ -60,6 +50,10 @@ BOOL shadow_client_capabilities(freerdp_peer* peer)
BOOL shadow_client_post_connect(freerdp_peer* peer)
{
rdpShadowClient* client;
client = (rdpShadowClient*) peer->context;
fprintf(stderr, "Client %s is activated", peer->hostname);
if (peer->settings->AutoLogonEnabled)
@@ -70,7 +64,7 @@ BOOL shadow_client_post_connect(freerdp_peer* peer)
}
fprintf(stderr, "\n");
fprintf(stderr, "Client requested desktop: %dx%dx%d\n",
fprintf(stderr, "Client requested desktop: %dx%d@%d\n",
peer->settings->DesktopWidth, peer->settings->DesktopHeight, peer->settings->ColorDepth);
if (!peer->settings->RemoteFxCodec)
@@ -79,8 +73,9 @@ BOOL shadow_client_post_connect(freerdp_peer* peer)
return FALSE;
}
//client->settings->DesktopWidth = 1024;
//client->settings->DesktopHeight = 768;
peer->settings->DesktopWidth = client->server->screen->width;
peer->settings->DesktopHeight = client->server->screen->height;
peer->settings->ColorDepth = 32;
peer->update->DesktopResize(peer->update->context);
@@ -89,9 +84,134 @@ BOOL shadow_client_post_connect(freerdp_peer* peer)
BOOL shadow_client_activate(freerdp_peer* peer)
{
rdpShadowClient* client;
client = (rdpShadowClient*) peer->context;
client->activated = TRUE;
return TRUE;
}
int shadow_client_send_surface_bits(rdpShadowClient* client)
{
int i;
wStream* s;
int numMessages;
rdpUpdate* update;
rdpContext* context;
rdpSettings* settings;
rdpShadowServer* server;
rdpShadowSurface* surface;
rdpShadowEncoder* encoder;
SURFACE_BITS_COMMAND cmd;
BYTE* pSrcData;
int nSrcStep;
int nXSrc;
int nYSrc;
int nWidth;
int nHeight;
context = (rdpContext*) client;
update = context->update;
settings = context->settings;
server = client->server;
encoder = server->encoder;
surface = server->surface;
pSrcData = surface->data;
nSrcStep = surface->scanline;
nWidth = surface->width;
nHeight = surface->height;
nXSrc = 0;
nYSrc = 0;
if (settings->RemoteFxCodec)
{
RFX_RECT rect;
RFX_MESSAGE* messages;
s = encoder->rfx_s;
rect.x = nXSrc;
rect.y = nYSrc;
rect.width = nWidth;
rect.height = nHeight;
messages = rfx_encode_messages(encoder->rfx, &rect, 1, pSrcData,
surface->width, surface->height, nSrcStep, &numMessages,
settings->MultifragMaxRequestSize);
cmd.codecID = settings->RemoteFxCodecId;
cmd.destLeft = 0;
cmd.destTop = 0;
cmd.destRight = surface->width;
cmd.destBottom = surface->height;
cmd.bpp = 32;
cmd.width = surface->width;
cmd.height = surface->height;
for (i = 0; i < numMessages; i++)
{
Stream_SetPosition(s, 0);
rfx_write_message(encoder->rfx, s, &messages[i]);
rfx_message_free(encoder->rfx, &messages[i]);
cmd.bitmapDataLength = Stream_GetPosition(s);
cmd.bitmapData = Stream_Buffer(s);
IFCALL(update->SurfaceBits, update->context, &cmd);
}
free(messages);
return 0;
}
else if (settings->NSCodec)
{
NSC_MESSAGE* messages;
s = encoder->nsc_s;
messages = nsc_encode_messages(encoder->nsc, pSrcData,
nXSrc, nYSrc, nWidth, nHeight, nSrcStep,
&numMessages, settings->MultifragMaxRequestSize);
cmd.bpp = 32;
cmd.codecID = settings->NSCodecId;
for (i = 0; i < numMessages; i++)
{
Stream_SetPosition(s, 0);
nsc_write_message(encoder->nsc, s, &messages[i]);
nsc_message_free(encoder->nsc, &messages[i]);
cmd.destLeft = messages[i].x;
cmd.destTop = messages[i].y;
cmd.destRight = messages[i].x + messages[i].width;
cmd.destBottom = messages[i].y + messages[i].height;
cmd.width = messages[i].width;
cmd.height = messages[i].height;
cmd.bitmapDataLength = Stream_GetPosition(s);
cmd.bitmapData = Stream_Buffer(s);
IFCALL(update->SurfaceBits, update->context, &cmd);
}
free(messages);
return 0;
}
return 0;
}
static const char* makecert_argv[4] =
{
"makecert",
@@ -174,7 +294,7 @@ void* shadow_client_thread(rdpShadowClient* client)
nCount = 0;
events[nCount++] = ClientEvent;
status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
status = WaitForMultipleObjects(nCount, events, FALSE, 100);
if (WaitForSingleObject(ClientEvent, 0) == WAIT_OBJECT_0)
{
@@ -184,6 +304,9 @@ void* shadow_client_thread(rdpShadowClient* client)
break;
}
}
if (client->activated)
shadow_client_send_surface_bits(client);
}
peer->Disconnect(peer);

View File

@@ -20,6 +20,8 @@
#include "config.h"
#endif
#include "shadow.h"
#include "shadow_encoder.h"
int shadow_encoder_grid_init(rdpShadowEncoder* encoder)
@@ -88,8 +90,8 @@ rdpShadowEncoder* shadow_encoder_new(rdpShadowServer* server)
encoder->server = server;
encoder->width = 1024;
encoder->height = 768;
encoder->width = server->screen->width;
encoder->height = server->screen->height;
encoder->bitsPerPixel = 32;
encoder->bytesPerPixel = 4;

View File

@@ -20,11 +20,15 @@
#include "config.h"
#endif
#include "shadow_surface.h"
#include "shadow_screen.h"
rdpShadowScreen* shadow_screen_new(rdpShadowServer* server)
{
MONITOR_DEF* primary;
rdpShadowScreen* screen;
rdpShadowSubsystem* subsystem;
screen = (rdpShadowScreen*) calloc(1, sizeof(rdpShadowScreen));
@@ -32,6 +36,18 @@ rdpShadowScreen* shadow_screen_new(rdpShadowServer* server)
return NULL;
screen->server = server;
subsystem = server->subsystem;
primary = &(subsystem->monitors[0]);
screen->width = primary->right;
screen->height = primary->bottom;
screen->primary = shadow_surface_new(server, screen->width, screen->height);
if (!screen->primary)
return NULL;
server->surface = screen->primary;
return screen;
}

View File

@@ -25,6 +25,9 @@ struct rdp_shadow_screen
{
rdpShadowServer* server;
int width;
int height;
rdpShadowSurface* primary;
};

View File

@@ -22,7 +22,7 @@
#include "shadow_surface.h"
rdpShadowSurface* shadow_surface_new(rdpShadowServer* server)
rdpShadowSurface* shadow_surface_new(rdpShadowServer* server, int width, int height)
{
rdpShadowSurface* surface;
@@ -33,6 +33,17 @@ rdpShadowSurface* shadow_surface_new(rdpShadowServer* server)
surface->server = server;
surface->width = width;
surface->height = height;
surface->scanline = (surface->width + (surface->width % 4)) * 4;
surface->data = (BYTE*) malloc(surface->scanline * surface->height);
if (!surface->data)
return NULL;
ZeroMemory(surface->data, surface->scanline * surface->height);
return surface;
}

View File

@@ -35,7 +35,7 @@ struct rdp_shadow_surface
extern "C" {
#endif
rdpShadowSurface* shadow_surface_new(rdpShadowServer* server);
rdpShadowSurface* shadow_surface_new(rdpShadowServer* server, int width, int height);
void shadow_surface_free(rdpShadowSurface* surface);
#ifdef __cplusplus