shadow: add ability to select monitor to share
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Wed, 10 Sep 2014 18:58:14 +0000 (14:58 -0400)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Wed, 10 Sep 2014 18:58:14 +0000 (14:58 -0400)
include/freerdp/server/shadow.h
server/shadow/X11/x11_shadow.c
server/shadow/shadow_client.c
server/shadow/shadow_screen.c
server/shadow/shadow_server.c

index 0620cf6..159ca02 100644 (file)
@@ -111,6 +111,7 @@ struct rdp_shadow_server
 #define RDP_SHADOW_SUBSYSTEM_COMMON() \
        HANDLE event; \
        int monitorCount; \
+       int selectedMonitor; \
        MONITOR_DEF monitors[16]; \
        MONITOR_DEF virtualScreen; \
        HANDLE updateEvent; \
index ffd068e..717181f 100644 (file)
@@ -88,6 +88,11 @@ void x11_shadow_input_mouse_event(x11ShadowSubsystem* subsystem, UINT16 flags, U
 #ifdef WITH_XTEST
        int button = 0;
        BOOL down = FALSE;
+       rdpShadowServer* server;
+       rdpShadowSurface* surface;
+
+       server = subsystem->server;
+       surface = server->surface;
 
        XTestGrabControl(subsystem->display, True);
 
@@ -105,6 +110,9 @@ void x11_shadow_input_mouse_event(x11ShadowSubsystem* subsystem, UINT16 flags, U
        }
        else
        {
+               x += surface->x;
+               y += surface->y;
+
                if (flags & PTR_FLAGS_MOVE)
                        XTestFakeMotionEvent(subsystem->display, 0, x, y, 0);
 
@@ -131,6 +139,14 @@ void x11_shadow_input_extended_mouse_event(x11ShadowSubsystem* subsystem, UINT16
 #ifdef WITH_XTEST
        int button = 0;
        BOOL down = FALSE;
+       rdpShadowServer* server;
+       rdpShadowSurface* surface;
+
+       server = subsystem->server;
+       surface = server->surface;
+
+       x += surface->x;
+       y += surface->y;
 
        XTestGrabControl(subsystem->display, True);
        XTestFakeMotionEvent(subsystem->display, 0, x, y, CurrentTime);
@@ -201,6 +217,11 @@ int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
        surface = server->surface;
        screen = server->screen;
 
+       count = ArrayList_Count(server->clients);
+
+       if (count < 1)
+               return 1;
+
        if (subsystem->use_xshm)
        {
                XLockDisplay(subsystem->display);
@@ -215,7 +236,7 @@ int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
                image = subsystem->fb_image;
 
                status = shadow_capture_compare(surface->data, surface->scanline, surface->width, surface->height,
-                               (BYTE*) image->data, image->bytes_per_line, &invalidRect);
+                               (BYTE*) &(image->data[surface->width * 4]), image->bytes_per_line, &invalidRect);
 
                if (status > 0)
                {
@@ -251,7 +272,7 @@ int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
                XLockDisplay(subsystem->display);
 
                image = XGetImage(subsystem->display, subsystem->root_window,
-                               0, 0, subsystem->width, subsystem->height, AllPlanes, ZPixmap);
+                               surface->x, surface->y, surface->width, surface->height, AllPlanes, ZPixmap);
 
                XUnlockDisplay(subsystem->display);
 
@@ -266,7 +287,7 @@ int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
                        height = invalidRect.bottom - invalidRect.top;
 
                        freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32,
-                                       surface->scanline, x - surface->x, y - surface->y, width, height,
+                                       surface->scanline, xy, width, height,
                                        (BYTE*) image->data, PIXEL_FORMAT_XRGB32,
                                        image->bytes_per_line, x, y);
 
@@ -768,7 +789,7 @@ x11ShadowSubsystem* x11_shadow_subsystem_new(rdpShadowServer* server)
        subsystem->ExtendedMouseEvent = (pfnShadowExtendedMouseEvent) x11_shadow_input_extended_mouse_event;
 
        subsystem->composite = FALSE;
-       subsystem->use_xshm = TRUE;
+       subsystem->use_xshm = FALSE; /* temporarily disabled */
        subsystem->use_xfixes = TRUE;
        subsystem->use_xdamage = FALSE;
        subsystem->use_xinerama = TRUE;
index 5098a35..d7afb84 100644 (file)
@@ -550,10 +550,10 @@ int shadow_client_send_surface_update(rdpShadowClient* client)
 
        LeaveCriticalSection(&(client->lock));
 
-       surfaceRect.left = surface->x;
-       surfaceRect.top = surface->y;
-       surfaceRect.right = surface->x + surface->width;
-       surfaceRect.bottom = surface->y + surface->height;
+       surfaceRect.left = 0;
+       surfaceRect.top = 0;
+       surfaceRect.right = surface->width;
+       surfaceRect.bottom = surface->height;
 
        region16_intersect_rect(&invalidRegion, &invalidRegion, &surfaceRect);
 
@@ -565,8 +565,8 @@ int shadow_client_send_surface_update(rdpShadowClient* client)
 
        extents = region16_extents(&invalidRegion);
 
-       nXSrc = extents->left - surface->x;
-       nYSrc = extents->top - surface->y;
+       nXSrc = extents->left - 0;
+       nYSrc = extents->top - 0;
        nWidth = extents->right - extents->left;
        nHeight = extents->bottom - extents->top;
 
index 0b4c87f..3182b64 100644 (file)
@@ -45,7 +45,7 @@ rdpShadowScreen* shadow_screen_new(rdpShadowServer* server)
 
        region16_init(&(screen->invalidRegion));
 
-       primary = &(subsystem->monitors[0]);
+       primary = &(subsystem->monitors[subsystem->selectedMonitor]);
 
        x = primary->left;
        y = primary->top;
index c990d1f..a408372 100644 (file)
@@ -213,16 +213,27 @@ int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** a
 
        if (arg && (arg->Flags & COMMAND_LINE_ARGUMENT_PRESENT))
        {
+               int index;
+               rdpShadowSubsystem* subsystem = server->subsystem;
+
                if (arg->Flags & COMMAND_LINE_VALUE_PRESENT)
                {
                        /* Select monitors */
+
+                       index = atoi(arg->Value);
+
+                       if (index < 0)
+                               index = 0;
+
+                       if (index >= subsystem->monitorCount)
+                               index = 0;
+
+                       subsystem->selectedMonitor = index;
                }
                else
                {
-                       int index;
                        int width, height;
                        MONITOR_DEF* monitor;
-                       rdpShadowSubsystem* subsystem = server->subsystem;
 
                        /* List monitors */
 
@@ -343,6 +354,16 @@ int shadow_server_start(rdpShadowServer* server)
        signal(SIGPIPE, SIG_IGN);
 #endif
 
+       server->screen = shadow_screen_new(server);
+
+       if (!server->screen)
+               return -1;
+
+       server->capture = shadow_capture_new(server);
+
+       if (!server->capture)
+               return -1;
+
        if (!server->ipcSocket)
                status = server->listener->Open(server->listener, NULL, (UINT16) server->port);
        else
@@ -369,6 +390,18 @@ int shadow_server_stop(rdpShadowServer* server)
                server->listener->Close(server->listener);
        }
 
+       if (server->screen)
+       {
+               shadow_screen_free(server->screen);
+               server->screen = NULL;
+       }
+
+       if (server->capture)
+       {
+               shadow_capture_free(server->capture);
+               server->capture = NULL;
+       }
+
        return 0;
 }
 
@@ -476,16 +509,6 @@ int shadow_server_init(rdpShadowServer* server)
                        fprintf(stderr, "subsystem init failure: %d\n", status);
        }
 
-       server->screen = shadow_screen_new(server);
-
-       if (!server->screen)
-               return -1;
-
-       server->capture = shadow_capture_new(server);
-
-       if (!server->capture)
-               return -1;
-
        return 1;
 }