From 3d57659efb51c7b288aa4d413b5db991de7302cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Fri, 11 Jul 2014 23:01:34 -0400 Subject: [PATCH] shadow: start structuring X11 code as shadow subsystem --- include/freerdp/server/shadow.h | 10 ++ server/shadow/X11/x11_client.c | 289 -------------------------------- server/shadow/X11/x11_input.c | 74 +++----- server/shadow/X11/x11_shadow.c | 289 +++++++++++++++++++++++++++++++- server/shadow/X11/x11_shadow.h | 34 +--- server/shadow/X11/x11_update.c | 113 +++---------- server/shadow/shadow.c | 15 +- server/shadow/shadow_client.c | 4 +- 8 files changed, 352 insertions(+), 476 deletions(-) diff --git a/include/freerdp/server/shadow.h b/include/freerdp/server/shadow.h index a759b769b..f49fa15b4 100644 --- a/include/freerdp/server/shadow.h +++ b/include/freerdp/server/shadow.h @@ -30,6 +30,7 @@ typedef struct rdp_shadow_server rdpShadowServer; typedef struct rdp_shadow_screen rdpShadowScreen; typedef struct rdp_shadow_surface rdpShadowSurface; typedef struct rdp_shadow_encoder rdpShadowEncoder; +typedef struct rdp_shadow_subsystem rdpShadowSubsystem; struct rdp_shadow_client { @@ -47,10 +48,19 @@ struct rdp_shadow_server rdpShadowScreen* screen; rdpShadowSurface* surface; rdpShadowEncoder* encoder; + rdpShadowSubsystem* subsystem; DWORD port; freerdp_listener* listener; }; +#define RDP_SHADOW_SUBSYSTEM_COMMON() \ + rdpShadowServer* server + +struct rdp_shadow_subsystem +{ + RDP_SHADOW_SUBSYSTEM_COMMON(); +}; + #endif /* FREERDP_SERVER_SHADOW_H */ diff --git a/server/shadow/X11/x11_client.c b/server/shadow/X11/x11_client.c index 2796ab076..79d254b6f 100644 --- a/server/shadow/X11/x11_client.c +++ b/server/shadow/X11/x11_client.c @@ -38,294 +38,5 @@ #include #include -#include -#include -#include - -#include - #include "x11_shadow.h" -#ifdef WITH_XDAMAGE - -void x11_shadow_xdamage_init(x11ShadowServer* server) -{ - int damage_event; - int damage_error; - int major, minor; - XGCValues values; - - if (XDamageQueryExtension(server->display, &damage_event, &damage_error) == 0) - { - fprintf(stderr, "XDamageQueryExtension failed\n"); - return; - } - - XDamageQueryVersion(server->display, &major, &minor); - - if (XDamageQueryVersion(server->display, &major, &minor) == 0) - { - fprintf(stderr, "XDamageQueryVersion failed\n"); - return; - } - else if (major < 1) - { - fprintf(stderr, "XDamageQueryVersion failed: major:%d minor:%d\n", major, minor); - return; - } - - server->xdamage_notify_event = damage_event + XDamageNotify; - server->xdamage = XDamageCreate(server->display, server->root_window, XDamageReportDeltaRectangles); - - if (server->xdamage == None) - { - fprintf(stderr, "XDamageCreate failed\n"); - return; - } - -#ifdef WITH_XFIXES - server->xdamage_region = XFixesCreateRegion(server->display, NULL, 0); - - if (server->xdamage_region == None) - { - fprintf(stderr, "XFixesCreateRegion failed\n"); - XDamageDestroy(server->display, server->xdamage); - server->xdamage = None; - return; - } -#endif - - values.subwindow_mode = IncludeInferiors; - server->xdamage_gc = XCreateGC(server->display, server->root_window, GCSubwindowMode, &values); - XSetFunction(server->display, server->xdamage_gc, GXcopy); -} - -#endif - -int x11_shadow_xshm_init(x11ShadowServer* server) -{ - Bool pixmaps; - int major, minor; - - if (XShmQueryExtension(server->display) != False) - { - XShmQueryVersion(server->display, &major, &minor, &pixmaps); - - if (pixmaps != True) - { - fprintf(stderr, "XShmQueryVersion failed\n"); - return -1; - } - } - else - { - fprintf(stderr, "XShmQueryExtension failed\n"); - return -1; - } - - server->fb_shm_info.shmid = -1; - server->fb_shm_info.shmaddr = (char*) -1; - - server->fb_image = XShmCreateImage(server->display, server->visual, server->depth, - ZPixmap, NULL, &(server->fb_shm_info), server->width, server->height); - - if (!server->fb_image) - { - fprintf(stderr, "XShmCreateImage failed\n"); - return -1; - } - - server->fb_shm_info.shmid = shmget(IPC_PRIVATE, - server->fb_image->bytes_per_line * server->fb_image->height, IPC_CREAT | 0600); - - if (server->fb_shm_info.shmid == -1) - { - fprintf(stderr, "shmget failed\n"); - return -1; - } - - server->fb_shm_info.readOnly = False; - server->fb_shm_info.shmaddr = shmat(server->fb_shm_info.shmid, 0, 0); - server->fb_image->data = server->fb_shm_info.shmaddr; - - if (server->fb_shm_info.shmaddr == ((char*) -1)) - { - fprintf(stderr, "shmat failed\n"); - return -1; - } - - XShmAttach(server->display, &(server->fb_shm_info)); - XSync(server->display, False); - - shmctl(server->fb_shm_info.shmid, IPC_RMID, 0); - - fprintf(stderr, "display: %p root_window: %p width: %d height: %d depth: %d\n", - server->display, (void*) server->root_window, server->fb_image->width, server->fb_image->height, server->fb_image->depth); - - server->fb_pixmap = XShmCreatePixmap(server->display, - server->root_window, server->fb_image->data, &(server->fb_shm_info), - server->fb_image->width, server->fb_image->height, server->fb_image->depth); - - return 0; -} - -x11ShadowClient* x11_shadow_client_new(rdpShadowClient* rdp) -{ - int i; - int pf_count; - int vi_count; - XVisualInfo* vi; - XVisualInfo* vis; - XVisualInfo template; - XPixmapFormatValues* pf; - XPixmapFormatValues* pfs; - x11ShadowServer* server; - x11ShadowClient* client; - - client = (x11ShadowClient*) calloc(1, sizeof(x11ShadowClient)); - - if (!client) - return NULL; - - server = (x11ShadowServer*) rdp->server->ext; - client->server = server; - - /** - * Recent X11 servers drop support for shared pixmaps - * To see if your X11 server supports shared pixmaps, use: - * xdpyinfo -ext MIT-SHM | grep "shared pixmaps" - */ - server->use_xshm = TRUE; - - setenv("DISPLAY", ":0", 1); /* Set DISPLAY variable if not already set */ - - if (!XInitThreads()) - fprintf(stderr, "warning: XInitThreads() failure\n"); - - server->display = XOpenDisplay(NULL); - - if (!server->display) - { - fprintf(stderr, "failed to open display: %s\n", XDisplayName(NULL)); - exit(1); - } - - server->xfds = ConnectionNumber(server->display); - server->number = DefaultScreen(server->display); - server->screen = ScreenOfDisplay(server->display, server->number); - server->depth = DefaultDepthOfScreen(server->screen); - server->width = WidthOfScreen(server->screen); - server->height = HeightOfScreen(server->screen); - server->root_window = DefaultRootWindow(server->display); - - pfs = XListPixmapFormats(server->display, &pf_count); - - if (!pfs) - { - fprintf(stderr, "XListPixmapFormats failed\n"); - exit(1); - } - - for (i = 0; i < pf_count; i++) - { - pf = pfs + i; - - if (pf->depth == server->depth) - { - server->bpp = pf->bits_per_pixel; - server->scanline_pad = pf->scanline_pad; - break; - } - } - XFree(pfs); - - ZeroMemory(&template, sizeof(template)); - template.class = TrueColor; - template.screen = server->number; - - vis = XGetVisualInfo(server->display, VisualClassMask | VisualScreenMask, &template, &vi_count); - - if (!vis) - { - fprintf(stderr, "XGetVisualInfo failed\n"); - exit(1); - } - - for (i = 0; i < vi_count; i++) - { - vi = vis + i; - - if (vi->depth == server->depth) - { - server->visual = vi->visual; - break; - } - } - XFree(vis); - - XSelectInput(server->display, server->root_window, SubstructureNotifyMask); - - if (server->use_xshm) - { - if (x11_shadow_xshm_init(server) < 0) - server->use_xshm = FALSE; - } - - if (server->use_xshm) - printf("Using X Shared Memory Extension (XShm)\n"); - -#ifdef WITH_XDAMAGE - x11_shadow_xdamage_init(server); -#endif - - x11_shadow_cursor_init(server); - - server->bytesPerPixel = 4; - server->activePeerCount = 0; - - freerdp_keyboard_init(0); - - client->rfx_context = rfx_context_new(TRUE); - client->rfx_context->mode = RLGR3; - client->rfx_context->width = server->width; - client->rfx_context->height = server->height; - - rfx_context_set_pixel_format(client->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8); - - client->s = Stream_New(NULL, 65536); - Stream_Clear(client->s); - - return client; -} - -void x11_shadow_client_free(x11ShadowClient* client) -{ - x11ShadowServer* server; - - if (!client) - return; - - server = client->server; - - if (server->display) - XCloseDisplay(server->display); - - Stream_Free(client->s, TRUE); - rfx_context_free(client->rfx_context); -} - -BOOL x11_shadow_peer_activate(freerdp_peer* client) -{ - x11ShadowClient* context = (x11ShadowClient*) client->context; - x11ShadowServer* server = context->server; - - rfx_context_reset(context->rfx_context); - context->activated = TRUE; - - server->activePeerCount++; - - context->monitorThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) - x11_shadow_update_thread, (void*) client, 0, NULL); - - return TRUE; -} diff --git a/server/shadow/X11/x11_input.c b/server/shadow/X11/x11_input.c index f614abf3f..6601def85 100644 --- a/server/shadow/X11/x11_input.c +++ b/server/shadow/X11/x11_input.c @@ -23,46 +23,22 @@ #include -#include - #include #include #include "x11_shadow.h" -int x11_shadow_cursor_init(x11ShadowServer* server) -{ -#ifdef WITH_XFIXES - int event; - int error; - - if (!XFixesQueryExtension(server->display, &event, &error)) - { - fprintf(stderr, "XFixesQueryExtension failed\n"); - return -1; - } - - server->xfixes_notify_event = event + XFixesCursorNotify; - - XFixesSelectCursorInput(server->display, DefaultRootWindow(server->display), XFixesDisplayCursorNotifyMask); -#endif - - return 0; -} - -void x11_shadow_input_synchronize_event(rdpInput* input, UINT32 flags) +void x11_shadow_input_synchronize_event(x11ShadowSubsystem* subsystem, UINT32 flags) { fprintf(stderr, "Client sent a synchronize event (flags:0x%X)\n", flags); } -void x11_shadow_input_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) +void x11_shadow_input_keyboard_event(x11ShadowSubsystem* subsystem, UINT16 flags, UINT16 code) { #ifdef WITH_XTEST DWORD vkcode; DWORD keycode; BOOL extended = FALSE; - x11ShadowClient* context = (x11ShadowClient*) input->context; - x11ShadowServer* server = context->server; if (flags & KBD_FLAGS_EXTENDED) extended = TRUE; @@ -75,32 +51,30 @@ void x11_shadow_input_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) if (keycode != 0) { - XTestGrabControl(server->display, True); + XTestGrabControl(subsystem->display, True); if (flags & KBD_FLAGS_DOWN) - XTestFakeKeyEvent(server->display, keycode, True, 0); + XTestFakeKeyEvent(subsystem->display, keycode, True, 0); else if (flags & KBD_FLAGS_RELEASE) - XTestFakeKeyEvent(server->display, keycode, False, 0); + XTestFakeKeyEvent(subsystem->display, keycode, False, 0); - XTestGrabControl(server->display, False); + XTestGrabControl(subsystem->display, False); } #endif } -void x11_shadow_input_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) +void x11_shadow_input_unicode_keyboard_event(x11ShadowSubsystem* subsystem, UINT16 flags, UINT16 code) { fprintf(stderr, "Client sent a unicode keyboard event (flags:0x%X code:0x%X)\n", flags, code); } -void x11_shadow_input_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) +void x11_shadow_input_mouse_event(x11ShadowSubsystem* subsystem, UINT16 flags, UINT16 x, UINT16 y) { #ifdef WITH_XTEST int button = 0; BOOL down = FALSE; - x11ShadowClient* context = (x11ShadowClient*) input->context; - x11ShadowServer* server = context->server; - XTestGrabControl(server->display, True); + XTestGrabControl(subsystem->display, True); if (flags & PTR_FLAGS_WHEEL) { @@ -111,13 +85,13 @@ void x11_shadow_input_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT1 button = (negative) ? 5 : 4; - XTestFakeButtonEvent(server->display, button, True, 0); - XTestFakeButtonEvent(server->display, button, False, 0); + XTestFakeButtonEvent(subsystem->display, button, True, 0); + XTestFakeButtonEvent(subsystem->display, button, False, 0); } else { if (flags & PTR_FLAGS_MOVE) - XTestFakeMotionEvent(server->display, 0, x, y, 0); + XTestFakeMotionEvent(subsystem->display, 0, x, y, 0); if (flags & PTR_FLAGS_BUTTON1) button = 1; @@ -130,23 +104,21 @@ void x11_shadow_input_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT1 down = TRUE; if (button != 0) - XTestFakeButtonEvent(server->display, button, down, 0); + XTestFakeButtonEvent(subsystem->display, button, down, 0); } - XTestGrabControl(server->display, False); + XTestGrabControl(subsystem->display, False); #endif } -void x11_shadow_input_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) +void x11_shadow_input_extended_mouse_event(x11ShadowSubsystem* subsystem, UINT16 flags, UINT16 x, UINT16 y) { #ifdef WITH_XTEST int button = 0; BOOL down = FALSE; - x11ShadowClient* context = (x11ShadowClient*) input->context; - x11ShadowServer* server = context->server; - XTestGrabControl(server->display, True); - XTestFakeMotionEvent(server->display, 0, x, y, CurrentTime); + XTestGrabControl(subsystem->display, True); + XTestFakeMotionEvent(subsystem->display, 0, x, y, CurrentTime); if (flags & PTR_XFLAGS_BUTTON1) button = 8; @@ -157,17 +129,9 @@ void x11_shadow_input_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 down = TRUE; if (button != 0) - XTestFakeButtonEvent(server->display, button, down, 0); + XTestFakeButtonEvent(subsystem->display, button, down, 0); - XTestGrabControl(server->display, False); + XTestGrabControl(subsystem->display, False); #endif } -void x11_shadow_input_register_callbacks(rdpInput* input) -{ - input->SynchronizeEvent = x11_shadow_input_synchronize_event; - input->KeyboardEvent = x11_shadow_input_keyboard_event; - input->UnicodeKeyboardEvent = x11_shadow_input_unicode_keyboard_event; - input->MouseEvent = x11_shadow_input_mouse_event; - input->ExtendedMouseEvent = x11_shadow_input_extended_mouse_event; -} diff --git a/server/shadow/X11/x11_shadow.c b/server/shadow/X11/x11_shadow.c index d599f42e9..da77f4266 100644 --- a/server/shadow/X11/x11_shadow.c +++ b/server/shadow/X11/x11_shadow.c @@ -20,7 +20,10 @@ #include #include #include +#include +#include +#include #include #include @@ -29,24 +32,292 @@ #include "x11_shadow.h" -x11ShadowServer* x11_shadow_server_new(rdpShadowServer* rdp) +int x11_shadow_cursor_init(x11ShadowSubsystem* subsystem) { - x11ShadowServer* server; +#ifdef WITH_XFIXES + int event; + int error; - server = (x11ShadowServer*) calloc(1, sizeof(x11ShadowServer)); + if (!XFixesQueryExtension(subsystem->display, &event, &error)) + { + fprintf(stderr, "XFixesQueryExtension failed\n"); + return -1; + } - if (!server) + subsystem->xfixes_notify_event = event + XFixesCursorNotify; + + XFixesSelectCursorInput(subsystem->display, DefaultRootWindow(subsystem->display), XFixesDisplayCursorNotifyMask); +#endif + + return 0; +} + +#ifdef WITH_XDAMAGE + +void x11_shadow_xdamage_init(x11ShadowSubsystem* subsystem) +{ + int damage_event; + int damage_error; + int major, minor; + XGCValues values; + + if (XDamageQueryExtension(subsystem->display, &damage_event, &damage_error) == 0) + { + fprintf(stderr, "XDamageQueryExtension failed\n"); + return; + } + + XDamageQueryVersion(subsystem->display, &major, &minor); + + if (XDamageQueryVersion(subsystem->display, &major, &minor) == 0) + { + fprintf(stderr, "XDamageQueryVersion failed\n"); + return; + } + else if (major < 1) + { + fprintf(stderr, "XDamageQueryVersion failed: major:%d minor:%d\n", major, minor); + return; + } + + subsystem->xdamage_notify_event = damage_event + XDamageNotify; + subsystem->xdamage = XDamageCreate(subsystem->display, subsystem->root_window, XDamageReportDeltaRectangles); + + if (subsystem->xdamage == None) + { + fprintf(stderr, "XDamageCreate failed\n"); + return; + } + +#ifdef WITH_XFIXES + subsystem->xdamage_region = XFixesCreateRegion(subsystem->display, NULL, 0); + + if (subsystem->xdamage_region == None) + { + fprintf(stderr, "XFixesCreateRegion failed\n"); + XDamageDestroy(subsystem->display, subsystem->xdamage); + subsystem->xdamage = None; + return; + } +#endif + + values.subwindow_mode = IncludeInferiors; + subsystem->xdamage_gc = XCreateGC(subsystem->display, subsystem->root_window, GCSubwindowMode, &values); + XSetFunction(subsystem->display, subsystem->xdamage_gc, GXcopy); +} + +#endif + +int x11_shadow_xshm_init(x11ShadowSubsystem* server) +{ + Bool pixmaps; + int major, minor; + + if (XShmQueryExtension(server->display) != False) + { + XShmQueryVersion(server->display, &major, &minor, &pixmaps); + + if (pixmaps != True) + { + fprintf(stderr, "XShmQueryVersion failed\n"); + return -1; + } + } + else + { + fprintf(stderr, "XShmQueryExtension failed\n"); + return -1; + } + + server->fb_shm_info.shmid = -1; + server->fb_shm_info.shmaddr = (char*) -1; + + server->fb_image = XShmCreateImage(server->display, server->visual, server->depth, + ZPixmap, NULL, &(server->fb_shm_info), server->width, server->height); + + if (!server->fb_image) + { + fprintf(stderr, "XShmCreateImage failed\n"); + return -1; + } + + server->fb_shm_info.shmid = shmget(IPC_PRIVATE, + server->fb_image->bytes_per_line * server->fb_image->height, IPC_CREAT | 0600); + + if (server->fb_shm_info.shmid == -1) + { + fprintf(stderr, "shmget failed\n"); + return -1; + } + + server->fb_shm_info.readOnly = False; + server->fb_shm_info.shmaddr = shmat(server->fb_shm_info.shmid, 0, 0); + server->fb_image->data = server->fb_shm_info.shmaddr; + + if (server->fb_shm_info.shmaddr == ((char*) -1)) + { + fprintf(stderr, "shmat failed\n"); + return -1; + } + + XShmAttach(server->display, &(server->fb_shm_info)); + XSync(server->display, False); + + shmctl(server->fb_shm_info.shmid, IPC_RMID, 0); + + fprintf(stderr, "display: %p root_window: %p width: %d height: %d depth: %d\n", + server->display, (void*) server->root_window, server->fb_image->width, server->fb_image->height, server->fb_image->depth); + + server->fb_pixmap = XShmCreatePixmap(server->display, + server->root_window, server->fb_image->data, &(server->fb_shm_info), + server->fb_image->width, server->fb_image->height, server->fb_image->depth); + + return 0; +} + +int x11_shadow_subsystem_init(x11ShadowSubsystem* subsystem) +{ + int i; + int pf_count; + int vi_count; + XVisualInfo* vi; + XVisualInfo* vis; + XVisualInfo template; + XPixmapFormatValues* pf; + XPixmapFormatValues* pfs; + + /** + * Recent X11 servers drop support for shared pixmaps + * To see if your X11 server supports shared pixmaps, use: + * xdpyinfo -ext MIT-SHM | grep "shared pixmaps" + */ + subsystem->use_xshm = TRUE; + + setenv("DISPLAY", ":0", 1); /* Set DISPLAY variable if not already set */ + + if (!XInitThreads()) + fprintf(stderr, "warning: XInitThreads() failure\n"); + + subsystem->display = XOpenDisplay(NULL); + + if (!subsystem->display) + { + fprintf(stderr, "failed to open display: %s\n", XDisplayName(NULL)); + exit(1); + } + + subsystem->xfds = ConnectionNumber(subsystem->display); + subsystem->number = DefaultScreen(subsystem->display); + subsystem->screen = ScreenOfDisplay(subsystem->display, subsystem->number); + subsystem->depth = DefaultDepthOfScreen(subsystem->screen); + subsystem->width = WidthOfScreen(subsystem->screen); + subsystem->height = HeightOfScreen(subsystem->screen); + subsystem->root_window = DefaultRootWindow(subsystem->display); + + pfs = XListPixmapFormats(subsystem->display, &pf_count); + + if (!pfs) + { + fprintf(stderr, "XListPixmapFormats failed\n"); + exit(1); + } + + for (i = 0; i < pf_count; i++) + { + pf = pfs + i; + + if (pf->depth == subsystem->depth) + { + subsystem->bpp = pf->bits_per_pixel; + subsystem->scanline_pad = pf->scanline_pad; + break; + } + } + XFree(pfs); + + ZeroMemory(&template, sizeof(template)); + template.class = TrueColor; + template.screen = subsystem->number; + + vis = XGetVisualInfo(subsystem->display, VisualClassMask | VisualScreenMask, &template, &vi_count); + + if (!vis) + { + fprintf(stderr, "XGetVisualInfo failed\n"); + exit(1); + } + + for (i = 0; i < vi_count; i++) + { + vi = vis + i; + + if (vi->depth == subsystem->depth) + { + subsystem->visual = vi->visual; + break; + } + } + XFree(vis); + + XSelectInput(subsystem->display, subsystem->root_window, SubstructureNotifyMask); + + if (subsystem->use_xshm) + { + if (x11_shadow_xshm_init(subsystem) < 0) + subsystem->use_xshm = FALSE; + } + + if (subsystem->use_xshm) + printf("Using X Shared Memory Extension (XShm)\n"); + +#ifdef WITH_XDAMAGE + x11_shadow_xdamage_init(subsystem); +#endif + + x11_shadow_cursor_init(subsystem); + + subsystem->bytesPerPixel = 4; + + return 1; +} + +int x11_shadow_subsystem_uninit(x11ShadowSubsystem* subsystem) +{ + if (!subsystem) + return -1; + + if (subsystem->display) + { + XCloseDisplay(subsystem->display); + subsystem->display = NULL; + } + + return 1; +} + +rdpShadowSubsystem* x11_shadow_subsystem_new(rdpShadowServer* server) +{ + x11ShadowSubsystem* subsystem; + + subsystem = (x11ShadowSubsystem*) calloc(1, sizeof(x11ShadowSubsystem)); + + if (!subsystem) return NULL; - signal(SIGPIPE, SIG_IGN); + subsystem->server = server; - return server; + x11_shadow_subsystem_init(subsystem); + + return (rdpShadowSubsystem*) subsystem; } -void x11_shadow_server_free(x11ShadowServer* server) +void x11_shadow_subsystem_free(rdpShadowSubsystem* subsystem) { - if (!server) + if (!subsystem) return; - free(server); + x11_shadow_subsystem_uninit((x11ShadowSubsystem*) subsystem); + + free(subsystem); } + diff --git a/server/shadow/X11/x11_shadow.h b/server/shadow/X11/x11_shadow.h index 59783a068..ea5e77fcc 100644 --- a/server/shadow/X11/x11_shadow.h +++ b/server/shadow/X11/x11_shadow.h @@ -21,8 +21,7 @@ #include -typedef struct x11_shadow_client x11ShadowClient; -typedef struct x11_shadow_server x11ShadowServer; +typedef struct x11_shadow_subsystem x11ShadowSubsystem; #include #include @@ -55,11 +54,11 @@ typedef struct x11_shadow_server x11ShadowServer; #include #endif -struct x11_shadow_server +struct x11_shadow_subsystem { - DWORD port; + RDP_SHADOW_SUBSYSTEM_COMMON(); + HANDLE thread; - freerdp_listener* listener; int bpp; int xfds; @@ -73,7 +72,6 @@ struct x11_shadow_server Display* display; int scanline_pad; int bytesPerPixel; - int activePeerCount; BOOL use_xshm; XImage* fb_image; @@ -93,32 +91,12 @@ struct x11_shadow_server #endif }; -struct x11_shadow_client -{ - rdpContext _p; - - wStream* s; - BOOL activated; - HANDLE monitorThread; - RFX_CONTEXT* rfx_context; - x11ShadowServer* server; -}; - #ifdef __cplusplus extern "C" { #endif -FREERDP_API x11ShadowServer* x11_shadow_server_new(rdpShadowServer* rdp); -FREERDP_API void x11_shadow_server_free(x11ShadowServer* server); - -x11ShadowClient* x11_shadow_client_new(rdpShadowClient* rdp); -void x11_shadow_client_free(x11ShadowClient* client); - -void* x11_shadow_update_thread(void* param); - -int x11_shadow_cursor_init(x11ShadowServer* server); -void x11_shadow_input_register_callbacks(rdpInput* input); -int x11_shadow_update_encode(freerdp_peer* client, int x, int y, int width, int height); +rdpShadowSubsystem* x11_shadow_subsystem_new(rdpShadowServer* server); +void x11_shadow_subsystem_free(rdpShadowSubsystem* subsystem); #ifdef __cplusplus } diff --git a/server/shadow/X11/x11_update.c b/server/shadow/X11/x11_update.c index bbdcee37b..94160f965 100644 --- a/server/shadow/X11/x11_update.c +++ b/server/shadow/X11/x11_update.c @@ -29,28 +29,26 @@ #include "x11_shadow.h" -XImage* x11_shadow_snapshot(x11ShadowClient* context, int x, int y, int width, int height) +XImage* x11_shadow_snapshot(x11ShadowSubsystem* subsystem, int x, int y, int width, int height) { XImage* image; - x11ShadowServer* server = context->server; - if (server->use_xshm) + if (subsystem->use_xshm) { - XCopyArea(server->display, server->root_window, server->fb_pixmap, server->xdamage_gc, x, y, width, height, x, y); - image = server->fb_image; + XCopyArea(subsystem->display, subsystem->root_window, subsystem->fb_pixmap, subsystem->xdamage_gc, x, y, width, height, x, y); + image = subsystem->fb_image; } else { - image = XGetImage(server->display, server->root_window, x, y, width, height, AllPlanes, ZPixmap); + image = XGetImage(subsystem->display, subsystem->root_window, x, y, width, height, AllPlanes, ZPixmap); } return image; } -void x11_shadow_xdamage_subtract_region(x11ShadowClient* context, int x, int y, int width, int height) +void x11_shadow_xdamage_subtract_region(x11ShadowSubsystem* subsystem, int x, int y, int width, int height) { XRectangle region; - x11ShadowServer* server = context->server; region.x = x; region.y = y; @@ -58,39 +56,18 @@ void x11_shadow_xdamage_subtract_region(x11ShadowClient* context, int x, int y, region.height = height; #ifdef WITH_XFIXES - XFixesSetRegion(server->display, server->xdamage_region, ®ion, 1); - XDamageSubtract(server->display, server->xdamage, server->xdamage_region, None); + XFixesSetRegion(subsystem->display, subsystem->xdamage_region, ®ion, 1); + XDamageSubtract(subsystem->display, subsystem->xdamage, subsystem->xdamage_region, None); #endif } -int x11_shadow_update_encode(freerdp_peer* client, int x, int y, int width, int height) +int x11_shadow_update_encode(x11ShadowSubsystem* subsystem, int x, int y, int width, int height) { - wStream* s; BYTE* data; - RFX_RECT rect; XImage* image; - rdpUpdate* update; - x11ShadowClient* context; - x11ShadowServer* server; - SURFACE_BITS_COMMAND* cmd; + RFX_RECT rect; - context = (x11ShadowClient*) client->context; - server = context->server; - - update = client->update; - cmd = &update->surface_bits_command; - - if (width * height <= 0) - { - cmd->bitmapDataLength = 0; - return -1; - } - - s = context->s; - Stream_Clear(s); - Stream_SetPosition(s, 0); - - if (server->use_xshm) + if (subsystem->use_xshm) { /** * Passing an offset source rectangle to rfx_compose_message() @@ -102,18 +79,10 @@ int x11_shadow_update_encode(freerdp_peer* client, int x, int y, int width, int rect.width = width; rect.height = height; - image = x11_shadow_snapshot(context, x, y, width, height); + image = x11_shadow_snapshot(subsystem, x, y, width, height); data = (BYTE*) image->data; data = &data[(y * image->bytes_per_line) + (x * image->bits_per_pixel / 8)]; - - rfx_compose_message(context->rfx_context, s, &rect, 1, data, - width, height, image->bytes_per_line); - - cmd->destLeft = x; - cmd->destTop = y; - cmd->destRight = x + width; - cmd->destBottom = y + height; } else { @@ -122,73 +91,40 @@ int x11_shadow_update_encode(freerdp_peer* client, int x, int y, int width, int rect.width = width; rect.height = height; - image = x11_shadow_snapshot(context, x, y, width, height); + image = x11_shadow_snapshot(subsystem, x, y, width, height); data = (BYTE*) image->data; - rfx_compose_message(context->rfx_context, s, &rect, 1, data, - width, height, image->bytes_per_line); - - cmd->destLeft = x; - cmd->destTop = y; - cmd->destRight = x + width; - cmd->destBottom = y + height; - XDestroyImage(image); } - cmd->bpp = 32; - cmd->codecID = client->settings->RemoteFxCodecId; - cmd->width = width; - cmd->height = height; - cmd->bitmapDataLength = Stream_GetPosition(s); - cmd->bitmapData = Stream_Buffer(s); - return 0; } -void x11_shadow_client_send_update(freerdp_peer* client) -{ - rdpUpdate* update; - SURFACE_BITS_COMMAND* cmd; - - update = client->update; - cmd = &update->surface_bits_command; - - if (cmd->bitmapDataLength) - update->SurfaceBits(update->context, cmd); -} - -void* x11_shadow_update_thread(void* param) +void* x11_shadow_update_thread(x11ShadowSubsystem* subsystem) { HANDLE event; XEvent xevent; DWORD beg, end; DWORD diff, rate; - x11ShadowClient* context; - x11ShadowServer* server; - freerdp_peer* client; + XFixesCursorImage* ci; int x, y, width, height; XDamageNotifyEvent* notify; - client = (freerdp_peer*) param; - context = (x11ShadowClient*) client->context; - server = context->server; - rate = 1000 / 10; - event = CreateFileDescriptorEvent(NULL, FALSE, FALSE, server->xfds); + event = CreateFileDescriptorEvent(NULL, FALSE, FALSE, subsystem->xfds); while (WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0) { beg = GetTickCount(); - while (XPending(server->display) > 0) + while (XPending(subsystem->display) > 0) { ZeroMemory(&xevent, sizeof(xevent)); - XNextEvent(server->display, &xevent); + XNextEvent(subsystem->display, &xevent); - if (xevent.type == server->xdamage_notify_event) + if (xevent.type == subsystem->xdamage_notify_event) { notify = (XDamageNotifyEvent*) &xevent; @@ -197,18 +133,17 @@ void* x11_shadow_update_thread(void* param) width = notify->area.width; height = notify->area.height; - if (x11_shadow_update_encode(client, x, y, width, height) >= 0) + if (x11_shadow_update_encode(subsystem, x, y, width, height) >= 0) { - x11_shadow_xdamage_subtract_region(context, x, y, width, height); + x11_shadow_xdamage_subtract_region(subsystem, x, y, width, height); - if (context->activated) - x11_shadow_client_send_update(client); + /* send update */ } } #ifdef WITH_XFIXES - else if (xevent.type == server->xfixes_notify_event) + else if (xevent.type == subsystem->xfixes_notify_event) { - XFixesCursorImage* ci = XFixesGetCursorImage(server->display); + ci = XFixesGetCursorImage(subsystem->display); XFree(ci); } #endif diff --git a/server/shadow/shadow.c b/server/shadow/shadow.c index bb75d5ba0..e8d04a76c 100644 --- a/server/shadow/shadow.c +++ b/server/shadow/shadow.c @@ -20,6 +20,11 @@ #include "config.h" #endif +#ifndef _WIN32 +#include +#include +#endif + #include "shadow.h" void* shadow_server_thread(rdpShadowServer* server) @@ -59,6 +64,10 @@ void* shadow_server_thread(rdpShadowServer* server) int shadow_server_start(rdpShadowServer* server) { +#ifndef _WIN32 + signal(SIGPIPE, SIG_IGN); +#endif + if (server->listener->Open(server->listener, NULL, server->port)) { server->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) @@ -116,9 +125,9 @@ rdpShadowServer* shadow_server_new(int argc, char** argv) if (!server->encoder) return NULL; - server->ext = x11_shadow_server_new(server); + server->subsystem = x11_shadow_subsystem_new(server); - if (!server->ext) + if (!server->subsystem) return NULL; return server; @@ -133,7 +142,7 @@ void shadow_server_free(rdpShadowServer* server) shadow_encoder_free(server->encoder); - x11_shadow_server_free(server->ext); + x11_shadow_subsystem_free(server->subsystem); free(server); } diff --git a/server/shadow/shadow_client.c b/server/shadow/shadow_client.c index 1947477ad..564701fb2 100644 --- a/server/shadow/shadow_client.c +++ b/server/shadow/shadow_client.c @@ -36,13 +36,11 @@ void shadow_client_context_new(freerdp_peer* peer, rdpShadowClient* client) server = (rdpShadowServer*) peer->ContextExtra; client->server = server; - - client->ext = x11_shadow_client_new(client); } void shadow_client_context_free(freerdp_peer* peer, rdpShadowClient* client) { - x11_shadow_client_free(client->ext); + } BOOL shadow_client_get_fds(freerdp_peer* peer, void** rfds, int* rcount)