Code Monkey home page Code Monkey logo

xrdp_dualmon's Introduction

xrdp_dualmon

About

A workaround solution to enable dual monitor in the xrdp server when using Sesman and X11rdp. This is a true multi monitor ("multimon") solution, every display is independent and can maximize x-windows to fit fullscreen. Usage: Pass the "/span" argument when RDPing to the xrdp server. The solution is based on the following:

Prerequisites

  • Screens are assumed to have the same resolution.
  • Only two screens are supported (this is what I needed), but this could easily be changed.
  • Dualmon ratio "threshold" is a const which is also tweakable (explained in detail later).
  • Update (29/05/2013) - It appears as if there's a resolution limitation, both screens' width combined should not exceed 2800px. That said, I got some good feedback from several hundred users on an xrdp server - looks like it works.

Installation

  • Download xrdp source and replace xrdp/sesman/session.c with the file in this repo.
  • Compile and install xrdp with the xinerama dependency.
  • Compile and install fake xinerama:
    • Run gcc -O2 -Wall Xinerama.c -fPIC -o libXinerama.so.1.0.0 -shared
    • Replace /usr/lib/libXinerama.so.1.0.0 with the new file you've just created.

How it works

  • The support of dualmon RDP experience to an xrdp server is achieved by "faking" two virtual screens.
  • When a user connects to an xrdp server using "/span", a wider window is sent to the xrdp server in client_info.
  • When width/height is larger then a certain ratio, it is safe to assume that this user is actually using two monitors.
  • At this point, and before the X11 session starts, we want to create the fake xinerama file, that creates two "virtual" screens.
  • In fact the two virtual screens are configured to be sized just like the physical ones - this creates the dualmon experience.
  • So not the most elegant solution, but it looks like it works just fine. Note that the RDP protocol does send a different header when "/multimon" is used, but I've decided to create a simpler version.

xrdp_dualmon's People

Contributors

asafge avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

xrdp_dualmon's Issues

Command used to point to the Xinerama dependency

Hello Asaf,

First of all thank you for this contribution!
We are trying out your short "how to" and are stuck on the step:

  • Compile and install xrdp with the xinerama dependency.

Could you share your command you used to do this?

Best regards,

Thomas

Unable to compile xrdp.sesman. "error: conflicting types for ‘int64_t'"

Looking for a way to have xrdp support dual monitors and use a remote system as a development environment. So, I found this project, and not sure if it is still being maintained or developed, last commit was 8 years ago. So, probably no longer works, but wanted to report my error just the same.

After replace session.c file in xrdp source was not able to complete compilation and generate the xrdp-sesman executable in /usr/local/sbin. Recieved the error of "conflicting types". My full error code is posted below.

In file included from sesman.h:30,                                                                                                                             
                 from session.c:27:                                                                                                                            
../common/arch.h:39:26: error: conflicting types for ‘int64_t’                                                                                                 
   39 | typedef signed long long int64_t;                                                                                                                      
      |                          ^~~~~~~                                                                                                                       
In file included from /usr/include/x86_64-linux-gnu/sys/types.h:155,                                                                                           
                 from /usr/include/stdlib.h:394,                                                                                                               
                 from ../common/arch.h:22,                                                                                                                     
                 from sesman.h:30,                                                                                                                             
                 from session.c:27:                                                                                                                            
/usr/include/x86_64-linux-gnu/bits/stdint-intn.h:27:19: note: previous declaration of ‘int64_t’ was here                                                       
   27 | typedef __int64_t int64_t;                                                                                                                             
      |                   ^~~~~~~                                                                                                                              
session.c:63:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘dumpItemsToString’                                                             
   63 | dumpItemsToString(struct list *self, char *outstr, int len)                                                                                            
      | ^~~~~~~~~~~~~~~~~                                                                                                                                      
session.c:93:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘session_get_bydata’                                                            
   93 | session_get_bydata(char *name, int width, int height, int bpp, int type)                                                                               
      | ^~~~~~~~~~~~~~~~~~                                                                                                                                     
session.c:159:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘x_server_running_check_ports’
  159 | x_server_running_check_ports(int display)
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
session.c:210:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘x_server_running’
  210 | x_server_running(int display)
      | ^~~~~~~~~~~~~~~~
session.c:230:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘session_start_sessvc’
  230 | session_start_sessvc(int xpid, int wmpid, long data, char *username, int display)
      | ^~~~~~~~~~~~~~~~~~~~
session.c:299:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘session_is_display_in_chain’
  299 | session_is_display_in_chain(int display)
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~
session.c:324:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘session_get_aval_display_from_chain’
  324 | session_get_aval_display_from_chain(void)
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
session.c:352:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘wait_for_xserver’
  352 | wait_for_xserver(int display)
      | ^~~~~~~~~~~~~~~~
