#!/usr/bin/env bash VERSION=3.1.1 red='\033[1;31m' green='\033[1;32m' yellow='\033[1;33m' blue='\033[1;34m' light_cyan='\033[1;96m' reset='\033[0m' WINKEXDIR="/usr/lib/win-kex" XSTARTUP="${WINKEXDIR}/xstartup" XRDPINI="/etc/xrdp/xrdp.ini" XRDPSERVICE="${WINKEXDIR}/xrdp/xrdpservice" XSERV="${WINKEXDIR}/VcXsrv/vcxsrv.exe" XSERVSESSION=3 VNCSRV=$(which tigervncserver) VNCCLIENT="${WINKEXDIR}/TigerVNC/win-kex-win-x64" SESSION_CACHE="${HOME}/.cache/sessions/xfce4-session-" WSLGSOCK="${WINKEXDIR}/wslg-sock/wslg-sock" HOST="localhost" ## Alt: awk '/nameserver/ {print $2; exit}' /etc/resolv.conf ## /sbin/ip route | awk '/default/ {print $3}' #HOSTIP=$(grep -m 1 nameserver /etc/resolv.conf | awk '{print $2}') # HOSTIP=$(route.exe print | grep 0.0.0.0 | head -1 | awk '{print $4}') HOSTIP=$(grep -m 1 nameserver /etc/resolve.conf | awk '{print $2}') RECONN_ON_ERR=1 VERBOSE= NOWGL= ARCH=$(uname -m) SLTIMEOUT=100 unset IP USR SOUND MULTISCREEN function print-help() { printf "\n\tWin-KeX provides a GUI desktop experience for Snigdha OS in Windows Subsystem for Linux (WSL 2)" printf "\n" printf "\n\tUsage:" printf "\n\t\tkex " printf "\n" printf "\n\t\t${blue}Mode:${reset}" printf "\n\t\t[none]\t\t : Window Mode (default)" printf "\n\t\t--esm\t\t : Enhanced Session Mode - Launch Win-KeX desktop in a dedicated window using Windows native RDP" printf "\n\t\t--sl\t\t : SeamLess mode - Seamlessly integrate Win-KeX into the Windows desktop" printf "\n\t\t--win\t\t : WINdow mode - Launch Win-KeX desktop in a dedicated window" printf "\n" printf "\n\t\t${blue}Command:${reset}" printf "\n\t\t[none]\t\t : Start Win-KeX server and launch Win-KeX client" printf "\n\t\t--start\t\t : Start Win-KeX server" printf "\n\t\t--start-client\t : Start Win-KeX client" printf "\n\t\t--wtstart\t : Start Win-KeX server and launch Win-KeX client in Windows Terminal session" printf "\n\t\t--stop\t\t : Stop Win-KeX server" printf "\n\t\t--status\t : Show Win-KeX server status" printf "\n\t\t--kill\t\t : Stop Win-KeX server and kill all related processes" printf "\n\t\t--passwd\t : Set Win-KeX server password" printf "\n\t\t--start-sound\t : Start Windows sound server" printf "\n\t\t--stop-sound\t : Stop Windows sound server" printf "\n\t\t--wslg-restore\t : Restore WSLg unix socket" printf "\n\t\t--wslg-remove\t : Remove WSLg unix socket" printf "\n\t\t--wslg-status\t : Display status of WSLg unix socket" printf "\n\t\t--version\t : Display Win-KeX version" printf "\n\t\t--help\t\t : Display this help" printf "\n" printf "\n\t\t${blue}(Optional) Parameters:${reset}" printf "\n\t\t--ip \t\t-i : Use container IP address instead of \"localhost\"" printf "\n\t\t--multiscreen \t-m : Optimized for multiscreen" printf "\n\t\t--sound \t-s : Sound support" printf "\n\t\t--nowgl \t-n : Disable Windows OpenGL" printf "\n\t\t--norc \t\t-r : Disable Win-KeX client reconnecting - once is enough!" printf "\n\t\t--wait \t\t-w : Wait longer for desktop to start when in SL mode" printf "\n\t\t--use-existing-gui-vars \t\t : Use existing DISPLAY and PULSE_SERVER variables, without changing. Useful if you have a custom setup outside of KeX or want to use WSLG." printf "\n\t\t--verbose\t : Verbose output" printf "\n" printf "\n\tExamples:" printf "\n\t\tkex -s\t\t : Start Win-KeX server in window mode and launch Win-KeX client with sound support" printf "\n\t\tkex --sl -s\t : Start Win-KeX in seamless mode and launch Win-KeX client with sound support" printf "\n\t\tkex --esm -i -s\t : Start Win-KeX in Enhanced Session Mode with ARM workaround and launch Win-KeX client with sound support" printf "\n\t\tsudo kex\t : Start Win-KeX server as root in window mode and launch Win-KeX client" printf "\n" } function print-verbose() { if [ -n "${VERBOSE}" ]; then printf "> $@\n" fi } function print-version() { printf "$0: ${VERSION}\n" } function print-wrong-arch() { printf "\n\t${light_cyan}The function is not supported on this architecture${SESSION_FILE}${reset}\n" } function ask() { # http://djm.me/ask while true; do if [ "${2:-}" = "Y" ]; then prompt="Y/n" default=Y elif [ "${2:-}" = "N" ]; then prompt="y/N" default=N else prompt="y/n" default= fi # Ask the question printf "${light_cyan}$1" read -p " [${prompt}] " REPLY # Default? if [ -z "${REPLY}" ]; then REPLY=${default} fi printf "${reset}" # Check if the reply is valid case "${REPLY}" in Y*|y*) return 0 ;; *) return 1 ;; esac done } function is-root() { print-verbose "Checking account type" if [ -z ${USR} ]; then USR=$(whoami) fi if [ "${USR}" == "root" ]; then print-verbose "Root user" # 0 = true return 0 else print-verbose "Non-root user" # 1 = false return 1 fi } function sudo-active() { print-verbose "Checking sudo" if sudo -nv 2>/dev/null; then print-verbose "Found sudo" # 0 = true return 0 else print-verbose "Without sudo" # 1 = false return 1 fi } function wslg-socket-check() { print-verbose "Checking for WSLg socket" if [ -L /tmp/.X11-unix ]; then print-verbose "Found existing WSLg socket (Bad)" # 0 = true return 0 else print-verbose "Missing socket (Good)" # 1 = false return 1 fi } function wslg-socket-remove(){ print-verbose "Converting WSLg socket to Win-KeX" #printf "\n\t${red}A WSLg socket exists that prevent Win-KeX from starting${reset}" #printf "\n\t${red}Removing the socket now. This will not adversely affect WSL or Win-KeX${reset}\n" sudo ${WSLGSOCK} remove return $? } function wslg-socket-restore(){ print-verbose "Restoring WSLg socket" sudo ${WSLGSOCK} restore return $? } function wslg-socket-status(){ status=$(${WSLGSOCK} status) result=$? if [ "${result}" != "0" ]; then printf "\t${green}${status}${reset}\n" else printf "\t${red}${status}${reset}\n" fi return ${result} } function start-kex-win() { printf 'Starting Win-KeX server (Win)\n' if wslg-socket-check; then wslg-socket-remove fi # if [ ! -f ~/.config/tigervnc/passwd ]; then # passwd-set-win # fi if [ ! -f ~/.vnc/passwd ]; then passwd-set-win fi if is-root; then SCREEN=":2" else SCREEN=":1" fi if ! grep -q "$SCREEN=$USER" "/etc/tigervnc/vncserver.users"; then echo "$SCREEN=$USER" | sudo tee -a /etc/tigervnc/vncserver.users fi if [ -z ${SOUND} ]; then print-verbose "Skipping sound support" unset PULSE_SERVER else print-verbose "Sound support requested" export PULSE_SERVER=tcp:${HOSTIP} # if [ -z "$PULSE_SERVER" ] || [ "${USE_EXISTING_GUI_VARS}" != 1 ]; then # export PULSE_SERVER=tcp:${HOSTIP} # fi fi ## REF: https://github.com/microsoft/WSL/issues/9303 if ! [ -w /tmp/.X11-unix ]; then print-verbose "/tmp/.X11-unix is mounted as read-only - attempting to re-mount" ## Clashes with wslg-socket-remove() / $ sudo ${WSLGSOCK} remove #sudo umount /tmp/.X11-unix #ln -sf /mnt/wslg/.X11-unix/X0 /tmp/.X11-unix/ sudo mount -o remount,rw /tmp/.X11-unix if ! [ -w /tmp/.X11-unix ]; then printf "\n\t${red}/tmp/.X11-unix is still read-only${reset}\n" mount | grep /tmp/.X11-unix else print-verbose "Remount successful" fi fi print-verbose "Running Win-KeX server (Win)" # ${VNCSRV} -useold -xstartup ${XSTARTUP} -SecurityTypes=VeNCrypt,TLSVnc ${SCREEN} >/dev/null 2>&1 /dev/null 2>&1 /dev/null 2>&1 /init /mnt/c/Windows/system32/taskkill.exe taskkill.exe /IM win-kex-win-x64 /T /F >/dev/null 2>&1 # local output_1=$(${VNCSRV} -kill :1 2>&1) # local output_2=$(${VNCSRV} -kill :2 2>&1) sudo systemctl stop vncserver@:1.sevice 2>&1 sudo systemctl stop vncserver@:2.sevice 2>&1 local output_1=$(systemctl is-active vncserver@:2.sevice 2>&1) local output_2=$(systemctl is-active vncserver@:2.sevice 2>&1) # sudo systemctl stop if [[ "${output_1}" == *"success!"* || "${output_2}" == *"success!"* ]]; then printf "\t${light_cyan}Win-KeX server (Win) stopped${reset}\n" return 0 fi return 1 } function start-kex-esm() { printf 'Starting Win-KeX server (ESM)\n' export DESKTOP="XFCE" sudo ${XRDPSERVICE} start status=$? print-verbose "Win-KeX server (ESM) started" status-kex-esm return ${status} } function stop-kex-esm() { print-verbose "Stopping Win-KeX server (ESM)" sudo ${XRDPSERVICE} stop if [ "$?" == "0" ]; then printf "\t${light_cyan}Win-KeX server (ESM) stopped${reset}\n" return 0 fi return 1 } function status-kex-esm(){ ${XRDPSERVICE} status result=$? if [ "${result}" != "0" ]; then printf "\t${green}Win-KeX server (ESM) is running${reset}\n" else printf "\tWin-KeX server (ESM) is stopped\n" fi return ${result} } function sessions-kex-sl() { ## Workaround, as something has changed (WSL app? Linux packages?) ## This check if vcxsrv is pre-installed, and running on host (requires manual setup) ## - https://sourceforge.net/p/vcxsrv/wiki/VcXsrv%20%26%20Win10/ ## - https://gist.github.com/alextsil/f8d861b8a2fc766c06aefc0c35c083ee vcxsrvhost=0 timeout 3 bash -c "(echo > /dev/tcp/${HOSTIP}/6000)" >/dev/null 2>&1 \ && vcxsrvhost=1 if [ "${vcxsrvhost}" == "1" ]; then print-verbose "Found possible Win-KeX server (SL) running on host: ${HOSTIP}" XSERVSESSION=0 # means server host display on :0.0 return 0 else printf "\tUnable to find Win-KeX server (SL) running on host: ${HOSTIP}" print-verbose "Will try to use Win-KeX server (SL) inside of WSL" XSERVSESSION=3 return 1 fi } function start-kex-sl() { printf 'Starting Win-KeX server (SL)\n' if wslg-socket-check; then wslg-socket-remove fi if [ "${NOWGL}" == "1" ]; then print-verbose "Skipping Windows OpenGL support" wgl="" else print-verbose "Windows OpenGL support requested" wgl="-wgl" fi log="/tmp/win-kex-sl_$(whoami).log" print-verbose "Log file: ${log}" # if [ "${USE_EXISTING_GUI_VARS}" != 1 ]; then # if ! sessions-kex-sl; then # stop-kex-sl # ${XSERV} :${XSERVSESSION} -ac -terminate ${XMULTIMONITORS} -logfile ${log} -logverbose 10 -multiwindow -lesspointer -clipboard ${wgl} >/dev/null 2>&1 & # result=$? # if [ "${result}" != "0" ]; then # print-verbose "${XSERV}: ${result}" # print-verbose "Possible Win-KeX server (SL) may not have been successful" # fi # status-kex-sl # fi # fi if ! session-kex-sl; then stop-kex-sl /init /${XSERV} ${XSERV} :${XSERVSESSION} -ac -terminate ${XMULTIMONITORS} -logfile ${log} -logverbose 10 -multiwindow -lesspointer -clipboard ${wgl} >/dev/null 2>&1 & result=$? if [ "${result}" != "0" ]; then print-verbose "${XSERV}: ${result}" print-verbose "Possible Win-KeX server (SL) may not have been successful" fi status-kex-sl fi return 0 } function stop-kex-sl() { print-verbose "Stopping Win-KeX server (SL)" # taskkill.exe /IM vcxsrv.exe /T /F >/dev/null 2>&1 /init /mnt/c/Windows/system32/taskkill.exe taskkill.exe /IM vcxsrv.exe /T /F >/dev/null 2>&1 if [ "$?" == "0" ]; then printf "\t${light_cyan}Win-KeX server (SL) stopped${reset}\n" return 0 fi return 1 } function status-kex-sl(){ ##status=$(powershell.exe get-process vcxsrv 2>&1) # status=$(tasklist.exe | grep vcxsrv) status=$(/init /mnt/c/Windows/system32/taskkill.exe taskkill.exe | grep vcxsrv) if [ $? == "0" ]; then printf "\t${green}Win-KeX server (SL) is running${reset}\n" # 0 = true return 0 else printf "\tWin-KeX server (SL) is stopped\n" # 1 = false return 1 fi } function passwd-set-win() { print-verbose "Setting Win-KeX server (Win) password" print-verbose "*Do not need to set a read-only password*" vncpasswd return $? } function passwd-read-esm() { print-verbose "Getting password" local passwd stty_orig=$(stty -g) # save original terminal setting stty -echo # turn-off echoing IFS= read -r passwd # read the password stty "${stty_orig}" # restore terminal setting echo "${passwd}" } function passwd-exist-esm() { print-verbose "Checking if password set for Win-KeX server (ESM)" USR=$(whoami) # cmdkey.exe /list:LegacyGeneric:target=TERMSRV/${HOST} | grep -q ${USR} /init /mnt/c/Windows/system32/cmdkey.exe cmdkey.exe /list:LegacyGeneric:target=TERMSRV/${HOST} | grep -q ${USR} return $? } function passwd-set-esm() { USR=$(whoami) printf "Please enter Win-KeX server (ESM) password for user ${USR}:" passwd=$(passwd-read-esm) printf "\n" # cmdkey.exe /generic:TERMSRV/${HOST} /user:${USR} /pass:${passwd} >/dev/null 2>&1 & /init /mnt/c/Windows/system32/cmdkey.exe cmdkey.exe /generic:TERMSRV/${HOST} /user:${USR} /pass:${passwd} >/dev/null 2>&1 & } function status-all() { status-kex-win status-kex-sl status-kex-esm wslg-socket-status } function status-kex-win() { if sessions-kex-win >/dev/null 2>&1; then printf "\t${green}Win-KeX server (Win) is running${reset}\n" else printf "\tWin-KeX server (Win) is stopped\n" fi } function sessions-kex-win() { local result # sessions=$(vncserver -list | sed s/"TigerVNC"/"Win-KeX"/) sessions=$(systemctl is-active vncserver@$SCREEN.service 2>&1) # if [[ ${sessions} == *"590"* ]]; then # printf "\n${sessions}\n" # printf "\nYou can use the Win-KeX client (Win) to connect to any of these displays\n" # result=0 if [[ ${sessions} == "active" ]]; then printf "\n$(echo "Port 590$SCREEN" | sed 's/://')\n" printf "\nYou can use the Win-KeX client (Win) to connect to any of these displays\n" result=0 else if [ -n ${starting_kex} ]; then printf '\nError connecting to the Win-KeX server (Win)\n' printf 'Please try "'$0' start" to start the service\n' printf 'If the server fails to start, please try "'$0' kill" or restart your WSL 2 session and try again\n' result=1 fi fi printf '\n\n' return ${result} } function start-client-win() { printf 'Starting Win-KeX client (Win)\n' if is-root; then SCREEN=":2" unset PASSWD else SCREEN=":1" # local PASSWD="-passwd ${HOME}/.config/tigervnc/passwd" local PASSWD="-passwd ${HOME}/.vnc/passwd" fi if [ -z ${MULTISCREEN} ]; then print-verbose "Skipping Multiscreen support" local FULLSCREEN="FullScreen=1" else print-verbose "Multiscreen support requested" local FULLSCREEN="FullScreen=0 FullScreenAllMonitors=0" fi # If Win-KeX is started from the Windows home directory, it fails to open the passwd file # Let's work around it by starting Win-KeX from the rootfs cd ~ print-verbose "Running Win-KeX client (Win)" # ${VNCCLIENT} -SecurityTypes VeNCrypt,TLSVnc -ReconnectOnError ${RECONN_ON_ERR} ${PASSWD} ${FULLSCREEN} 127.0.0.1${SCREEN} >/dev/null 2>&1 & /init ${VNCCLIENT} ${VNCCLIENT} -SecurityTypes VeNCrypt,TLSVnc -ReconnectOnError ${RECONN_ON_ERR} ${PASSWD} ${FULLSCREEN} 127.0.0.1${SCREEN} >/dev/null 2>&1 & result=$? if [ "${result}" != "0" ]; then print-verbose "${VNCCLIENT}: ${result}" print-verbose "Possible Win-KeX client (Win) may not have been successful" fi cd - >/dev/null 2>&1 } function start-client-esm() { printf 'Starting Win-KeX client (ESM)\n' if [ ! -f ~/.win-kex.rdp ]; then cp ${VERBOSE} ${WINKEXDIR}/xrdp/win-kex.rdp ~/.win-kex.rdp fi if ! passwd-exist-esm; then passwd-set-esm fi if [ -z ${SOUND} ]; then print-verbose "Skipping sound support" if [ -f ~/.config/autostart/pulseaudio.desktop ]; then rm -f ${VERBOSE} ~/.config/autostart/pulseaudio.desktop fi else print-verbose "Sound support requested" if [ ! -d ~/.config/autostart ]; then mkdir -p ${VERBOSE} ~/.config/autostart fi cp ${VERBOSE} ${WINKEXDIR}/xrdp/pulseaudio.desktop ~/.config/autostart/ fi cd ~ # mstsc.exe .win-kex.rdp /v:${HOST}:3390 & /init /mn/c/Windows/system32/mstsc.exe mstsc.exe .win-kex.rdp /v:${HOST}:3390 & result=$? if [ "${result}" != "0" ]; then print-verbose "mstsc.exe: ${result}" print-verbose "Possible Win-KeX client (ESM) may not have been successful" fi cd - >/dev/null 2>&1 return $? } function start-client-wt() { printf 'Starting Win-KeX client (Windows Terminal)\n' while true; do clear printf "\n\t${blue}Win-KeX session is active\n\tClose this window to terminate Win-KeX${reset}\n" # If Win-KeX is started from the Windows home directory, it fails to open the passwd file # Let's work around it by starting Win-KeX from the rootfs cd ~ if [ "${mode}" == "sl" ]; then start-client-sl while true; do read -n 1 done elif [ "${mode}" == "esm" ]; then start-client-esm local pid=$! while kill -0 ${pid} 2>/dev/null; do sleep 1 done else if [ -z ${MULTISCREEN} ]; then print-verbose "Skipping Multiscreen support" local FULLSCREEN="FullScreen=1" else print-verbose "Multiscreen support requested" local FULLSCREEN="FullScreen=0 FullScreenAllMonitors=0" fi # ${VNCCLIENT} -SecurityTypes VeNCrypt,TLSVnc -passwd ${HOME}/.config/tigervnc/passwd ${FULLSCREEN} 127.0.0.1:1 ${VNCCLIENT} -SecurityTypes VeNCrypt,TLSVnc -passwd ${HOME}/.vnc/passwd ${FULLSCREEN} 127.0.0.1:1 fi cd - >/dev/null 2>&1 if ask "\n\tWin-KeX session disconnected\n\tWould you like to reconnect?" "Y"; then printf "\n\tReconnecting Win-KeX session\n" else stop-kex-win exit 0 fi done } function run-xfdesktop() { print-verbose "Looking for: xfdesktop -Q" print-verbose "Waiting ${SLTIMEOUT} seconds" i=1 nopid=0 until pids=$(pidof xfdesktop); do xfdesktop -Q >/dev/null 2>&1 i=$((i + 1)) sleep 1 if [ ${i} -ge ${SLTIMEOUT} ]; then nopid=1 break fi if [ -n "${VERBOSE}" ]; then printf '.' fi done printf '\n' if [ ${nopid} == "1" ]; then printf "\t${light_cyan}Waited ${i} seconds for xfdesktop -Q (gave up)${reset}\n" fi return ${nopid} } function start-client-sl() { printf 'Starting Win-KeX client (SL)\n' # if [ "${USE_EXISTING_GUI_VARS}" != 1 ]; then # sessions-kex-sl # fi sessions-kex-sl XFCE_DESKTOP_DISABLED="0" SESSION=${HOSTIP}:${XSERVSESSION} # if [ -z "$DISPLAY" ] || [ "${USE_EXISTING_GUI_VARS}" != 1 ]; then # export DISPLAY=${SESSION}.0 # fi export DISPLAY=${SESSION}.0 export GDK_BACKEND=x11 if [ "${NOWGL}" == "1" ]; then print-verbose "Skipping Windows OpenGL support" else print-verbose "Windows OpenGL support requested" export LIBGL_ALWAYS_INDIRECT=1 fi if [ -z ${SOUND} ]; then print-verbose "Skipping sound support" unset PULSE_SERVER else print-verbose "Sound support requested" export PULSE_SERVER=tcp:${HOSTIP} # if [ -z "$PULSE_SERVER" ] || [ "${USE_EXISTING_GUI_VARS}" != 1 ]; then # export PULSE_SERVER=tcp:${HOSTIP} # fi fi ## Clean up stale sessions first print-verbose "Killing session" # pkill -ef "dbus-launch --exit-with-session xfce4-session" >/dev/null 2>&1 pkill -ef "exec xfce4-session" >/dev/null 2>&1 ## Launch new Xfce session print-verbose "Starting session" # dbus-launch --exit-with-session xfce4-session >/dev/null 2>&1 & exec xfce4-session >/dev/null 2>&1 & SESSION_CACHE="${XDG_CACHE_HOME:-$HOME/.cache}/sessions/xfce4-session-" SESSION_FILE="${SESSION_CACHE}${SESSION}" print-verbose "Checking session: ${SESSION_FILE}" if [ -f ${SESSION_FILE} ]; then print-verbose "Found session file" if ! grep -q "xfdesktop" ${SESSION_FILE} >/dev/null 2>&1; then XFCE_DESKTOP_DISABLED="1" printf "\t${light_cyan}Win-KeX client (SL) is already enabled${reset}\n" fi fi if [ ! ${XFCE_DESKTOP_DISABLED} == "1" ]; then printf "\t${light_cyan}Enabling Win-KeX client (SL)${reset}\n" print-verbose "Waiting ${SLTIMEOUT} seconds for Win-KeX server (SL)" i=1 nopid=0 until pids=$(pidof xfdesktop); do i=$((i + 1)) sleep 1 if [ ${i} -ge ${SLTIMEOUT} ]; then nopid=1 break fi if [ -n "${VERBOSE}" ]; then printf '.' fi done printf '\n' if [ ${nopid} == "0" ]; then printf "\t${light_cyan}xfDesktop started after ${i} seconds${reset}\n" printf "\t${light_cyan}Enabling transparency now${reset}\n" sleep 2 run-xfdesktop else printf "\t${light_cyan}Waited ${i} seconds for xfDesktop (gave up)${reset}\n" printf "\tTry either:\n $0 --sl --wait [...]\n" printf "\t\t$0 --sl --wait [...]\n" printf "\t\tInstall vcxsrv on the host outside of WSL: https://www.docs.snigdhaos.org/wsl/win-kex-sl/\n" if [ -n "${VERBOSE}" ]; then printf '\n' cat "${log}" fi return 1 fi ## Repeat, just in case if [ ${nopid} == "0" ]; then run-xfdesktop fi ## Save the session printf "\t${light_cyan}Saving Win-KeX server (SL) session${reset}\n" dbus-send --session --dest=org.xfce.SessionManager --print-reply /org/xfce/SessionManager org.xfce.Session.Manager.Checkpoint string:"" >/dev/null 2>&1 fi printf "\t${light_cyan}Started Win-KeX server (SL)${reset}\n" return 0 } function kill-kex() { print-verbose "Killing Win-KeX" stop-kex-win stop-kex-sl stop-kex-esm stop-sound wslg-socket-restore pkill ssh-agent pkill Xtigervnc pkill xiccd pkill pulseaudio pkill -9 -f pulseaudio.exe pkill xcape pkill Xorg pkill xrdp-chansrv return $? } function start-sound() { print-verbose "Starting sound" cd /usr/lib/win-kex/pulse # ./pulseaudio.exe -F config.pa >/dev/null 2>&1 & /init ./pulseaudio.exe pulseaudio.exe -F config.pa >/dev/null 2>&1 & cd - >/dev/null 2>&1 } function stop-sound() { print-verbose "Stopping sound" pkill -9 -f pulseaudio.exe } # Deleting wayland is necessary rm -rf /run/user/1000/wayland-0* unset mode unset cmd while [[ $# -gt 0 ]]; do case $1 in # PARAMETERS: -i|--ip) # Use IP address instead of localhost # Fixes latency issues on ARM (as with version 19041.423) IP=1 shift ;; -s|--sound) SOUND=1 shift ;; -m|--multiscreen) MULTISCREEN=1 XMULTIMONITORS="-nomultimonitors" shift ;; -n|--nowgl) NOWGL=1 shift ;; -r|--norc) RECONN_ON_ERR=0 shift ;; -w|--wait) # Wait longer for desktop to start in SL mode when launched for first time # Can be used on slower machines where the desktop takes longer than # 100 seconds to start. Only required on first start to enable transparency SLTIMEOUT=300 shift ;; # --use-existing-gui-vars) # USE_EXISTING_GUI_VARS=1 # shift ;; # MODES: esm|--esm) mode=esm shift ;; sl|--sl) mode=sl shift ;; win|--win) mode=win shift ;; # COMMANDS: wslg-remove|--wslg-remove) cmd=remove_wslg shift ;; wslg-restore|--wslg-restore) cmd=restore_wslg shift ;; wslg-status|--wslg-status) cmd=status_wslg shift ;; kill|--kill) cmd=kill shift ;; passwd|--passwd) cmd=passwd shift ;; start|--start) cmd=start shift ;; start-client|start-c|--start-client|--start-c) cmd=start-client shift ;; start-sound|--start-sound) cmd=start-sound shift ;; status|--status) cmd=status shift ;; stop|--stop) cmd=stop shift ;; stop-sound|--stop-sound) cmd=stop-sound shift ;; wtstart|--wtstart) cmd=wtstart shift ;; help|-h|--help) cmd=help shift ;; --version) cmd=version shift ;; --verbose) VERBOSE=-v shift ;; *) printf "Unknown option: $1\n" if [ -z ${cmd} ]; then cmd=default fi shift ;; esac done if [ "${SOUND}" == "1" ] && [ ! "${mode}" == "esm" ] && [ ! "${ARCH}" == "aarch64" ]; then stop-sound start-sound fi if [ "${IP}" == "1" ]; then HOST=$(ip addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}') print-verbose "IP: ${HOST}" fi case ${cmd} in remove_wslg) if wslg-socket-check; then wslg-socket-remove fi exit ;; restore_wslg) if ! wslg-socket-check; then wslg-socket-restore fi exit ;; status_wslg) wslg-socket-status exit ;; esac if [ "${ARCH}" == "aarch64" ]; then case ${cmd} in start) if [ "${mode}" == "sl" ]; then print-wrong-arch elif [ "${mode}" == "esm" ]; then start-kex-esm else start-kex-esm fi ;; stop) if [ "${mode}" == "sl" ]; then print-wrong-arch elif [ "${mode}" == "esm" ]; then stop-kex-esm else stop-kex-esm fi ;; start-client) if [ "${mode}" == "sl" ]; then print-wrong-arch elif [ "${mode}" == "esm" ]; then start-client-esm else start-client-esm fi ;; status) if [ "${mode}" == "sl" ]; then status-kex-sl elif [ "${mode}" == "esm" ]; then status-kex-esm elif [ "${mode}" == "win" ]; then status-kex-win else status-all fi ;; passwd) if [ "${mode}" == "esm" ]; then passwd-set-esm elif [ ! "${mode}" == "sl" ]; then passwd-set-esm else printf "\n\t${red}This command is not supported in \"${mode}\" mode${reset}\n" fi ;; kill) kill-kex ;; start-sound) print-wrong-arch ;; stop-sound) print-wrong-arch ;; wtstart) if [ "${mode}" == "sl" ]; then print-wrong-arch elif [ "${mode}" == "esm" ]; then stop-kex-esm start-kex-esm start-client-wt else mode=esm stop-kex-esm start-kex-esm start-client-wt fi ;; help) print-help ;; version) print-version ;; *) if [ "${mode}" == "sl" ]; then print-wrong-arch elif [ "${mode}" == "win" ]; then print-wrong-arch else start-kex-esm start-client-esm fi ;; esac else case ${cmd} in start) if [ "${mode}" == "sl" ]; then start-kex-sl elif [ "${mode}" == "esm" ]; then start-kex-esm else start-kex-win fi ;; stop) if [ "${mode}" == "sl" ]; then stop-kex-sl elif [ "${mode}" == "esm" ]; then stop-kex-esm else stop-kex-win fi ;; start-client) if [ "${mode}" == "sl" ]; then start-client-sl elif [ "${mode}" == "esm" ]; then start-client-esm else start-client-win fi ;; status) if [ "${mode}" == "sl" ]; then status-kex-sl elif [ "${mode}" == "esm" ]; then status-kex-esm elif [ "${mode}" == "win" ]; then status-kex-win else status-all fi ;; passwd) if [ "${mode}" == "esm" ]; then passwd-set-esm elif [ ! "${mode}" == "sl" ]; then passwd-set-win else printf "\n\t${red}This command is not supported in \"${mode}\" mode${reset}\n" fi ;; kill) kill-kex ;; start-sound) stop-sound start-sound ;; stop-sound) stop-sound ;; wtstart) if [ "${mode}" == "sl" ]; then start-kex-sl start-client-wt elif [ "${mode}" == "esm" ]; then stop-kex-esm start-kex-esm start-client-wt else start-kex-win start-client-wt fi ;; help) print-help ;; version) print-version ;; *) if [ "${mode}" == "sl" ]; then start-kex-sl start-client-sl elif [ "${mode}" == "esm" ]; then start-kex-esm start-client-esm else start-kex-win start-client-win fi ;; esac fi