diff options
Diffstat (limited to 'client')
38 files changed, 325 insertions, 286 deletions
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index fcb0d40..1a8f347 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -92,6 +92,11 @@ if(WITH_CLIENT) endforeach() endif() +if (WITH_FUSE) + list(APPEND FREERDP_CLIENT_PC_PRIVATE_LIBS "-lfuse3") +endif() + +list(JOIN FREERDP_CLIENT_PC_PRIVATE_LIBS " " FREERDP_CLIENT_PC_PRIVATE_LIBS) include(pkg-config-install-prefix) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/freerdp-client.pc.in ${CMAKE_CURRENT_BINARY_DIR}/freerdp-client${FREERDP_VERSION_MAJOR}.pc @ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/freerdp-client${FREERDP_VERSION_MAJOR}.pc DESTINATION ${PKG_CONFIG_PC_INSTALL_DIR}) diff --git a/client/FreeRDP-ClientConfig.cmake.in b/client/FreeRDP-ClientConfig.cmake.in index 35b74c1..409dbed 100644 --- a/client/FreeRDP-ClientConfig.cmake.in +++ b/client/FreeRDP-ClientConfig.cmake.in @@ -1,6 +1,9 @@ include(CMakeFindDependencyMacro) find_dependency(WinPR @FREERDP_VERSION@) find_dependency(FreeRDP @FREERDP_VERSION@) +if("@WITH_SMARTCARD_EMULATE@") + find_dependency(ZLIB) +endif() @PACKAGE_INIT@ diff --git a/client/SDL/CMakeLists.txt b/client/SDL/CMakeLists.txt index 6d2b778..0b3aa1b 100644 --- a/client/SDL/CMakeLists.txt +++ b/client/SDL/CMakeLists.txt @@ -46,7 +46,7 @@ option(WITH_WIN_CONSOLE "Build ${PROJECT_NAME} with console support" ON) option(WITH_SDL_LINK_SHARED "link SDL dynamic or static" ON) if(WITH_WIN_CONSOLE) - set(WIN32_GUI_FLAG "") + set(WIN32_GUI_FLAG "TRUE") else() set(WIN32_GUI_FLAG "WIN32") endif() @@ -113,14 +113,8 @@ else() list(APPEND LIBS ${SDL2_LIBRARIES}) endif() -add_executable(${PROJECT_NAME} - ${WIN32_GUI_FLAG} - ${SRCS} - ) +AddTargetWithResourceFile(${PROJECT_NAME} "${WIN32_GUI_FLAG}" "${PROJECT_VERSION}" SRCS) -if (WITH_BINARY_VERSIONING) - set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "${PROJECT_NAME}${PROJECT_VERSION_MAJOR}") -endif() target_link_libraries(${PROJECT_NAME} PRIVATE ${LIBS}) set_property(TARGET ${PROJECT_NAME} PROPERTY FOLDER "Client/SDL") install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT client) diff --git a/client/SDL/dialogs/res/convert_res_to_c.cpp b/client/SDL/dialogs/res/convert_res_to_c.cpp index 07309d5..8ef828a 100644 --- a/client/SDL/dialogs/res/convert_res_to_c.cpp +++ b/client/SDL/dialogs/res/convert_res_to_c.cpp @@ -79,6 +79,10 @@ static int readwrite(std::ofstream& out, std::ifstream& ifs) { size_t pos = 0; char c = 0; + + std::ios backup(nullptr); + backup.copyfmt(out); + while (ifs.read(&c, 1) && ifs.good()) { unsigned val = c & 0xff; @@ -89,6 +93,8 @@ static int readwrite(std::ofstream& out, std::ifstream& ifs) out << std::endl; } + out.copyfmt(backup); + return 0; } diff --git a/client/SDL/dialogs/res/sdl_resource_manager.cpp b/client/SDL/dialogs/res/sdl_resource_manager.cpp index 90ccf31..0f0682a 100644 --- a/client/SDL/dialogs/res/sdl_resource_manager.cpp +++ b/client/SDL/dialogs/res/sdl_resource_manager.cpp @@ -49,7 +49,7 @@ SDL_RWops* SDLResourceManager::get(const std::string& type, const std::string& i << fs::absolute(path) << std::endl; std::cerr << "file not found, application will fail" << std::endl; } - return SDL_RWFromFile(path.native().c_str(), "rb"); + return SDL_RWFromFile(path.u8string().c_str(), "rb"); #endif } diff --git a/client/SDL/dialogs/sdl_connection_dialog.cpp b/client/SDL/dialogs/sdl_connection_dialog.cpp index cbb6349..56c3853 100644 --- a/client/SDL/dialogs/sdl_connection_dialog.cpp +++ b/client/SDL/dialogs/sdl_connection_dialog.cpp @@ -164,6 +164,7 @@ bool SDLConnectionDialog::clearWindow(SDL_Renderer* renderer) bool SDLConnectionDialog::update(SDL_Renderer* renderer) { + std::lock_guard lock(_mux); if (!renderer) return false; @@ -217,7 +218,7 @@ bool SDLConnectionDialog::handle(const SDL_Event& event) case SDL_KEYUP: if (visible()) { - auto ev = reinterpret_cast<const SDL_KeyboardEvent&>(event); + auto& ev = reinterpret_cast<const SDL_KeyboardEvent&>(event); update(_renderer); switch (event.key.keysym.sym) { @@ -244,7 +245,7 @@ bool SDLConnectionDialog::handle(const SDL_Event& event) case SDL_MOUSEMOTION: if (visible()) { - auto ev = reinterpret_cast<const SDL_MouseMotionEvent&>(event); + auto& ev = reinterpret_cast<const SDL_MouseMotionEvent&>(event); _buttons.set_mouseover(event.button.x, event.button.y); update(_renderer); @@ -255,7 +256,7 @@ bool SDLConnectionDialog::handle(const SDL_Event& event) case SDL_MOUSEBUTTONUP: if (visible()) { - auto ev = reinterpret_cast<const SDL_MouseButtonEvent&>(event); + auto& ev = reinterpret_cast<const SDL_MouseButtonEvent&>(event); update(_renderer); auto button = _buttons.get_selected(event.button); @@ -274,7 +275,7 @@ bool SDLConnectionDialog::handle(const SDL_Event& event) case SDL_MOUSEWHEEL: if (visible()) { - auto ev = reinterpret_cast<const SDL_MouseWheelEvent&>(event); + auto& ev = reinterpret_cast<const SDL_MouseWheelEvent&>(event); update(_renderer); return windowID == ev.windowID; } @@ -283,7 +284,7 @@ bool SDLConnectionDialog::handle(const SDL_Event& event) case SDL_FINGERDOWN: if (visible()) { - auto ev = reinterpret_cast<const SDL_TouchFingerEvent&>(event); + auto& ev = reinterpret_cast<const SDL_TouchFingerEvent&>(event); update(_renderer); #if SDL_VERSION_ATLEAST(2, 0, 18) return windowID == ev.windowID; @@ -294,7 +295,7 @@ bool SDLConnectionDialog::handle(const SDL_Event& event) return false; case SDL_WINDOWEVENT: { - auto ev = reinterpret_cast<const SDL_WindowEvent&>(event); + auto& ev = reinterpret_cast<const SDL_WindowEvent&>(event); switch (ev.event) { case SDL_WINDOWEVENT_CLOSE: diff --git a/client/SDL/man/CMakeLists.txt b/client/SDL/man/CMakeLists.txt index 1fb2adc..e2dfd7a 100644 --- a/client/SDL/man/CMakeLists.txt +++ b/client/SDL/man/CMakeLists.txt @@ -5,8 +5,4 @@ set(DEPS sdl-freerdp-envvar.1.xml ) -set(MANPAGE_NAME ${PROJECT_NAME}) -if (WITH_BINARY_VERSIONING) - set(MANPAGE_NAME ${PROJECT_NAME}${PROJECT_VERSION_MAJOR}) -endif() -generate_and_install_freerdp_man_from_xml(${PROJECT_NAME}.1 ${MANPAGE_NAME}.1 "${DEPS}") +generate_and_install_freerdp_man_from_xml(${PROJECT_NAME} "1" "${FREERDP_API_VERSION}" "${DEPS}") diff --git a/client/SDL/man/sdl-freerdp.1.xml.in b/client/SDL/man/sdl-freerdp.1.xml.in index c4b9918..ba5b6cb 100644 --- a/client/SDL/man/sdl-freerdp.1.xml.in +++ b/client/SDL/man/sdl-freerdp.1.xml.in @@ -3,7 +3,6 @@ PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ <!ENTITY syntax SYSTEM "freerdp-argument.1.xml"> - <!ENTITY channels SYSTEM "sdl-freerdp-channels.1.xml"> <!ENTITY config SYSTEM "sdl-freerdp-config.1.xml"> <!ENTITY envvar SYSTEM "sdl-freerdp-envvar.1.xml"> <!ENTITY examples SYSTEM "sdl-freerdp-examples.1.xml"> @@ -50,8 +49,6 @@ PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" &syntax; - &channels; - &config; &envvar; diff --git a/client/SDL/sdl_freerdp.cpp b/client/SDL/sdl_freerdp.cpp index 890bf77..b157d3d 100644 --- a/client/SDL/sdl_freerdp.cpp +++ b/client/SDL/sdl_freerdp.cpp @@ -1301,7 +1301,7 @@ terminate: default: { std::lock_guard<CriticalSection> lock(sdl->critical); - if (sdl->connection_dialog) + if (sdl->connection_dialog && error_msg) sdl->connection_dialog->showError(error_msg); } break; diff --git a/client/SDL/sdl_kbd.cpp b/client/SDL/sdl_kbd.cpp index 4d62389..984614e 100644 --- a/client/SDL/sdl_kbd.cpp +++ b/client/SDL/sdl_kbd.cpp @@ -380,7 +380,7 @@ BOOL sdlInput::keyboard_set_ime_status(rdpContext* context, UINT16 imeId, UINT32 uint32_t sdlInput::prefToMask() { - const std::map<std::string, SDL_Keymod> mapping = { + const std::map<std::string, uint32_t> mapping = { { "KMOD_LSHIFT", KMOD_LSHIFT }, { "KMOD_RSHIFT", KMOD_RSHIFT }, { "KMOD_LCTRL", KMOD_LCTRL }, diff --git a/client/SDL/sdl_monitor.cpp b/client/SDL/sdl_monitor.cpp index e637b48..c857028 100644 --- a/client/SDL/sdl_monitor.cpp +++ b/client/SDL/sdl_monitor.cpp @@ -189,7 +189,7 @@ static BOOL sdl_apply_display_properties(SdlContext* sdl) for (UINT32 x = 0; x < numIds; x++) { - auto id = static_cast<const UINT32*>( + auto id = static_cast<const int*>( freerdp_settings_get_pointer_array(settings, FreeRDP_MonitorIds, x)); WINPR_ASSERT(id); @@ -198,8 +198,17 @@ static BOOL sdl_apply_display_properties(SdlContext* sdl) float vdpi = 1.0f; SDL_Rect rect = {}; - SDL_GetDisplayBounds(*id, &rect); - SDL_GetDisplayDPI(*id, &ddpi, &hdpi, &vdpi); + if (SDL_GetDisplayBounds(*id, &rect) < 0) + return FALSE; + + if (SDL_GetDisplayDPI(*id, &ddpi, &hdpi, &vdpi) < 0) + return FALSE; + + WINPR_ASSERT(rect.w > 0); + WINPR_ASSERT(rect.h > 0); + WINPR_ASSERT(ddpi > 0); + WINPR_ASSERT(hdpi > 0); + WINPR_ASSERT(vdpi > 0); bool highDpi = hdpi > 100; diff --git a/client/SDL/sdl_window.cpp b/client/SDL/sdl_window.cpp index c5437bc..1706d33 100644 --- a/client/SDL/sdl_window.cpp +++ b/client/SDL/sdl_window.cpp @@ -186,9 +186,9 @@ bool SdlWindow::blit(SDL_Surface* surface, const SDL_Rect& srcRect, SDL_Rect& ds if (!screen || !surface) return false; if (!SDL_SetClipRect(surface, &srcRect)) - return false; + return true; if (!SDL_SetClipRect(screen, &dstRect)) - return false; + return true; auto rc = SDL_BlitScaled(surface, &srcRect, screen, &dstRect); if (rc != 0) { diff --git a/client/Sample/CMakeLists.txt b/client/Sample/CMakeLists.txt index db4e947..dfef11b 100644 --- a/client/Sample/CMakeLists.txt +++ b/client/Sample/CMakeLists.txt @@ -45,23 +45,7 @@ set(SRCS tf_freerdp.h tf_freerdp.c) -# On windows create dll version information. -# Vendor, product and year are already set in top level CMakeLists.txt -if (WIN32) - set (RC_VERSION_MAJOR ${FREERDP_VERSION_MAJOR}) - set (RC_VERSION_MINOR ${FREERDP_VERSION_MINOR}) - set (RC_VERSION_BUILD ${FREERDP_VERSION_REVISION}) - set (RC_VERSION_FILE "${PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}" ) - - configure_file( - ${PROJECT_SOURCE_DIR}/../../cmake/WindowsDLLVersion.rc.in - ${CMAKE_CURRENT_BINARY_DIR}/version.rc - @ONLY) - -list (APPEND SRCS ${CMAKE_CURRENT_BINARY_DIR}/version.rc) -endif() - -add_executable(${PROJECT_NAME} ${SRCS}) +AddTargetWithResourceFile(${PROJECT_NAME} TRUE "${PROJECT_VERSION}" SRCS) set(LIBS freerdp-client @@ -70,8 +54,5 @@ set(LIBS ) target_link_libraries(${PROJECT_NAME} PRIVATE ${LIBS}) -if (WITH_BINARY_VERSIONING) - set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "${PROJECT_NAME}${PROJECT_VERSION_MAJOR}") -endif() set_property(TARGET ${PROJECT_NAME} PROPERTY FOLDER "Client/Sample") install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT client) diff --git a/client/Wayland/CMakeLists.txt b/client/Wayland/CMakeLists.txt index 7076ff1..41226ba 100644 --- a/client/Wayland/CMakeLists.txt +++ b/client/Wayland/CMakeLists.txt @@ -46,17 +46,11 @@ endif() list (APPEND ${MODULE_PREFIX}_LIBS freerdp-client freerdp uwac) -add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) +AddTargetWithResourceFile(${MODULE_NAME} TRUE ${FREERDP_VERSION} ${MODULE_PREFIX}_SRCS) -set(MANPAGE_NAME ${MODULE_NAME}) -if (WITH_BINARY_VERSIONING) - set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME "${MODULE_NAME}${FREERDP_API_VERSION}") - set(MANPAGE_NAME ${MODULE_NAME}${FREERDP_API_VERSION}) -endif() target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT client) set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Client/Wayland") -configure_file(wlfreerdp.1.in ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE_NAME}.1) -install_freerdp_man(${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE_NAME}.1 1) +generate_and_install_freerdp_man_from_template(${MODULE_NAME} "1" "${FREERDP_API_VERSION}") diff --git a/client/Wayland/wlf_cliprdr.c b/client/Wayland/wlf_cliprdr.c index dc189d5..f0c3318 100644 --- a/client/Wayland/wlf_cliprdr.c +++ b/client/Wayland/wlf_cliprdr.c @@ -849,6 +849,7 @@ wlf_cliprdr_server_format_data_response(CliprdrClientContext* context, ClipboardLock(clipboard->system); EnterCriticalSection(&clipboard->lock); + BYTE* cdata = NULL; UINT32 srcFormatId = 0; UINT32 dstFormatId = 0; switch (request->responseFormat) @@ -895,14 +896,14 @@ wlf_cliprdr_server_format_data_response(CliprdrClientContext* context, const BOOL sres = ClipboardSetData(clipboard->system, srcFormatId, data, size); if (sres) - data = ClipboardGetData(clipboard->system, dstFormatId, &len); + cdata = ClipboardGetData(clipboard->system, dstFormatId, &len); - if (!sres || !data) + if (!sres || !cdata) goto unlock; if (request->responseFile) { - const size_t res = fwrite(data, 1, len, request->responseFile); + const size_t res = fwrite(cdata, 1, len, request->responseFile); if (res == len) rc = CHANNEL_RC_OK; } @@ -910,6 +911,7 @@ wlf_cliprdr_server_format_data_response(CliprdrClientContext* context, rc = CHANNEL_RC_OK; unlock: + free(cdata); ClipboardUnlock(clipboard->system); LeaveCriticalSection(&clipboard->lock); fail: diff --git a/client/Wayland/wlfreerdp.c b/client/Wayland/wlfreerdp.c index 037c999..3007d41 100644 --- a/client/Wayland/wlfreerdp.c +++ b/client/Wayland/wlfreerdp.c @@ -224,29 +224,29 @@ static BOOL wl_pre_connect(freerdp* instance) static BOOL wl_post_connect(freerdp* instance) { - rdpGdi* gdi = NULL; - UwacWindow* window = NULL; - wlfContext* context = NULL; - rdpSettings* settings = NULL; - char* title = "FreeRDP"; - char* app_id = "wlfreerdp"; - UINT32 w = 0; - UINT32 h = 0; - if (!instance || !instance->context) return FALSE; - context = (wlfContext*)instance->context; - settings = instance->context->settings; + wlfContext* context = (wlfContext*)instance->context; + WINPR_ASSERT(context); + rdpSettings* settings = instance->context->settings; + WINPR_ASSERT(settings); + + const char* title = "FreeRDP"; const char* wtitle = freerdp_settings_get_string(settings, FreeRDP_WindowTitle); if (wtitle) title = wtitle; + const char* app_id = "wlfreerdp"; + const char* wmclass = freerdp_settings_get_string(settings, FreeRDP_WmClass); + if (wmclass) + app_id = wmclass; + if (!gdi_init(instance, PIXEL_FORMAT_BGRA32)) return FALSE; - gdi = instance->context->gdi; + rdpGdi* gdi = instance->context->gdi; if (!gdi || (gdi->width < 0) || (gdi->height < 0)) return FALSE; @@ -254,8 +254,8 @@ static BOOL wl_post_connect(freerdp* instance) if (!wlf_register_pointer(instance->context->graphics)) return FALSE; - w = (UINT32)gdi->width; - h = (UINT32)gdi->height; + UINT32 w = (UINT32)gdi->width; + UINT32 h = (UINT32)gdi->height; if (freerdp_settings_get_bool(settings, FreeRDP_SmartSizing) && !context->fullscreen) { @@ -268,15 +268,16 @@ static BOOL wl_post_connect(freerdp* instance) h = sh; } - context->window = window = UwacCreateWindowShm(context->display, w, h, WL_SHM_FORMAT_XRGB8888); + context->window = UwacCreateWindowShm(context->display, w, h, WL_SHM_FORMAT_XRGB8888); - if (!window) + if (!context->window) return FALSE; UwacWindowSetFullscreenState( - window, NULL, freerdp_settings_get_bool(instance->context->settings, FreeRDP_Fullscreen)); - UwacWindowSetTitle(window, title); - UwacWindowSetAppId(window, app_id); + context->window, NULL, + freerdp_settings_get_bool(instance->context->settings, FreeRDP_Fullscreen)); + UwacWindowSetTitle(context->window, title); + UwacWindowSetAppId(context->window, app_id); UwacWindowSetOpaqueRegion(context->window, 0, 0, w, h); instance->context->update->EndPaint = wl_end_paint; instance->context->update->DesktopResize = wl_resize_display; diff --git a/client/X11/CMakeLists.txt b/client/X11/CMakeLists.txt index 099d00d..bf7c842 100644 --- a/client/X11/CMakeLists.txt +++ b/client/X11/CMakeLists.txt @@ -21,7 +21,7 @@ if (NOT FREERDP_DEFAULT_PROJECT_VERSION) set(FREERDP_DEFAULT_PROJECT_VERSION "1.0.0.0") endif() -project(xfreerdp +project(xfreerdp-client LANGUAGES C VERSION ${FREERDP_DEFAULT_PROJECT_VERSION} ) @@ -84,29 +84,14 @@ if (CHANNEL_TSMF_CLIENT) ) endif() -if(WITH_CLIENT_INTERFACE) - if(CLIENT_INTERFACE_SHARED) - add_library(${PROJECT_NAME} SHARED ${SRCS}) - if (WITH_LIBRARY_VERSIONING) - set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${FREERDP_VERSION} SOVERSION ${FREERDP_API_VERSION}) - endif() - else() - add_library(${PROJECT_NAME} ${SRCS}) - endif() - target_include_directories(${PROJECT_NAME} INTERFACE $<INSTALL_INTERFACE:include>) - +if(CLIENT_INTERFACE_SHARED) + AddTargetWithResourceFile(${PROJECT_NAME} "SHARED" "${PROJECT_VERSION}" SRCS) else() - list(APPEND SRCS - cli/xfreerdp.c xfreerdp.h - ) - add_executable(${PROJECT_NAME} ${SRCS}) - if (WITH_BINARY_VERSIONING) - set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "${PROJECT_NAME}${PROJECT_VERSION_MAJOR}") - endif() - include_directories(..) + AddTargetWithResourceFile(${PROJECT_NAME} "STATIC" "${PROJECT_VERSION}" SRCS) endif() +target_include_directories(${PROJECT_NAME} INTERFACE $<INSTALL_INTERFACE:include>) -set(LIBS +set(PRIV_LIBS ${X11_LIBRARIES} ) @@ -116,7 +101,7 @@ find_package(X11 REQUIRED) if(X11_XShm_FOUND) add_definitions(-DWITH_XSHM) include_directories(${X11_XShm_INCLUDE_PATH}) - list(APPEND LIBS + list(APPEND PRIV_LIBS ${X11_Xext_LIB} ) endif() @@ -128,7 +113,7 @@ if (WITH_XINERAMA) if(X11_Xinerama_FOUND) add_definitions(-DWITH_XINERAMA) include_directories(${X11_Xinerama_INCLUDE_PATH}) - list(APPEND LIBS + list(APPEND PRIV_LIBS ${X11_Xinerama_LIB} ) endif() @@ -139,7 +124,7 @@ if (WITH_XEXT) find_package(X11 REQUIRED) if(X11_Xext_FOUND) add_definitions(-DWITH_XEXT) - list(APPEND LIBS + list(APPEND PRIV_LIBS ${X11_Xext_LIB} ) endif() @@ -151,7 +136,7 @@ if (WITH_XCURSOR) if(X11_Xcursor_FOUND) add_definitions(-DWITH_XCURSOR) include_directories(${X11_Xcursor_INCLUDE_PATH}) - list(APPEND LIBS + list(APPEND PRIV_LIBS ${X11_Xcursor_LIB} ) endif() @@ -163,7 +148,7 @@ if (WITH_XV) if(X11_Xv_FOUND) add_definitions(-DWITH_XV) include_directories(${X11_Xv_INCLUDE_PATH}) - list(APPEND LIBS + list(APPEND PRIV_LIBS ${X11_Xv_LIB} ) endif() @@ -175,7 +160,7 @@ if (WITH_XI) if(X11_Xi_FOUND) add_definitions(-DWITH_XI) include_directories(${X11_Xi_INCLUDE_PATH}) - list(APPEND LIBS + list(APPEND PRIV_LIBS ${X11_Xi_LIB} ) endif() @@ -187,7 +172,7 @@ if(WITH_XRENDER) if(X11_Xrender_FOUND) add_definitions(-DWITH_XRENDER) include_directories(${X11_Xrender_INCLUDE_PATH}) - list(APPEND LIBS + list(APPEND PRIV_LIBS ${X11_Xrender_LIB} ) endif() @@ -199,7 +184,7 @@ if (WITH_XRANDR) if(X11_Xrandr_FOUND) add_definitions(-DWITH_XRANDR) include_directories(${X11_Xrandr_INCLUDE_PATH}) - list(APPEND LIBS + list(APPEND PRIV_LIBS ${X11_Xrandr_LIB} ) endif() @@ -211,7 +196,7 @@ if (WITH_XFIXES) if(X11_Xfixes_FOUND) add_definitions(-DWITH_XFIXES) include_directories(${X11_Xfixes_INCLUDE_PATH}) - list(APPEND LIBS + list(APPEND PRIV_LIBS ${X11_Xfixes_LIB} ) endif() @@ -219,27 +204,23 @@ endif() include_directories(${PROJECT_SOURCE_DIR}/resources) -list(APPEND LIBS +list(APPEND PUB_LIBS freerdp-client - freerdp +) + +list(APPEND PRIV_LIBS m ) if (NOT APPLE) - list(APPEND LIBS rt) + list(APPEND PRIV_LIBS rt) endif() -target_link_libraries(${PROJECT_NAME} PRIVATE ${LIBS}) +target_link_libraries(${PROJECT_NAME} PUBLIC ${PUB_LIBS}) +target_link_libraries(${PROJECT_NAME} PRIVATE ${PRIV_LIBS}) -if(WITH_IPP) - target_link_libraries(${PROJECT_NAME} PRIVATE ${IPP_LIBRARY_LIST}) -endif() - -option(WITH_CLIENT_INTERFACE "Build clients as a library with an interface" OFF) if(WITH_CLIENT_INTERFACE) install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libraries) - add_subdirectory(cli) -else() - install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT client) endif() +add_subdirectory(cli) set_property(TARGET ${PROJECT_NAME} PROPERTY FOLDER "Client/X11") diff --git a/client/X11/cli/CMakeLists.txt b/client/X11/cli/CMakeLists.txt index 580337b..0761b2f 100644 --- a/client/X11/cli/CMakeLists.txt +++ b/client/X11/cli/CMakeLists.txt @@ -15,32 +15,20 @@ # See the License for the specific language governing permissions and # limitations under the License. -set(MODULE_NAME "xfreerdp-cli") +set(MODULE_NAME "xfreerdp") set(MODULE_PREFIX "FREERDP_CLIENT_X11") set(SRCS - xfreerdp.c + xfreerdp.c ) -add_executable(${MODULE_NAME} ${SRCS}) - -if (WITH_BINARY_VERSIONING) - set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME "xfreerdp${PROJECT_VERSION_MAJOR}") -else() - set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME "xfreerdp") -endif() +AddTargetWithResourceFile(${MODULE_NAME} TRUE "${PROJECT_VERSION}" SRCS) set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "..") list(APPEND LIBS - xfreerdp-client freerdp-client + xfreerdp-client ) -if(OPENBSD) - list(APPEND LIBS - ossaudio - ) -endif() - target_link_libraries(${MODULE_NAME} PRIVATE ${LIBS}) install(TARGETS ${MODULE_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT client) diff --git a/client/X11/cli/xfreerdp.c b/client/X11/cli/xfreerdp.c index 33b2a96..4bdaf4c 100644 --- a/client/X11/cli/xfreerdp.c +++ b/client/X11/cli/xfreerdp.c @@ -31,6 +31,25 @@ #include "../xf_client.h" #include "../xfreerdp.h" +static void xfreerdp_print_help(void) +{ + printf("Keyboard Shortcuts:\n"); + printf("\t<Right CTRL>\n"); + printf("\t\treleases keyboard and mouse grab\n"); + printf("\t<CTRL>+<ALT>+<Return>\n"); + printf("\t\ttoggles fullscreen state of the application\n"); + printf("\t<CTRL>+<ALT>+c\n"); + printf("\t\ttoggles remote control in a remote assistance session\n"); + printf("\tAction Script\n"); + printf("\t\tExecutes a predefined script on key press.\n"); + printf("\t\tShould the script not exist it is ignored.\n"); + printf("\t\tScripts can be provided at the default localtion ~/.config/freerdp/action.sh or as " + "command line argument /action:script:<path>\n"); + printf("\t\tThe script will receive the current key combination as argument.\n"); + printf("\t\tThe output of the script is parsed for 'key-local' which tells that the script " + "used the key combination, otherwise the combination is forwarded to the remote.\n"); +} + int main(int argc, char* argv[]) { int rc = 1; @@ -59,6 +78,8 @@ int main(int argc, char* argv[]) { rc = freerdp_client_settings_command_line_status_print(settings, status, argc, argv); + xfreerdp_print_help(); + if (freerdp_settings_get_bool(settings, FreeRDP_ListMonitors)) xf_list_monitors(xfc); diff --git a/client/X11/man/CMakeLists.txt b/client/X11/man/CMakeLists.txt index 386f13d..ed50e63 100644 --- a/client/X11/man/CMakeLists.txt +++ b/client/X11/man/CMakeLists.txt @@ -1,11 +1,8 @@ set(DEPS xfreerdp-channels.1.xml xfreerdp-examples.1.xml + xfreerdp-shortcuts.1.xml xfreerdp-envvar.1.xml ) -set(MANPAGE_NAME ${PROJECT_NAME}) -if (WITH_BINARY_VERSIONING) - set(MANPAGE_NAME ${PROJECT_NAME}${PROJECT_VERSION_MAJOR}) -endif() -generate_and_install_freerdp_man_from_xml(${PROJECT_NAME}.1 ${MANPAGE_NAME}.1 ${DEPS}) +generate_and_install_freerdp_man_from_xml("xfreerdp" "1" "${FREERDP_API_VERSION}" ${DEPS}) diff --git a/client/X11/man/xfreerdp-shortcuts.1.xml b/client/X11/man/xfreerdp-shortcuts.1.xml new file mode 100644 index 0000000..a6b96ea --- /dev/null +++ b/client/X11/man/xfreerdp-shortcuts.1.xml @@ -0,0 +1,25 @@ +<refsect1> + <title>Keyboard Shortcuts</title> + <variablelist> + <varlistentry> + <term><Right CTRL></term> + <listitem><para>releases keyboard and mouse grab</para></listitem> + </varlistentry> + <varlistentry> + <term><CTRL>+<ALT>+<Return></term> + <listitem><para>toggles fullscreen state of the application</para></listitem> + </varlistentry> + <varlistentry> + <term><CTRL>+<ALT>+c</term> + <listitem><para>toggles remote control in a remote assistance session</para></listitem> + </varlistentry> + <varlistentry> + <term>Action Script</term> + <listitem><para>executes a predefined script on key press.</para></listitem> + <listitem><para>Should the script not exist it is ignored.</para></listitem> + <listitem><para>Scripts can be provided at the default localtion ~/.config/freerdp/action.sh or as command line argument /action:script:<path>.</para></listitem> + <listitem><para>The script will receive the current key combination as argument.</para></listitem> + <listitem><para>The output of the script is parsed for key-local which tells that the script used the key combination, otherwise the combination is forwarded to the remote.</para></listitem> + </varlistentry> + </variablelist> +</refsect1> diff --git a/client/X11/man/xfreerdp.1.xml.in b/client/X11/man/xfreerdp.1.xml.in index 271e39d..7e7c782 100644 --- a/client/X11/man/xfreerdp.1.xml.in +++ b/client/X11/man/xfreerdp.1.xml.in @@ -3,6 +3,7 @@ PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ <!ENTITY syntax SYSTEM "freerdp-argument.1.xml"> + <!ENTITY shortcuts SYSTEM "xfreerdp-shortcuts.1.xml"> <!ENTITY channels SYSTEM "xfreerdp-channels.1.xml"> <!ENTITY envvar SYSTEM "xfreerdp-envvar.1.xml"> <!ENTITY examples SYSTEM "xfreerdp-examples.1.xml"> @@ -49,6 +50,8 @@ PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" &syntax; + &shortcuts; + &channels; &envvar; diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index 0f51745..7324bdc 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -1156,11 +1156,10 @@ static BOOL xf_pre_connect(freerdp* instance) { if (!xf_keyboard_init(xfc)) return FALSE; + if (!xf_detect_monitors(xfc, &maxWidth, &maxHeight)) + return FALSE; } - if (!xf_detect_monitors(xfc, &maxWidth, &maxHeight)) - return FALSE; - if (maxWidth && maxHeight && !freerdp_settings_get_bool(settings, FreeRDP_SmartSizing)) { if (!freerdp_settings_set_uint32(settings, FreeRDP_DesktopWidth, maxWidth)) diff --git a/client/X11/xf_cliprdr.c b/client/X11/xf_cliprdr.c index a68dae9..de92b41 100644 --- a/client/X11/xf_cliprdr.c +++ b/client/X11/xf_cliprdr.c @@ -181,7 +181,7 @@ static xfCachedData* xf_cached_data_new(BYTE* data, UINT32 data_length) return cached_data; } -static xfCachedData* xf_cached_data_new_copy(BYTE* data, UINT32 data_length) +static xfCachedData* xf_cached_data_new_copy(const BYTE* data, size_t data_length) { BYTE* copy = NULL; if (data_length > 0) @@ -214,26 +214,28 @@ static void xf_clipboard_free_server_formats(xfClipboard* clipboard) } } -static void xf_cliprdr_check_owner(xfClipboard* clipboard) +static BOOL xf_cliprdr_update_owner(xfClipboard* clipboard) { - Window owner = 0; - xfContext* xfc = NULL; - WINPR_ASSERT(clipboard); - xfc = clipboard->xfc; + xfContext* xfc = clipboard->xfc; WINPR_ASSERT(xfc); - if (clipboard->sync) - { - owner = XGetSelectionOwner(xfc->display, clipboard->clipboard_atom); + if (!clipboard->sync) + return FALSE; - if (clipboard->owner != owner) - { - clipboard->owner = owner; - xf_cliprdr_send_client_format_list(clipboard, FALSE); - } - } + Window owner = XGetSelectionOwner(xfc->display, clipboard->clipboard_atom); + if (clipboard->owner == owner) + return FALSE; + + clipboard->owner = owner; + return TRUE; +} + +static void xf_cliprdr_check_owner(xfClipboard* clipboard) +{ + if (xf_cliprdr_update_owner(clipboard)) + xf_cliprdr_send_client_format_list(clipboard, FALSE); } static BOOL xf_cliprdr_is_self_owned(xfClipboard* clipboard) @@ -580,9 +582,11 @@ static CLIPRDR_FORMAT* xf_cliprdr_get_raw_server_formats(xfClipboard* clipboard, WINPR_ASSERT(xfc); *numFormats = 0; - LogTagAndXGetWindowProperty( - TAG, xfc->display, clipboard->owner, clipboard->raw_format_list_atom, 0, 4096, False, - clipboard->raw_format_list_atom, &type, &format, &length, &remaining, &data); + + Window owner = XGetSelectionOwner(xfc->display, clipboard->clipboard_atom); + LogTagAndXGetWindowProperty(TAG, xfc->display, owner, clipboard->raw_format_list_atom, 0, 4096, + False, clipboard->raw_format_list_atom, &type, &format, &length, + &remaining, &data); if (data && length > 0 && format == 8 && type == clipboard->raw_format_list_atom) { diff --git a/client/X11/xf_event.c b/client/X11/xf_event.c index 6bc4c4d..a00a950 100644 --- a/client/X11/xf_event.c +++ b/client/X11/xf_event.c @@ -41,10 +41,13 @@ #define TAG CLIENT_TAG("x11") #define CLAMP_COORDINATES(x, y) \ - if (x < 0) \ - x = 0; \ - if (y < 0) \ - y = 0 + do \ + { \ + if ((x) < 0) \ + (x) = 0; \ + if ((y) < 0) \ + (y) = 0; \ + } while (0) const char* x11_event_string(int event) { @@ -201,7 +204,7 @@ BOOL xf_event_action_script_init(xfContext* xfc) char* context = NULL; strtok_s(buffer, "\n", &context); - if (!buffer || !ArrayList_Append(xfc->xevents, buffer)) + if (!ArrayList_Append(xfc->xevents, buffer)) { pclose(actionScript); ArrayList_Free(xfc->xevents); @@ -447,7 +450,8 @@ static BOOL xf_event_MotionNotify(xfContext* xfc, const XMotionEvent* event, BOO { WINPR_ASSERT(xfc); - if (xfc->xi_event) + if (xfc->xi_event || + (xfc->common.mouse_grabbed && freerdp_client_use_relative_mouse_events(&xfc->common))) return TRUE; if (xfc->window) @@ -556,7 +560,8 @@ static BOOL xf_event_ButtonPress(xfContext* xfc, const XButtonEvent* event, BOOL { xf_grab_mouse(xfc); - if (xfc->xi_event) + if (xfc->xi_event || + (xfc->common.mouse_grabbed && freerdp_client_use_relative_mouse_events(&xfc->common))) return TRUE; return xf_generic_ButtonEvent(xfc, event->x, event->y, event->button, event->window, app, TRUE); } @@ -565,7 +570,8 @@ static BOOL xf_event_ButtonRelease(xfContext* xfc, const XButtonEvent* event, BO { xf_grab_mouse(xfc); - if (xfc->xi_event) + if (xfc->xi_event || + (xfc->common.mouse_grabbed && freerdp_client_use_relative_mouse_events(&xfc->common))) return TRUE; return xf_generic_ButtonEvent(xfc, event->x, event->y, event->button, event->window, app, FALSE); @@ -645,6 +651,8 @@ static BOOL xf_event_FocusIn(xfContext* xfc, const XFocusInEvent* event, BOOL ap * if the WM decided to use an alternate event order */ if (!app) xf_keyboard_release_all_keypress(xfc); + else + xf_rail_send_activate(xfc, event->window, TRUE); xf_pointer_update_scale(xfc); @@ -673,6 +681,8 @@ static BOOL xf_event_FocusOut(xfContext* xfc, const XFocusOutEvent* event, BOOL XUngrabKeyboard(xfc->display, CurrentTime); xf_keyboard_release_all_keypress(xfc); + if (app) + xf_rail_send_activate(xfc, event->window, FALSE); return TRUE; } diff --git a/client/X11/xf_input.c b/client/X11/xf_input.c index f1cdc83..dfbe051 100644 --- a/client/X11/xf_input.c +++ b/client/X11/xf_input.c @@ -200,7 +200,7 @@ static BOOL register_raw_events(xfContext* xfc, Window window) settings = xfc->common.context.settings; WINPR_ASSERT(settings); - if (freerdp_client_use_relative_mouse_events(&xfc->common)) + if (freerdp_settings_get_bool(settings, FreeRDP_MouseUseRelativeMove)) { XISetMask(mask_bytes, XI_RawMotion); XISetMask(mask_bytes, XI_RawButtonPress); @@ -780,21 +780,26 @@ int xf_input_event(xfContext* xfc, const XEvent* xevent, XIDeviceEvent* event, i switch (evtype) { case XI_ButtonPress: - xfc->xi_event = TRUE; - xf_generic_ButtonEvent(xfc, (int)event->event_x, (int)event->event_y, event->detail, - event->event, xfc->remote_app, TRUE); - break; - case XI_ButtonRelease: - xfc->xi_event = TRUE; - xf_generic_ButtonEvent(xfc, (int)event->event_x, (int)event->event_y, event->detail, - event->event, xfc->remote_app, FALSE); + xfc->xi_event = !xfc->common.mouse_grabbed || + !freerdp_client_use_relative_mouse_events(&xfc->common); + + if (xfc->xi_event) + { + xf_generic_ButtonEvent(xfc, (int)event->event_x, (int)event->event_y, event->detail, + event->event, xfc->remote_app, evtype == XI_ButtonPress); + } break; case XI_Motion: - xfc->xi_event = TRUE; - xf_generic_MotionNotify(xfc, (int)event->event_x, (int)event->event_y, event->detail, - event->event, xfc->remote_app); + xfc->xi_event = !xfc->common.mouse_grabbed || + !freerdp_client_use_relative_mouse_events(&xfc->common); + + if (xfc->xi_event) + { + xf_generic_MotionNotify(xfc, (int)event->event_x, (int)event->event_y, + event->detail, event->event, xfc->remote_app); + } break; case XI_RawButtonPress: case XI_RawButtonRelease: diff --git a/client/X11/xf_keyboard.c b/client/X11/xf_keyboard.c index 9b575c2..cfbd6ca 100644 --- a/client/X11/xf_keyboard.c +++ b/client/X11/xf_keyboard.c @@ -120,7 +120,7 @@ static BOOL xf_keyboard_action_script_init(xfContext* xfc) char* context = NULL; strtok_s(buffer, "\n", &context); - if (!buffer || !ArrayList_Append(xfc->keyCombinations, buffer)) + if (!ArrayList_Append(xfc->keyCombinations, buffer)) { ArrayList_Free(xfc->keyCombinations); xfc->actionScriptExists = FALSE; @@ -180,7 +180,7 @@ void xf_keyboard_key_press(xfContext* xfc, const XKeyEvent* event, KeySym keysym WINPR_ASSERT(xfc); WINPR_ASSERT(event); - WINPR_ASSERT(event->keycode <= ARRAYSIZE(xfc->KeyboardState)); + WINPR_ASSERT(event->keycode < ARRAYSIZE(xfc->KeyboardState)); last = xfc->KeyboardState[event->keycode]; xfc->KeyboardState[event->keycode] = TRUE; @@ -195,7 +195,7 @@ void xf_keyboard_key_release(xfContext* xfc, const XKeyEvent* event, KeySym keys { WINPR_ASSERT(xfc); WINPR_ASSERT(event); - WINPR_ASSERT(event->keycode <= ARRAYSIZE(xfc->KeyboardState)); + WINPR_ASSERT(event->keycode < ARRAYSIZE(xfc->KeyboardState)); BOOL last = xfc->KeyboardState[event->keycode]; xfc->KeyboardState[event->keycode] = FALSE; @@ -555,11 +555,11 @@ BOOL xf_keyboard_handle_special_keys(xfContext* xfc, KeySym keysym) // do not return anything such that the key could be used by client if ungrab is not the goal if (keysym == XK_Control_R) { - if (mod.RightCtrl && xfc->firstPressRightCtrl) + if (mod.RightCtrl && !xfc->wasRightCtrlAlreadyPressed) { // Right Ctrl is pressed, getting ready to ungrab xfc->ungrabKeyboardWithRightCtrl = TRUE; - xfc->firstPressRightCtrl = FALSE; + xfc->wasRightCtrlAlreadyPressed = TRUE; } } else @@ -689,7 +689,7 @@ void xf_keyboard_handle_special_keys_release(xfContext* xfc, KeySym keysym) if (keysym != XK_Control_R) return; - xfc->firstPressRightCtrl = TRUE; + xfc->wasRightCtrlAlreadyPressed = FALSE; if (!xfc->ungrabKeyboardWithRightCtrl) return; diff --git a/client/X11/xf_window.c b/client/X11/xf_window.c index a5e68c7..1d7330d 100644 --- a/client/X11/xf_window.c +++ b/client/X11/xf_window.c @@ -562,6 +562,7 @@ xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int heig else res_class = _strdup("xfreerdp"); + classHints->res_class = res_class; XSetClassHint(xfc->display, window->handle, classHints); XFree(classHints); free(res_class); diff --git a/client/X11/xfreerdp.h b/client/X11/xfreerdp.h index 314c63d..42a2224 100644 --- a/client/X11/xfreerdp.h +++ b/client/X11/xfreerdp.h @@ -277,7 +277,7 @@ struct xf_context button_map button_map[NUM_BUTTONS_MAPPED]; BYTE savedMaximizedState; UINT32 locked; - BOOL firstPressRightCtrl; + BOOL wasRightCtrlAlreadyPressed; BOOL ungrabKeyboardWithRightCtrl; #if defined(WITH_XI) diff --git a/client/common/CMakeLists.txt b/client/common/CMakeLists.txt index 6040bf3..1773533 100644 --- a/client/common/CMakeLists.txt +++ b/client/common/CMakeLists.txt @@ -58,30 +58,9 @@ if(WITH_FUSE) add_definitions(-D_FILE_OFFSET_BITS=64) endif() -# On windows create dll version information. -# Vendor, product and year are already set in top level CMakeLists.txt -if (WIN32 AND BUILD_SHARED_LIBS) - set (RC_VERSION_MAJOR ${FREERDP_VERSION_MAJOR}) - set (RC_VERSION_MINOR ${FREERDP_VERSION_MINOR}) - set (RC_VERSION_BUILD ${FREERDP_VERSION_REVISION}) - set (RC_VERSION_FILE "${CMAKE_SHARED_LIBRARY_PREFIX}${MODULE_NAME}${FREERDP_API_VERSION}${CMAKE_SHARED_LIBRARY_SUFFIX}" ) - - configure_file( - ${PROJECT_SOURCE_DIR}/cmake/WindowsDLLVersion.rc.in - ${CMAKE_CURRENT_BINARY_DIR}/version.rc - @ONLY) - -list (APPEND SRCS ${CMAKE_CURRENT_BINARY_DIR}/version.rc) -endif() - include_directories(${OPENSSL_INCLUDE_DIR}) -add_library(${MODULE_NAME} ${SRCS}) - -set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME ${MODULE_NAME}${FREERDP_API_VERSION}) -if (WITH_LIBRARY_VERSIONING) - set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION} SOVERSION ${FREERDP_API_VERSION}) -endif() +AddTargetWithResourceFile(${MODULE_NAME} FALSE "${FREERDP_VERSION}" SRCS) list(APPEND LIBS freerdp winpr) @@ -94,11 +73,6 @@ install(TARGETS ${MODULE_NAME} COMPONENT libraries EXPORT FreeRDP-ClientTargets LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) -if (WITH_DEBUG_SYMBOLS AND MSVC AND BUILD_SHARED_LIBS) - get_target_property(OUTPUT_FILENAME ${MODULE_NAME} OUTPUT_NAME) - install(FILES ${CMAKE_PDB_BINARY_DIR}/${OUTPUT_FILENAME}.pdb DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT symbols) -endif() - set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Client/Common") if(BUILD_TESTING) diff --git a/client/common/client.c b/client/common/client.c index 9d6ec03..83a5746 100644 --- a/client/common/client.c +++ b/client/common/client.c @@ -1574,8 +1574,9 @@ BOOL freerdp_client_send_button_event(rdpClientContext* cctx, BOOL relative, UIN WINPR_ASSERT(cctx); - const BOOL relativeInput = freerdp_client_use_relative_mouse_events(cctx); - if (relative && relativeInput) + const BOOL haveRelative = + freerdp_settings_get_bool(cctx->context.settings, FreeRDP_HasRelativeMouseEvent); + if (relative && haveRelative) { return freerdp_input_send_rel_mouse_event(cctx->context.input, mflags, x, y); } @@ -1585,7 +1586,7 @@ BOOL freerdp_client_send_button_event(rdpClientContext* cctx, BOOL relative, UIN { UINT64 flags = 0; - if (cctx->mouse_grabbed && relativeInput) + if (cctx->mouse_grabbed && freerdp_client_use_relative_mouse_events(cctx)) flags |= AINPUT_FLAGS_HAVE_REL; if (relative) @@ -1630,7 +1631,9 @@ BOOL freerdp_client_send_extended_button_event(rdpClientContext* cctx, BOOL rela BOOL handled = FALSE; WINPR_ASSERT(cctx); - if (relative && freerdp_client_use_relative_mouse_events(cctx)) + const BOOL haveRelative = + freerdp_settings_get_bool(cctx->context.settings, FreeRDP_HasRelativeMouseEvent); + if (relative && haveRelative) { return freerdp_input_send_rel_mouse_event(cctx->context.input, mflags, x, y); } @@ -2147,8 +2150,8 @@ BOOL freerdp_client_use_relative_mouse_events(rdpClientContext* ccontext) const rdpSettings* settings = ccontext->context.settings; const BOOL useRelative = freerdp_settings_get_bool(settings, FreeRDP_MouseUseRelativeMove); const BOOL haveRelative = freerdp_settings_get_bool(settings, FreeRDP_HasRelativeMouseEvent); - BOOL ainput = false; -#if defined(CHANNEL_AINPUT_SERVER) + BOOL ainput = FALSE; +#if defined(CHANNEL_AINPUT_CLIENT) ainput = ccontext->ainput != NULL; #endif diff --git a/client/common/client_cliprdr_file.c b/client/common/client_cliprdr_file.c index 9b3ee22..df9226f 100644 --- a/client/common/client_cliprdr_file.c +++ b/client/common/client_cliprdr_file.c @@ -353,7 +353,6 @@ static BOOL maybe_clear_fuse_request(const void* key, void* value, void* arg) fuse_reply_err(fuse_request->fuse_req, EIO); HashTable_Remove(file_context->request_table, key); - free(fuse_request); return TRUE; } @@ -505,16 +504,15 @@ static void clear_no_cdi_entry(CliprdrFileContext* file_context) { WINPR_ASSERT(file_context); - if (!file_context->clip_data_entry_without_id) - return; - WINPR_ASSERT(file_context->inode_table); - HashTable_Lock(file_context->inode_table); - clear_entry_selection(file_context->clip_data_entry_without_id); + if (file_context->clip_data_entry_without_id) + { + clear_entry_selection(file_context->clip_data_entry_without_id); - clip_data_entry_free(file_context->clip_data_entry_without_id); - file_context->clip_data_entry_without_id = NULL; + clip_data_entry_free(file_context->clip_data_entry_without_id); + file_context->clip_data_entry_without_id = NULL; + } HashTable_Unlock(file_context->inode_table); } @@ -555,6 +553,7 @@ static UINT prepare_clip_data_entry_with_id(CliprdrFileContext* file_context) { WLog_Print(file_context->log, WLOG_ERROR, "Failed to insert clipDataEntry"); clip_data_entry_free(clip_data_entry); + HashTable_Unlock(file_context->inode_table); return ERROR_INTERNAL_ERROR; } HashTable_Unlock(file_context->inode_table); @@ -748,7 +747,6 @@ static BOOL request_file_size_async(CliprdrFileContext* file_context, CliprdrFus "Failed to send FileContentsRequest for file \"%s\"", fuse_file->filename_with_root); HashTable_Remove(file_context->request_table, (void*)(UINT_PTR)fuse_request->stream_id); - free(fuse_request); return FALSE; } DEBUG_CLIPRDR(file_context->log, "Requested file size for file \"%s\" with stream id %u", @@ -1191,18 +1189,17 @@ static UINT cliprdr_file_context_server_file_contents_response( HashTable_Unlock(file_context->inode_table); return CHANNEL_RC_OK; } - HashTable_Remove(file_context->request_table, - (void*)(UINT_PTR)file_contents_response->streamId); if (!(file_contents_response->common.msgFlags & CB_RESPONSE_OK)) { WLog_Print(file_context->log, WLOG_WARN, "FileContentsRequests for file \"%s\" was unsuccessful", fuse_request->fuse_file->filename); - HashTable_Unlock(file_context->inode_table); fuse_reply_err(fuse_request->fuse_req, EIO); - free(fuse_request); + HashTable_Remove(file_context->request_table, + (void*)(UINT_PTR)file_contents_response->streamId); + HashTable_Unlock(file_context->inode_table); return CHANNEL_RC_OK; } @@ -1213,10 +1210,10 @@ static UINT cliprdr_file_context_server_file_contents_response( WLog_Print(file_context->log, WLOG_WARN, "Received invalid file size for file \"%s\" from the client", fuse_request->fuse_file->filename); - HashTable_Unlock(file_context->inode_table); - fuse_reply_err(fuse_request->fuse_req, EIO); - free(fuse_request); + HashTable_Remove(file_context->request_table, + (void*)(UINT_PTR)file_contents_response->streamId); + HashTable_Unlock(file_context->inode_table); return CHANNEL_RC_OK; } @@ -1258,7 +1255,8 @@ static UINT cliprdr_file_context_server_file_contents_response( break; } - free(fuse_request); + HashTable_Remove(file_context->request_table, + (void*)(UINT_PTR)file_contents_response->streamId); return CHANNEL_RC_OK; } @@ -1806,7 +1804,7 @@ static CliprdrFuseFile* get_parent_directory(CliprdrFileContext* file_context, c static BOOL set_selection_for_clip_data_entry(CliprdrFileContext* file_context, CliprdrFuseClipDataEntry* clip_data_entry, - FILEDESCRIPTORW* files, UINT32 n_files) + const FILEDESCRIPTORW* files, UINT32 n_files) { CliprdrFuseFile* clip_data_dir = NULL; @@ -1826,7 +1824,7 @@ static BOOL set_selection_for_clip_data_entry(CliprdrFileContext* file_context, // NOLINTBEGIN(clang-analyzer-unix.Malloc) HashTable_Insert owns fuse_file for (UINT32 i = 0; i < n_files; ++i) { - FILEDESCRIPTORW* file = &files[i]; + const FILEDESCRIPTORW* file = &files[i]; CliprdrFuseFile* fuse_file = NULL; char* filename = NULL; size_t path_length = 0; @@ -2016,6 +2014,7 @@ BOOL cliprdr_file_context_update_server_data(CliprdrFileContext* file_context, w } HashTable_Unlock(file_context->inode_table); + free(files); return TRUE; #else return FALSE; @@ -2417,9 +2416,16 @@ CliprdrFileContext* cliprdr_file_context_new(void* context) if (!file->inode_table || !file->clip_data_table || !file->request_table) goto fail; - wObject* ctobj = HashTable_ValueObject(file->clip_data_table); - WINPR_ASSERT(ctobj); - ctobj->fnObjectFree = clip_data_entry_free; + { + wObject* ctobj = HashTable_ValueObject(file->request_table); + WINPR_ASSERT(ctobj); + ctobj->fnObjectFree = free; + } + { + wObject* ctobj = HashTable_ValueObject(file->clip_data_table); + WINPR_ASSERT(ctobj); + ctobj->fnObjectFree = clip_data_entry_free; + } file->root_dir = fuse_file_new_root(file); if (!file->root_dir) diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 2ce693b..01d5b37 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -214,18 +214,20 @@ static BOOL freerdp_client_add_drive(rdpSettings* settings, const char* path, co if (!path) goto fail; - else + { BOOL isSpecial = FALSE; BOOL isPath = freerdp_path_valid(path, &isSpecial); if (!isPath && !isSpecial) + { + WLog_WARN(TAG, "Invalid drive to redirect: '%s' does not exist, skipping.", path); + freerdp_device_free(device); + } + else if (!freerdp_device_collection_add(settings, device)) goto fail; } - if (!freerdp_device_collection_add(settings, device)) - goto fail; - return TRUE; fail: @@ -370,7 +372,7 @@ static char* print_token(char* text, size_t start_offset, size_t* current, size_ const size_t tlen = strnlen(text, limit); size_t len = tlen; const SSIZE_T force_at = forced_newline_at(text, len, limit - *current, force_newline); - BOOL isForce = (force_at > 0); + BOOL isForce = (force_at >= 0); if (isForce) len = MIN(len, (size_t)force_at); @@ -394,7 +396,7 @@ static char* print_token(char* text, size_t start_offset, size_t* current, size_ printf("\n"); *current = 0; - const size_t offset = len + (isForce ? 1 : 0); + const size_t offset = len + ((isForce && (force_at == 0)) ? 1 : 0); return &text[offset]; } @@ -411,8 +413,10 @@ static size_t print_optionals(const char* text, size_t start_offset, size_t curr char* str = _strdup(text); char* cur = str; - while ((cur = print_token(cur, start_offset + 1, ¤t, limit, "[], ", "\r\n")) != NULL) - ; + do + { + cur = print_token(cur, start_offset + 1, ¤t, limit, "[], ", "\r\n"); + } while (cur != NULL); free(str); return current; @@ -424,8 +428,10 @@ static size_t print_description(const char* text, size_t start_offset, size_t cu char* str = _strdup(text); char* cur = str; - while ((cur = print_token(cur, start_offset, ¤t, limit, " ", "\r\n")) != NULL) - ; + do + { + cur = print_token(cur, start_offset, ¤t, limit, " ", "\r\n"); + } while (cur != NULL); free(str); current += (size_t)printf("\n"); @@ -895,7 +901,10 @@ static BOOL read_pem_file(rdpSettings* settings, FreeRDP_Settings_Keys_String id size_t length = 0; char* pem = crypto_read_pem(file, &length); if (!pem || (length == 0)) + { + free(pem); return FALSE; + } BOOL rc = freerdp_settings_set_string_len(settings, id, pem, length); free(pem); @@ -1167,6 +1176,14 @@ static int freerdp_client_command_line_post_filter(void* context, COMMAND_LINE_A static BOOL freerdp_parse_username_ptr(const char* username, const char** user, size_t* userlen, const char** domain, size_t* domainlen) { + WINPR_ASSERT(user); + WINPR_ASSERT(userlen); + WINPR_ASSERT(domain); + WINPR_ASSERT(domainlen); + + if (!username) + return FALSE; + const char* p = strchr(username, '\\'); *user = NULL; @@ -1184,7 +1201,7 @@ static BOOL freerdp_parse_username_ptr(const char* username, const char** user, *domain = username; *domainlen = length; } - else if (username) + else { /* Do not break up the name for '@'; both credSSP and the * ClientInfo PDU expect 'user@corp.net' to be transmitted @@ -1193,8 +1210,6 @@ static BOOL freerdp_parse_username_ptr(const char* username, const char** user, *user = username; *userlen = strlen(username); } - else - return FALSE; return TRUE; } @@ -1382,24 +1397,27 @@ BOOL freerdp_set_connection_type(rdpSettings* settings, UINT32 type) static UINT32 freerdp_get_keyboard_layout_for_type(const char* name, DWORD type) { + UINT32 res = 0; size_t count = 0; RDP_KEYBOARD_LAYOUT* layouts = freerdp_keyboard_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_STANDARD, &count); if (!layouts || (count == 0)) - return FALSE; + goto fail; for (size_t x = 0; x < count; x++) { const RDP_KEYBOARD_LAYOUT* layout = &layouts[x]; if (option_equals(layout->name, name)) { - return layout->code; + res = layout->code; + break; } } +fail: freerdp_keyboard_layouts_free(layouts, count); - return 0; + return res; } static UINT32 freerdp_map_keyboard_layout_name_to_id(const char* name) @@ -2308,7 +2326,8 @@ static int parse_codec_cache_options(rdpSettings* settings, const COMMAND_LINE_A } else if (option_equals(arg->Value, "nsc")) { - freerdp_settings_set_bool(settings, FreeRDP_NSCodec, TRUE); + if (!freerdp_settings_set_bool(settings, FreeRDP_NSCodec, TRUE)) + return COMMAND_LINE_ERROR; } #if defined(WITH_JPEG) @@ -2325,6 +2344,7 @@ static int parse_codec_cache_options(rdpSettings* settings, const COMMAND_LINE_A } #endif + return 0; } #endif @@ -3576,18 +3596,18 @@ static int parse_app_options(rdpSettings* settings, const COMMAND_LINE_ARGUMENT_ struct app_map { const char* name; - FreeRDP_Settings_Keys_String id; + SSIZE_T id; int (*fkt)(rdpSettings* settings, const char* value); }; - const struct app_map amap[] = { - { "program:", FreeRDP_RemoteApplicationProgram, parse_app_option_program }, - { "workdir:", FreeRDP_RemoteApplicationWorkingDir, NULL }, - { "name:", FreeRDP_RemoteApplicationName, NULL }, - { "icon:", FreeRDP_RemoteApplicationIcon, NULL }, - { "cmd:", FreeRDP_RemoteApplicationCmdLine, NULL }, - { "file:", FreeRDP_RemoteApplicationFile, NULL }, - { "guid:", FreeRDP_RemoteApplicationGuid, NULL }, - }; + const struct app_map amap[] = { { "program:", FreeRDP_RemoteApplicationProgram, + parse_app_option_program }, + { "workdir:", FreeRDP_RemoteApplicationWorkingDir, NULL }, + { "name:", FreeRDP_RemoteApplicationName, NULL }, + { "icon:", FreeRDP_RemoteApplicationIcon, NULL }, + { "cmd:", FreeRDP_RemoteApplicationCmdLine, NULL }, + { "file:", FreeRDP_RemoteApplicationFile, NULL }, + { "guid:", FreeRDP_RemoteApplicationGuid, NULL }, + { "hidef:", FreeRDP_HiDefRemoteApp, NULL } }; for (size_t x = 0; x < count; x++) { BOOL handled = FALSE; @@ -3601,8 +3621,12 @@ static int parse_app_options(rdpSettings* settings, const COMMAND_LINE_ARGUMENT_ const char* xval = &val[strlen(cur->name)]; if (cur->fkt) rc = cur->fkt(settings, xval); - else if (!freerdp_settings_set_string(settings, cur->id, xval)) - rc = COMMAND_LINE_ERROR_MEMORY; + else + { + const char* name = freerdp_settings_get_name_for_key(cur->id); + if (!freerdp_settings_set_value_for_name(settings, name, xval)) + rc = COMMAND_LINE_ERROR_MEMORY; + } handled = TRUE; break; @@ -4749,11 +4773,14 @@ static int freerdp_client_settings_parse_command_line_arguments_int( "vs-debug") || !freerdp_settings_set_string(settings, FreeRDP_ServerHostname, "localhost") || !freerdp_settings_set_string(settings, FreeRDP_AuthenticationPackageList, "ntlm") || + !freerdp_settings_set_string(settings, FreeRDP_ClientAddress, "0.0.0.0") || !freerdp_settings_set_bool(settings, FreeRDP_NegotiateSecurityLayer, FALSE) || !freerdp_settings_set_bool(settings, FreeRDP_VmConnectMode, TRUE) || !freerdp_settings_set_bool(settings, FreeRDP_ConnectChildSession, TRUE) || !freerdp_settings_set_bool(settings, FreeRDP_NlaSecurity, TRUE) || - !freerdp_settings_set_uint32(settings, FreeRDP_AuthenticationLevel, 0)) + !freerdp_settings_set_uint32(settings, FreeRDP_AuthenticationLevel, 0) || + !freerdp_settings_set_bool(settings, FreeRDP_NetworkAutoDetect, TRUE) || + !freerdp_settings_set_uint32(settings, FreeRDP_ConnectionType, CONNECTION_TYPE_LAN)) return COMMAND_LINE_ERROR_MEMORY; } #endif diff --git a/client/common/cmdline.h b/client/common/cmdline.h index 8186cc6..3afddb1 100644 --- a/client/common/cmdline.h +++ b/client/common/cmdline.h @@ -34,7 +34,7 @@ static const COMMAND_LINE_ARGUMENT_A global_cmd_args[] = { "desktop composition" }, { "app", COMMAND_LINE_VALUE_REQUIRED, "program:[<path>|<||alias>],cmd:<command>,file:<filename>,guid:<guid>,icon:<filename>,name:<" - "name>,workdir:<directory>", + "name>,workdir:<directory>,hidef:[on|off]", NULL, NULL, -1, NULL, "Remote application program" }, #if defined(WITH_FREERDP_DEPRECATED_COMMANDLINE) { "app-cmd", COMMAND_LINE_VALUE_REQUIRED, "<parameters>", NULL, NULL, -1, NULL, diff --git a/client/common/file.c b/client/common/file.c index 760c62e..a72ab41 100644 --- a/client/common/file.c +++ b/client/common/file.c @@ -1309,7 +1309,7 @@ BOOL freerdp_client_populate_rdp_file_from_settings(rdpFile* file, const rdpSett file->RedirectComPorts = (freerdp_settings_get_bool(settings, FreeRDP_RedirectSerialPorts) || freerdp_settings_get_bool(settings, FreeRDP_RedirectParallelPorts)); file->RedirectLocation = - freerdp_dynamic_channel_collection_find(settings, LOCATION_DVC_CHANNEL_NAME) ? TRUE : FALSE; + freerdp_dynamic_channel_collection_find(settings, LOCATION_CHANNEL_NAME) ? TRUE : FALSE; if (!FILE_POPULATE_STRING(&file->DrivesToRedirect, settings, FreeRDP_DrivesToRedirect) || !FILE_POPULATE_STRING(&file->PreconnectionBlob, settings, FreeRDP_PreconnectionBlob) || !FILE_POPULATE_STRING(&file->KdcProxyName, settings, FreeRDP_KerberosKdcUrl)) @@ -2296,13 +2296,18 @@ BOOL freerdp_client_populate_settings_from_rdp_file(const rdpFile* file, rdpSett return FALSE; } - if (~file->RedirectLocation) + if (~file->RedirectLocation && file->RedirectLocation != 0) { size_t count = 0; - char** str = - CommandLineParseCommaSeparatedValuesEx(LOCATION_DVC_CHANNEL_NAME, NULL, &count); - const BOOL rc = freerdp_client_add_dynamic_channel(settings, count, str); - free(str); + union + { + void* pv; + char** str; + const char** cstr; + } cnv; + cnv.str = CommandLineParseCommaSeparatedValuesEx(LOCATION_CHANNEL_NAME, NULL, &count); + const BOOL rc = freerdp_client_add_dynamic_channel(settings, count, cnv.cstr); + free(cnv.pv); if (!rc) return FALSE; } diff --git a/client/common/man/generate_argument_docbook.c b/client/common/man/generate_argument_docbook.c index 156d809..a591dd0 100644 --- a/client/common/man/generate_argument_docbook.c +++ b/client/common/man/generate_argument_docbook.c @@ -15,6 +15,7 @@ static char* resize(char** buffer, size_t* size, size_t increment) fprintf(stderr, "Could not reallocate string buffer from %" PRIuz " to %" PRIuz " bytes.\n", *size, nsize); free(*buffer); + return NULL; } memset(&tmp[*size], '\0', increment); *size = nsize; diff --git a/client/common/test/TestClientCmdLine.c b/client/common/test/TestClientCmdLine.c index 2ce0c47..ba0cfe6 100644 --- a/client/common/test/TestClientCmdLine.c +++ b/client/common/test/TestClientCmdLine.c @@ -191,11 +191,11 @@ static const test tests[] = { check_settings_smartcard_no_redirection, { "testfreerdp", "/list:monitor", 0 }, { { 0 } } }, - { COMMAND_LINE_ERROR, + { 0, check_settings_smartcard_no_redirection, { "testfreerdp", "/sound", "/drive:media:" DRIVE_REDIRECT_PATH, "/v:test.freerdp.com", 0 }, { { 0 } } }, - { COMMAND_LINE_ERROR, + { 0, check_settings_smartcard_no_redirection, { "testfreerdp", "/sound", "/drive:media,/foo/bar/blabla", "/v:test.freerdp.com", 0 }, { { 0 } } }, diff --git a/client/freerdp-client.pc.in b/client/freerdp-client.pc.in index eca4ab8..e446657 100644 --- a/client/freerdp-client.pc.in +++ b/client/freerdp-client.pc.in @@ -11,5 +11,5 @@ Version: @FREERDP_VERSION@ Requires: Requires.private: @WINPR_PKG_CONFIG_FILENAME@ freerdp@FREERDP_VERSION_MAJOR@ Libs: -L${libdir} ${libs} -Libs.private: -ldl -lpthread +Libs.private: -ldl -lpthread @FREERDP_CLIENT_PC_PRIVATE_LIBS@ Cflags: -I${includedir} |