#!/bin/sh
# Compiz wrapper
# 
# parts taken from 
#  git://anongit.opencompositing.org/users/3v1n0/compiz-wrapper
# 
# thanks to Treviño (3v1n0) <trevi55@gmail.com>, full copyright
# notice below:
# 
# Compiz wrapper, born as loader in Ubuntu Packages
#
# 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
#
#
# Much of this code is based on Beryl code, also licensed under the GPL.
# This script will detect what options we need to pass to compiz to get it
# started, and start a default plugin and possibly window decorator.
# 

# Set to yes to enable verbose
VERBOSE="yes"

GLXINFO="/usr/bin/glxinfo"

# driver blacklist
BLACKLIST="nv vga vesa vmware via sis"

COMPIZ_OPTIONS="--ignore-desktop-hints"
COMPIZ_PLUGINS=""
ENV=""

FALLBACKWM="/usr/bin/metacity"
FALLBACKWM_OPTIONS="--replace $@"

# No indirect by default
INDIRECT="yes"

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

# abort script and run fallback windowmanager
abort_with_fallback_wm()
{
    verbose "aborting and using fallback: $FALLBACKWM \n"

    if [ -x $FALLBACKWM ]; then
	exec $FALLBACKWM $FALLBACKWM_OPTIONS
    else
	echo "no $FALLBACKWM found, exiting"
	exit 1
    fi
}

# Check for non power of two texture support
check_npot_texture()
{
	verbose "Checking for non power of two support: "
	if glxinfo 2> /dev/null | egrep -q '(GL_ARB_texture_non_power_of_two|GL_NV_texture_rectangle|GL_EXT_texture_rectangle|GL_ARB_texture_rectangle)' ; then
		verbose "present. \n";
		return 0;
	else
		verbose "Not present. \n"
		return 1;
	fi

}

# Check for TFP
check_tfp()
{
	verbose "Checking for texture_from_pixmap: "
	if [ $($GLXINFO 2>/dev/null | grep GLX_EXT_texture_from_pixmap -c) -gt 2 ] ; then
		verbose "present. \n"
		return 0;
	else
		verbose "not present. \n"
		if [ "$INDIRECT" = "yes" ]; then
			unset LIBGL_ALWAYS_INDIRECT
			INDIRECT="no"
			return 1;
		else
			verbose "Trying again with indirect rendering:\n";
			INDIRECT="yes"
			export LIBGL_ALWAYS_INDIRECT=1
			check_tfp;
			return $?
		fi
	fi
}

# Check wether the composite extension is present
check_composite()
{
	verbose "Checking for Composite extension: "
	if xdpyinfo -queryExtensions | grep -q Composite ; then
		verbose "present. \n";
		return 0;
	else
		verbose "not present. \n";
		return 1;
	fi
}

# Detects if Xgl is running
check_xgl()
{
	verbose "Checking for Xgl: "
	if xvinfo | grep -q Xgl ; then
		verbose "present. \n"
		return 0;
	else
		verbose "not present. \n"
		return 1;
	fi
}

# 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 ${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
}

build_env()
{
        if check_nvidia; then
	        ENV="__GL_YIELD=NOTHING "
	fi
	if [ "$INDIRECT" = "yes" ]; then
		ENV="$ENV LIBGL_ALWAYS_INDIRECT=1 "
	fi
	if check_xgl; then
		if [ -f /usr/lib/nvidia/libGL.so.1.2.xlibmesa ]; then
			ENV="$ENV LD_PRELOAD=/usr/lib/nvidia/libGL.so.1.2.xlibmesa"
			verbose "Enabling Xgl with nVidia drivers...\n"
		fi
		if [ -f /usr/lib/fglrx/libGL.so.1.2.xlibmesa ]; then
			ENV="$ENV LD_PRELOAD=/usr/lib/fglrx/libGL.so.1.2.xlibmesa"
			verbose "Enabling Xgl with fglrx ATi drivers...\n"
		fi
	fi
	if [ -n "$ENV" ]; then
		export $ENV
	fi
}

build_args()
{
    if [ $INDIRECT = "yes" ]; then
	COMPIZ_OPTIONS="$COMPIZ_OPTIONS --indirect-rendering "
    fi
}

####################
# Execution begins here.

# Don't use compiz when running the failsafe session
if [ "$GNOME_DESKTOP_SESSION_ID" = "Failsafe" ]; then
    abort_with_fallback_wm
fi

# if we run under Xgl, we can skip some tests here
if ! check_xgl; then
    # if vesa or vga are in use, do not even try glxinfo (LP#119341)
    if running_under_blacklisted_driver; then
	abort_with_fallback_wm
    fi
    # check if we have the required bits to run compiz and if not, 
    # fallback
    if ! check_tfp || ! check_npot_texture || ! check_composite; then
	abort_with_fallback_wm
    fi
fi

# load the ccp plugin if present and fallback to plain gconf if not
if [ -f /usr/lib/compiz/libccp.so ]; then
	COMPIZ_PLUGINS="$COMPIZ_PLUGINS ccp"
elif [ -f /usr/lib/compiz/libgconf.so ]; then
	COMPIZ_PLUGINS="$COMPIZ_PLUGINS glib gconf"
fi

# get environment
build_env
build_args

# start the gtk-window-decorator if present
if [ -x /usr/bin/gtk-window-decorator ] && [ -n "$GNOME_DESKTOP_SESSION_ID" ]; then
	/usr/bin/gtk-window-decorator --replace &
elif [ -x /usr/bin/kde-window-decorator ] && [ -n "$KDE_FULL_SESSION" ]; then
        /usr/bin/kde-window-decorator --replace &
	FALLBACKWM="/usr/bin/kwin"
fi

/usr/bin/compiz.real $COMPIZ_OPTIONS "$@" $COMPIZ_PLUGINS || exec $FALLBACKWM $FALLBACKWM_OPTIONS

