From a312d47599b43db9cc4c11d014f1c98b992464fb Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Sat, 20 Aug 2011 10:02:24 +0800 Subject: [PATCH 1/3] Use named struct rdpChan. --- cunit/test_gcc.c | 2 +- include/freerdp/settings.h | 4 +++- libfreerdp-chanman/libchanman.c | 18 +++++++++--------- libfreerdp-core/vchan.c | 2 +- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/cunit/test_gcc.c b/cunit/test_gcc.c index 7762b7452..bdb9edb7f 100644 --- a/cunit/test_gcc.c +++ b/cunit/test_gcc.c @@ -198,7 +198,7 @@ void test_gcc_write_client_network_data(void) settings = settings_new(); settings->num_channels = 3; - memset(settings->channels, 0, sizeof(struct rdp_chan) * settings->num_channels); + memset(settings->channels, 0, sizeof(rdpChan) * settings->num_channels); strcpy(settings->channels[0].name, "rdpdr"); settings->channels[0].options = 0x80800000; diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index 6be6e28a7..c00c3dede 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -125,8 +125,10 @@ struct rdp_chan char name[8]; /* ui sets */ int options; /* ui sets */ int chan_id; /* core sets */ + boolean joined; /* client has joined the channel */ void * handle; /* just for ui */ }; +typedef struct rdp_chan rdpChan; struct rdp_ext_set { @@ -185,7 +187,7 @@ struct rdp_settings uint32 redirected_session_id; int num_channels; - struct rdp_chan channels[16]; + rdpChan channels[16]; int num_monitors; struct rdp_monitor monitors[16]; diff --git a/libfreerdp-chanman/libchanman.c b/libfreerdp-chanman/libchanman.c index 6fefdf6be..f776a70ef 100644 --- a/libfreerdp-chanman/libchanman.c +++ b/libfreerdp-chanman/libchanman.c @@ -210,13 +210,13 @@ static struct chan_data* freerdp_chanman_find_chan_data_by_name(rdpChanMan* chan return NULL; } -/* returns struct rdp_chan for the channel id passed in */ -static struct rdp_chan* freerdp_chanman_find_rdp_chan_by_id(rdpChanMan* chan_man, +/* returns rdpChan for the channel id passed in */ +static rdpChan* freerdp_chanman_find_rdp_chan_by_id(rdpChanMan* chan_man, rdpSettings* settings, int chan_id, int* pindex) { int lindex; int lcount; - struct rdp_chan* lrdp_chan; + rdpChan* lrdp_chan; lcount = settings->num_channels; for (lindex = 0; lindex < lcount; lindex++) @@ -234,13 +234,13 @@ static struct rdp_chan* freerdp_chanman_find_rdp_chan_by_id(rdpChanMan* chan_man return NULL; } -/* returns struct rdp_chan for the channel name passed in */ -static struct rdp_chan* freerdp_chanman_find_rdp_chan_by_name(rdpChanMan* chan_man, +/* returns rdpChan for the channel name passed in */ +static rdpChan* freerdp_chanman_find_rdp_chan_by_name(rdpChanMan* chan_man, rdpSettings* settings, const char* chan_name, int* pindex) { int lindex; int lcount; - struct rdp_chan* lrdp_chan; + rdpChan* lrdp_chan; lcount = settings->num_channels; for (lindex = 0; lindex < lcount; lindex++) @@ -271,7 +271,7 @@ static uint32 FREERDP_CC MyVirtualChannelInit(void** ppInitHandle, PCHANNEL_DEF int index; struct lib_data* llib; struct chan_data* lchan; - struct rdp_chan* lrdp_chan; + rdpChan* lrdp_chan; PCHANNEL_DEF lchan_def; chan_man = g_init_chan_man; @@ -745,7 +745,7 @@ int freerdp_chanman_data(freerdp* instance, int chan_id, void* data, int data_si int flags, int total_size) { rdpChanMan* chan_man; - struct rdp_chan* lrdp_chan; + rdpChan* lrdp_chan; struct chan_data* lchan_data; int index; @@ -828,7 +828,7 @@ FREERDP_API int freerdp_chanman_send_event(rdpChanMan* chan_man, RDP_EVENT* even static void freerdp_chanman_process_sync(rdpChanMan* chan_man, freerdp* instance) { struct chan_data* lchan_data; - struct rdp_chan* lrdp_chan; + rdpChan* lrdp_chan; struct sync_data* item; while (chan_man->sync_data_list->head != NULL) diff --git a/libfreerdp-core/vchan.c b/libfreerdp-core/vchan.c index d498c6ef1..b587da609 100644 --- a/libfreerdp-core/vchan.c +++ b/libfreerdp-core/vchan.c @@ -32,7 +32,7 @@ boolean vchan_send(rdpVchan* vchan, uint16 channel_id, uint8* data, int size) { STREAM* s; uint32 flags; - struct rdp_chan* channel = NULL; + rdpChan* channel = NULL; int i; int chunk_size; From 4a126a55b042bcde2c6187e80be827bdf1b83d95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Fri, 19 Aug 2011 22:21:09 -0400 Subject: [PATCH 2/3] xfreerdp: handle RAIL window title updates --- client/X11/xf_rail.c | 37 +++++++++++++++++++++++++------------ client/X11/xf_window.c | 3 +++ include/freerdp/rail/rail.h | 2 ++ libfreerdp-rail/window.c | 5 +++++ 4 files changed, 35 insertions(+), 12 deletions(-) diff --git a/client/X11/xf_rail.c b/client/X11/xf_rail.c index cd8abf6bd..a78d7d874 100644 --- a/client/X11/xf_rail.c +++ b/client/X11/xf_rail.c @@ -99,6 +99,17 @@ void xf_rail_MoveWindow(rdpRail* rail, rdpWindow* window) window->windowWidth, window->windowHeight); } +void xf_rail_SetWindowText(rdpRail* rail, rdpWindow* window) +{ + xfInfo* xfi; + xfWindow* xfw; + + xfi = (xfInfo*) rail->extra; + xfw = (xfWindow*) window->extra; + + XStoreName(xfi->display, xfw->handle, window->title); +} + void xf_rail_DestroyWindow(rdpRail* rail, rdpWindow* window) { xfWindow* xfw; @@ -111,6 +122,7 @@ void xf_rail_register_callbacks(xfInfo* xfi, rdpRail* rail) rail->extra = (void*) xfi; rail->CreateWindow = xf_rail_CreateWindow; rail->MoveWindow = xf_rail_MoveWindow; + rail->SetWindowText = xf_rail_SetWindowText; rail->DestroyWindow = xf_rail_DestroyWindow; } @@ -142,21 +154,22 @@ void xf_process_rail_get_sysparams_event(xfInfo* xfi, rdpChanMan* chanman, RDP_E freerdp_chanman_send_event(chanman, new_event); } +const char* error_code_names[] = +{ + "RAIL_EXEC_S_OK", + "RAIL_EXEC_E_HOOK_NOT_LOADED", + "RAIL_EXEC_E_DECODE_FAILED", + "RAIL_EXEC_E_NOT_IN_ALLOWLIST", + "RAIL_EXEC_E_FILE_NOT_FOUND", + "RAIL_EXEC_E_FAIL", + "RAIL_EXEC_E_SESSION_LOCKED" +}; + void xf_process_rail_exec_result_event(xfInfo* xfi, rdpChanMan* chanman, RDP_EVENT* event) { - RAIL_EXEC_RESULT_ORDER * exec_result; - const char* error_code_names[] = - { - "RAIL_EXEC_S_OK", - "RAIL_EXEC_E_HOOK_NOT_LOADED", - "RAIL_EXEC_E_DECODE_FAILED", - "RAIL_EXEC_E_NOT_IN_ALLOWLIST", - "RAIL_EXEC_E_FILE_NOT_FOUND", - "RAIL_EXEC_E_FAIL", - "RAIL_EXEC_E_SESSION_LOCKED" - }; + RAIL_EXEC_RESULT_ORDER* exec_result; - exec_result = (RAIL_EXEC_RESULT_ORDER *)event->user_data; + exec_result = (RAIL_EXEC_RESULT_ORDER*) event->user_data; if (exec_result->execResult != RAIL_EXEC_S_OK) { diff --git a/client/X11/xf_window.c b/client/X11/xf_window.c index 8265e6ba6..429ae352c 100644 --- a/client/X11/xf_window.c +++ b/client/X11/xf_window.c @@ -273,6 +273,9 @@ void xf_MoveWindow(xfInfo* xfi, xfWindow* window, int x, int y, int width, int h Pixmap surface; XSizeHints* size_hints; + if ((width * height) < 1) + return; + size_hints = XAllocSizeHints(); if (size_hints) diff --git a/include/freerdp/rail/rail.h b/include/freerdp/rail/rail.h index e26938b85..8a22a1e19 100644 --- a/include/freerdp/rail/rail.h +++ b/include/freerdp/rail/rail.h @@ -34,6 +34,7 @@ typedef struct rdp_rail rdpRail; typedef void (*railCreateWindow)(rdpRail* rail, rdpWindow* window); typedef void (*railDestroyWindow)(rdpRail* rail, rdpWindow* window); typedef void (*railMoveWindow)(rdpRail* rail, rdpWindow* window); +typedef void (*railSetWindowText)(rdpRail* rail, rdpWindow* window); struct rdp_rail { @@ -43,6 +44,7 @@ struct rdp_rail railCreateWindow CreateWindow; railDestroyWindow DestroyWindow; railMoveWindow MoveWindow; + railSetWindowText SetWindowText; }; FREERDP_API void rail_register_update_callbacks(rdpRail* rail, rdpUpdate* update); diff --git a/libfreerdp-rail/window.c b/libfreerdp-rail/window.c index 68ceec41b..e844d6d07 100644 --- a/libfreerdp-rail/window.c +++ b/libfreerdp-rail/window.c @@ -162,7 +162,12 @@ void rail_UpdateWindow(rdpRail* rail, rdpWindow* window) if (window->fieldFlags & WINDOW_ORDER_FIELD_TITLE) { + if (window->title != NULL) + xfree(window->title); + window->title = freerdp_uniconv_in(rail->uniconv, window->titleInfo.string, window->titleInfo.length); + + IFCALL(rail->SetWindowText, rail, window); } if (window->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) From ec77c8ecbfff9f4728b322b73d0b257005032c1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Fri, 19 Aug 2011 23:15:49 -0400 Subject: [PATCH 3/3] xfreerdp: added support for multiple monitors --- client/X11/CMakeLists.txt | 7 ++++++ client/X11/xfreerdp.c | 50 +++++++++++++++++++++++++++++++++++++++ cmake/FindXinerama.cmake | 49 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+) create mode 100644 cmake/FindXinerama.cmake diff --git a/client/X11/CMakeLists.txt b/client/X11/CMakeLists.txt index 610dcc9e1..7f33b7472 100644 --- a/client/X11/CMakeLists.txt +++ b/client/X11/CMakeLists.txt @@ -30,6 +30,13 @@ add_executable(xfreerdp xf_window.h xfreerdp.c xfreerdp.h) + +find_package(Xinerama) +if(XINERAMA_FOUND) + add_definitions(-DWITH_XINERAMA) + include_directories(${XINERAMA_INCLUDE_DIRS}) + target_link_libraries(xfreerdp ${XINERAMA_LIBRARIES}) +endif() target_link_libraries(xfreerdp freerdp-core) target_link_libraries(xfreerdp freerdp-gdi) diff --git a/client/X11/xfreerdp.c b/client/X11/xfreerdp.c index d39496313..004a5c9a3 100644 --- a/client/X11/xfreerdp.c +++ b/client/X11/xfreerdp.c @@ -20,6 +20,10 @@ #include #include +#ifdef WITH_XINERAMA +#include +#endif + #include #include #include @@ -115,6 +119,11 @@ boolean xf_pre_connect(freerdp* instance) xfInfo* xfi; rdpSettings* settings; +#ifdef WITH_XINERAMA + int n, ignored, ignored2; + XineramaScreenInfo* screen_info = NULL; +#endif + xfi = (xfInfo*) xzalloc(sizeof(xfInfo)); SET_XFI(instance, xfi); @@ -176,6 +185,47 @@ boolean xf_pre_connect(freerdp* instance) settings->height = xfi->workArea.height; } + if (settings->fullscreen != True && settings->workarea != True) + return True; + +#ifdef WITH_XINERAMA + if (XineramaQueryExtension(xfi->display, &ignored, &ignored2)) + { + if (XineramaIsActive(xfi->display)) + { + screen_info = XineramaQueryScreens(xfi->display, &settings->num_monitors); + + if (settings->num_monitors > 16) + settings->num_monitors = 0; + + if (settings->num_monitors) + { + for (n = 0; n < settings->num_monitors; n++) + { + if (settings->workarea) + { + settings->monitors[n].x = screen_info[n].x_org; + settings->monitors[n].y = screen_info[n].y_org; + settings->monitors[n].width = screen_info[n].width; + settings->monitors[n].height = xfi->workArea.height; + } + else + { + settings->monitors[n].x = screen_info[n].x_org; + settings->monitors[n].y = screen_info[n].y_org; + settings->monitors[n].width = screen_info[n].width; + settings->monitors[n].height = screen_info[n].height; + } + + settings->monitors[n].is_primary = screen_info[n].x_org == 0 && screen_info[n].y_org == 0; + } + } + + XFree(screen_info); + } + } +#endif + return True; } diff --git a/cmake/FindXinerama.cmake b/cmake/FindXinerama.cmake new file mode 100644 index 000000000..fc032b916 --- /dev/null +++ b/cmake/FindXinerama.cmake @@ -0,0 +1,49 @@ +# - Find XINERAMA +# Find the XINERAMA libraries +# +# This module defines the following variables: +# XINERAMA_FOUND - True if XINERAMA_INCLUDE_DIR & XINERAMA_LIBRARY are found +# XINERAMA_LIBRARIES - Set when XINERAMA_LIBRARY is found +# XINERAMA_INCLUDE_DIRS - Set when XINERAMA_INCLUDE_DIR is found +# +# XINERAMA_INCLUDE_DIR - where to find Xinerama.h, etc. +# XINERAMA_LIBRARY - the XINERAMA library +# + +#============================================================================= +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= + +find_path(XINERAMA_INCLUDE_DIR NAMES Xinerama.h + PATH_SUFFIXES X11/extensions + DOC "The Xinerama include directory" +) + +find_library(XINERAMA_LIBRARY NAMES Xinerama + DOC "The Xinerama library" +) + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(XINERAMA DEFAULT_MSG XINERAMA_LIBRARY XINERAMA_INCLUDE_DIR) + +if(XINERAMA_FOUND) + set( XINERAMA_LIBRARIES ${XINERAMA_LIBRARY} ) + set( XINERAMA_INCLUDE_DIRS ${XINERAMA_INCLUDE_DIR} ) +endif() + +mark_as_advanced(XINERAMA_INCLUDE_DIR XINERAMA_LIBRARY) +