mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
shadow: start hooking X11 subsystem with shadow server core
This commit is contained in:
@@ -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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,9 @@ struct rdp_shadow_screen
|
||||
{
|
||||
rdpShadowServer* server;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
|
||||
rdpShadowSurface* primary;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user