session.c:381:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘session_start_fork’
  381 | session_start_fork(int width, int height, int bpp, char *username,
      | ^~~~~~~~~~~~~~~~~~
session.c:686:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘session_reconnect_fork’
  686 | session_reconnect_fork(int display, char *username)
      | ^~~~~~~~~~~~~~~~~~~~~~
session.c:715:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘xrdp_handle_dualmon’
  715 | xrdp_handle_dualmon(int width, int height, int display)                                                                                                
      | ^~~~~~~~~~~~~~~~~~~                                                                                                                                    
session.c:752:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘session_start’                                                                
  752 | session_start(int width, int height, int bpp, char *username, char *password,
      | ^~~~~~~~~~~~~
session.c:788:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘session_reconnect’
  788 | session_reconnect(int display, char *username)
      | ^~~~~~~~~~~~~~~~~
session.c:808:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘session_sync_start’
  808 | session_sync_start(void)
      | ^~~~~~~~~~~~~~~~~~
session.c:830:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘session_kill’
  830 | session_kill(int pid)
      | ^~~~~~~~~~~~
session.c:900:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘session_sigkill_all’
  900 | session_sigkill_all()
      | ^~~~~~~~~~~~~~~~~~~
session.c:931:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘session_get_bypid’
  931 | session_get_bypid(int pid)
      | ^~~~~~~~~~~~~~~~~
session.c:980:1: error: conflicting types for ‘session_get_byuser’
  980 | session_get_byuser(char *user, int *cnt, unsigned char flags)
      | ^~~~~~~~~~~~~~~~~~
In file included from sesman.h:38,
                 from session.c:27:
session.h:151:1: note: previous declaration of ‘session_get_byuser’ was here
  151 | session_get_byuser(const char *user, int *cnt, unsigned char flags);
      | ^~~~~~~~~~~~~~~~~~
session.c: In function ‘session_get_byuser’:
session.c:990:5: error: implicit declaration of function ‘lock_chain_acquire’ [-Werror=implicit-function-declaration]
  990 |     lock_chain_acquire();
      |     ^~~~~~~~~~~~~~~~~~
session.c:996:9: error: implicit declaration of function ‘LOG_DBG’; did you mean ‘LOG_H’? [-Werror=implicit-function-declaration]
  996 |         LOG_DBG("user: %s", user);
      |         ^~~~~~~
      |         LOG_H
session.c:998:33: error: implicit declaration of function ‘g_strncasecmp’ [-Werror=implicit-function-declaration]
  998 |         if ((NULL == user) || (!g_strncasecmp(user, tmp->item->name, 256)))
      |                                 ^~~~~~~~~~~~~
session.c:1018:9: error: implicit declaration of function ‘lock_chain_release’ [-Werror=implicit-function-declaration]
 1018 |         lock_chain_release();
      |         ^~~~~~~~~~~~~~~~~~
session.c:1038:2: error: #warning FIXME: we should get only disconnected sessions! [-Werror=cpp]
 1038 | #warning FIXME: we should get only disconnected sessions!
      |  ^~~~~~~                                                                                                                                               
session.c:1048:2: error: #warning FIXME: setting idle times and such [-Werror=cpp]                                                                             
 1048 | #warning FIXME: setting idle times and such                                                                                                            
      |  ^~~~~~~                                                                                                                                               
At top level:
session.c:53:12: error: ‘g_sync_cmd’ defined but not used [-Werror=unused-variable]
   53 | static int g_sync_cmd;
      |            ^~~~~~~~~~
session.c:52:12: error: ‘g_sync_result’ defined but not used [-Werror=unused-variable]
   52 | static int g_sync_result;
      |            ^~~~~~~~~~~~~
session.c:51:13: error: ‘g_sync_type’ defined but not used [-Werror=unused-variable]
   51 | static tui8 g_sync_type;
      |             ^~~~~~~~~~~
session.c:50:13: error: ‘g_sync_data’ defined but not used [-Werror=unused-variable]
   50 | static tbus g_sync_data;
      |             ^~~~~~~~~~~
session.c:49:14: error: ‘g_sync_client_ip’ defined but not used [-Werror=unused-variable]
   49 | static char *g_sync_client_ip;
      |              ^~~~~~~~~~~~~~~~
session.c:48:14: error: ‘g_sync_directory’ defined but not used [-Werror=unused-variable]
   48 | static char *g_sync_directory;
      |              ^~~~~~~~~~~~~~~~
session.c:47:14: error: ‘g_sync_program’ defined but not used [-Werror=unused-variable]
   47 | static char *g_sync_program;
      |              ^~~~~~~~~~~~~~
session.c:46:14: error: ‘g_sync_domain’ defined but not used [-Werror=unused-variable]
   46 | static char *g_sync_domain;
      |              ^~~~~~~~~~~~~
session.c:45:14: error: ‘g_sync_password’ defined but not used [-Werror=unused-variable]
   45 | static char *g_sync_password;
      |              ^~~~~~~~~~~~~~~
session.c:44:14: error: ‘g_sync_username’ defined but not used [-Werror=unused-variable]
   44 | static char *g_sync_username;
      |              ^~~~~~~~~~~~~~~
session.c:43:12: error: ‘g_sync_bpp’ defined but not used [-Werror=unused-variable]
   43 | static int g_sync_bpp;
      |            ^~~~~~~~~~
session.c:42:12: error: ‘g_sync_height’ defined but not used [-Werror=unused-variable]
   42 | static int g_sync_height;
      |            ^~~~~~~~~~~~~
session.c:41:12: error: ‘g_sync_width’ defined but not used [-Werror=unused-variable]
   41 | static int g_sync_width;
      |            ^~~~~~~~~~~~
cc1: all warnings being treated as errors

I am sure there is someone who knows more about what they are looking at than I am and/or is aware of another solution and/or knows whether this fix is even needed or supported any more.

Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.