From ded17d9d0c46fb6bf7959e049714fdcbd5b6603e Mon Sep 17 00:00:00 2001 From: David FORT Date: Wed, 6 Jan 2016 23:56:05 +0100 Subject: [PATCH] Move wayland client to UWAC --- client/Wayland/CMakeLists.txt | 14 ++- client/Wayland/wlf_display.c | 112 --------------------- client/Wayland/wlf_display.h | 43 --------- client/Wayland/wlf_input.c | 200 ++++++-------------------------------- client/Wayland/wlf_input.h | 25 ++--- client/Wayland/wlf_window.c | 220 ------------------------------------------ client/Wayland/wlf_window.h | 58 ----------- client/Wayland/wlfreerdp.c | 167 +++++++++++++++++++++++--------- client/Wayland/wlfreerdp.h | 12 +-- cmake/FindWayland.cmake | 68 ++++++------- 10 files changed, 200 insertions(+), 719 deletions(-) delete mode 100644 client/Wayland/wlf_display.c delete mode 100644 client/Wayland/wlf_display.h delete mode 100644 client/Wayland/wlf_window.c delete mode 100644 client/Wayland/wlf_window.h diff --git a/client/Wayland/CMakeLists.txt b/client/Wayland/CMakeLists.txt index 66cb0d1..2329891 100644 --- a/client/Wayland/CMakeLists.txt +++ b/client/Wayland/CMakeLists.txt @@ -2,6 +2,7 @@ # FreeRDP Wayland Client cmake build script # # Copyright 2014 Manuel Bachmann +# Copyright 2015 David Fort # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,22 +19,19 @@ set(MODULE_NAME "wlfreerdp") set(MODULE_PREFIX "FREERDP_CLIENT_WAYLAND") -include_directories(${WAYLAND_INCLUDE_DIRS}) +include_directories(${UWAC_INCLUDE_DIRS}) set(${MODULE_PREFIX}_SRCS - wlf_display.c - wlf_display.h - wlf_window.c - wlf_window.h + wlfreerdp.c + wlfreerdp.h wlf_input.c wlf_input.h - wlfreerdp.c - wlfreerdp.h) + ) add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${CMAKE_DL_LIBS}) -set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${WAYLAND_LIBRARIES} freerdp-client freerdp) +set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${UWAC_LIBS} freerdp-client freerdp) target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT client) diff --git a/client/Wayland/wlf_display.c b/client/Wayland/wlf_display.c deleted file mode 100644 index 4ab9712..0000000 --- a/client/Wayland/wlf_display.c +++ /dev/null @@ -1,112 +0,0 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * Wayland Displays - * - * Copyright 2014 Manuel Bachmann - * - * 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. - */ - -#include -#include - -#include "wlf_display.h" - -static void wl_registry_handle_global(void* data, struct wl_registry* registry, uint32_t id, const char *interface, uint32_t version) -{ - wlfDisplay* display = data; - - if (strcmp(interface, "wl_compositor") == 0) - display->compositor = wl_registry_bind(registry, id, &wl_compositor_interface, 1); - else if (strcmp(interface, "wl_shell") == 0) - display->shell = wl_registry_bind(registry, id, &wl_shell_interface, 1); - else if (strcmp(interface, "wl_shm") == 0) - display->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1); - else if (strcmp(interface, "wl_seat") == 0) - display->seat = wl_registry_bind(registry, id, &wl_seat_interface, 1); -} - -static void wl_registry_handle_global_remove(void* data, struct wl_registry* registry, uint32_t name) -{ - -} - -static const struct wl_registry_listener wl_registry_listener = -{ - wl_registry_handle_global, - wl_registry_handle_global_remove -}; - - -wlfDisplay* wlf_CreateDisplay(void) -{ - wlfDisplay* display; - - display = (wlfDisplay*) calloc(1, sizeof(wlfDisplay)); - - if (display) - { - display->display = wl_display_connect(NULL); - - if (!display->display) - { - WLog_ERR(TAG, "wl_pre_connect: failed to connect to Wayland compositor"); - WLog_ERR(TAG, "Please check that the XDG_RUNTIME_DIR environment variable is properly set."); - free(display); - return NULL; - } - - display->registry = wl_display_get_registry(display->display); - wl_registry_add_listener(display->registry, &wl_registry_listener, display); - wl_display_roundtrip(display->display); - - if (!display->compositor || !display->shell || !display->shm) - { - WLog_ERR(TAG, "wl_pre_connect: failed to find needed compositor interfaces"); - free(display); - return NULL; - } - } - - return display; -} - -BOOL wlf_RefreshDisplay(wlfDisplay* display) -{ - if (wl_display_dispatch(display->display) == -1) - return FALSE; - return TRUE; -} - -void wlf_DestroyDisplay(wlfContext* wlfc, wlfDisplay* display) -{ - if (display == NULL) - return; - - if (wlfc->display == display) - wlfc->display = NULL; - - if (display->seat) - wl_seat_destroy(display->seat); - if (display->shm) - wl_shm_destroy(display->shm); - if (display->shell) - wl_shell_destroy(display->shell); - if (display->compositor) - wl_compositor_destroy(display->compositor); - if (display->registry) - wl_registry_destroy(display->registry); - wl_display_disconnect(display->display); - - free(display); -} diff --git a/client/Wayland/wlf_display.h b/client/Wayland/wlf_display.h deleted file mode 100644 index d92d899..0000000 --- a/client/Wayland/wlf_display.h +++ /dev/null @@ -1,43 +0,0 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * Wayland Displays - * - * Copyright 2014 Manuel Bachmann - * - * 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. - */ - -#ifndef __WLF_DISPLAY_H -#define __WLF_DISPLAY_H - -#include - -typedef struct wlf_display wlfDisplay; - -#include "wlfreerdp.h" - -struct wlf_display -{ - struct wl_display* display; - struct wl_registry* registry; - struct wl_compositor* compositor; - struct wl_shell* shell; - struct wl_shm* shm; - struct wl_seat* seat; -}; - -wlfDisplay* wlf_CreateDisplay(void); -BOOL wlf_RefreshDisplay(wlfDisplay* display); -void wlf_DestroyDisplay(wlfContext* wlfc, wlfDisplay* display); - -#endif /* __WLF_DISPLAY_H */ diff --git a/client/Wayland/wlf_input.c b/client/Wayland/wlf_input.c index 76ab555..00435ff 100644 --- a/client/Wayland/wlf_input.c +++ b/client/Wayland/wlf_input.c @@ -3,6 +3,7 @@ * Wayland Input * * Copyright 2014 Manuel Bachmann + * Copyright 2015 David Fort * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,50 +25,30 @@ #include "wlf_input.h" -static void wl_pointer_enter(void* data, struct wl_pointer* pointer, uint32_t serial, struct wl_surface* surface, wl_fixed_t sx_w, wl_fixed_t sy_w) -{ +BOOL wlf_handle_pointer_enter(freerdp *instance, UwacPointerEnterLeaveEvent *ev) { + rdpInput* input = instance->input; + return input->MouseEvent(input, PTR_FLAGS_MOVE, ev->x, ev->y); } -static void wl_pointer_leave(void* data, struct wl_pointer* pointer, uint32_t serial, struct wl_surface* surface) -{ - -} - -static void wl_pointer_motion(void* data, struct wl_pointer* pointer, uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w) -{ - wlfInput* input_w = data; - rdpInput* input; - UINT16 x; - UINT16 y; - - input = input_w->input; +BOOL wlf_handle_pointer_motion(freerdp *instance, UwacPointerMotionEvent *ev) { + rdpInput* input = instance->input; - x = (UINT16) wl_fixed_to_int(sx_w); - y = (UINT16) wl_fixed_to_int(sy_w); - - input->MouseEvent(input, PTR_FLAGS_MOVE, x, y); - - input_w->last_x = x; - input_w->last_y = y; + return input->MouseEvent(input, PTR_FLAGS_MOVE, ev->x, ev->y); } -static void wl_pointer_button(void* data, struct wl_pointer* pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state) -{ - wlfInput* input_w = data; +BOOL wlf_handle_pointer_buttons(freerdp *instance, UwacPointerButtonEvent *ev) { rdpInput* input; - UINT16 x; - UINT16 y; UINT16 flags; - input = input_w->input; + input = instance->input; - if (state == WL_POINTER_BUTTON_STATE_PRESSED) + if (ev->state == WL_POINTER_BUTTON_STATE_PRESSED) flags = PTR_FLAGS_DOWN; else flags = 0; - switch (button) + switch (ev->button) { case BTN_LEFT: flags |= PTR_FLAGS_BUTTON1; @@ -79,175 +60,50 @@ static void wl_pointer_button(void* data, struct wl_pointer* pointer, uint32_t s flags |= PTR_FLAGS_BUTTON3; break; default: - return; + return TRUE; } - x = input_w->last_x; - y = input_w->last_y; - - input->MouseEvent(input, flags, x, y); + return input->MouseEvent(input, flags, ev->x, ev->y); } -static void wl_pointer_axis(void* data, struct wl_pointer* pointer, uint32_t time, uint32_t axis, wl_fixed_t value) -{ - wlfInput* input_w = data; + +BOOL wlf_handle_pointer_axis(freerdp *instance, UwacPointerAxisEvent *ev) { rdpInput* input; UINT16 flags; int direction; - input = input_w->input; + input = instance->input; flags = PTR_FLAGS_WHEEL; - if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL) + if (ev->axis == WL_POINTER_AXIS_VERTICAL_SCROLL) { - direction = wl_fixed_to_int(value); + direction = wl_fixed_to_int(ev->value); if (direction < 0) flags |= 0x0078; else flags |= PTR_FLAGS_WHEEL_NEGATIVE | 0x0088; } - input->MouseEvent(input, flags, 0, 0); -} - -static const struct wl_pointer_listener wl_pointer_listener = -{ - wl_pointer_enter, - wl_pointer_leave, - wl_pointer_motion, - wl_pointer_button, - wl_pointer_axis -}; - -static void wl_keyboard_keymap(void* data, struct wl_keyboard* keyboard, uint32_t format, int fd, uint32_t size) -{ - + return input->MouseEvent(input, flags, ev->x, ev->y); } -static void wl_keyboard_enter(void* data, struct wl_keyboard* keyboard, uint32_t serial, struct wl_surface* surface, struct wl_array* keys) -{ - wlfInput* input_w = data; - rdpInput* input; - UINT16 x; - UINT16 y; - - input = input_w->input; - - x = input_w->last_x; - y = input_w->last_y; - - input->FocusInEvent(input, 0); - input->MouseEvent(input, PTR_FLAGS_MOVE, x, y); -} - -static void wl_keyboard_leave(void* data, struct wl_keyboard* keyboard, uint32_t serial, struct wl_surface* surface) -{ - -} - -static void wl_keyboard_key(void* data, struct wl_keyboard* keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state) -{ - wlfInput* input_w = data; - rdpInput* input; - BOOL key_down; +BOOL wlf_handle_key(freerdp *instance, UwacKeyEvent *ev) { + rdpInput* input = instance->input; DWORD rdp_scancode; - input = input_w->input; - - if (state == WL_KEYBOARD_KEY_STATE_PRESSED) - key_down = TRUE; - else - key_down = FALSE; - - rdp_scancode = (DWORD) key; + rdp_scancode = (DWORD) ev->raw_key; if (rdp_scancode == RDP_SCANCODE_UNKNOWN) - return; + return TRUE; - freerdp_input_send_keyboard_event_ex(input, key_down, rdp_scancode); + return freerdp_input_send_keyboard_event_ex(input, ev->pressed, rdp_scancode); } -static void wl_keyboard_modifiers(void* data, struct wl_keyboard* keyboard, uint32_t serial, uint32_t mods_depr, uint32_t mods_latch, uint32_t mods_lock, uint32_t group) -{ - -} - -static const struct wl_keyboard_listener wl_keyboard_listener = -{ - wl_keyboard_keymap, - wl_keyboard_enter, - wl_keyboard_leave, - wl_keyboard_key, - wl_keyboard_modifiers -}; - -static void wl_seat_handle_capabilities(void* data, struct wl_seat* seat, enum wl_seat_capability capabilities) -{ - wlfInput* input = data; - struct wl_pointer* pointer; - struct wl_keyboard* keyboard; - - if (capabilities & WL_SEAT_CAPABILITY_POINTER) - { - pointer = wl_seat_get_pointer(seat); - - input->pointer = pointer; - wl_pointer_add_listener(pointer, &wl_pointer_listener, input); - } - - if (capabilities & WL_SEAT_CAPABILITY_KEYBOARD) - { - keyboard = wl_seat_get_keyboard(seat); - - input->keyboard = keyboard; - wl_keyboard_add_listener(keyboard, &wl_keyboard_listener, input); - } - -} - -static const struct wl_seat_listener wl_seat_listener = { - wl_seat_handle_capabilities -}; - - -wlfInput* wlf_CreateInput(wlfContext* wlfc) -{ - wlfInput* input; - struct wl_seat* seat; - - if (!wlfc->display) - return NULL; - if (!wlfc->display->seat) - return NULL; - seat = wlfc->display->seat; - - input = (wlfInput*) calloc(1, sizeof(wlfInput)); - - if (input) - { - input->input = wlfc->context.input; - input->last_x = 0; - input->last_y = 0; - - wl_seat_add_listener(seat, &wl_seat_listener, input); - } - - return input; -} - -void wlf_DestroyInput(wlfContext* wlfc, wlfInput* input) -{ - if (input == NULL) - return; - - if (wlfc->input == input) - wlfc->input = NULL; +BOOL wlf_keyboard_enter(freerdp *instance, UwacKeyboardEnterLeaveEvent *ev) { + rdpInput* input = instance->input; - if (input->pointer) - wl_pointer_release(input->pointer); - if (input->keyboard) - wl_keyboard_release(input->keyboard); + return input->FocusInEvent(input, 0) && + input->MouseEvent(input, PTR_FLAGS_MOVE, 0, 0); - free(input); } diff --git a/client/Wayland/wlf_input.h b/client/Wayland/wlf_input.h index 46f2447..0529f01 100644 --- a/client/Wayland/wlf_input.h +++ b/client/Wayland/wlf_input.h @@ -3,6 +3,7 @@ * Wayland Input * * Copyright 2014 Manuel Bachmann + * Copyright 2015 David Fort * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,23 +21,15 @@ #ifndef __WLF_INPUT_H #define __WLF_INPUT_H -#include +#include +#include -typedef struct wlf_input wlfInput; +BOOL wlf_handle_pointer_enter(freerdp* instance, UwacPointerEnterLeaveEvent *ev); +BOOL wlf_handle_pointer_motion(freerdp* instance, UwacPointerMotionEvent *ev); +BOOL wlf_handle_pointer_buttons(freerdp* instance, UwacPointerButtonEvent *ev); +BOOL wlf_handle_pointer_axis(freerdp* instance, UwacPointerAxisEvent *ev); -#include "wlfreerdp.h" - -struct wlf_input -{ - rdpInput* input; - UINT16 last_x; - UINT16 last_y; - - struct wl_pointer* pointer; - struct wl_keyboard* keyboard; -}; - -wlfInput* wlf_CreateInput(wlfContext* wlfc); -void wlf_DestroyInput(wlfContext* wlfc, wlfInput* input); +BOOL wlf_handle_key(freerdp* instance, UwacKeyEvent *ev); +BOOL wlf_keyboard_enter(freerdp *instance, UwacKeyboardEnterLeaveEvent *ev); #endif /* __WLF_INPUT_H */ diff --git a/client/Wayland/wlf_window.c b/client/Wayland/wlf_window.c deleted file mode 100644 index 72b57ea..0000000 --- a/client/Wayland/wlf_window.c +++ /dev/null @@ -1,220 +0,0 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * Wayland Windows - * - * Copyright 2014 Manuel Bachmann - * - * 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. - */ - -#include -#include -#include -#include -#include - -#include "wlf_window.h" - -static void wl_shell_surface_handle_ping(void* data, struct wl_shell_surface* shell_surface, uint32_t serial) -{ - wl_shell_surface_pong(shell_surface, serial); -} - -static void wl_shell_surface_handle_configure(void* data, struct wl_shell_surface* shell_surface, unsigned int edges, int32_t width, int32_t height) -{ - wlfWindow* window = data; - - window->width = width; - window->height = height; -} - -static const struct wl_shell_surface_listener wl_shell_surface_listener = -{ - wl_shell_surface_handle_ping, - wl_shell_surface_handle_configure, - NULL -}; - -static void wl_buffer_release(void* data, struct wl_buffer* wl_buffer) -{ - wlfBuffer* buffer = data; - - buffer->busy = FALSE; -} - -static const struct wl_buffer_listener wl_buffer_listener = -{ - wl_buffer_release -}; - -static const struct wl_callback_listener wl_callback_listener; - -static void wl_callback_done(void* data, struct wl_callback* callback, uint32_t time) -{ - wlfWindow* window = data; - wlfBuffer* buffer; - struct wl_shm_pool* shm_pool; - void* shm_data; - void* free_data; - int fd; - int fdt; - - if (!window->buffers[0].busy) - buffer = &window->buffers[0]; - else if (!window->buffers[1].busy) - buffer = &window->buffers[1]; - else - return; - - if (!buffer->buffer) { - fd = shm_open("/wlfreerdp_shm", O_CREAT | O_RDWR, 0666); - fdt = ftruncate(fd, window->width * window->height * 4); - if (fdt != 0) - { - WLog_ERR(TAG, "window_redraw: could not allocate memory"); - close(fd); - return; - } - - shm_data = mmap(NULL, window->width * window->height * 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if (shm_data == MAP_FAILED) - { - WLog_ERR(TAG, "window_redraw: failed to memory map buffer"); - close(fd); - return; - } - - shm_pool = wl_shm_create_pool(window->display->shm, fd, window->width * window->height * 4); - buffer->buffer = wl_shm_pool_create_buffer(shm_pool, 0, window->width, window->height, window->width* 4, WL_SHM_FORMAT_XRGB8888); - wl_buffer_add_listener(buffer->buffer, &wl_buffer_listener, buffer); - wl_shm_pool_destroy(shm_pool); - shm_unlink("/wlfreerdp_shm"); - close(fd); - - free_data = buffer->shm_data; - buffer->shm_data = shm_data; - munmap(free_data, window->width * window->height * 4); - } - - /* this is the real surface data */ - memcpy(buffer->shm_data, (void*) window->data, window->width * window->height * 4); - wl_surface_attach(window->surface, buffer->buffer, 0, 0); - wl_surface_damage(window->surface, 0, 0, window->width, window->height); - - if (callback) wl_callback_destroy(callback); - window->callback = wl_surface_frame(window->surface); - wl_callback_add_listener(window->callback, &wl_callback_listener, window); - wl_surface_commit(window->surface); - - buffer->busy = TRUE; -} - -static const struct wl_callback_listener wl_callback_listener = -{ - wl_callback_done -}; - - -wlfWindow* wlf_CreateDesktopWindow(wlfContext* wlfc, char* name, int width, int height, BOOL decorations) -{ - wlfWindow* window; - - window = (wlfWindow*) calloc(1, sizeof(wlfWindow)); - - if (window) - { - window->width = width; - window->height = height; - window->fullscreen = FALSE; - window->buffers[0].busy = FALSE; - window->buffers[1].busy = FALSE; - window->callback = NULL; - window->display = wlfc->display; - - window->surface = wl_compositor_create_surface(window->display->compositor); - window->shell_surface = wl_shell_get_shell_surface(window->display->shell, window->surface); - wl_shell_surface_add_listener(window->shell_surface, &wl_shell_surface_listener, window); - wl_shell_surface_set_toplevel(window->shell_surface); - - wlf_ResizeDesktopWindow(wlfc, window, width, height); - - wl_surface_damage(window->surface, 0, 0, window->width, window->height); - - wlf_SetWindowText(wlfc, window, name); - } - - return window; -} - -void wlf_ResizeDesktopWindow(wlfContext* wlfc, wlfWindow* window, int width, int height) -{ - window->width = width; - window->height = height; -} - -void wlf_SetWindowText(wlfContext* wlfc, wlfWindow* window, char* name) -{ - wl_shell_surface_set_title(window->shell_surface, name); -} - -void wlf_SetWindowFullscreen(wlfContext* wlfc, wlfWindow* window, BOOL fullscreen) -{ - if (fullscreen) - { - wl_shell_surface_set_fullscreen(window->shell_surface, WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 0, NULL); - window->fullscreen = TRUE; - } -} - -void wlf_ShowWindow(wlfContext* wlfc, wlfWindow* window, BYTE state) -{ - switch (state) - { - case WINDOW_HIDE: - case WINDOW_SHOW_MINIMIZED: - /* xdg_surface_set_minimized(window->xdg_surface); */ - break; - case WINDOW_SHOW_MAXIMIZED: - wl_shell_surface_set_maximized(window->shell_surface, NULL); - break; - case WINDOW_SHOW: - wl_shell_surface_set_toplevel(window->shell_surface); - break; - } -} - -void wlf_UpdateWindowArea(wlfContext* wlfc, wlfWindow* window, int x, int y, int width, int height) -{ - wl_callback_done(window, NULL, 0); -} - -void wlf_DestroyWindow(wlfContext* wlfc, wlfWindow* window) -{ - if (window == NULL) - return; - - if (wlfc->window == window) - wlfc->window = NULL; - - if (window->buffers[0].buffer) - wl_buffer_destroy(window->buffers[0].buffer); - if (window->buffers[1].buffer) - wl_buffer_destroy(window->buffers[1].buffer); - if (window->shell_surface) - wl_shell_surface_destroy(window->shell_surface); - if (window->surface) - wl_surface_destroy(window->surface); - - free(window->data); - free(window); -} diff --git a/client/Wayland/wlf_window.h b/client/Wayland/wlf_window.h deleted file mode 100644 index df36289..0000000 --- a/client/Wayland/wlf_window.h +++ /dev/null @@ -1,58 +0,0 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * Wayland Windows - * - * Copyright 2014 Manuel Bachmann - * - * 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. - */ - -#ifndef __WLF_WINDOW_H -#define __WLF_WINDOW_H - -#include - -typedef struct wlf_window wlfWindow; - -#include "wlfreerdp.h" - -struct wlf_buffer -{ - struct wl_buffer* buffer; - void* shm_data; - BOOL busy; -}; -typedef struct wlf_buffer wlfBuffer; - -struct wlf_window -{ - int width; - int height; - struct wl_surface* surface; - struct wl_shell_surface* shell_surface; - struct wl_callback* callback; - wlfBuffer buffers[2]; - wlfDisplay* display; - void* data; - BOOL fullscreen; -}; - -wlfWindow* wlf_CreateDesktopWindow(wlfContext* wlfc, char* name, int width, int height, BOOL decorations); -void wlf_ResizeDesktopWindow(wlfContext* wlfc, wlfWindow* window, int width, int height); -void wlf_SetWindowText(wlfContext* wlfc, wlfWindow* window, char* name); -void wlf_SetWindowFullscreen(wlfContext* wlfc, wlfWindow* window, BOOL fullscree); -void wlf_ShowWindow(wlfContext* wlfc, wlfWindow* window, BYTE state); -void wlf_UpdateWindowArea(wlfContext* wlfc, wlfWindow* window, int x, int y, int width, int height); -void wlf_DestroyWindow(wlfContext* wlfc, wlfWindow* window); - -#endif /* __WLF_WINDOW_H */ diff --git a/client/Wayland/wlfreerdp.c b/client/Wayland/wlfreerdp.c index 4aeda18..6c61ae4 100644 --- a/client/Wayland/wlfreerdp.c +++ b/client/Wayland/wlfreerdp.c @@ -23,8 +23,13 @@ #include #include #include +#include #include "wlfreerdp.h" +#include "wlf_input.h" + +UwacDisplay *g_display; +HANDLE g_displayHandle; static BOOL wl_context_new(freerdp* instance, rdpContext* context) { @@ -44,6 +49,18 @@ static void wl_context_free(freerdp* instance, rdpContext* context) } } +BOOL wl_update_content(wlfContext *context_w) +{ + if (!context_w->waitingFrameDone && context_w->haveDamage) + { + UwacWindowSubmitBuffer(context_w->window, true); + context_w->waitingFrameDone = TRUE; + context_w->haveDamage = FALSE; + } + + return TRUE; +} + static BOOL wl_begin_paint(rdpContext* context) { rdpGdi* gdi; @@ -53,12 +70,12 @@ static BOOL wl_begin_paint(rdpContext* context) return TRUE; } + static BOOL wl_end_paint(rdpContext* context) { rdpGdi* gdi; - wlfDisplay* display; - wlfWindow* window; - wlfContext* context_w; + char *data; + wlfContext *context_w; INT32 x, y; UINT32 w, h; int i; @@ -73,21 +90,23 @@ static BOOL wl_end_paint(rdpContext* context) h = gdi->primary->hdc->hwnd->invalid->h; context_w = (wlfContext*) context; - display = context_w->display; - window = context_w->window; + data = UwacWindowGetDrawingBuffer(context_w->window); for (i = 0; i < h; i++) - memcpy(window->data + ((i+y)*(gdi->width*4)) + x*4, + { + memcpy(data + ((i+y)*(gdi->width*4)) + x*4, gdi->primary_buffer + ((i+y)*(gdi->width*4)) + x*4, w*4); + } - return wlf_RefreshDisplay(display); + UwacWindowAddDamage(context_w->window, x, y, w, h); + context_w->haveDamage = TRUE; + return wl_update_content(context_w); } + static BOOL wl_pre_connect(freerdp* instance) { - wlfDisplay* display; - wlfInput* input; wlfContext* context; if (freerdp_channels_pre_connect(instance->context->channels, instance)) @@ -97,17 +116,7 @@ static BOOL wl_pre_connect(freerdp* instance) if (!context) return FALSE; - display = wlf_CreateDisplay(); - if (!display) - return FALSE; - - context->display = display; - - input = wlf_CreateInput(context); - if (!input) - return FALSE; - - context->input = input; + context->display = g_display; return TRUE; } @@ -115,7 +124,7 @@ static BOOL wl_pre_connect(freerdp* instance) static BOOL wl_post_connect(freerdp* instance) { rdpGdi* gdi; - wlfWindow* window; + UwacWindow* window; wlfContext* context; if (!gdi_init(instance, CLRCONV_ALPHA | CLRBUF_32BPP, NULL)) @@ -126,28 +135,23 @@ static BOOL wl_post_connect(freerdp* instance) return FALSE; context = (wlfContext*) instance->context; - window = wlf_CreateDesktopWindow(context, "FreeRDP", gdi->width, gdi->height, FALSE); + context->window = window = UwacCreateWindowShm(context->display, gdi->width, gdi->height, WL_SHM_FORMAT_XRGB8888); if (!window) return FALSE; - /* fill buffer with first image here */ - window->data = malloc (gdi->width * gdi->height *4); - if (!window->data) - return FALSE; + UwacWindowSetTitle(window, "FreeRDP"); - memcpy(window->data, (void*) gdi->primary_buffer, gdi->width * gdi->height * 4); instance->update->BeginPaint = wl_begin_paint; instance->update->EndPaint = wl_end_paint; - /* put Wayland data in the context here */ - context->window = window; - if (freerdp_channels_post_connect(instance->context->channels, instance) < 0) return FALSE; - wlf_UpdateWindowArea(context, window, 0, 0, gdi->width, gdi->height); - return TRUE; + memcpy(UwacWindowGetDrawingBuffer(context->window), gdi->primary_buffer, gdi->width * gdi->height * 4); + UwacWindowAddDamage(context->window, 0, 0, gdi->width, gdi->height); + context->haveDamage = TRUE; + return wl_update_content(context); } static void wl_post_disconnect(freerdp* instance) @@ -161,15 +165,67 @@ static void wl_post_disconnect(freerdp* instance) context = (wlfContext*) instance->context; + gdi_free(instance); + if (context->window) + UwacDestroyWindow(&context->window); + if (context->display) - wlf_DestroyDisplay(context, context->display); + UwacCloseDisplay(&context->display); - if (context->input) - wlf_DestroyInput(context, context->input); +} - gdi_free(instance); - if (context->window) - wlf_DestroyWindow(context, context->window); +static BOOL handle_uwac_events(freerdp* instance, UwacDisplay *display) { + UwacEvent event; + wlfContext *context; + + if (UwacDisplayDispatch(display, 1) < 0) + return FALSE; + + while (UwacHasEvent(display)) + { + if (UwacNextEvent(display, &event) != UWAC_SUCCESS) + return FALSE; + + /*printf("UWAC event type %d\n", event.type);*/ + switch (event.type) { + case UWAC_EVENT_FRAME_DONE: + if (!instance) + continue; + + context = (wlfContext *)instance->context; + context->waitingFrameDone = FALSE; + if (context->haveDamage && !wl_end_paint(instance->context)) + return FALSE; + break; + case UWAC_EVENT_POINTER_ENTER: + if (!wlf_handle_pointer_enter(instance, &event.mouse_enter_leave)) + return FALSE; + break; + case UWAC_EVENT_POINTER_MOTION: + if (!wlf_handle_pointer_motion(instance, &event.mouse_motion)) + return FALSE; + break; + case UWAC_EVENT_POINTER_BUTTONS: + if (!wlf_handle_pointer_buttons(instance, &event.mouse_button)) + return FALSE; + break; + case UWAC_EVENT_POINTER_AXIS: + if (!wlf_handle_pointer_axis(instance, &event.mouse_axis)) + return FALSE; + break; + case UWAC_EVENT_KEY: + if (!wlf_handle_key(instance, &event.key)) + return FALSE; + break; + case UWAC_EVENT_KEYBOARD_ENTER: + if (!wlf_keyboard_enter(instance, &event.keyboard_enter_leave)) + return FALSE; + break; + default: + break; + } + } + return TRUE; } static int wlfreerdp_run(freerdp* instance) @@ -184,27 +240,39 @@ static int wlfreerdp_run(freerdp* instance) return -1; } + handle_uwac_events(instance, g_display); + while (!freerdp_shall_disconnect(instance)) { - count = freerdp_get_event_handles(instance->context, handles, 64); + handles[0] = g_displayHandle; + + count = freerdp_get_event_handles(instance->context, &handles[1], 63); if (!count) { printf("Failed to get FreeRDP file descriptor\n"); break; } - status = WaitForMultipleObjects(count, handles, FALSE, INFINITE); + status = WaitForMultipleObjects(count+1, handles, FALSE, INFINITE); if (WAIT_FAILED == status) { printf("%s: WaitForMultipleObjects failed\n", __FUNCTION__); break; } - if (freerdp_check_event_handles(instance->context) != TRUE) - { - printf("Failed to check FreeRDP file descriptor\n"); + if (!handle_uwac_events(instance, g_display)) { + printf("error handling UWAC events\n"); break; } + + //if (WaitForMultipleObjects(count, &handles[1], FALSE, INFINITE)) { + if (freerdp_check_event_handles(instance->context) != TRUE) + { + printf("Failed to check FreeRDP file descriptor\n"); + break; + } + //} + } freerdp_channels_disconnect(instance->context->channels, instance); @@ -215,9 +283,20 @@ static int wlfreerdp_run(freerdp* instance) int main(int argc, char* argv[]) { - int status; + UwacReturnCode status; freerdp* instance; + g_display = UwacOpenDisplay(NULL, &status); + if (!g_display) + exit(1); + + g_displayHandle = CreateFileDescriptorEvent(NULL, FALSE, FALSE, UwacDisplayGetFd(g_display), WINPR_FD_READ); + if (!g_displayHandle) + exit(1); + + //if (!handle_uwac_events(NULL, g_display)) + // exit(1); + instance = freerdp_new(); instance->PreConnect = wl_pre_connect; instance->PostConnect = wl_post_connect; diff --git a/client/Wayland/wlfreerdp.h b/client/Wayland/wlfreerdp.h index bf4da6f..575d7e4 100644 --- a/client/Wayland/wlfreerdp.h +++ b/client/Wayland/wlfreerdp.h @@ -23,22 +23,22 @@ #include #include #include +#include #define TAG CLIENT_TAG("wayland") typedef struct wlf_context wlfContext; -#include "wlf_display.h" -#include "wlf_window.h" -#include "wlf_input.h" struct wlf_context { rdpContext context; - wlfDisplay* display; - wlfWindow* window; - wlfInput* input; + UwacDisplay *display; + UwacWindow *window; + + BOOL waitingFrameDone; + BOOL haveDamage; }; #endif /* __WLFREERDP_H */ diff --git a/cmake/FindWayland.cmake b/cmake/FindWayland.cmake index a34fdb2..76ec854 100644 --- a/cmake/FindWayland.cmake +++ b/cmake/FindWayland.cmake @@ -1,19 +1,14 @@ -# - Find Wayland -# Find the Wayland libraries +# - Finds UWAC +# Find the UWAC libraries and its dependencies # # This module defines the following variables: -# WAYLAND_FOUND - true if WAYLAND_INCLUDE_DIR & WAYLAND_LIBRARY are found -# WAYLAND_LIBRARIES - Set when WAYLAND_LIBRARY is found -# WAYLAND_INCLUDE_DIRS - Set when WAYLAND_INCLUDE_DIR is found -# -# WAYLAND_INCLUDE_DIR - where to find wayland-client.h, etc. -# WAYLAND_LIBRARY - the Wayland client library -# WAYLAND_VERSION - wayland client version if found and pkg-config was used +# UWAC_FOUND - true if UWAC has been found +# UWAC_LIBS - Set to the full path to UWAC libraries and its dependencies +# UWAC_INCLUDE_DIRS - Set to the include directories for UWAC # #============================================================================= -# Copyright 2014 Manuel Bachmann -# Copyright 2015 Bernhard Miklautz +# Copyright 2015 David Fort # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -28,38 +23,31 @@ # limitations under the License. #============================================================================= -set(REQUIRED_WAYLAND_CLIENT_VERSION 1.3.0) include(FindPkgConfig) if(PKG_CONFIG_FOUND) - pkg_check_modules(WAYLAND wayland-client) -endif() - -find_path(WAYLAND_INCLUDE_DIR NAMES wayland-client.h - PATHS ${WAYLAND_INCLUDE_DIRS} - DOC "The Wayland include directory" -) + pkg_check_modules(UWAC uwac) + + # find the complete path to each dependant library + set(UWAC_LIBS, "") + foreach(libname ${UWAC_LIBRARIES}) + find_library(FOUND_LIB NAMES ${libname} + PATHS ${UWAC_LIBRARY_DIRS} + ) + + if (FOUND_LIB) + list(APPEND UWAC_LIBS ${FOUND_LIB}) + endif() + unset(FOUND_LIB CACHE) + endforeach() + + + find_path(UWAC_INCLUDE_DIR NAMES uwac/uwac.h + PATHS ${UWAC_INCLUDE_DIRS} + DOC "The UWAC include directory" + ) -find_library(WAYLAND_LIBRARY NAMES wayland-client - PATHS ${WAYLAND_LIBRARY_DIRS} - DOC "The Wayland client library" -) - -include(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND DEFAULT_MSG WAYLAND_LIBRARY WAYLAND_INCLUDE_DIR) - -if(WAYLAND_VERSION) - if (${WAYLAND_VERSION} VERSION_LESS ${REQUIRED_WAYLAND_CLIENT_VERSION}) - message(WARNING "Installed wayland version ${WAYLAND_VERSION} is too old - minimum required version ${REQUIRED_WAYLAND_CLIENT_VERSION}") - set(WAYLAND_FOUND FALSE) - endif() -else() - message(WARNING "Couldn't detect wayland version - no version check is done") -endif() - -if(WAYLAND_FOUND) - set(WAYLAND_LIBRARIES ${WAYLAND_LIBRARY}) - set(WAYLAND_INCLUDE_DIRS ${WAYLAND_INCLUDE_DIR}) endif() -mark_as_advanced(WAYLAND_INCLUDE_DIR WAYLAND_LIBRARY WAYLAND_VERSION) +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(UWAC DEFAULT_MSG UWAC_LIBS UWAC_INCLUDE_DIR) -- 2.7.4