#!/bin/bash

#=============================================================================
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
# You may have to adjust these settings:

XGLCOMMAND="/usr/bin/nice -n -20 /opt/Xgl/bin/Xgl"
XGLPRELOAD=/usr/lib/libGL.so
XEVDEVSERVERCOMMAND="/usr/local/sbin/startsched 20 /usr/local/sbin/xevdevserver"
SETXKBMAP=/usr/X11R6/bin/setxkbmap

# The rest of the script should probably be left alone
#=============================================================================

echo "XglScript.sh v1.6"
echo "Processing command arguments"

UNDERLYINGDISPLAY="not set"
XGLDISPLAY="not set"
KEYBOARDDEVICE="not set"
MOUSEDEVICE="not set"
XGLAUTH="not set"
UNDERLYINGAUTH="not set"
KBMAP=""
OTHEROPTIONS=""
kbset="no"
mouseset="no"
startxevdevserver="maybe"

while [ $# != 0 ] ; do
	if [ "$1" = "-auth" ] ; then
		XGLAUTH="$2"
		OTHEROPTIONS="$OTHEROPTIONS -auth $XGLAUTH"
		shift
	elif [ "$1" = "-display" ] ; then
		UNDERLYINGDISPLAY="$2"
		shift
	elif [ "$1" = "-keyboard" ] ; then
		KEYBOARDDEVICE="$2"	
		kbset="yes"
		shift
	elif [ "$1" = "-mouse" ] ; then
		MOUSEDEVICE="$2"
		mouseset="yes"
		shift
	elif [ "$1" = "-xkbmap" ] ; then
		KBMAP="$2"
		shift
	else
		dispcheck=`echo "$1"|grep -e "\(^:[0-9]\+$\)\|\(^:[0-9]\+\.[0-9]\+$\)"`
		if [ "bla$dispcheck" != "bla" ] ; then 
			XGLDISPLAY="$1"
		else
			# check if it's something like 'vt7' which Xgl doesn't understand
			vtcheck=`echo "$1"|grep -e "^vt[0-9]\+$"`
			if [ "bla$vtcheck" = "bla" ] ; then
				OTHEROPTIONS="$OTHEROPTIONS $1"
			fi
		fi
	fi
	
	shift
done

# If keyboard and mouse are both set, start xevdevserver. Otherwise, assume that
# a xevdevserver has been started in fork mode by a XevdevScript.sh script.

if [ "$mouseset" = "yes" ] && [ "$kbset" = "yes" ] ; then
	echo "Will be starting xevdevserver"
	startxevdevserver="yes"
elif [ "$mouseset" = "no" ] && [ "$kbset" = "no" ] ; then
	echo "Won't be starting xevdevserver"
	startxevdevserver="no"
else
	echo "Both the mouse and keyboard should be set, or neither of them should be set"
	exit -1
fi

echo "Detected settings:"
echo "XGLDISPLAY=$XGLDISPLAY"
echo "KEYBOARDDEVICE=$KEYBOARDDEVICE"
echo "MOUSEDEVICE=$MOUSEDEVICE"
echo "XGLAUTH=$XGLAUTH"
echo "OTHEROPTIONS=$OTHEROPTIONS"
echo "UNDERLYINGDISPLAY=$UNDERLYINGDISPLAY"

if [ "$startxevdevserver" = "yes" ] ; then
	# Check if the device names need translating

	echo "Checking keyboard device name"

	tmp=`echo "$KEYBOARDDEVICE" | grep -e "^/dev/"`
	if [ "tmp$tmp" = "tmp" ] ; then # look in /proc/bus/input/devices
		echo "Doesn't start with /dev, checking /proc/bus/input/devices"
		IFS=$'\t'
		for i in `cat /proc/bus/input/devices |grep -A 5 -e "^I:"|sed -e "s/^--/\t/"` ;do 
			tmp=`echo "$i" | grep -e "^H: " | grep "kbd"`
			if [ "tmp$tmp" != "tmp" ] ; then 
				tmp=`echo "$i" | grep "$KEYBOARDDEVICE"`
				if [ "tmp$tmp" != "tmp" ] ; then 
					echo "Found keyboard device:"
					echo "$i"
					KEYBOARDDEVICE=/dev/input/`echo "$i" | grep -e "^H: " | grep --only-matching -e "event[0-9]\+"`
					echo "Device stored"
				fi
			fi
		done
		IFS=$' \t\n'
	else
		echo "Starts with /dev, passing it directly to xevdevserver"
	fi

	echo "KEYBOARDDEVICE=$KEYBOARDDEVICE"

	tmp=`echo "$KEYBOARDDEVICE" | grep -e "^/dev/"`
	if [ "tmp$tmp" = "tmp" ] ; then
		echo "Detected invalid keyboard specification"
		exit -1
	fi

	echo "Checking mouse device name"

	tmp=`echo "$MOUSEDEVICE" | grep -e "^/dev/"`
	if [ "tmp$tmp" = "tmp" ] ; then # look in /proc/bus/input/devices
		echo "Doesn't start with /dev, checking /proc/bus/input/devices"
		IFS=$'\t'
		for i in `cat /proc/bus/input/devices |grep -A 5 -e "^I:"|sed -e "s/^--/\t/"` ;do 
			tmp=`echo "$i" | grep -e "^H: " | grep "mouse"`
			if [ "tmp$tmp" != "tmp" ] ; then 
				tmp=`echo "$i" | grep "$MOUSEDEVICE"`
				if [ "tmp$tmp" != "tmp" ] ; then 
					echo "Found mouse device:"
					echo "$i"
					MOUSEDEVICE=/dev/input/`echo "$i" | grep -e "^H: " | grep --only-matching -e "event[0-9]\+"`
					echo "Device stored"
				fi
			fi
		done
		IFS=$' \t\n'
	else
		echo "Starts with /dev, passing it directly to xevdevserver"
	fi

	echo "MOUSEDEVICE=$MOUSEDEVICE"

	tmp=`echo $MOUSEDEVICE | grep -e "^/dev/"`
	if [ "tmp$tmp" = "tmp" ] ; then
		echo "Detected invalid mouse specification"
		exit -1
	fi

	echo "Mouse and keyboard device detected, continuing"
fi

tmp=`echo "$UNDERLYINGDISPLAY" | grep -e "\(^:[0-9]\+$\)\|\(^:[0-9]\+\.[0-9]\+$\)"`
if [ "tmp$tmp" = "tmp" ] ; then
	echo "Detected invalid underlying display"
	exit -1
fi

tmp=`echo "$XGLDISPLAY" | grep -e "\(^:[0-9]\+$\)\|\(^:[0-9]\+\.[0-9]\+$\)"`
if [ "tmp$tmp" = "tmp" ] ; then
	echo "Detected invalid Xgl display"
	exit -1
fi

if ! [ -e $XGLAUTH ] ; then
	echo "Couldn't detect Xgl authority file"
	exit -1
fi

underlyingdisplaynum=`echo "$UNDERLYINGDISPLAY"|cut -f 2 -d :|cut -f 1 -d .`
xgldisplaynum=`echo "$XGLDISPLAY"|cut -f 2 -d :|cut -f 1 -d .`
authdir=`dirname $XGLAUTH`
authname=`basename $XGLAUTH`
underlyingauthname=`echo $authname|sed -e "s/$xgldisplaynum/$underlyingdisplaynum/"`
UNDERLYINGAUTH="$authdir/$underlyingauthname"

if ! [ -e $UNDERLYINGAUTH ] ; then
	echo "Couldn't detect underlying authority file"
	exit -1
fi

if [ "$startxevdevserver" = "yes" ] ; then
	# Make it try a few times
	(i=0;while [ "$i" != "5" ] ; do
		if ! XAUTHORITY=$XGLAUTH $XEVDEVSERVERCOMMAND -d $XGLDISPLAY -k $KEYBOARDDEVICE -m $MOUSEDEVICE ; then
			i=$(( $i + 1 ))
		else
			i=5
		fi
		sleep 1
	done)&
fi
	
if [ "x$KBMAP" != "x" ] ; then
	( ( DISPLAY=$XGLDISPLAY XAUTHORITY=$XGLAUTH $SETXKBMAP $KBMAP ) & ) &
fi

if [ "x$XGLPRELOAD" != "x" ] ; then
	export LD_PRELOAD="$XGLPRELOAD"
fi

export DISPLAY="$UNDERLYINGDISPLAY"
export XAUTHORITY="$UNDERLYINGAUTH"
exec $XGLCOMMAND $OTHEROPTIONS $XGLDISPLAY


