Merge pull request #2739 from realjiangms/shadow_resize
server/shadow: Enhancement regarding the screen and resolution - addresize support and fix subRect feature
This commit is contained in:
commit
97c38e7d8c
@ -90,7 +90,6 @@ struct rdp_shadow_client
|
||||
CRITICAL_SECTION lock;
|
||||
REGION16 invalidRegion;
|
||||
rdpShadowServer* server;
|
||||
rdpShadowSurface* lobby;
|
||||
rdpShadowEncoder* encoder;
|
||||
rdpShadowSubsystem* subsystem;
|
||||
|
||||
@ -112,6 +111,7 @@ struct rdp_shadow_server
|
||||
wArrayList* clients;
|
||||
rdpShadowScreen* screen;
|
||||
rdpShadowSurface* surface;
|
||||
rdpShadowSurface* lobby;
|
||||
rdpShadowCapture* capture;
|
||||
rdpShadowSubsystem* subsystem;
|
||||
|
||||
@ -282,6 +282,8 @@ FREERDP_API int shadow_client_boardcast_quit(rdpShadowServer* server, int nExitC
|
||||
FREERDP_API int shadow_encoder_preferred_fps(rdpShadowEncoder* encoder);
|
||||
FREERDP_API UINT32 shadow_encoder_inflight_frames(rdpShadowEncoder* encoder);
|
||||
|
||||
FREERDP_API BOOL shadow_screen_resize(rdpShadowScreen* screen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -51,6 +51,8 @@
|
||||
|
||||
#define TAG SERVER_TAG("shadow.x11")
|
||||
|
||||
int x11_shadow_enum_monitors(MONITOR_DEF* monitors, int maxMonitors);
|
||||
|
||||
#ifdef WITH_PAM
|
||||
|
||||
#include <security/pam_appl.h>
|
||||
@ -273,12 +275,6 @@ void x11_shadow_input_mouse_event(x11ShadowSubsystem* subsystem, UINT16 flags, U
|
||||
x += surface->x;
|
||||
y += surface->y;
|
||||
|
||||
if (server->shareSubRect)
|
||||
{
|
||||
x += server->subRect.left;
|
||||
y += server->subRect.top;
|
||||
}
|
||||
|
||||
XTestGrabControl(subsystem->display, True);
|
||||
|
||||
if (flags & PTR_FLAGS_WHEEL)
|
||||
@ -332,12 +328,6 @@ void x11_shadow_input_extended_mouse_event(x11ShadowSubsystem* subsystem, UINT16
|
||||
x += surface->x;
|
||||
y += surface->y;
|
||||
|
||||
if (server->shareSubRect)
|
||||
{
|
||||
x += server->subRect.left;
|
||||
y += server->subRect.top;
|
||||
}
|
||||
|
||||
XTestGrabControl(subsystem->display, True);
|
||||
|
||||
XTestFakeMotionEvent(subsystem->display, 0, x, y, CurrentTime);
|
||||
@ -495,6 +485,13 @@ int x11_shadow_query_cursor(x11ShadowSubsystem* subsystem, BOOL getImage)
|
||||
y = root_y;
|
||||
}
|
||||
|
||||
/* Convert to offset based on current surface */
|
||||
if (surface)
|
||||
{
|
||||
x -= surface->x;
|
||||
y -= surface->y;
|
||||
}
|
||||
|
||||
if ((x != subsystem->pointerX) || (y != subsystem->pointerY))
|
||||
{
|
||||
subsystem->pointerX = x;
|
||||
@ -572,8 +569,8 @@ int x11_shadow_blend_cursor(x11ShadowSubsystem* subsystem)
|
||||
nWidth = subsystem->cursorWidth;
|
||||
nHeight = subsystem->cursorHeight;
|
||||
|
||||
nXDst = subsystem->pointerX - surface->x - subsystem->cursorHotX;
|
||||
nYDst = subsystem->pointerY - surface->y - subsystem->cursorHotY;
|
||||
nXDst = subsystem->pointerX - subsystem->cursorHotX;
|
||||
nYDst = subsystem->pointerY - subsystem->cursorHotY;
|
||||
|
||||
if (nXDst >= surface->width)
|
||||
return 1;
|
||||
@ -659,6 +656,51 @@ int x11_shadow_blend_cursor(x11ShadowSubsystem* subsystem)
|
||||
return 1;
|
||||
}
|
||||
|
||||
BOOL x11_shadow_check_resize(x11ShadowSubsystem* subsystem)
|
||||
{
|
||||
MONITOR_DEF* virtualScreen;
|
||||
XWindowAttributes attr;
|
||||
XGetWindowAttributes(subsystem->display, subsystem->root_window, &attr);
|
||||
|
||||
if (attr.width != subsystem->width || attr.height != subsystem->height)
|
||||
{
|
||||
/* Screen size changed. Refresh monitor definitions and trigger screen resize */
|
||||
subsystem->numMonitors = x11_shadow_enum_monitors(subsystem->monitors, 16);
|
||||
|
||||
shadow_screen_resize(subsystem->server->screen);
|
||||
|
||||
subsystem->width = attr.width;
|
||||
subsystem->height = attr.height;
|
||||
|
||||
virtualScreen = &(subsystem->virtualScreen);
|
||||
virtualScreen->left = 0;
|
||||
virtualScreen->top = 0;
|
||||
virtualScreen->right = subsystem->width;
|
||||
virtualScreen->bottom = subsystem->height;
|
||||
virtualScreen->flags = 1;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int x11_shadow_error_handler_for_capture(Display * display, XErrorEvent * event)
|
||||
{
|
||||
char msg[256];
|
||||
XGetErrorText(display, event->error_code, (char *) &msg, sizeof(msg));
|
||||
WLog_ERR(TAG, "X11 error: %s Error code: %x, request code: %x, minor code: %x",
|
||||
msg, event->error_code, event->request_code, event->minor_code);
|
||||
|
||||
/* Ignore BAD MATCH error during image capture. Abort in other case */
|
||||
if (event->error_code != BadMatch)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
|
||||
{
|
||||
int count;
|
||||
@ -692,6 +734,12 @@ int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
|
||||
|
||||
XLockDisplay(subsystem->display);
|
||||
|
||||
/*
|
||||
* Ignore BadMatch error during image capture. The screen size may be
|
||||
* changed outside. We will resize to correct resolution at next frame
|
||||
*/
|
||||
XSetErrorHandler(x11_shadow_error_handler_for_capture);
|
||||
|
||||
if (subsystem->use_xshm)
|
||||
{
|
||||
image = subsystem->fb_image;
|
||||
@ -707,10 +755,22 @@ int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
|
||||
image = XGetImage(subsystem->display, subsystem->root_window,
|
||||
surface->x, surface->y, surface->width, surface->height, AllPlanes, ZPixmap);
|
||||
|
||||
if (!image)
|
||||
{
|
||||
/*
|
||||
* BadMatch error happened. The size may have been changed again.
|
||||
* Give up this frame and we will resize again in next frame
|
||||
*/
|
||||
goto fail_capture;
|
||||
}
|
||||
|
||||
status = shadow_capture_compare(surface->data, surface->scanline, surface->width, surface->height,
|
||||
(BYTE*) image->data, image->bytes_per_line, &invalidRect);
|
||||
}
|
||||
|
||||
/* Restore the default error handler */
|
||||
XSetErrorHandler(NULL);
|
||||
|
||||
XSync(subsystem->display, False);
|
||||
|
||||
XUnlockDisplay(subsystem->display);
|
||||
@ -757,6 +817,12 @@ int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
|
||||
XDestroyImage(image);
|
||||
|
||||
return 1;
|
||||
|
||||
fail_capture:
|
||||
XSetErrorHandler(NULL);
|
||||
XSync(subsystem->display, False);
|
||||
XUnlockDisplay(subsystem->display);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int x11_shadow_subsystem_process_message(x11ShadowSubsystem* subsystem, wMessage* message)
|
||||
@ -866,6 +932,7 @@ void* x11_shadow_subsystem_thread(x11ShadowSubsystem* subsystem)
|
||||
|
||||
if ((status == WAIT_TIMEOUT) || (GetTickCount64() > frameTime))
|
||||
{
|
||||
x11_shadow_check_resize(subsystem);
|
||||
x11_shadow_screen_grab(subsystem);
|
||||
x11_shadow_query_cursor(subsystem, FALSE);
|
||||
|
||||
@ -1127,6 +1194,8 @@ int x11_shadow_enum_monitors(MONITOR_DEF* monitors, int maxMonitors)
|
||||
}
|
||||
#endif
|
||||
|
||||
XCloseDisplay(display);
|
||||
|
||||
if (numMonitors < 1)
|
||||
{
|
||||
index = 0;
|
||||
|
@ -150,12 +150,6 @@ void shadow_client_context_free(freerdp_peer* peer, rdpShadowClient* client)
|
||||
MessageQueue_Clear(client->MsgQueue);
|
||||
MessageQueue_Free(client->MsgQueue);
|
||||
|
||||
if (client->lobby)
|
||||
{
|
||||
shadow_surface_free(client->lobby);
|
||||
client->lobby = NULL;
|
||||
}
|
||||
|
||||
if (client->encoder)
|
||||
{
|
||||
shadow_encoder_free(client->encoder);
|
||||
@ -188,6 +182,19 @@ BOOL shadow_client_capabilities(freerdp_peer* peer)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static INLINE void shadow_client_calc_desktop_size(rdpShadowServer* server, int* pWidth, int* pHeight)
|
||||
{
|
||||
RECTANGLE_16 viewport = {0, 0, server->screen->width, server->screen->height};
|
||||
|
||||
if (server->shareSubRect)
|
||||
{
|
||||
rectangles_intersection(&viewport, &(server->subRect), &viewport);
|
||||
}
|
||||
|
||||
(*pWidth) = viewport.right - viewport.left;
|
||||
(*pHeight) = viewport.bottom - viewport.top;
|
||||
}
|
||||
|
||||
BOOL shadow_client_post_connect(freerdp_peer* peer)
|
||||
{
|
||||
int authStatus;
|
||||
@ -203,17 +210,7 @@ BOOL shadow_client_post_connect(freerdp_peer* peer)
|
||||
server = client->server;
|
||||
subsystem = server->subsystem;
|
||||
|
||||
if (!server->shareSubRect)
|
||||
{
|
||||
width = server->screen->width;
|
||||
height = server->screen->height;
|
||||
}
|
||||
else
|
||||
{
|
||||
width = server->subRect.right - server->subRect.left;
|
||||
height = server->subRect.bottom - server->subRect.top;
|
||||
}
|
||||
|
||||
shadow_client_calc_desktop_size(server, &width, &height);
|
||||
settings->DesktopWidth = width;
|
||||
settings->DesktopHeight = height;
|
||||
|
||||
@ -232,13 +229,11 @@ BOOL shadow_client_post_connect(freerdp_peer* peer)
|
||||
|
||||
invalidRect.left = 0;
|
||||
invalidRect.top = 0;
|
||||
invalidRect.right = width;
|
||||
invalidRect.bottom = height;
|
||||
invalidRect.right = server->screen->width;
|
||||
invalidRect.bottom = server->screen->height;
|
||||
|
||||
region16_union_rect(&(client->invalidRegion), &(client->invalidRegion), &invalidRect);
|
||||
|
||||
shadow_client_init_lobby(client);
|
||||
|
||||
authStatus = -1;
|
||||
|
||||
if (settings->Username && settings->Password)
|
||||
@ -270,6 +265,30 @@ BOOL shadow_client_post_connect(freerdp_peer* peer)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Convert rects in sub rect coordinate to client/surface coordinate */
|
||||
static INLINE void shadow_client_convert_rects(rdpShadowClient* client,
|
||||
RECTANGLE_16* dst, RECTANGLE_16* src, UINT32 numRects)
|
||||
{
|
||||
if (client->server->shareSubRect)
|
||||
{
|
||||
int i = 0;
|
||||
UINT16 offsetX = client->server->subRect.left;
|
||||
UINT16 offsetY = client->server->subRect.top;
|
||||
|
||||
for (i = 0; i < numRects; i++)
|
||||
{
|
||||
dst[i].left = src[i].left + offsetX;
|
||||
dst[i].right = src[i].right + offsetX;
|
||||
dst[i].top = src[i].top + offsetY;
|
||||
dst[i].bottom = src[i].bottom + offsetY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CopyMemory(dst, src, numRects * sizeof(RECTANGLE_16));
|
||||
}
|
||||
}
|
||||
|
||||
BOOL shadow_client_refresh_rect(rdpShadowClient* client, BYTE count, RECTANGLE_16* areas)
|
||||
{
|
||||
wMessage message = { 0 };
|
||||
@ -294,7 +313,7 @@ BOOL shadow_client_refresh_rect(rdpShadowClient* client, BYTE count, RECTANGLE_1
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CopyMemory(wParam->rects, areas, wParam->numRects * sizeof(RECTANGLE_16));
|
||||
shadow_client_convert_rects(client, wParam->rects, areas, wParam->numRects);
|
||||
}
|
||||
|
||||
message.id = SHADOW_MSG_IN_REFRESH_OUTPUT_ID;
|
||||
@ -319,7 +338,7 @@ BOOL shadow_client_suppress_output(rdpShadowClient* client, BYTE allow, RECTANGL
|
||||
wParam->allow = (UINT32) allow;
|
||||
|
||||
if (area)
|
||||
CopyMemory(&(wParam->rect), area, sizeof(RECTANGLE_16));
|
||||
shadow_client_convert_rects(client, &(wParam->rect), area, 1);
|
||||
|
||||
message.id = SHADOW_MSG_IN_SUPPRESS_OUTPUT_ID;
|
||||
message.wParam = (void*) wParam;
|
||||
@ -445,7 +464,7 @@ int shadow_client_send_surface_bits(rdpShadowClient* client, rdpShadowSurface* s
|
||||
rect.height = nHeight;
|
||||
|
||||
if (!(messages = rfx_encode_messages(encoder->rfx, &rect, 1, pSrcData,
|
||||
surface->width, surface->height, nSrcStep, &numMessages,
|
||||
settings->DesktopWidth, settings->DesktopHeight, nSrcStep, &numMessages,
|
||||
settings->MultifragMaxRequestSize)))
|
||||
{
|
||||
return 0;
|
||||
@ -455,12 +474,12 @@ int shadow_client_send_surface_bits(rdpShadowClient* client, rdpShadowSurface* s
|
||||
|
||||
cmd.destLeft = 0;
|
||||
cmd.destTop = 0;
|
||||
cmd.destRight = surface->width;
|
||||
cmd.destBottom = surface->height;
|
||||
cmd.destRight = settings->DesktopWidth;
|
||||
cmd.destBottom = settings->DesktopHeight;
|
||||
|
||||
cmd.bpp = 32;
|
||||
cmd.width = surface->width;
|
||||
cmd.height = surface->height;
|
||||
cmd.width = settings->DesktopWidth;
|
||||
cmd.height = settings->DesktopHeight;
|
||||
cmd.skipCompression = TRUE;
|
||||
|
||||
if (numMessages > 0)
|
||||
@ -569,6 +588,21 @@ int shadow_client_send_bitmap_update(rdpShadowClient* client, rdpShadowSurface*
|
||||
nSrcStep = surface->scanline;
|
||||
SrcFormat = PIXEL_FORMAT_RGB32;
|
||||
|
||||
if (server->shareSubRect)
|
||||
{
|
||||
int subX, subY;
|
||||
int subWidth, subHeight;
|
||||
|
||||
subX = server->subRect.left;
|
||||
subY = server->subRect.top;
|
||||
subWidth = server->subRect.right - server->subRect.left;
|
||||
subHeight = server->subRect.bottom - server->subRect.top;
|
||||
|
||||
nXSrc -= subX;
|
||||
nYSrc -= subY;
|
||||
pSrcData = &pSrcData[(subY * nSrcStep) + (subX * 4)];
|
||||
}
|
||||
|
||||
if ((nXSrc % 4) != 0)
|
||||
{
|
||||
nWidth += (nXSrc % 4);
|
||||
@ -747,7 +781,7 @@ int shadow_client_send_surface_update(rdpShadowClient* client)
|
||||
server = client->server;
|
||||
encoder = client->encoder;
|
||||
|
||||
surface = client->inLobby ? client->lobby : server->surface;
|
||||
surface = client->inLobby ? server->lobby : server->surface;
|
||||
|
||||
EnterCriticalSection(&(client->lock));
|
||||
|
||||
@ -915,6 +949,12 @@ int shadow_client_subsystem_process_message(rdpShadowClient* client, wMessage* m
|
||||
pointerPosition.xPos = msg->xPos;
|
||||
pointerPosition.yPos = msg->yPos;
|
||||
|
||||
if (client->server->shareSubRect)
|
||||
{
|
||||
pointerPosition.xPos -= client->server->subRect.left;
|
||||
pointerPosition.yPos -= client->server->subRect.top;
|
||||
}
|
||||
|
||||
if (client->activated)
|
||||
{
|
||||
if ((msg->xPos != client->pointerX) || (msg->yPos != client->pointerY))
|
||||
@ -1060,15 +1100,44 @@ void* shadow_client_thread(rdpShadowClient* client)
|
||||
int index;
|
||||
int numRects = 0;
|
||||
const RECTANGLE_16* rects;
|
||||
int width, height;
|
||||
|
||||
rects = region16_rects(&(subsystem->invalidRegion), &numRects);
|
||||
|
||||
for (index = 0; index < numRects; index++)
|
||||
/* Check resize */
|
||||
shadow_client_calc_desktop_size(server, &width, &height);
|
||||
if (settings->DesktopWidth != (UINT32)width || settings->DesktopHeight != (UINT32)height)
|
||||
{
|
||||
region16_union_rect(&(client->invalidRegion), &(client->invalidRegion), &rects[index]);
|
||||
}
|
||||
/* Screen size changed, do resize */
|
||||
settings->DesktopWidth = width;
|
||||
settings->DesktopHeight = height;
|
||||
|
||||
shadow_client_send_surface_update(client);
|
||||
/**
|
||||
* Unset client activated flag to avoid sending update message during
|
||||
* resize. DesktopResize will reactive the client and
|
||||
* shadow_client_activate would be invoked later.
|
||||
*/
|
||||
client->activated = FALSE;
|
||||
|
||||
/* Send Resize */
|
||||
peer->update->DesktopResize(peer->update->context); // update_send_desktop_resize
|
||||
|
||||
/* Clear my invalidRegion. shadow_client_activate refreshes fullscreen */
|
||||
region16_clear(&(client->invalidRegion));
|
||||
|
||||
WLog_ERR(TAG, "Client from %s is resized (%dx%d@%d)",
|
||||
peer->hostname, settings->DesktopWidth, settings->DesktopHeight, settings->ColorDepth);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Send frame */
|
||||
rects = region16_rects(&(subsystem->invalidRegion), &numRects);
|
||||
|
||||
for (index = 0; index < numRects; index++)
|
||||
{
|
||||
region16_union_rect(&(client->invalidRegion), &(client->invalidRegion), &rects[index]);
|
||||
}
|
||||
|
||||
shadow_client_send_surface_update(client);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -224,6 +224,9 @@ int shadow_encoder_init_interleaved(rdpShadowEncoder* encoder)
|
||||
|
||||
int shadow_encoder_init(rdpShadowEncoder* encoder)
|
||||
{
|
||||
encoder->width = encoder->server->screen->width;
|
||||
encoder->height = encoder->server->screen->height;
|
||||
|
||||
encoder->maxTileWidth = 64;
|
||||
encoder->maxTileHeight = 64;
|
||||
|
||||
@ -401,9 +404,6 @@ rdpShadowEncoder* shadow_encoder_new(rdpShadowClient* client)
|
||||
encoder->fps = 16;
|
||||
encoder->maxFps = 32;
|
||||
|
||||
encoder->width = server->screen->width;
|
||||
encoder->height = server->screen->height;
|
||||
|
||||
if (shadow_encoder_init(encoder) < 0)
|
||||
{
|
||||
free (encoder);
|
||||
|
@ -72,6 +72,12 @@ BOOL shadow_input_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
|
||||
rdpShadowClient* client = (rdpShadowClient*) input->context;
|
||||
rdpShadowSubsystem* subsystem = client->server->subsystem;
|
||||
|
||||
if (client->server->shareSubRect)
|
||||
{
|
||||
x += client->server->subRect.left;
|
||||
y += client->server->subRect.top;
|
||||
}
|
||||
|
||||
if (!(flags & PTR_FLAGS_WHEEL))
|
||||
{
|
||||
client->pointerX = x;
|
||||
@ -102,6 +108,12 @@ BOOL shadow_input_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x,
|
||||
rdpShadowClient* client = (rdpShadowClient*) input->context;
|
||||
rdpShadowSubsystem* subsystem = client->server->subsystem;
|
||||
|
||||
if (client->server->shareSubRect)
|
||||
{
|
||||
x += client->server->subRect.left;
|
||||
y += client->server->subRect.top;
|
||||
}
|
||||
|
||||
client->pointerX = x;
|
||||
client->pointerY = y;
|
||||
|
||||
|
@ -26,31 +26,44 @@
|
||||
|
||||
#include "shadow_lobby.h"
|
||||
|
||||
int shadow_client_init_lobby(rdpShadowClient* client)
|
||||
BOOL shadow_client_init_lobby(rdpShadowServer* server)
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
rdtkEngine* engine;
|
||||
rdtkSurface* surface;
|
||||
RECTANGLE_16 invalidRect;
|
||||
rdpShadowSurface* lobby;
|
||||
rdpContext* context = (rdpContext*) client;
|
||||
rdpSettings* settings = context->settings;
|
||||
rdpShadowSurface* lobby = server->lobby;
|
||||
|
||||
width = settings->DesktopWidth;
|
||||
height = settings->DesktopHeight;
|
||||
if (!lobby)
|
||||
return FALSE;
|
||||
|
||||
lobby = client->lobby = shadow_surface_new(client->server, 0, 0, width, height);
|
||||
if (!(engine = rdtk_engine_new()))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!client->lobby)
|
||||
return -1;
|
||||
if (!(surface = rdtk_surface_new(engine, lobby->data, lobby->width, lobby->height, lobby->scanline)))
|
||||
{
|
||||
rdtk_engine_free(engine);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
engine = rdtk_engine_new();
|
||||
invalidRect.left = 0;
|
||||
invalidRect.top = 0;
|
||||
invalidRect.right = lobby->width;
|
||||
invalidRect.bottom = lobby->height;
|
||||
if (server->shareSubRect)
|
||||
{
|
||||
/* If we have shared sub rect setting, only fill shared rect */
|
||||
rectangles_intersection(&invalidRect, &(server->subRect), &invalidRect);
|
||||
}
|
||||
|
||||
surface = rdtk_surface_new(engine, lobby->data, lobby->width, lobby->height, lobby->scanline);
|
||||
width = invalidRect.right - invalidRect.left;
|
||||
height = invalidRect.bottom - invalidRect.top;
|
||||
rdtk_surface_fill(surface, invalidRect.left, invalidRect.top, width, height, 0x3BB9FF);
|
||||
|
||||
rdtk_surface_fill(surface, 0, 0, width, height, 0x3BB9FF);
|
||||
//rdtk_label_draw(surface, 16, 16, 128, 32, NULL, "label", 0, 0);
|
||||
rdtk_label_draw(surface, invalidRect.left, invalidRect.top, width, height, NULL, "Welcome", 0, 0);
|
||||
//rdtk_button_draw(surface, 16, 64, 128, 32, NULL, "button");
|
||||
//rdtk_text_field_draw(surface, 16, 128, 128, 32, NULL, "text field");
|
||||
|
||||
@ -58,12 +71,7 @@ int shadow_client_init_lobby(rdpShadowClient* client)
|
||||
|
||||
rdtk_engine_free(engine);
|
||||
|
||||
invalidRect.left = 0;
|
||||
invalidRect.top = 0;
|
||||
invalidRect.right = width;
|
||||
invalidRect.bottom = height;
|
||||
|
||||
region16_union_rect(&(lobby->invalidRegion), &(lobby->invalidRegion), &invalidRect);
|
||||
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -30,7 +30,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int shadow_client_init_lobby(rdpShadowClient* client);
|
||||
BOOL shadow_client_init_lobby(rdpShadowServer* server);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "shadow_surface.h"
|
||||
|
||||
#include "shadow_screen.h"
|
||||
#include "shadow_lobby.h"
|
||||
|
||||
rdpShadowScreen* shadow_screen_new(rdpShadowServer* server)
|
||||
{
|
||||
@ -30,35 +31,27 @@ rdpShadowScreen* shadow_screen_new(rdpShadowServer* server)
|
||||
int width, height;
|
||||
rdpShadowScreen* screen;
|
||||
rdpShadowSubsystem* subsystem;
|
||||
MONITOR_DEF* primary;
|
||||
|
||||
screen = (rdpShadowScreen*) calloc(1, sizeof(rdpShadowScreen));
|
||||
|
||||
if (!screen)
|
||||
return NULL;
|
||||
goto out_error;
|
||||
|
||||
screen->server = server;
|
||||
subsystem = server->subsystem;
|
||||
|
||||
if (!InitializeCriticalSectionAndSpinCount(&(screen->lock), 4000))
|
||||
return NULL;
|
||||
goto out_free;
|
||||
|
||||
region16_init(&(screen->invalidRegion));
|
||||
|
||||
if (server->shareSubRect) {
|
||||
x = server->subRect.left;
|
||||
y = server->subRect.top;
|
||||
width = server->subRect.right - server->subRect.left;
|
||||
height = server->subRect.bottom - server->subRect.top;
|
||||
} else {
|
||||
MONITOR_DEF* primary;
|
||||
primary = &(subsystem->monitors[subsystem->selectedMonitor]);
|
||||
|
||||
primary = &(subsystem->monitors[subsystem->selectedMonitor]);
|
||||
|
||||
x = primary->left;
|
||||
y = primary->top;
|
||||
width = primary->right - primary->left;
|
||||
height = primary->bottom - primary->top;
|
||||
}
|
||||
x = primary->left;
|
||||
y = primary->top;
|
||||
width = primary->right - primary->left;
|
||||
height = primary->bottom - primary->top;
|
||||
|
||||
screen->width = width;
|
||||
screen->height = height;
|
||||
@ -66,11 +59,31 @@ rdpShadowScreen* shadow_screen_new(rdpShadowServer* server)
|
||||
screen->primary = shadow_surface_new(server, x, y, width, height);
|
||||
|
||||
if (!screen->primary)
|
||||
return NULL;
|
||||
goto out_free_region;
|
||||
|
||||
server->surface = screen->primary;
|
||||
|
||||
screen->lobby = shadow_surface_new(server, x, y, width, height);
|
||||
|
||||
if (!screen->lobby)
|
||||
goto out_free_primary;
|
||||
|
||||
server->lobby = screen->lobby;
|
||||
|
||||
shadow_client_init_lobby(server);
|
||||
|
||||
return screen;
|
||||
|
||||
out_free_primary:
|
||||
shadow_surface_free(screen->primary);
|
||||
server->surface = screen->primary = NULL;
|
||||
out_free_region:
|
||||
region16_uninit(&(screen->invalidRegion));
|
||||
DeleteCriticalSection(&(screen->lock));
|
||||
out_free:
|
||||
free(screen);
|
||||
out_error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void shadow_screen_free(rdpShadowScreen* screen)
|
||||
@ -88,6 +101,45 @@ void shadow_screen_free(rdpShadowScreen* screen)
|
||||
screen->primary = NULL;
|
||||
}
|
||||
|
||||
if (screen->lobby)
|
||||
{
|
||||
shadow_surface_free(screen->lobby);
|
||||
screen->lobby = NULL;
|
||||
}
|
||||
|
||||
free(screen);
|
||||
}
|
||||
|
||||
BOOL shadow_screen_resize(rdpShadowScreen* screen)
|
||||
{
|
||||
int x, y;
|
||||
int width, height;
|
||||
MONITOR_DEF* primary;
|
||||
rdpShadowSubsystem* subsystem;
|
||||
|
||||
if (!screen)
|
||||
return FALSE;
|
||||
|
||||
subsystem = screen->server->subsystem;
|
||||
primary = &(subsystem->monitors[subsystem->selectedMonitor]);
|
||||
|
||||
x = primary->left;
|
||||
y = primary->top;
|
||||
width = primary->right - primary->left;
|
||||
height = primary->bottom - primary->top;
|
||||
|
||||
if (shadow_surface_resize(screen->primary, x, y, width, height)
|
||||
&& shadow_surface_resize(screen->lobby, x, y, width, height))
|
||||
{
|
||||
if ((width != screen->width) || (height != screen->height))
|
||||
{
|
||||
/* screen size is changed. Store new size and reinit lobby */
|
||||
screen->width = width;
|
||||
screen->height = height;
|
||||
shadow_client_init_lobby(screen->server);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ struct rdp_shadow_screen
|
||||
REGION16 invalidRegion;
|
||||
|
||||
rdpShadowSurface* primary;
|
||||
rdpShadowSurface* lobby;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -41,16 +41,13 @@ rdpShadowSurface* shadow_surface_new(rdpShadowServer* server, int x, int y, int
|
||||
surface->height = height;
|
||||
surface->scanline = (surface->width + (surface->width % 4)) * 4;
|
||||
|
||||
surface->data = (BYTE*) malloc(surface->scanline * surface->height);
|
||||
|
||||
surface->data = (BYTE*) calloc(1, surface->scanline * surface->height);
|
||||
if (!surface->data)
|
||||
{
|
||||
free (surface);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZeroMemory(surface->data, surface->scanline * surface->height);
|
||||
|
||||
if (!InitializeCriticalSectionAndSpinCount(&(surface->lock), 4000))
|
||||
{
|
||||
free (surface->data);
|
||||
@ -76,3 +73,35 @@ void shadow_surface_free(rdpShadowSurface* surface)
|
||||
|
||||
free(surface);
|
||||
}
|
||||
|
||||
BOOL shadow_surface_resize(rdpShadowSurface *surface, int x, int y, int width, int height)
|
||||
{
|
||||
BYTE* buffer = NULL;
|
||||
int scanline = (width + (width % 4)) * 4;
|
||||
|
||||
if (!surface)
|
||||
return FALSE;
|
||||
|
||||
if ((width == surface->width) && (height == surface->height))
|
||||
{
|
||||
/* We don't need to reset frame buffer, just update left top */
|
||||
surface->x = x;
|
||||
surface->y = y;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
buffer = (BYTE*) realloc(surface->data, scanline * height);
|
||||
if (buffer)
|
||||
{
|
||||
surface->x = x;
|
||||
surface->y = y;
|
||||
surface->width = width;
|
||||
surface->height = height;
|
||||
surface->scanline = scanline;
|
||||
surface->data = buffer;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -45,6 +45,7 @@ extern "C" {
|
||||
|
||||
rdpShadowSurface* shadow_surface_new(rdpShadowServer* server, int x, int y, int width, int height);
|
||||
void shadow_surface_free(rdpShadowSurface* surface);
|
||||
BOOL shadow_surface_resize(rdpShadowSurface *surface, int x, int y, int width, int height);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user