#!/usr/bin/env bash ### # File: sunshine-run # Project: bin # File Created: Tuesday, 23rd August 2023 3:28:52 pm # Author: Josh.5 (jsunnex@gmail.com) # ----- # Last Modified: Friday, 23rd August 2023 4:21:00 pm # Modified By: Josh.5 (jsunnex@gmail.com) ### set -e exec >> >(tee -a ${USER_HOME:?}/.cache/log/sunshine_run.log) 2>&1 echo echo "-------------------------------" echo date echo echo "-------------------------------" echo echo "**** Execute sunshine-run ****" echo # Trap SIGINT, SIGQUIT, SIGHUP, SIGTERM to forward signals to the child process _term() { if [ -n "${proc_pid}" ]; then # Read all child processes of proc_pid first child_pids=$(pgrep -P $proc_pid) # Forward the signal proc_pid echo " - Checking for status of main process ${proc_pid}" if kill -0 "${proc_pid}" 2>/dev/null; then echo " - Forwarding signal $1 to process ${proc_pid}" kill -s "${1}" "${proc_pid}" else echo " - Process ${proc_pid} is already stopped. Nothing to do here." fi for child_pid in ${child_pids:-}; do echo " - Checking for status of child process ${child_pid}" if kill -0 "${child_pid}" 2>/dev/null; then echo " - Forwarding signal $1 to process ${child_pid}" kill -s "${1}" "${child_pid}" else echo " - Process ${child_pid} is already stopped. Nothing to do here." fi done fi } trap '_term INT' SIGINT trap '_term QUIT' SIGQUIT trap '_term HUP' SIGHUP trap '_term TERM' SIGTERM # Record sunshine-run PID echo " - Recording sunshine-run PID '$$' in /tmp/sunshine-exec-run.pid" echo "$$" > /tmp/sunshine-exec-run.pid # Wipe session config echo "" > /tmp/sunshine-exec-run.conf # Update display resolution and refresh reate if client provided the required details if ([ "X${SUNSHINE_CLIENT_WIDTH:-}" != "X" ] && [ "X${SUNSHINE_CLIENT_HEIGHT:-}" != "X" ] && [ "X${SUNSHINE_CLIENT_FPS:-}" != "X" ]); then # Don't fail script if something goes wrong here. Set +e in subprocess ( set +e echo " - Setting display resolution to ${SUNSHINE_CLIENT_WIDTH:?}x${SUNSHINE_CLIENT_HEIGHT:?} ${SUNSHINE_CLIENT_FPS:?}Hz" # Read current display mode and extract resolution and refresh rate from the mode string __xrandr_out="$(xrandr)" __current_current_mode=$(echo "${__xrandr_out:?}" | awk '/\*/ {print $0}') __current_resolution=$(echo ${__current_current_mode:?} | awk '{print $1}') __current_refresh_rate=$(echo ${__current_current_mode:?} | awk '{sub(/\*/, "", $2); print $2}') # Get the primary output device __primary_output="$(echo "${__xrandr_out:?}" | grep primary | awk '{print $1}')" # Get the modeline from cvt and extract the second line (which contains the modeline) __client_modeline=$(cvt "${SUNSHINE_CLIENT_WIDTH:?}" "${SUNSHINE_CLIENT_HEIGHT:?}" "${SUNSHINE_CLIENT_FPS:?}" | grep Modeline | sed -e 's/Modeline //') # Create a new mode for this. This allows us to force a set refresh rate that may not be supported by the display __client_mode=$(echo "${__client_modeline:?}" | awk -F '"' '{print $2}') # Check if tthis mode is alread added to the primary display if ! echo "${__xrandr_out:?}" | grep -q "${__client_mode:?}"; then echo " - Adding new mode '${__client_mode:?}' with new modeline '${__client_modeline:?}'" xrandr --newmode "${__client_mode:?}" ${__client_modeline##*\"} echo " - Adding new mode '${__client_mode:?}' to device '${__primary_output:?}'" xrandr --addmode "${__primary_output:?}" "${__client_mode:?}" __mode_added=$? fi # Set the current resoultion to the new mode if [ "${__mode_added:-0}" -gt 0 ]; then echo " - Attempting to set the display mode to a supported '${SUNSHINE_CLIENT_WIDTH:?}x${SUNSHINE_CLIENT_HEIGHT:?}' mode" xrandr --output "${__primary_output:?}" --mode ${SUNSHINE_CLIENT_WIDTH:?}x${SUNSHINE_CLIENT_HEIGHT:?} --refresh ${SUNSHINE_CLIENT_FPS:?} [ $? -eq 0 ] && echo " - SUCCESS" else echo " - Setting the display mode to '${__client_mode:?}'" xrandr --output "${__primary_output:?}" --mode "${__client_mode:?}" --rate "${SUNSHINE_CLIENT_FPS:?}" [ $? -eq 0 ] && echo " - SUCCESS" fi # Save original display settings to config file. This will be read and used to restore the original display settings when the client disconnects. echo "primary_output='${__primary_output:?}'" >> /tmp/sunshine-exec-run.conf echo "display_mode='${__current_resolution:?}'" >> /tmp/sunshine-exec-run.conf echo "display_rate='${__current_refresh_rate:?}'" >> /tmp/sunshine-exec-run.conf ) fi # Run child process /usr/bin/dumb-init "${@}" & proc_pid=$! # Wait for child process to exit: echo " - Waiting for PID '${proc_pid}' to exit" wait "$proc_pid" # Clean up PID file if [ -f /tmp/sunshine-exec-run.pid ]; then echo " - Removing sunshine-run pidfile." rm -f /tmp/sunshine-exec-run.pid else echo " - WARNING: No sunshine-run pidfile found for removal." fi echo "DONE"