#!/bin/sh
#
# Xgl Wrapper
# - Do some sanity checks, work out what acceleration options to pass to
#   Xgl, add Xgl's cookie to xauth, then set DISPLAY and run the command
#   passed from the command line.
#
# Based on:
#  Compiz Manager
#    Copyright (c) 2007 Kristian Lyngstøl <kristian@bohemians.org>
#    Addons by Treviño (3v1n0) <trevi55@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#

XGL_BLACKLIST="nv vga vesa vmware savage radeonhd"

XGL_NV_ACCEL_OPTS="-accel xv:fbo -accel glx:pbuffer"
XGL_OTHER_ACCEL_OPTS="-accel xv:pbuffer -accel glx:pbuffer"

XGL_VERBOSE="yes"

# (Temporary) Wrapper to clean up after Xgl
XGL_WRAPPER="/usr/share/xserver-xgl/Xgl-lockfile-wrapper"

# Echos the arguments if verbose
verbose()
{
	if [ "x$XGL_VERBOSE" = "xyes" ]; then
		echo -n "$*"
	fi
}

usage()
{
    echo "Usage: $0 XglDisplay [Xgl options] [--execute command [argument [...]]]" >&2
}

# Check for existence if NV-GLX
check_nvidia()
{
	verbose "Checking for nVidia: "
	if xdpyinfo | grep -q NV-GLX ; then
		verbose "present. \n"
		return 0;
	else
		verbose "not present. \n"
		return 1;
	fi
}

# check driver blacklist
running_under_blacklisted_driver()
{
    LOG=$(xset q|grep "Log file"|awk '{print $3}')
    if [ -z "$LOG" ];then
	verbose "AIEEEEH, no Log file found \n"
	verbose "$(xset q) \n"
	return 0
    fi
    for DRV in ${XGL_BLACKLIST}; do
	if egrep -q "Loading /usr/lib/xorg/modules/drivers/+${DRV}_drv\.so" $LOG &&
	   ! egrep -q "Unloading /usr/lib/xorg/modules/drivers/+${DRV}_drv\.so" $LOG; 
	then
	    verbose "Blacklisted '$DRV' driver is in use \n"
	    return 0
	fi
    done
    return 1
}

# Find an unused DISPLAY by searching the lockfiles
find_free_display()
{
    if [ ! -f /tmp/.X$1-lock ] ; then
	return $1
    fi
    find_free_display $(($1 + 1))
}

#######################
# Execution starts here
#######################

#Parse options.  First option is (preferred) display number, then everthing 
# before --execute is for Xgl, everthing after is the command we want to run
if [ -z "$1" ] ; then
    usage
    exit 0
else
    DISPLAYNUM=${1##*:}  #Strip off all but the display number
    shift
fi
XGL_OPTS=""
for OPT in $@ ;
do
    if [ "$OPT" = "--execute" ] ; then
	shift
	break
    else
	XGL_OPTS="$XGL_OPTS $OPT"
	shift
    fi
done

if running_under_blacklisted_driver ;
then
    verbose "The video driver '$DRV' you are using does not provide features\n"
    verbose "necessary for Xgl to work.  Using a different driver, or enabling\n"
    verbose "a restricted driver may provide the functionality required for Xgl.\n"
    verbose "Continuing without Xgl...\n"
elif [ -x $XGL_WRAPPER ] ;
then
    if check_nvidia ;
    then
	XGL_ACCEL_OPTS=$XGL_NV_ACCEL_OPTS
    else
	XGL_ACCEL_OPTS=$XGL_OTHER_ACCEL_OPTS
    fi

    find_free_display $DISPLAYNUM
    XGL_DISPLAYNUM="$?"
    XGL_DISPLAY=":$XGL_DISPLAYNUM"

#Add auth record for Xgl - this takes the underlying X server's xauth
#record, and duplicates it for the Xgl server
    xauth add $XGL_DISPLAY . $(xauth nextract - $DISPLAY | cut -d ' ' -f 9)

    verbose "Starting Xgl with options: " $XGL_ACCEL_OPTS $XGL_OPTS "\n"
    $XGL_WRAPPER $XGL_DISPLAY $XGL_ACCEL_OPTS $XGL_OPTS &
    
    #Wait for Xgl process to start
    TIMEOUT=10
    while [ ! -e /tmp/.X$XGL_DISPLAYNUM-lock -a $TIMEOUT -ge 0 ] ;
    do
	echo "Waiting $TIMEOUT more seconds for Xgl to start..."
	sleep 1
	TIMEOUT=$(( $TIMEOUT - 1))
   done
    
    #Now set $DISPLAY to Xgl's server, or raise a warning if
    #it hasn't started
    if [ $TIMEOUT -ge 0 ] ;
    then
	DISPLAY=$XGL_DISPLAY

        #Don't use Shift+Backspace as terminate_server
	xmodmap -e "keycode 22 = BackSpace"
    else
	echo "Xgl server failed to start!  Continuing without Xgl."
	echo "Desktop effects may be unavailable without Xgl"
    fi

else
    verbose "Xgl wrapper $XGL_WRAPPER not found!  Continuing without Xgl\n"
fi

exec $@
