diff --git a/server/shadow/CMakeLists.txt b/server/shadow/CMakeLists.txt index af7258a30..27b2aa94f 100644 --- a/server/shadow/CMakeLists.txt +++ b/server/shadow/CMakeLists.txt @@ -130,9 +130,6 @@ set(${MODULE_PREFIX}_SRCS shadow.h) set(${MODULE_PREFIX}_X11_SRCS - X11/x11_input.c - X11/x11_client.c - X11/x11_update.c X11/x11_shadow.c X11/x11_shadow.h) diff --git a/server/shadow/X11/x11_client.c b/server/shadow/X11/x11_client.c deleted file mode 100644 index 79d254b6f..000000000 --- a/server/shadow/X11/x11_client.c +++ /dev/null @@ -1,42 +0,0 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * - * Copyright 2011-2014 Marc-Andre Moreau - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "x11_shadow.h" - diff --git a/server/shadow/X11/x11_input.c b/server/shadow/X11/x11_input.c deleted file mode 100644 index 42cfc5b3b..000000000 --- a/server/shadow/X11/x11_input.c +++ /dev/null @@ -1,137 +0,0 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * X11 Server Input - * - * Copyright 2011 Marc-Andre Moreau - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include -#include - -#include "x11_shadow.h" - -void x11_shadow_input_synchronize_event(x11ShadowSubsystem* subsystem, UINT32 flags) -{ - -} - -void x11_shadow_input_keyboard_event(x11ShadowSubsystem* subsystem, UINT16 flags, UINT16 code) -{ -#ifdef WITH_XTEST - DWORD vkcode; - DWORD keycode; - BOOL extended = FALSE; - - if (flags & KBD_FLAGS_EXTENDED) - extended = TRUE; - - if (extended) - code |= KBDEXT; - - vkcode = GetVirtualKeyCodeFromVirtualScanCode(code, 4); - keycode = GetKeycodeFromVirtualKeyCode(vkcode, KEYCODE_TYPE_EVDEV); - - if (keycode != 0) - { - XTestGrabControl(subsystem->display, True); - - if (flags & KBD_FLAGS_DOWN) - XTestFakeKeyEvent(subsystem->display, keycode, True, 0); - else if (flags & KBD_FLAGS_RELEASE) - XTestFakeKeyEvent(subsystem->display, keycode, False, 0); - - XTestGrabControl(subsystem->display, False); - } -#endif -} - -void x11_shadow_input_unicode_keyboard_event(x11ShadowSubsystem* subsystem, UINT16 flags, UINT16 code) -{ - -} - -void x11_shadow_input_mouse_event(x11ShadowSubsystem* subsystem, UINT16 flags, UINT16 x, UINT16 y) -{ -#ifdef WITH_XTEST - int button = 0; - BOOL down = FALSE; - - XTestGrabControl(subsystem->display, True); - - if (flags & PTR_FLAGS_WHEEL) - { - BOOL negative = FALSE; - - if (flags & PTR_FLAGS_WHEEL_NEGATIVE) - negative = TRUE; - - button = (negative) ? 5 : 4; - - XTestFakeButtonEvent(subsystem->display, button, True, 0); - XTestFakeButtonEvent(subsystem->display, button, False, 0); - } - else - { - if (flags & PTR_FLAGS_MOVE) - XTestFakeMotionEvent(subsystem->display, 0, x, y, 0); - - if (flags & PTR_FLAGS_BUTTON1) - button = 1; - else if (flags & PTR_FLAGS_BUTTON2) - button = 3; - else if (flags & PTR_FLAGS_BUTTON3) - button = 2; - - if (flags & PTR_FLAGS_DOWN) - down = TRUE; - - if (button != 0) - XTestFakeButtonEvent(subsystem->display, button, down, 0); - } - - XTestGrabControl(subsystem->display, False); -#endif -} - -void x11_shadow_input_extended_mouse_event(x11ShadowSubsystem* subsystem, UINT16 flags, UINT16 x, UINT16 y) -{ -#ifdef WITH_XTEST - int button = 0; - BOOL down = FALSE; - - XTestGrabControl(subsystem->display, True); - XTestFakeMotionEvent(subsystem->display, 0, x, y, CurrentTime); - - if (flags & PTR_XFLAGS_BUTTON1) - button = 8; - else if (flags & PTR_XFLAGS_BUTTON2) - button = 9; - - if (flags & PTR_XFLAGS_DOWN) - down = TRUE; - - if (button != 0) - XTestFakeButtonEvent(subsystem->display, button, down, 0); - - XTestGrabControl(subsystem->display, False); -#endif -} - diff --git a/server/shadow/X11/x11_shadow.c b/server/shadow/X11/x11_shadow.c index a362e5574..01e049eeb 100644 --- a/server/shadow/X11/x11_shadow.c +++ b/server/shadow/X11/x11_shadow.c @@ -30,8 +30,217 @@ #include #include +#include +#include +#include + +#include +#include + +#include "../shadow_surface.h" + #include "x11_shadow.h" +void x11_shadow_input_synchronize_event(x11ShadowSubsystem* subsystem, UINT32 flags) +{ + +} + +void x11_shadow_input_keyboard_event(x11ShadowSubsystem* subsystem, UINT16 flags, UINT16 code) +{ +#ifdef WITH_XTEST + DWORD vkcode; + DWORD keycode; + BOOL extended = FALSE; + + if (flags & KBD_FLAGS_EXTENDED) + extended = TRUE; + + if (extended) + code |= KBDEXT; + + vkcode = GetVirtualKeyCodeFromVirtualScanCode(code, 4); + keycode = GetKeycodeFromVirtualKeyCode(vkcode, KEYCODE_TYPE_EVDEV); + + if (keycode != 0) + { + XTestGrabControl(subsystem->display, True); + + if (flags & KBD_FLAGS_DOWN) + XTestFakeKeyEvent(subsystem->display, keycode, True, 0); + else if (flags & KBD_FLAGS_RELEASE) + XTestFakeKeyEvent(subsystem->display, keycode, False, 0); + + XTestGrabControl(subsystem->display, False); + } +#endif +} + +void x11_shadow_input_unicode_keyboard_event(x11ShadowSubsystem* subsystem, UINT16 flags, UINT16 code) +{ + +} + +void x11_shadow_input_mouse_event(x11ShadowSubsystem* subsystem, UINT16 flags, UINT16 x, UINT16 y) +{ +#ifdef WITH_XTEST + int button = 0; + BOOL down = FALSE; + + XTestGrabControl(subsystem->display, True); + + if (flags & PTR_FLAGS_WHEEL) + { + BOOL negative = FALSE; + + if (flags & PTR_FLAGS_WHEEL_NEGATIVE) + negative = TRUE; + + button = (negative) ? 5 : 4; + + XTestFakeButtonEvent(subsystem->display, button, True, 0); + XTestFakeButtonEvent(subsystem->display, button, False, 0); + } + else + { + if (flags & PTR_FLAGS_MOVE) + XTestFakeMotionEvent(subsystem->display, 0, x, y, 0); + + if (flags & PTR_FLAGS_BUTTON1) + button = 1; + else if (flags & PTR_FLAGS_BUTTON2) + button = 3; + else if (flags & PTR_FLAGS_BUTTON3) + button = 2; + + if (flags & PTR_FLAGS_DOWN) + down = TRUE; + + if (button != 0) + XTestFakeButtonEvent(subsystem->display, button, down, 0); + } + + XTestGrabControl(subsystem->display, False); +#endif +} + +void x11_shadow_input_extended_mouse_event(x11ShadowSubsystem* subsystem, UINT16 flags, UINT16 x, UINT16 y) +{ +#ifdef WITH_XTEST + int button = 0; + BOOL down = FALSE; + + XTestGrabControl(subsystem->display, True); + XTestFakeMotionEvent(subsystem->display, 0, x, y, CurrentTime); + + if (flags & PTR_XFLAGS_BUTTON1) + button = 8; + else if (flags & PTR_XFLAGS_BUTTON2) + button = 9; + + if (flags & PTR_XFLAGS_DOWN) + down = TRUE; + + if (button != 0) + XTestFakeButtonEvent(subsystem->display, button, down, 0); + + XTestGrabControl(subsystem->display, False); +#endif +} + +void x11_shadow_xdamage_subtract_region(x11ShadowSubsystem* subsystem, int x, int y, int width, int height) +{ + XRectangle region; + + region.x = x; + region.y = y; + region.width = width; + region.height = height; + +#ifdef WITH_XFIXES + XFixesSetRegion(subsystem->display, subsystem->xdamage_region, ®ion, 1); + XDamageSubtract(subsystem->display, subsystem->xdamage, subsystem->xdamage_region, None); +#endif +} + +int x11_shadow_surface_copy(x11ShadowSubsystem* subsystem, int x, int y, int width, int height) +{ + XImage* image; + rdpShadowServer* server; + rdpShadowSurface* surface; + RECTANGLE_16 invalidRect; + + server = subsystem->server; + surface = server->surface; + + printf("x11_shadow_surface_copy: x: %d y: %d width: %d height: %d\n", + x, y, width, height); + + if (subsystem->use_xshm) + { + XCopyArea(subsystem->display, subsystem->root_window, subsystem->fb_pixmap, + subsystem->xdamage_gc, x, y, width, height, x, y); + + image = subsystem->fb_image; + + freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32, + surface->scanline, x, y, width, height, + (BYTE*) image->data, PIXEL_FORMAT_XRGB32, + image->bytes_per_line, x, y); + } + else + { + image = XGetImage(subsystem->display, subsystem->root_window, + x, y, width, height, AllPlanes, ZPixmap); + + freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32, + surface->scanline, x, y, width, height, + (BYTE*) image->data, PIXEL_FORMAT_XRGB32, + image->bytes_per_line, x, y); + + XDestroyImage(image); + } + + invalidRect.left = x; + invalidRect.top = y; + invalidRect.right = width; + invalidRect.bottom = height; + + region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), &invalidRect); + + return 1; +} + +int x11_shadow_check_event(x11ShadowSubsystem* subsystem) +{ + XEvent xevent; + int x, y, width, height; + XDamageNotifyEvent* notify; + + while (XPending(subsystem->display) > 0) + { + ZeroMemory(&xevent, sizeof(xevent)); + XNextEvent(subsystem->display, &xevent); + + if (xevent.type == subsystem->xdamage_notify_event) + { + notify = (XDamageNotifyEvent*) &xevent; + + x = notify->area.x; + y = notify->area.y; + width = notify->area.width; + height = notify->area.height; + + if (x11_shadow_surface_copy(subsystem, x, y, width, height) > 0) + { + x11_shadow_xdamage_subtract_region(subsystem, x, y, width, height); + } + } + } + + return 1; +} + int x11_shadow_cursor_init(x11ShadowSubsystem* subsystem) { #ifdef WITH_XFIXES @@ -113,19 +322,15 @@ int x11_shadow_xshm_init(x11ShadowSubsystem* server) Bool pixmaps; int major, minor; - if (XShmQueryExtension(server->display) != False) - { - XShmQueryVersion(server->display, &major, &minor, &pixmaps); + if (!XShmQueryExtension(server->display)) + return -1; - if (pixmaps != True) - { - fprintf(stderr, "XShmQueryVersion failed\n"); - return -1; - } - } - else + if (!XShmQueryVersion(server->display, &major, &minor, &pixmaps)) + return -1; + + if (!pixmaps) { - fprintf(stderr, "XShmQueryExtension failed\n"); + fprintf(stderr, "XShmQueryVersion failed\n"); return -1; } @@ -160,7 +365,9 @@ int x11_shadow_xshm_init(x11ShadowSubsystem* server) return -1; } - XShmAttach(server->display, &(server->fb_shm_info)); + if (!XShmAttach(server->display, &(server->fb_shm_info))) + return -1; + XSync(server->display, False); shmctl(server->fb_shm_info.shmid, IPC_RMID, 0); @@ -172,7 +379,10 @@ int x11_shadow_xshm_init(x11ShadowSubsystem* server) 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; + if (!server->fb_pixmap) + return -1; + + return 1; } int x11_shadow_subsystem_init(x11ShadowSubsystem* subsystem) @@ -191,12 +401,18 @@ int x11_shadow_subsystem_init(x11ShadowSubsystem* subsystem) * To see if your X11 server supports shared pixmaps, use: * xdpyinfo -ext MIT-SHM | grep "shared pixmaps" */ - subsystem->use_xshm = FALSE; + subsystem->use_xshm = TRUE; - setenv("DISPLAY", ":0", 1); /* Set DISPLAY variable if not already set */ + if (!getenv("DISPLAY")) + { + /* Set DISPLAY variable if not already set */ + setenv("DISPLAY", ":0", 1); + } if (!XInitThreads()) + { fprintf(stderr, "warning: XInitThreads() failure\n"); + } subsystem->display = XOpenDisplay(NULL); diff --git a/server/shadow/X11/x11_update.c b/server/shadow/X11/x11_update.c deleted file mode 100644 index c3f0cb912..000000000 --- a/server/shadow/X11/x11_update.c +++ /dev/null @@ -1,142 +0,0 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * - * Copyright 2011-2014 Marc-Andre Moreau - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include - -#include - -#include -#include - -#include "../shadow_surface.h" - -#include "x11_shadow.h" - -XImage* x11_shadow_snapshot(x11ShadowSubsystem* subsystem, int x, int y, int width, int height) -{ - XImage* image; - - if (subsystem->use_xshm) - { - 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(subsystem->display, subsystem->root_window, - x, y, width, height, AllPlanes, ZPixmap); - } - - return image; -} - -void x11_shadow_xdamage_subtract_region(x11ShadowSubsystem* subsystem, int x, int y, int width, int height) -{ - XRectangle region; - - region.x = x; - region.y = y; - region.width = width; - region.height = height; - -#ifdef WITH_XFIXES - XFixesSetRegion(subsystem->display, subsystem->xdamage_region, ®ion, 1); - XDamageSubtract(subsystem->display, subsystem->xdamage, subsystem->xdamage_region, None); -#endif -} - -int x11_shadow_surface_copy(x11ShadowSubsystem* subsystem, int x, int y, int width, int height) -{ - XImage* image; - rdpShadowServer* server; - rdpShadowSurface* surface; - RECTANGLE_16 invalidRect; - - server = subsystem->server; - surface = server->surface; - - printf("x11_shadow_surface_copy: x: %d y: %d width: %d height: %d\n", - x, y, width, height); - - if (subsystem->use_xshm) - { - image = x11_shadow_snapshot(subsystem, x, y, width, height); - - freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32, - surface->scanline, x, y, width, height, - (BYTE*) image->data, PIXEL_FORMAT_XRGB32, - image->bytes_per_line, x, y); - } - else - { - image = x11_shadow_snapshot(subsystem, x, y, width, height); - - freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32, - surface->scanline, x, y, width, height, - (BYTE*) image->data, PIXEL_FORMAT_XRGB32, - image->bytes_per_line, x, y); - - XDestroyImage(image); - } - - invalidRect.left = x; - invalidRect.top = y; - invalidRect.right = width; - invalidRect.bottom = height; - - region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), &invalidRect); - - return 1; -} - -int x11_shadow_check_event(x11ShadowSubsystem* subsystem) -{ - XEvent xevent; - int x, y, width, height; - XDamageNotifyEvent* notify; - - while (XPending(subsystem->display) > 0) - { - ZeroMemory(&xevent, sizeof(xevent)); - XNextEvent(subsystem->display, &xevent); - - if (xevent.type == subsystem->xdamage_notify_event) - { - notify = (XDamageNotifyEvent*) &xevent; - - x = notify->area.x; - y = notify->area.y; - width = notify->area.width; - height = notify->area.height; - - if (x11_shadow_surface_copy(subsystem, x, y, width, height) > 0) - { - x11_shadow_xdamage_subtract_region(subsystem, x, y, width, height); - } - } - } - - return 1; -}