Script to connect to remote desktop using XDMCP

As readers of my previous posts may have noticed I’m a bit of a fan of being able to work on multiple desktops, however trying to remember the right command parameters, or keep track of the next available display number is a little tedious so I wrote a short script to make like a little easier.

Using this script I can easily create a nested display window of a particular resolution that I can use to create screenshots that are a suitable size to include in documents or posts on this blog without the text being too small to read.

Note – Using XDMCP is not secure since passwords and other key strokes are basically passed as plain text, so you probably want to avoid using it on an un-trusted network (unless tunneling the connection over ssh).

# Starts an X windows session on a remote machine using XDMCP.
# Define  some will known screen resolutions - these are used to  check
# the  size of the desktop window later.  I prefer the size of  my  new
# desktops to be the same as a 'real' display - particularly when using 
# a nested desktop to capture screenshots.
XGA="1280x1024" # 5:4
VGA="640x480|768x576|800x600|1024x768|1280x960|1440x1050" # 4:3
CGA="320x200|1280x800|1440x900|1680x1050" # 16:10
HDV="1280x720|1366x768" # 16:9
WSVGA="1024x600" # 128:75

function validate_address()
# Checks  to  see  if an IP address is properly  formatted.  There  are
# almost certainly 'better' ways to do this so feel free to improve  on 
# this.
  local address=$1
  local status=1
  local regex=""
  # Build  a regular expression to check that an IP address consists of
  # four  three digit numbers, without leading zeros, separated by full
  # stops. 
  # Check that the IP address is formatted properly.
  if [[ $address =~ $regex ]]; then
    # Check each octet to ensure that it is less than 255. Substituting
    # each  full  stop  for  a space  and  putting  the  result  inside
    # parenthesis and assigning it to itself turns it into an array.
    address=(${address//./ })
    # Check that each octet is less than 255
    if [[ ${address[0]} -le 255 && \
       ${address[1]} -le 255 && \
       ${address[2]} -le 255 && \
       ${address[3]} -le 255 ]]; then status=0; fi
  return $status

function get_display()
# Finds  the  first  unused  display number  (attempting  to  create  a
# duplicate  display  results in and error, and when creating  multiple
# displays it can take a little while for X to release a display number
# so  I found it easier just to work out what the first available  free
# display number was rather than try to keep track of them myself.
  local count=1 # Nothing complicated - just start from one!
  while [ -e "/tmp/.X11-unix/X$count" ] # Lock file exists.
    count=$((count + 1)) # Increment counter.
  echo ":$count" # Returns next available display number
# Create a list of all the 'valid' resolutions.
default="1280x800" # Resolution to use if none specified.
host=$1 # IP address of host to connect to.
resolution=$2 # Desired display resolution (optional)
title=$3 # Window title (optional - will default to the IP address.)
if [ -z "$4" ]; then # No extraneous parameters found.
  if [ -z "$title" ]; then title=$host; fi
  manager=$(command -v Xephyr) >/dev/null 2>&1 
  if [ -x "$manager" ]; then # Does the display manager exist? 
    # Check to see if the IP address is properly formatted.
    if validate_address $host; then 
      # If no resolution was specified use the default.
      if [ -z "$resolution" ]; then resolution=$default; fi
      # Check if the display resolution is 'valid'.
      if [[ $resolution =~ ^($valid)$ ]]; then 
        # Time to find an unused display number for the display manager
        # to use.
        # Finally we can start the new display manager.
        $manager -query $host -screen $resolution -dpi 96 -retro \
          -terminate $display -title $title
        echo 'Invalid display resolution.'
      echo 'Missing or invalid host address.'
    echo 'Display manager not found.'

  echo 'Too many parameters.'
exit $status

This script above has been reformatted slightly from the original to make it easier to read, which is the only reason why the regular expression is defined the way it is and some commands are split over multiple lines.

Let me know if you find it useful.

This entry was posted in Linux and tagged , , , . Bookmark the permalink.

Leave a Reply

Please log in using one of these methods to post your comment: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s