Skip to content

Instantly share code, notes, and snippets.

@rpavlik
Last active May 18, 2019 21:34
Show Gist options
  • Save rpavlik/ef988aefa4bb3d1a9e6c to your computer and use it in GitHub Desktop.
Save rpavlik/ef988aefa4bb3d1a9e6c to your computer and use it in GitHub Desktop.
Cygwin X for a virtual machine

Using Cygwin X as a display for a Linux VM without SSH overhead

This is primarily for my own record and knowledge. If it helps you, great! If it breaks something, don't say I didn't warn you - this is just documentation of what I did to get this to work at the time I wrote this on one particular machine.

Environment

  • I have a 64-bit cygwin install in c:\cygwin64 (possible in 32-bit too, I just messed up that install and it no longer works, so these were tested on my machine in a 64-bit install). I use my Cygwin setup scripts to simplify this part.
  • I'm using VirtualBox on Windows 8.1.
    • Importantly (at least for VirtualBox), I added a "host-only networking" adapter for communication between the guest (VM) and host machine - this seems to be required.
    • Totally optional but useful part of my setup: I'm using VBoxHeadlessTray to be able to easily have my virtual machine running without taking up precious taskbar space, so I only rarely actually use the VM direct (vs. over SSH). This might or might not explain some of my choices, but I figured I'd mention it, if nothing else than because that's a slick tool. I think once you install SSH in the VM and have the networking interfaces right, you could run it entirely with this app (vs. the full VirtualBox GUI).
    • Presumably the same basic approach below works with other VM software, as long as you can ssh into your VM and your VM can access TCP ports on your host.
  • My VM is running a Debian Jessie install
    • I'd expect any Linux with X clients and an SSH server to work.

Host setup

  • In Cygwin, install :
    • the X-related things. I think if you install startx or xinit it will pull in everything else needed. You may also opt for the "start menu shortcuts" package - though you won't usually use those, they're handy for testing.
    • ssh client
  • Run the Cygwin X server from the start menu once to see that it does work for you before we do crazy stuff.
  • It can be handy to set your user-profile-wide DISPLAY environment variable to :0.0 if you'll want to be able to launch X apps from a normal cygwin shell (that is, not an xterm)
  • Create a shortcut with the target C:\cygwin64\bin\run.exe --quote /usr/bin/bash.exe -l -c "/usr/bin/XWin :0 -listen tcp -multiwindow -clipboard -wgl -ac" ("start in:" C:\cygwin64) - This will launch a suitable X server. Argument explanation:
    • listen on TCP, which is how the VM will get to us (this didn't used to be required, default must have changed)
    • built-in multi-window mode
    • clipboard integration
    • OpenGL support
    • Disable access control (xhost)
  • Alternately if you're sick of seeing warnings about auth failures, etc. you can actually use startxwin, just takes a little more finagling.
    • Your shortcut now would be to C:\cygwin64\bin\run.exe --quote /usr/bin/bash.exe -l -c "/usr/bin/startxwin -- :0 -listen tcp -multiwindow -clipboard -wgl -ac"
    • To avoid starting a bunch of junk along with your xserver, you'll need to create/edit a .startxwinrc file in your Cygwin home directory:
      • You could start from the system one's (/etc/X11/xinit/startxwinrc) fallback section, and comment out the xterm and fbpanel lines, or you could start with a blank file.
      • Either way, you need to end the file with exec sleep inf - long story short, when startxwinrc exits, the X server shuts down, and so this as your last command means it never exits.

VM setup

  • I like the terminator terminal emulator - install it or your preferred.
  • You'll need to be able to SSH in.
  • On your VM it is helpful to add an entry to /etc/hosts for the "host-only network" IP of your host machine, with the hostname host. (Similarly, on the host machine, it can be handy to add a hosts-file entry for the guest - here, called jessie - you get one guess why)
  • On your VM, for bonus points, put export DISPLAY=host:0.0 in some profile script - not strictly necessary, but makes it simpler if you ssh into your vm directly or use the vm's console directly.

Initial tests

  • Just ssh in to your VM: you can use the SSH in Git or Cygwin, both work - but we'll be using Cygwin later, so probably use that. You might have to export DISPLAY=:0.0 first. Pass -X to the ssh command for X-forwarding, then launch some X app on the VM. This should work easy-peasy - it should have worked even without the advanced tinkering, so this is just a smoketest of your X server.
  • Now, ssh in to your VM without forwarding X. If it's not in your profile (hint: try echo $DISPLAY), you may need to export DISPLAY=host:0.0, then try running an X app. If this doesn't work, either X access control is screwed up, your host-only network is screwed up, or there's a firewall getting in the way.
  • Now, try the "canned command" from the host that we'll be scripting later: ssh ryan@jessie 'env DISPLAY=host:0.0 terminator'
    • If you haven't already, you probably want to use ssh-keygen and ssh-copy-id at this point to get passwordless login to your VM over SSH.

Final setup: useful shortcuts to make

All these have their "start in" directory as c:\cygwin64 but I'm not sure it matters.

  • Open Terminator on Jessie: C:\cygwin64\bin\run.exe --quote /usr/bin/bash.exe -l -c "ssh ryan@jessie 'env DISPLAY=host:0.0 terminator'"
    • You can use this to start other X apps.

Other tips

Some new-fangled GTK+3 apps (like Gedit) end up being unresizable with these default settings on Windows. Lacking a better solution at the moment, in Cygwin, cp /etc/X11/system.XWinrc ~/.XWinrc if you don't already have one in your user account - this sets up special windows-specific X stuff. You can add to the nearly-bottom (right after the menus) something like this:

styles {
    gedit NOTITLE
}

with as many of those middle lines as needed. The first parameter is the window name or class, which you can find by running xprop (you can get it in cygwin) and clicking the window in question. Then, once you restart the X server (or reload .XWinrc - not sure if that works if you are creating a user-specific one for the first time), any new windows meeting the criteria will get an extra border for resizability. Not perfect, and clearly a hack, but it makes gedit usable so I'm OK with it for now.

@cphuntington97
Copy link

Thank you for this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment