|
#!/bin/sh |
|
|
|
# This is just a sample implementation of a slightly less primitive |
|
# interface than xinit. It looks for user .xinitrc and .xserverrc |
|
# files, then system xinitrc and xserverrc files, else lets xinit choose |
|
# its default. The system xinitrc should probably do things like check |
|
# for .Xresources files and merge them in, start up a window manager, |
|
# and pop a clock and several xterms. |
|
# |
|
# Site administrators are STRONGLY urged to write nicer versions. |
|
# |
|
|
|
unset DBUS_SESSION_BUS_ADDRESS |
|
unset SESSION_MANAGER |
|
userclientrc=$HOME/.startxwinrc |
|
sysclientrc=/etc/X11/xinit/startxwinrc |
|
|
|
userserverrc=$HOME/.xserverrc |
|
sysserverrc=/etc/X11/xinit/xserverrc |
|
defaultclient=xterm |
|
defaultserver=/usr/bin/XWin |
|
defaultclientargs="" |
|
defaultserverargs="-listen tcp" |
|
defaultdisplay=":0" |
|
clientargs="" |
|
serverargs="" |
|
vtarg="" |
|
display="" |
|
enable_xauth=1 |
|
|
|
|
|
# Automatically determine an unused $DISPLAY |
|
d=0 |
|
while true ; do |
|
[ -e "/tmp/.X$d-lock" -o -S "/tmp/.X11-unix/X$d" ] || break |
|
kill -0 `cat /tmp/.X$d-lock` 2>/dev/null || break |
|
d=$(($d + 1)) |
|
done |
|
defaultdisplay=":$d" |
|
unset d |
|
|
|
whoseargs="client" |
|
while [ x"$1" != x ]; do |
|
case "$1" in |
|
# '' required to prevent cpp from treating "/*" as a C comment. |
|
/''*|\./''*) |
|
if [ "$whoseargs" = "client" ]; then |
|
if [ x"$client" = x ] && [ x"$clientargs" = x ]; then |
|
client="$1" |
|
else |
|
clientargs="$clientargs $1" |
|
fi |
|
else |
|
if [ x"$server" = x ] && [ x"$serverargs" = x ]; then |
|
server="$1" |
|
else |
|
serverargs="$serverargs $1" |
|
fi |
|
fi |
|
;; |
|
--) |
|
whoseargs="server" |
|
;; |
|
*) |
|
if [ "$whoseargs" = "client" ]; then |
|
clientargs="$clientargs $1" |
|
else |
|
# display must be the FIRST server argument |
|
if [ x"$serverargs" = x ] && \ |
|
expr "$1" : ':[0-9][0-9]*$' > /dev/null 2>&1; then |
|
display="$1" |
|
else |
|
serverargs="$serverargs $1" |
|
fi |
|
fi |
|
;; |
|
esac |
|
shift |
|
done |
|
|
|
# process client arguments |
|
if [ x"$client" = x ]; then |
|
client=$defaultclient |
|
|
|
# For compatibility reasons, only use startxwinrc if there were no client command line arguments |
|
if [ x"$clientargs" = x ]; then |
|
if [ -f "$userclientrc" ] && [ ! -x "$userclientrc" ]; then |
|
echo "Skipping $userclientrc; present but not executable" |
|
fi |
|
if [ -x "$userclientrc" ]; then |
|
client=$userclientrc |
|
elif [ -f "$sysclientrc" ]; then |
|
client=$sysclientrc |
|
fi |
|
fi |
|
fi |
|
|
|
# if no client arguments, use defaults |
|
if [ x"$clientargs" = x ]; then |
|
clientargs=$defaultclientargs |
|
fi |
|
|
|
# process server arguments |
|
if [ x"$server" = x ]; then |
|
server=$defaultserver |
|
# For compatibility reasons, only use xserverrc if there were no server command line arguments |
|
if [ x"$serverargs" = x -a x"$display" = x ]; then |
|
if [ -f "$userserverrc" ]; then |
|
server=$userserverrc |
|
elif [ -f "$sysserverrc" ]; then |
|
server=$sysserverrc |
|
fi |
|
fi |
|
fi |
|
|
|
# if no server arguments, use defaults |
|
if [ x"$serverargs" = x ]; then |
|
serverargs=$defaultserverargs |
|
fi |
|
serverargs="-multiwindow $serverargs" |
|
|
|
# if no vt is specified add vtarg (which may be empty) |
|
have_vtarg="no" |
|
for i in $serverargs; do |
|
if expr match "$i" '^vt[0-9]\+$' > /dev/null; then |
|
have_vtarg="yes" |
|
fi |
|
done |
|
if [ "$have_vtarg" = "no" ]; then |
|
serverargs="$serverargs $vtarg" |
|
fi |
|
|
|
# if no display, use default |
|
if [ x"$display" = x ]; then |
|
display=$defaultdisplay |
|
fi |
|
|
|
# The wsl CLI API changed between V1 and V2 when I used the insider edition. |
|
# This has nothing to do with if the Linux is running in V1 or V2, only if the |
|
# cli installed supports only V1 or V2 too, so I know which args to use. |
|
if wsl -l -q > /dev/null 2>&1; then |
|
WSL_VERSION=2 |
|
else |
|
WSL_VERSION=1 |
|
fi |
|
|
|
if [ x"$enable_xauth" = x1 ] ; then |
|
if [ x"$XAUTHORITY" = x ]; then |
|
XAUTHORITY=$HOME/.Xauthority |
|
export XAUTHORITY |
|
fi |
|
|
|
removelist= |
|
|
|
# set up default Xauth info for this machine |
|
case `uname` in |
|
Linux*) |
|
if [ -z "`hostname --version 2>&1 | grep GNU`" ]; then |
|
hostname=`hostname -f` |
|
else |
|
hostname=`hostname` |
|
fi |
|
;; |
|
*) |
|
hostname=`hostname` |
|
;; |
|
esac |
|
|
|
authdisplay=${display:-:0} |
|
|
|
mcookie=`/usr/bin/mcookie` |
|
|
|
if test x"$mcookie" = x; then |
|
echo "Couldn't create cookie" |
|
exit 1 |
|
fi |
|
dummy=0 |
|
|
|
# create a file with auth information for the server. ':0' is a dummy. |
|
xserverauthfile=$HOME/.serverauth.$$ |
|
trap "rm -f '$xserverauthfile'" HUP INT QUIT ILL TRAP KILL BUS TERM |
|
touch "$xserverauthfile" |
|
xauth -q -f "$xserverauthfile" add ":${dummy}" . "${mcookie}" |
|
|
|
xserverauthfilequoted=$(echo ${xserverauthfile} | sed "s/'/'\\\\''/g") |
|
serverargs=${serverargs}" -auth '"${xserverauthfilequoted}"'" |
|
|
|
display_names=("${authdisplay}" "${hostname}${authdisplay}") |
|
|
|
OLD_IFS="${IFS}" |
|
IFS=$'\n' # Incase spaces are allowed, YOU KNOW WINDOWS! |
|
case "${WSL_VERSION}" in |
|
1) |
|
wsls=($(wsl -l | (iconv -f UCS-2LE -t ASCII//TRANSLIT || tr -d '\0') | sed -e '1d' -e 's/ (Default)//' | tr -d '\r')) |
|
;; |
|
2) |
|
wsls=($(wsl -l -q | (iconv -f UCS-2LE -t ASCII//TRANSLIT || tr -d '\0') | tr -d '\r')) |
|
# WSL 2 can't use localhost, this netstat command works on normal and Sonicwall Mobile conntect |
|
# Other VPNs may not work as expected. |
|
# Works on WSL2 using Sonicwall Netextender when using VPN Kit |
|
# wsl2_accessible_ip="$(netstat -rvn | grep '^ *0\.0\.0\.0' | awk 'NR==1{print $4}')" |
|
wsl2_accessible_ip="$(ipconfig | sed -En '/vEthernet \(WSL\)/,/Default Gateway/s/.*IPv4 Address( *\.)* *: *//p' | tr -d '\r\n')" |
|
|
|
# This will not work right if multiple ethernet devices say WSL |
|
# You may want to use this line on your particualr computer setup |
|
# wsl2_accessible_ip="$(powershell "(Get-NetIPAddress -AddressFamily IPV4 -InterfaceAlias *WSL*).IPAddress" | tr -d '\r\n')" |
|
if [ -n "${wsl2_accessible_ip}" ]; then |
|
display_names+=("${wsl2_accessible_ip}${authdisplay}") |
|
fi |
|
;; |
|
*) |
|
echo "Unknown version of WSL detected" |
|
exit 123 |
|
;; |
|
esac |
|
IFS="${OLD_IFS}" |
|
unset OLD_IFS |
|
|
|
# now add the same credentials to the client authority file |
|
# if '$displayname' already exists do not overwrite it as another |
|
# server man need it. Add them to the '$xserverauthfile' instead. |
|
for displayname in "${display_names[@]}"; do |
|
authcookie=`xauth list "${displayname}" | \ |
|
sed -n "s/.*${displayname}[[:space:]*].*[[:space:]*]//p"` 2>/dev/null; |
|
|
|
if [ "z${authcookie}" = "z" ] ; then |
|
xauth -q add "${displayname}" . "${mcookie}" |
|
for wsl in "${wsls[@]}"; do |
|
wsl -d "${wsl}" sh -c " |
|
if command -v xauth > /dev/null 2>&1; then |
|
if [ -n \"\${WSL_INTEROP-}\" ]; then |
|
xauth -q add '${wsl2_accessible_ip}${display}' . '${mcookie}' |
|
fi |
|
xauth -q add '${displayname}' . '${mcookie}' |
|
fi" |
|
done |
|
removelist="${display_names[*]}" |
|
else |
|
dummy=$(($dummy+1)); |
|
xauth -q -f "$xserverauthfile" add ":${dummy}" . "${authcookie}" |
|
|
|
for wsl in "${wsls[@]}"; do |
|
wsl -d "${wsl}" sh -c " |
|
if command -v xauth > /dev/null 2>&1; then |
|
if [ -n \"\${WSL_INTEROP-}\" ]; then |
|
xauth -q -f '${xserverauthfile}' add '${wsl2_accessible_ip}${dummy}' . '${mcookie}' |
|
fi |
|
xauth -q -f '${xserverauthfile}' add ':${dummy}' . '${authcookie}' |
|
fi" |
|
done |
|
fi |
|
done |
|
fi |
|
|
|
# Copy to WSLs' home |
|
for wsl in "${wsls[@]}"; do |
|
wsl -d "${wsl}" sh -c ' |
|
# If running WSL2 |
|
if [ -n "${WSL_INTEROP-}" ]; then'" |
|
echo 'export DISPLAY=${wsl2_accessible_ip}${display}' > ~/.displayrc |
|
else |
|
echo 'export DISPLAY=${display}' > ~/.displayrc |
|
fi |
|
" |
|
done |
|
|
|
# Copy to cygwin's home |
|
echo "export DISPLAY=${display}" > ~/.displayrc |
|
|
|
# Copy to Windows home, used by mingw et al. |
|
echo "export DISPLAY=${display}" > "${USERPROFILE}/.displayrc" |
|
|
|
echo "Starting xinit..." |
|
eval xinit \"$client\" $clientargs -- \"$server\" $display $serverargs |
|
retval=$? |
|
echo "Cleaning up xinit..." |
|
|
|
if [ x"$enable_xauth" = x1 ] ; then |
|
if [ x"$removelist" != x ]; then |
|
xauth remove $removelist |
|
for wsl in "${wsls[@]}"; do |
|
wsl -d "${wsl}" sh -c "if command -v xauth > /dev/null 2>&1; then xauth remove $removelist; fi" |
|
done |
|
fi |
|
if [ x"$xserverauthfile" != x ]; then |
|
rm -f "$xserverauthfile" |
|
for wsl in "${wsls[@]}"; do |
|
wsl -d "${wsl}" rm -f "$xserverauthfile" |
|
done |
|
fi |
|
fi |
|
exit $retval |
Windows 11 can finally stop using this script: https://docs.nvidia.com/cuda/wsl-user-guide/index.html#wsl2-system-requirements
Windows 10 still needs insider program, which isn't for everyone :(