diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a72b24f3..90101c07 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -43,7 +43,7 @@ variables: FDO_UPSTREAM_REPO: wayland/weston FDO_REPO_SUFFIX: "$BUILD_OS-$FDO_DISTRIBUTION_VERSION/$BUILD_ARCH" - FDO_DISTRIBUTION_TAG: '2024-08-05-00-rm-plugins' + FDO_DISTRIBUTION_TAG: '2024-08-14-00-freerdp3.x' include: @@ -89,6 +89,7 @@ stages: variables: BUILD_OS: debian LLVM_VERSION: 11 + FREERDP_VERSION: 2 FDO_DISTRIBUTION_VERSION: bullseye FDO_DISTRIBUTION_EXEC: 'env FDO_CI_CONCURRENT=${FDO_CI_CONCURRENT} BUILD_ARCH=${BUILD_ARCH} KERNEL_IMAGE=${KERNEL_IMAGE} KERNEL_DEFCONFIG=${KERNEL_DEFCONFIG} LLVM_VERSION=${LLVM_VERSION} FDO_DISTRIBUTION_VERSION=${FDO_DISTRIBUTION_VERSION} bash .gitlab-ci/debian-install.sh' @@ -96,6 +97,8 @@ stages: variables: BUILD_OS: debian LLVM_VERSION: 15 + FREERDP_VERSION: 3 + USE_BOOKWORM_BACKPORTS: y # If you upgrade from bookworm, see the use_tls=0 notes in tests/meson.build. FDO_DISTRIBUTION_VERSION: bookworm FDO_DISTRIBUTION_EXEC: 'env FDO_CI_CONCURRENT=${FDO_CI_CONCURRENT} BUILD_ARCH=${BUILD_ARCH} KERNEL_IMAGE=${KERNEL_IMAGE} KERNEL_DEFCONFIG=${KERNEL_DEFCONFIG} LLVM_VERSION=${LLVM_VERSION} FDO_DISTRIBUTION_VERSION=${FDO_DISTRIBUTION_VERSION} bash .gitlab-ci/debian-install.sh' @@ -142,6 +145,10 @@ check-commit: - .os-debian variables: BUILD_ARCH: "armv7" + # Armv7 doesn't have freerdp3 in bookworm-backports so we don't build FreeRDP + MESON_DIST_OPTIONS: "-Dbackend-rdp=false" + # Inhibit installation of freerdp-dev + FREERDP_VERSION: 0 .debian-lts-aarch64: extends: @@ -276,7 +283,7 @@ aarch64-debian-container_prep: - .default-rules script: - cd "$BUILDDIR" - - meson --prefix="$PREFIX" --wrap-mode=nofallback -Db_sanitize=address ${MESON_OPTIONS} ${MESON_TOOLCHAIN_OPTIONS} .. + - meson --prefix="$PREFIX" --wrap-mode=nofallback -Db_sanitize=address ${MESON_OPTIONS} ${MESON_TOOLCHAIN_OPTIONS} ${MESON_DIST_OPTIONS} .. - ninja -k0 -j${FDO_CI_CONCURRENT:-4} - ninja install - test -n "${QEMU_SMP}" || QEMU_SMP=${FDO_CI_CONCURRENT:-4} @@ -304,7 +311,7 @@ aarch64-debian-container_prep: - .default-rules script: - cd "$BUILDDIR" - - meson --prefix="$PREFIX" --wrap-mode=nofallback ${MESON_OPTIONS} .. + - meson --prefix="$PREFIX" --wrap-mode=nofallback ${MESON_OPTIONS} ${MESON_DIST_OPTIONS} .. - ninja -k0 -j${FDO_CI_CONCURRENT:-4} - ninja install - ninja clean diff --git a/.gitlab-ci/debian-install.sh b/.gitlab-ci/debian-install.sh index 6999097b..e9c512cb 100644 --- a/.gitlab-ci/debian-install.sh +++ b/.gitlab-ci/debian-install.sh @@ -31,6 +31,9 @@ MESA_RUNTIME_PKGS=" libllvm${LLVM_VERSION} " +if [ x"$USE_BOOKWORM_BACKPORTS" = "xy" ] ; then + echo 'deb http://deb.debian.org/debian bookworm-backports main' >> /etc/apt/sources.list +fi apt-get update apt-get -y --no-install-recommends install \ autoconf \ @@ -40,7 +43,6 @@ apt-get -y --no-install-recommends install \ curl \ doxygen \ graphviz \ - freerdp2-dev \ gcovr \ git \ hwdata \ @@ -123,6 +125,9 @@ apt-get -y --no-install-recommends install \ $MESA_RUNTIME_PKGS \ $LINUX_DEV_PKGS \ +if [ "$FREERDP_VERSION" -ne 0 ] ; then + apt-get -y --no-install-recommends install freerdp${FREERDP_VERSION}-dev +fi # Actually build our dependencies ... ./.gitlab-ci/build-deps.sh diff --git a/libweston/backend-rdp/meson.build b/libweston/backend-rdp/meson.build index 4245252c..81f1e12a 100644 --- a/libweston/backend-rdp/meson.build +++ b/libweston/backend-rdp/meson.build @@ -1,46 +1,64 @@ if not get_option('backend-rdp') - subdir_done() + subdir_done() endif config_h.set('BUILD_RDP_COMPOSITOR', '1') -dep_frdp = dependency('freerdp2', version: '>= 2.3.0', required: false) -if not dep_frdp.found() - error('RDP-backend requires freerdp >= 2.3.0 which was not found. Or, you can use \'-Dbackend-rdp=false\'.') -endif +dep_frdp3 = dependency('freerdp3', version: '>= 3.0.0', required: false) +dep_frdp2 = dependency('freerdp2', version: '>= 2.3.0', required: false) -dep_frdp_server = dependency('freerdp-server2', version: '>= 2.3.0', required: false) -if not dep_frdp_server.found() - error('RDP-backend requires freerdp-server2 >= 2.3.0 which was not found. Or, you can use \'-Dbackend-rdp=false\'.') -endif +if dep_frdp3.found() + config_h.set('USE_FREERDP_VERSION', '3') + dep_frdp = dep_frdp3 + dep_frdp_server = dependency('freerdp-server3', version: '>= 3.0.0', required: false) + if not dep_frdp_server.found() + error('RDP-backend v3 requires freerdp-server3 >= 3.0.0 which was not found. Or, you can use \'-Dbackend-rdp=false\'.') + endif -dep_wpr = dependency('winpr2', version: '>= 2.3.0', required: false) -if not dep_wpr.found() - error('RDP-backend requires winpr >= 2.3.0 which was not found. Or, you can use \'-Dbackend-rdp=false\'.') + dep_wpr = dependency('winpr3', version: '>= 3.0.0', required: false) + if not dep_wpr.found() + error('RDP-backend v3 requires winpr >= 3.0.0 which was not found. Or, you can use \'-Dbackend-rdp=false\'.') + endif + message('Using FreeRDP 3.x for RDP backend') +elif dep_frdp2.found() + config_h.set('USE_FREERDP_VERSION', '2') + dep_frdp = dep_frdp2 + dep_frdp_server = dependency('freerdp-server2', version: '>= 2.3.0', required: false) + if not dep_frdp_server.found() + error('RDP-backend v2 requires freerdp-server2 >= 2.3.0 which was not found. Or, you can use \'-Dbackend-rdp=false\'.') + endif + + dep_wpr = dependency('winpr2', version: '>= 2.3.0', required: false) + if not dep_wpr.found() + error('RDP-backend requires v2 winpr >= 2.3.0 which was not found. Or, you can use \'-Dbackend-rdp=false\'.') + endif + message('Using FreeRDP 2.x for RDP backend') +else + error('RDP-backend requires freerdp3 >= 3.0.0 or freerdp2 >= 2.3.0 which was not found. Or, you can use \'-Dbackend-rdp=false\'.') endif deps_rdp = [ - dep_libweston_private, - dep_frdp, - dep_frdp_server, - dep_wpr, - dep_libdrm_headers, + dep_libweston_private, + dep_frdp, + dep_frdp_server, + dep_wpr, + dep_libdrm_headers, ] srcs_rdp = [ 'rdp.c', 'rdpclip.c', - 'rdpdisp.c', + 'rdpdisp.c', 'rdputil.c', ] plugin_rdp = shared_library( - 'rdp-backend', - srcs_rdp, - include_directories: common_inc, - dependencies: deps_rdp, - name_prefix: '', - install: true, - install_dir: dir_module_libweston + 'rdp-backend', + srcs_rdp, + include_directories: common_inc, + dependencies: deps_rdp, + name_prefix: '', + install: true, + install_dir: dir_module_libweston ) env_modmap += 'rdp-backend.so=@0@;'.format(plugin_rdp.full_path()) install_headers(backend_rdp_h, subdir: dir_include_libweston_install) diff --git a/libweston/backend-rdp/rdp.c b/libweston/backend-rdp/rdp.c index 7267ceca..0059b418 100644 --- a/libweston/backend-rdp/rdp.c +++ b/libweston/backend-rdp/rdp.c @@ -100,7 +100,7 @@ rdp_peer_refresh_rfx(pixman_region32_t *damage, pixman_image_t *image, freerdp_p cmd.destRight = damage->extents.x2; cmd.destBottom = damage->extents.y2; cmd.bmp.bpp = 32; - cmd.bmp.codecID = peer->context->settings->RemoteFxCodecId; + cmd.bmp.codecID = freerdp_settings_get_uint32(peer->context->settings, FreeRDP_RemoteFxCodecId); cmd.bmp.width = width; cmd.bmp.height = height; @@ -161,7 +161,7 @@ rdp_peer_refresh_nsc(pixman_region32_t *damage, pixman_image_t *image, freerdp_p cmd.destRight = damage->extents.x2; cmd.destBottom = damage->extents.y2; cmd.bmp.bpp = 32; - cmd.bmp.codecID = peer->context->settings->NSCodecId; + cmd.bmp.codecID = freerdp_settings_get_uint32(peer->context->settings, FreeRDP_NSCodecId); cmd.bmp.width = width; cmd.bmp.height = height; @@ -220,7 +220,8 @@ rdp_peer_refresh_raw(pixman_region32_t *region, pixman_image_t *image, freerdp_p cmd.destRight = rect->x2; cmd.bmp.width = (rect->x2 - rect->x1); - heightIncrement = peer->context->settings->MultifragMaxRequestSize / (16 + cmd.bmp.width * 4); + heightIncrement = freerdp_settings_get_uint32(peer->context->settings, + FreeRDP_MultifragMaxRequestSize) / (16 + cmd.bmp.width * 4); remainingHeight = rect->y2 - rect->y1; top = rect->y1; @@ -259,9 +260,9 @@ rdp_peer_refresh_region(pixman_region32_t *region, freerdp_peer *peer) struct rdp_output *output = rdp_get_first_output(context->rdpBackend); rdpSettings *settings = peer->context->settings; - if (settings->RemoteFxCodec) + if (freerdp_settings_get_bool(settings, FreeRDP_RemoteFxCodec)) rdp_peer_refresh_rfx(region, output->shadow_surface, peer); - else if (settings->NSCodec) + else if (freerdp_settings_get_bool(settings, FreeRDP_NSCodec)) rdp_peer_refresh_nsc(region, output->shadow_surface, peer); else rdp_peer_refresh_raw(region, output->shadow_surface, peer); @@ -398,17 +399,17 @@ rdp_output_set_mode(struct weston_output *base, struct weston_mode *mode) */ wl_list_for_each(rdpPeer, &b->peers, link) { settings = rdpPeer->peer->context->settings; - if (settings->DesktopWidth == (uint32_t)mode->width && - settings->DesktopHeight == (uint32_t)mode->height) + if (freerdp_settings_get_uint32(settings, FreeRDP_DesktopWidth) == (uint32_t)mode->width && + freerdp_settings_get_uint32(settings, FreeRDP_DesktopHeight) == (uint32_t)mode->height) continue; - if (!settings->DesktopResize) { + if (!freerdp_settings_get_bool(settings, FreeRDP_DesktopResize)) { /* too bad this peer does not support desktop resize */ weston_log("desktop resize is not allowed\n"); rdpPeer->peer->Close(rdpPeer->peer); } else { - settings->DesktopWidth = mode->width; - settings->DesktopHeight = mode->height; + freerdp_settings_set_uint32(settings, FreeRDP_DesktopWidth, mode->width); + freerdp_settings_set_uint32(settings, FreeRDP_DesktopHeight, mode->height); rdpPeer->peer->context->update->DesktopResize(rdpPeer->peer->context); } } @@ -758,9 +759,16 @@ rdp_peer_context_new(freerdp_peer* client, RdpPeerContext* context) if (!context->rfx_context) return FALSE; +#if USE_FREERDP_VERSION >= 3 + rfx_context_set_mode(context->rfx_context, RLGR3); + rfx_context_reset(context->rfx_context, + freerdp_settings_get_uint32(client->context->settings, FreeRDP_DesktopWidth), + freerdp_settings_get_uint32(client->context->settings, FreeRDP_DesktopHeight)); +#else context->rfx_context->mode = RLGR3; context->rfx_context->width = client->context->settings->DesktopWidth; context->rfx_context->height = client->context->settings->DesktopHeight; +#endif rfx_context_set_pixel_format(context->rfx_context, DEFAULT_PIXEL_FORMAT); context->nsc_context = nsc_context_new(); @@ -1015,7 +1023,7 @@ convert_rdp_keyboard_to_xkb_rule_names(UINT32 KeyboardType, xkbRuleNames->variant = "kr104"; /* kr(ralt_hangul)/kr(rctrl_hanja) */ else if (KeyboardSubType == 6) /* PC/AT 103 Enhanced Korean Keyboard */ xkbRuleNames->variant = "kr106"; /* kr(hw_keys) */ - } else if (KeyboardType != KBD_TYPE_JAPANESE && ((KeyboardLayout & 0xFFFF) == 0x411)) { + } else if (KeyboardType != WINPR_KBD_TYPE_JAPANESE && ((KeyboardLayout & 0xFFFF) == 0x411)) { /* when Japanese keyboard layout is used without a Japanese 106/109 * keyboard (keyboard type 7), use the "us" layout, since the "jp" * layout in xkb expects the Japanese 106/109 keyboard layout. @@ -1061,6 +1069,8 @@ xf_peer_activate(freerdp_peer* client) char seat_name[50]; POINTER_SYSTEM_UPDATE pointer_system; int width, height; + const char *cl_hostname; + BOOL audio_playback, audio_capture; peerCtx = (RdpPeerContext *)client->context; b = peerCtx->rdpBackend; @@ -1068,31 +1078,32 @@ xf_peer_activate(freerdp_peer* client) output = rdp_get_first_output(b); settings = client->context->settings; - if (!settings->SurfaceCommandsEnabled) { + if (!freerdp_settings_get_bool(settings, FreeRDP_SurfaceCommandsEnabled)) { weston_log("client doesn't support required SurfaceCommands\n"); return FALSE; } - if (b->force_no_compression && settings->CompressionEnabled) { + if (b->force_no_compression && freerdp_settings_get_bool(settings, FreeRDP_CompressionEnabled)) { rdp_debug(b, "Forcing compression off\n"); - settings->CompressionEnabled = FALSE; + freerdp_settings_set_bool(settings, FreeRDP_CompressionEnabled, FALSE); } - settings->AudioPlayback = b->audio_out_setup && b->audio_out_teardown; - settings->AudioCapture = b->audio_in_setup && b->audio_in_teardown; + audio_playback = b->audio_out_setup && b->audio_out_teardown; + freerdp_settings_set_bool(settings, FreeRDP_AudioPlayback, audio_playback); + audio_capture = b->audio_in_setup && b->audio_in_teardown; + freerdp_settings_set_bool(settings, FreeRDP_AudioCapture, audio_capture); - if (settings->RedirectClipboard || - settings->AudioPlayback || - settings->AudioCapture) { + if (freerdp_settings_get_bool(settings, FreeRDP_RedirectClipboard) || + audio_playback || audio_capture) { if (!peerCtx->vcm) { weston_log("Virtual channel is required for clipboard, audio playback/capture\n"); goto error_exit; } /* Audio setup will return NULL on failure, and we'll proceed without audio */ - if (settings->AudioPlayback) + if (audio_playback) peerCtx->audio_out_private = b->audio_out_setup(b->compositor, peerCtx->vcm); - if (settings->AudioCapture) + if (audio_capture) peerCtx->audio_in_private = b->audio_in_setup(b->compositor, peerCtx->vcm); } @@ -1103,15 +1114,15 @@ xf_peer_activate(freerdp_peer* client) if (!b->resizeable) { struct weston_mode *mode = output->base.current_mode; - if (mode->width != (int)settings->DesktopWidth || - mode->height != (int)settings->DesktopHeight) { - if (!settings->DesktopResize) { + if (mode->width != (int)freerdp_settings_get_uint32(settings, FreeRDP_DesktopWidth) || + mode->height != (int)freerdp_settings_get_uint32(settings, FreeRDP_DesktopHeight)) { + if (!freerdp_settings_get_bool(settings, FreeRDP_DesktopResize)) { /* peer does not support desktop resize */ weston_log("client doesn't support resizing, closing connection\n"); return FALSE; } else { - settings->DesktopWidth = mode->width; - settings->DesktopHeight = mode->height; + freerdp_settings_set_uint32(settings, FreeRDP_DesktopWidth, mode->width); + freerdp_settings_set_uint32(settings, FreeRDP_DesktopHeight, mode->height); client->context->update->DesktopResize(client->context); } } @@ -1130,12 +1141,14 @@ xf_peer_activate(freerdp_peer* client) /* when here it's the first reactivation, we need to setup a little more */ rdp_debug(b, "kbd_layout:0x%x kbd_type:0x%x kbd_subType:0x%x kbd_functionKeys:0x%x\n", - settings->KeyboardLayout, settings->KeyboardType, settings->KeyboardSubType, - settings->KeyboardFunctionKey); + freerdp_settings_get_uint32(settings, FreeRDP_KeyboardLayout), + freerdp_settings_get_uint32(settings, FreeRDP_KeyboardType), + freerdp_settings_get_uint32(settings, FreeRDP_KeyboardSubType), + freerdp_settings_get_uint32(settings, FreeRDP_KeyboardFunctionKey)); - convert_rdp_keyboard_to_xkb_rule_names(settings->KeyboardType, - settings->KeyboardSubType, - settings->KeyboardLayout, + convert_rdp_keyboard_to_xkb_rule_names(freerdp_settings_get_uint32(settings, FreeRDP_KeyboardType), + freerdp_settings_get_uint32(settings, FreeRDP_KeyboardSubType), + freerdp_settings_get_uint32(settings, FreeRDP_KeyboardLayout), &xkbRuleNames); keymap = NULL; @@ -1144,10 +1157,12 @@ xf_peer_activate(freerdp_peer* client) &xkbRuleNames, 0); } - if (settings->ClientHostname) - snprintf(seat_name, sizeof(seat_name), "RDP %s", settings->ClientHostname); + cl_hostname = freerdp_settings_get_string(settings, FreeRDP_ClientHostname); + if (cl_hostname) + snprintf(seat_name, sizeof(seat_name), "RDP %s", cl_hostname); else - snprintf(seat_name, sizeof(seat_name), "RDP peer @%s", settings->ClientAddress); + snprintf(seat_name, sizeof(seat_name), "RDP peer @%s", + freerdp_settings_get_string(settings, FreeRDP_ClientAddress)); peersItem->seat = zalloc(sizeof(*peersItem->seat)); if (!peersItem->seat) { @@ -1162,7 +1177,7 @@ xf_peer_activate(freerdp_peer* client) weston_seat_init_pointer(peersItem->seat); /* Initialize RDP clipboard after seat is initialized */ - if (settings->RedirectClipboard) + if (freerdp_settings_get_bool(settings, FreeRDP_RedirectClipboard)) if (rdp_clipboard_init(client) != 0) goto error_exit; @@ -1181,10 +1196,10 @@ error_exit: rdp_clipboard_destroy(peerCtx); - if (settings->AudioPlayback && peerCtx->audio_out_private) + if (audio_playback && peerCtx->audio_out_private) b->audio_out_teardown(peerCtx->audio_out_private); - if (settings->AudioCapture && peerCtx->audio_in_private) + if (audio_capture && peerCtx->audio_in_private) b->audio_in_teardown(peerCtx->audio_in_private); return FALSE; @@ -1502,7 +1517,7 @@ xf_input_synchronize_event(rdpInput *input, UINT32 flags) static BOOL -xf_input_keyboard_event(rdpInput *input, UINT16 flags, UINT16 code) +xf_input_keyboard_event(rdpInput *input, UINT16 flags, XF_KEV_CODE_TYPE code) { uint32_t scan_code, vk_code, full_code; enum wl_keyboard_key_state keyState; @@ -1512,15 +1527,23 @@ xf_input_keyboard_event(rdpInput *input, UINT16 flags, UINT16 code) int notify = 0; struct timespec time; - if (!(peerContext->item.flags & RDP_PEER_ACTIVATED)) - return TRUE; + rdp_debug_verbose(peerContext->rdpBackend, "RDP backend: %s flags:0x%x, code:0x%x\n", + __func__, flags, code); - if (flags & KBD_FLAGS_DOWN) { - keyState = WL_KEYBOARD_KEY_STATE_PRESSED; - notify = 1; - } else if (flags & KBD_FLAGS_RELEASE) { + if (!(peerContext->item.flags & RDP_PEER_ACTIVATED)) { + rdp_debug_verbose(peerContext->rdpBackend, " -> NOT ACTIVATED\n"); + return TRUE; + } + + /* Note: With FreeRDP 3.x, we seem to have KBD_FLAGS_RELEASE set when + * releasing a key and *NO* flag set when pressing... + */ + else if (flags & KBD_FLAGS_RELEASE) { keyState = WL_KEYBOARD_KEY_STATE_RELEASED; notify = 1; + } else if ((USE_FREERDP_VERSION >= 3) || flags & KBD_FLAGS_DOWN) { + keyState = WL_KEYBOARD_KEY_STATE_PRESSED; + notify = 1; } if (notify) { @@ -1531,8 +1554,8 @@ xf_input_keyboard_event(rdpInput *input, UINT16 flags, UINT16 code) /* Korean keyboard support: * WinPR's GetVirtualKeyCodeFromVirtualScanCode() can't handle hangul/hanja keys * hanja and hangeul keys are only present on Korean 103 keyboard (Type 8:SubType 6) */ - if (client->context->settings->KeyboardType == 8 && - client->context->settings->KeyboardSubType == 6 && + if (freerdp_settings_get_uint32(client->context->settings, FreeRDP_KeyboardType) == 8 && + freerdp_settings_get_uint32(client->context->settings, FreeRDP_KeyboardSubType) == 6 && ((full_code == (KBD_FLAGS_EXTENDED | ATKBD_RET_HANJA)) || (full_code == (KBD_FLAGS_EXTENDED | ATKBD_RET_HANGEUL)))) { if (full_code == (KBD_FLAGS_EXTENDED | ATKBD_RET_HANJA)) @@ -1552,7 +1575,10 @@ xf_input_keyboard_event(rdpInput *input, UINT16 flags, UINT16 code) } send_release_key = true; } else { - vk_code = GetVirtualKeyCodeFromVirtualScanCode(full_code, client->context->settings->KeyboardType); + vk_code = GetVirtualKeyCodeFromVirtualScanCode(full_code, + freerdp_settings_get_uint32(client->context->settings, + FreeRDP_KeyboardType)); + rdp_debug_verbose(peerContext->rdpBackend, " -> vk_code=0x%x\n", vk_code); } /* Korean keyboard support */ /* WinPR's GetKeycodeFromVirtualKeyCode() expects no extended bit for VK_HANGUL and VK_HANJA */ @@ -1560,7 +1586,7 @@ xf_input_keyboard_event(rdpInput *input, UINT16 flags, UINT16 code) if (flags & KBD_FLAGS_EXTENDED) vk_code |= KBDEXT; - scan_code = GetKeycodeFromVirtualKeyCode(vk_code, KEYCODE_TYPE_EVDEV); + scan_code = GetKeycodeFromVirtualKeyCode(vk_code, WINPR_KEYCODE_TYPE_XKB); /*weston_log("code=%x ext=%d vk_code=%x scan_code=%x\n", code, (flags & KBD_FLAGS_EXTENDED) ? 1 : 0, vk_code, scan_code);*/ @@ -1617,14 +1643,21 @@ xf_peer_adjust_monitor_layout(freerdp_peer *client) unsigned int i; rdp_debug(b, "%s:\n", __func__); - rdp_debug(b, " DesktopWidth:%d, DesktopHeight:%d\n", settings->DesktopWidth, settings->DesktopHeight); - rdp_debug(b, " UseMultimon:%d\n", settings->UseMultimon); - rdp_debug(b, " ForceMultimon:%d\n", settings->ForceMultimon); - rdp_debug(b, " MonitorCount:%d\n", settings->MonitorCount); - rdp_debug(b, " HasMonitorAttributes:%d\n", settings->HasMonitorAttributes); - rdp_debug(b, " HiDefRemoteApp:%d\n", settings->HiDefRemoteApp); + rdp_debug(b, " DesktopWidth:%d, DesktopHeight:%d\n", + freerdp_settings_get_uint32(settings, FreeRDP_DesktopWidth), + freerdp_settings_get_uint32(settings, FreeRDP_DesktopHeight)); + rdp_debug(b, " UseMultimon:%d\n", + freerdp_settings_get_bool(settings, FreeRDP_UseMultimon)); + rdp_debug(b, " ForceMultimon:%d\n", + freerdp_settings_get_bool(settings, FreeRDP_ForceMultimon)); + rdp_debug(b, " MonitorCount:%d\n", + freerdp_settings_get_uint32(settings, FreeRDP_MonitorCount)); + rdp_debug(b, " HasMonitorAttributes:%d\n", + freerdp_settings_get_bool(settings, FreeRDP_HasMonitorAttributes)); + rdp_debug(b, " HiDefRemoteApp:%d\n", + freerdp_settings_get_bool(settings, FreeRDP_HiDefRemoteApp)); - if (settings->MonitorCount > 1) { + if (freerdp_settings_get_uint32(settings, FreeRDP_MonitorCount) > 1) { weston_log("multiple monitor is not supported"); fallback = true; } @@ -1632,18 +1665,19 @@ xf_peer_adjust_monitor_layout(freerdp_peer *client) if (!b->resizeable) fallback = true; - if (settings->MonitorCount > RDP_MAX_MONITOR) { + if (freerdp_settings_get_uint32(settings, FreeRDP_MonitorCount) > RDP_MAX_MONITOR) { weston_log("Client reports more monitors then expected:(%d)\n", - settings->MonitorCount); + freerdp_settings_get_uint32(settings, FreeRDP_MonitorCount)); return FALSE; } - if ((settings->MonitorCount > 0 && settings->MonitorDefArray) && !fallback) { - rdpMonitor *rdp_monitor = settings->MonitorDefArray; - monitor_count = settings->MonitorCount; + if ((freerdp_settings_get_uint32(settings, FreeRDP_MonitorCount) > 0 && + freerdp_settings_get_pointer(settings, FreeRDP_MonitorDefArray)) && !fallback) { + const rdpMonitor *rdp_monitor = freerdp_settings_get_pointer(settings, FreeRDP_MonitorDefArray); + monitor_count = freerdp_settings_get_uint32(settings, FreeRDP_MonitorCount); monitors = xmalloc(sizeof(*monitors) * monitor_count); for (i = 0; i < monitor_count; i++) { monitors[i] = rdp_monitor[i]; - if (!settings->HasMonitorAttributes) { + if (!freerdp_settings_get_bool(settings, FreeRDP_HasMonitorAttributes)) { monitors[i].attributes.physicalWidth = 0; monitors[i].attributes.physicalHeight = 0; monitors[i].attributes.orientation = ORIENTATION_LANDSCAPE; @@ -1657,14 +1691,19 @@ xf_peer_adjust_monitor_layout(freerdp_peer *client) /* when no monitor array provided, generate from desktop settings */ monitors[0].x = 0; monitors[0].y = 0; - monitors[0].width = settings->DesktopWidth; - monitors[0].height = settings->DesktopHeight; + monitors[0].width = freerdp_settings_get_uint32(settings, FreeRDP_DesktopWidth); + monitors[0].height = freerdp_settings_get_uint32(settings, FreeRDP_DesktopHeight); monitors[0].is_primary = 1; - monitors[0].attributes.physicalWidth = settings->DesktopPhysicalWidth; - monitors[0].attributes.physicalHeight = settings->DesktopPhysicalHeight; - monitors[0].attributes.orientation = settings->DesktopOrientation; - monitors[0].attributes.desktopScaleFactor = settings->DesktopScaleFactor; - monitors[0].attributes.deviceScaleFactor = settings->DeviceScaleFactor; + monitors[0].attributes.physicalWidth = + freerdp_settings_get_uint32(settings, FreeRDP_DesktopPhysicalWidth); + monitors[0].attributes.physicalHeight = + freerdp_settings_get_uint32(settings, FreeRDP_DesktopPhysicalHeight); + monitors[0].attributes.orientation = + freerdp_settings_get_uint16(settings, FreeRDP_DesktopOrientation); + monitors[0].attributes.desktopScaleFactor = + freerdp_settings_get_uint32(settings, FreeRDP_DesktopScaleFactor); + monitors[0].attributes.deviceScaleFactor = + freerdp_settings_get_uint32(settings, FreeRDP_DeviceScaleFactor); monitors[0].orig_screen = 0; if (!b->resizeable) { @@ -1703,7 +1742,30 @@ rdp_peer_init(freerdp_peer *client, struct rdp_backend *b) peerCtx->rdpBackend = b; settings = client->context->settings; +#if USE_FREERDP_VERSION >= 3 /* configure security settings */ + if (b->rdp_key) { + rdpPrivateKey* key = freerdp_key_new_from_file(b->rdp_key); + if (!key) + goto error_initialize; + if (!freerdp_settings_set_pointer_len(settings, FreeRDP_RdpServerRsaKey, key, 1)) + goto error_initialize; + } + if (b->tls_enabled) { + rdpCertificate* cert = freerdp_certificate_new_from_file(b->server_cert); + if (!cert) + goto error_initialize; + if (!freerdp_settings_set_pointer_len(settings, FreeRDP_RdpServerCertificate, cert, 1)) + goto error_initialize; + rdpPrivateKey* key = freerdp_key_new_from_file(b->server_key); + if (!key) + goto error_initialize; + if (!freerdp_settings_set_pointer_len(settings, FreeRDP_RdpServerRsaKey, key, 1)) + goto error_initialize; + } else { + freerdp_settings_set_bool(settings, FreeRDP_TlsSecurity, FALSE); + } +#else if (b->rdp_key) settings->RdpKeyFile = strdup(b->rdp_key); if (b->tls_enabled) { @@ -1712,31 +1774,32 @@ rdp_peer_init(freerdp_peer *client, struct rdp_backend *b) } else { settings->TlsSecurity = FALSE; } - settings->NlaSecurity = FALSE; +#endif + freerdp_settings_set_bool(settings, FreeRDP_NlaSecurity, FALSE); if (!client->Initialize(client)) { weston_log("peer initialization failed\n"); goto error_initialize; } - settings->OsMajorType = OSMAJORTYPE_UNIX; - settings->OsMinorType = OSMINORTYPE_PSEUDO_XSERVER; - settings->ColorDepth = 32; - settings->RefreshRect = TRUE; - settings->RemoteFxCodec = b->remotefx_codec; - settings->NSCodec = TRUE; - settings->FrameMarkerCommandEnabled = TRUE; - settings->SurfaceFrameMarkerEnabled = TRUE; - settings->RedirectClipboard = TRUE; - settings->HasExtendedMouseEvent = TRUE; - settings->HasHorizontalWheel = TRUE; + freerdp_settings_set_uint32(settings, FreeRDP_OsMajorType, OSMAJORTYPE_UNIX); + freerdp_settings_set_uint32(settings, FreeRDP_OsMinorType, OSMINORTYPE_PSEUDO_XSERVER); + freerdp_settings_set_uint32(settings, FreeRDP_ColorDepth, 32); + freerdp_settings_set_bool(settings, FreeRDP_RefreshRect, TRUE); + freerdp_settings_set_bool(settings, FreeRDP_RemoteFxCodec, b->remotefx_codec); + freerdp_settings_set_bool(settings, FreeRDP_NSCodec, TRUE); + freerdp_settings_set_bool(settings, FreeRDP_FrameMarkerCommandEnabled, TRUE); + freerdp_settings_set_bool(settings, FreeRDP_SurfaceFrameMarkerEnabled, TRUE); + freerdp_settings_set_bool(settings, FreeRDP_RedirectClipboard, TRUE); + freerdp_settings_set_bool(settings, FreeRDP_HasExtendedMouseEvent, TRUE); + freerdp_settings_set_bool(settings, FreeRDP_HasHorizontalWheel, TRUE); client->Capabilities = xf_peer_capabilities; client->PostConnect = xf_peer_post_connect; client->Activate = xf_peer_activate; if (b->resizeable) { - settings->SupportMonitorLayoutPdu = TRUE; + freerdp_settings_set_bool(settings, FreeRDP_SupportMonitorLayoutPdu, TRUE); client->AdjustMonitorsLayout = xf_peer_adjust_monitor_layout; } @@ -1793,6 +1856,7 @@ error_dispatch_initialize: peerCtx->vcm = NULL; } + error_initialize: client->Close(client); return -1; diff --git a/libweston/backend-rdp/rdp.h b/libweston/backend-rdp/rdp.h index 818c316d..541579fe 100644 --- a/libweston/backend-rdp/rdp.h +++ b/libweston/backend-rdp/rdp.h @@ -27,6 +27,14 @@ #ifndef RDP_H #define RDP_H +/* Workaround an issue with clang and freerdp 3 headers. Another + * option would be to build with --std=c11 but weston itself isn't + * quite ready for that + */ +#if USE_FREERDP_VERSION >= 3 && defined(__clang__) +#pragma clang diagnostic ignored "-Wtypedef-redefinition" +#endif + #include #include @@ -44,6 +52,8 @@ #include #include +#include + #include "backend.h" #include "shared/helpers.h" @@ -68,6 +78,17 @@ #define ATKBD_RET_HANJA 0xf1 #define ATKBD_RET_HANGEUL 0xf2 +/* freerdp2 vs 3 compat */ +#if USE_FREERDP_VERSION >= 3 +#define FORM_DATA_RESP_COMM(r, f) (r).common.f +#define XF_KEV_CODE_TYPE UINT8 +#else +#define FORM_DATA_RESP_COMM(r, f) (r).f +#define WINPR_KBD_TYPE_JAPANESE KBD_TYPE_JAPANESE +#define WINPR_KEYCODE_TYPE_XKB KEYCODE_TYPE_EVDEV +#define XF_KEV_CODE_TYPE UINT16 +#endif + struct rdp_backend { struct weston_backend base; struct weston_compositor *compositor; diff --git a/libweston/backend-rdp/rdpclip.c b/libweston/backend-rdp/rdpclip.c index 27660efd..ce5708f4 100644 --- a/libweston/backend-rdp/rdpclip.c +++ b/libweston/backend-rdp/rdpclip.c @@ -37,6 +37,8 @@ #include "rdp.h" +#include + #include "libweston-internal.h" /* From MSDN, RegisterClipboardFormat API. @@ -194,10 +196,14 @@ clipboard_process_text_utf8(struct rdp_clipboard_data_source *source, bool is_se source->data_contents.size++; /* obtain size in UNICODE */ +#if USE_FREERDP_VERSION >= 3 + data_size = ConvertUtf8NToWChar(data, source->data_contents.size, NULL, 0); +#else data_size = MultiByteToWideChar(CP_UTF8, 0, data, source->data_contents.size, NULL, 0); +#endif if (data_size < 1) goto error_return; @@ -206,11 +212,18 @@ clipboard_process_text_utf8(struct rdp_clipboard_data_source *source, bool is_se goto error_return; /* convert to UNICODE */ +#if USE_FREERDP_VERSION >= 3 + data_size_in_char = ConvertUtf8NToWChar(data, + source->data_contents.size, + data_contents.data, + data_size); +#else data_size_in_char = MultiByteToWideChar(CP_UTF8, 0, data, source->data_contents.size, data_contents.data, data_size); +#endif assert(data_contents.size == (data_size_in_char * 2)); } else { /* Windows to Linux (UNICODE to utf-8) */ @@ -226,11 +239,17 @@ clipboard_process_text_utf8(struct rdp_clipboard_data_source *source, bool is_se goto error_return; /* obtain size in utf-8 */ +#if USE_FREERDP_VERSION >= 3 + data_size = ConvertWCharNToUtf8(source->data_contents.data, + data_size_in_char, + NULL, 0); +#else data_size = WideCharToMultiByte(CP_UTF8, 0, source->data_contents.data, data_size_in_char, NULL, 0, NULL, NULL); +#endif if (data_size < 1) goto error_return; @@ -238,12 +257,19 @@ clipboard_process_text_utf8(struct rdp_clipboard_data_source *source, bool is_se goto error_return; /* convert to utf-8 */ +#if USE_FREERDP_VERSION >= 3 + data_size = ConvertWCharNToUtf8(source->data_contents.data, + data_size_in_char, + data_contents.data, + data_size); +#else data_size = WideCharToMultiByte(CP_UTF8, 0, source->data_contents.data, data_size_in_char, data_contents.data, data_size, NULL, NULL); +#endif assert(data_contents.size == data_size); } @@ -721,9 +747,9 @@ clipboard_client_send_format_data_response(RdpPeerContext *ctx, struct rdp_clipb clipboard_supported_formats[source->format_index].mime_type, source->processed_data_size); - formatDataResponse.msgType = CB_FORMAT_DATA_RESPONSE; - formatDataResponse.msgFlags = CB_RESPONSE_OK; - formatDataResponse.dataLen = source->processed_data_size; + FORM_DATA_RESP_COMM(formatDataResponse, msgType) = CB_FORMAT_DATA_RESPONSE; + FORM_DATA_RESP_COMM(formatDataResponse, msgFlags) = CB_RESPONSE_OK; + FORM_DATA_RESP_COMM(formatDataResponse, dataLen) = source->processed_data_size; formatDataResponse.requestedFormatData = source->processed_data_start; ctx->clipboard_server_context->ServerFormatDataResponse(ctx->clipboard_server_context, &formatDataResponse); /* if here failed to send response, what can we do ? */ @@ -745,9 +771,9 @@ clipboard_client_send_format_data_response_fail(RdpPeerContext *ctx, struct rdp_ source->data_response_fail_count++; } - formatDataResponse.msgType = CB_FORMAT_DATA_RESPONSE; - formatDataResponse.msgFlags = CB_RESPONSE_FAIL; - formatDataResponse.dataLen = 0; + FORM_DATA_RESP_COMM(formatDataResponse, msgType) = CB_FORMAT_DATA_RESPONSE; + FORM_DATA_RESP_COMM(formatDataResponse, msgFlags) = CB_RESPONSE_FAIL; + FORM_DATA_RESP_COMM(formatDataResponse, dataLen) = 0; formatDataResponse.requestedFormatData = NULL; ctx->clipboard_server_context->ServerFormatDataResponse(ctx->clipboard_server_context, &formatDataResponse); /* if here failed to send response, what can we do ? */ @@ -1098,8 +1124,8 @@ clipboard_data_source_send(struct weston_data_source *base, /* update requesting format property */ source->format_index = index; /* request clipboard data from client */ - formatDataRequest.msgType = CB_FORMAT_DATA_REQUEST; - formatDataRequest.dataLen = 4; + FORM_DATA_RESP_COMM(formatDataRequest, msgType) = CB_FORMAT_DATA_REQUEST; + FORM_DATA_RESP_COMM(formatDataRequest, dataLen) = 4; formatDataRequest.requestedFormatId = source->client_format_id_table[index]; source->state = RDP_CLIPBOARD_SOURCE_REQUEST_DATA; rdp_debug_clipboard(b, "RDP %s (%p:%s) request data \"%s\" index:%d formatId:%d %s\n", @@ -1389,7 +1415,7 @@ clipboard_set_selection(struct wl_listener *listener, void *data) if (num_supported_format) { /* let client knows formats are available in server clipboard */ - formatList.msgType = CB_FORMAT_LIST; + FORM_DATA_RESP_COMM(formatList, msgType) = CB_FORMAT_LIST; formatList.numFormats = num_supported_format; formatList.formats = &format[0]; ctx->clipboard_server_context->ServerFormatList(ctx->clipboard_server_context, &formatList); @@ -1527,9 +1553,9 @@ clipboard_client_format_list(CliprdrServerContext *context, const CLIPRDR_FORMAT rdp_dispatch_task_to_display_loop(ctx, clipboard_data_source_publish, &source->task_base); fail: - formatListResponse.msgType = CB_FORMAT_LIST_RESPONSE; - formatListResponse.msgFlags = source ? CB_RESPONSE_OK : CB_RESPONSE_FAIL; - formatListResponse.dataLen = 0; + FORM_DATA_RESP_COMM(formatListResponse, msgType) = CB_FORMAT_LIST_RESPONSE; + FORM_DATA_RESP_COMM(formatListResponse, msgFlags) = source ? CB_RESPONSE_OK : CB_RESPONSE_FAIL; + FORM_DATA_RESP_COMM(formatListResponse, dataLen) = 0; if (ctx->clipboard_server_context->ServerFormatListResponse(ctx->clipboard_server_context, &formatListResponse) != 0) { source->state = RDP_CLIPBOARD_SOURCE_FAILED; weston_log("Client: %s (%p:%s) ServerFormatListResponse failed\n", @@ -1555,8 +1581,8 @@ clipboard_client_format_data_response(CliprdrServerContext *context, const CLIPR rdp_debug_clipboard(b, "Client: %s (%p:%s) flags:%d dataLen:%d\n", __func__, source, clipboard_data_source_state_to_string(source), - formatDataResponse->msgFlags, - formatDataResponse->dataLen); + FORM_DATA_RESP_COMM(*formatDataResponse, msgFlags), + FORM_DATA_RESP_COMM(*formatDataResponse, dataLen)); assert_not_compositor_thread(b); @@ -1574,13 +1600,13 @@ clipboard_client_format_data_response(CliprdrServerContext *context, const CLIPR return -1; } - if (formatDataResponse->msgFlags == CB_RESPONSE_OK) { + if (FORM_DATA_RESP_COMM(*formatDataResponse, msgFlags) == CB_RESPONSE_OK) { /* Recieved data from client, cache to data source */ - if (wl_array_add(&source->data_contents, formatDataResponse->dataLen+1)) { + if (wl_array_add(&source->data_contents, FORM_DATA_RESP_COMM(*formatDataResponse, dataLen)+1)) { memcpy(source->data_contents.data, formatDataResponse->requestedFormatData, - formatDataResponse->dataLen); - source->data_contents.size = formatDataResponse->dataLen; + FORM_DATA_RESP_COMM(*formatDataResponse, dataLen)); + source->data_contents.size = FORM_DATA_RESP_COMM(*formatDataResponse, dataLen); /* regardless data type, make sure it ends with NULL */ ((char *)source->data_contents.data)[source->data_contents.size] = '\0'; /* data is ready, waiting to be written to destination */ @@ -1621,7 +1647,8 @@ clipboard_client_format_list_response(CliprdrServerContext *context, RdpPeerContext *ctx = (RdpPeerContext *)client->context; struct rdp_backend *b = ctx->rdpBackend; - rdp_debug_clipboard(b, "Client: %s msgFlags:0x%x\n", __func__, formatListResponse->msgFlags); + rdp_debug_clipboard(b, "Client: %s msgFlags:0x%x\n", __func__, + FORM_DATA_RESP_COMM(*formatListResponse, msgFlags)); assert_not_compositor_thread(b); return 0; }