Wednesday, January 30, 2019

WSL GUI - Using Cygwin X-Server for Graphical Interface

As noted in my prior blog on nextpnr, WSL does not support graphic apps. Yes, in this case nextpnr is a Qt application that should compile in Windows. However, my entire toolchain is currently in WSL. Besides, I simply wanted to see if I could persuade a GUI app to work in WSL. I had used XMing X-windows in the past (click-bait ads on this softonic site, beware). My prior OpenWRT / Wireshark exercise worked well with XMing. However I could not get XMing to work with the latest version of WSL (Ubuntu 18.04 on Windows) so I tried Cygwin instead.

TL;DR: Install Cygwin/X to Windows, consider copy of .Xauthority and then launch the Cygwin server like this:
C:\cygwin64\bin\run.exe --quote /usr/bin/bash.exe -l -c "cd; exec /usr/bin/startxwin -- -listen tcp -nowgl"
Apparently every Cygwin user must have a corresponding Windows user. The user in WSL is not the Cygwin user.

Details: I selected all and only components related to "xorg":


Don't let the small numbers for download size fool you. I ended up with nearly 4GB in my local C:\cygwin64 - install takes a very long time.

In WSL:
# DOS (default C:\cygwin64\bin\) run.exe call to startxwin calls cygwin bash: "/usr/bin/XWin :0 ..." 
export DISPLAY=:0 # you may wish you put in this your ~/.bashrc
 
# copy the Cygwin/X user file to the WSL current user home directory
cp /mnt/c/cygwin64/home/gojimmypi/.Xauthority   ~/.Xauthority
Note that the username / security context in the DOS Windows may be different depending on the username selected when installing the Ubuntu WSL. When running a GUI app in WSL, remember that security is handled by the app started from the DOS prompt.

xclock can be a simple and useful X-Windows app to test if the XServer is working, and can be found in x11-apps:
sudo apt-get install x11-apps
xclock 
The default XWin Server launch as installed does not work for our WSL exercise:
C:\cygwin64\bin\run.exe --quote /usr/bin/bash.exe -l -c "cd; exec /usr/bin/startxwin"
Note: every time you attempt to launch the Cygwin X-Windows Server from a DOS prompt, you should close all running instances in the task bar before opening another. (mine was in the same pop-up menu on the taskbar where USB devices can be disconnected)

To properly launch a Cygwin X-Server for WSL, from a DOS command prompt, launch cygwin with two extra parameters: -- -listen tcp and -nowgl like this:
C:\cygwin64\bin\run.exe --quote /usr/bin/bash.exe -l -c "cd; exec /usr/bin/startxwin -- -listen tcp -nowgl"
The last two options are rather important. Prior to this exercise, I had never used cygwin, so this did take a bit of time to figure out. I've included some of the errors and solutions. Hopefully this document will help others avoid this frustration.

Without setting export DISPLAY=:0 in WSL, this error appears when trying to run xclock in WSL:
Error: Can't open display:
This is of course the same error when the X-Server is not running. Alternatively for nextpnr, we'd see this error:
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-gojimmypi'
qt.qpa.screen: QXcbConnection: Could not connect to display
Could not connect to any X display.
Without launching from DOS command prompt with -listen tcp, I saw this same error, as if the server was not running at all:
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-gojimmypi'
qt.qpa.screen: QXcbConnection: Could not connect to display :0
Could not connect to any X display.
Without the -nowgl option, I saw this error:
$ nextpnr-ice40 --gui
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-gojimmypi'
No XVisualInfo for format QSurfaceFormat(version 2.0, options QFlags(), depthBufferSize -1, redBufferSize 1, greenBufferSize 1, blueBufferSize 1, alphaBufferSize -1, stencilBufferSize -1, samples 1, swapBehavior QSurfaceFormat::SwapBehavior(SingleBuffer), swapInterval 1, profile  QSurfaceFormat::OpenGLContextProfile(CoreProfile))
Falling back to using screens root_visual.
Could not initialize GLX
Aborted (core dumped)
This error means you need a fresh copy of the .Xauthority from cygwin to WSL:
~$ nextpnr-ice40 --gui
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-gojimmypi'
Invalid MIT-MAGIC-COOKIE-1 keyqt.qpa.screen: QXcbConnection: Could not connect to display :0
Could not connect to any X display.


Resources, Inspiration, Credits, and Other Links:

        Follow @gojimmypi  

2 comments:

  1. That is nifty, though with these sorts of hoops to jump through I'm not convinced it's worth using a WSL based toolchain rather than using MSYS2-MinGW.
    I recently started maintaining some MSYS2 PKGBUILD files for building various FPGA toolchain packages including nextpnr-ice40 here https://github.com/DiodeRed/MinGW-FPGA-Packages/

    ReplyDelete
  2. This worked for me - and I agree that cygwin is better than Ming etc.

    However, for me everytime the cygwin server was restarted, the .Xauthority file had to re-copied. So instead of copying, I created a symlink via ln -s. That works perfectly now.

    ReplyDelete

comments are welcome, but I prefer not to allow links to promotions or other unrelated services.

Find gojimmypi at gojimmypi.github.io

I'm currently working on my new blog home at  gojimmypi.github.io After implementing a variety of features such as dark mode , syntax hi...