#!/bin/bash

#######################################################################
# This is the DRI installation script. It compiles the kernel modules 
# and installs the kernel, DRI and libGL modules.
#
#   Frank Worsley   <franco@nettaxi.com>
#   Alan Hourihane  <alanh@fairlite.demon.co.uk>
#
#######################################################################

###########################################################
# VARIABLE DEFINITIONS
###########################################################

LOGFILE="dri.log"
LOGFILE_TMP="tmp.log"

# Defaults
XF86_DIR="/usr/X11R6"
KERNEL_VER=`uname -r`
KERNEL_LIB_DIR="/lib/modules/$KERNEL_VER"
OPTION=$1

###########################################################
# FUNCTION DECLARATIONS
###########################################################

print_logo() {

	################################################################
	# This function prints a DRI logo and a general text header.
	################################################################

	clear
	echo ""
	echo "DIRECT RENDERING OPEN SOURCE PROJECT  -  DRIVER INSTALLATION SCRIPT"
	echo ""
	echo "[ http://dri.sourceforge.net ]"
	echo ""
	echo "=========================================================================="
	echo ""
}

set_values() {

	#####################################################################
	# Sets up default values.
	#####################################################################

	# Determine driver to be installed
	DRV_NAME=`echo "1 p" | ed -s pkginfo`
	DRV_DESC=`echo "2 p" | ed -s pkginfo`
	DRV_ARCH=`echo "3 p" | ed -s pkginfo`
	DRV_DATE=`echo "4 p" | ed -s pkginfo`
	DRV_MODULE=`echo "5 p" | ed -s pkginfo`
	DRV_VERSION=`echo "6 p" | ed -s pkginfo`
	DRV_BUILD_DESC=`echo "7 p" | ed -s pkginfo`
	
	# Determine directories from default or user values
	XF86_DRI_DIR="$XF86_DIR/lib/modules/dri"
	XF86_DRV_DIR="$XF86_DIR/lib/modules/drivers"
	XF86_GL_DIR="$XF86_DIR/lib"
	XF86_EXT_DIR="$XF86_DIR/lib/modules/extensions"
	XF86_OS_DIR="$XF86_DIR/lib/modules/linux"
	KERNEL_DRM_DIR="$KERNEL_LIB_DIR/kernel/drivers/char/drm"
}

check_values() {

	#####################################################################
	# Checks if default/user given values are correct.
	#####################################################################
	
	# Check if installation directories exist
	MSG=$'The following problems have occured:\n'
	FATAL=0
	ERR=0
	
	if [ ! -d "$XF86_DIR" ]; then
		MSG="$MSG"$'\n	- XFree86 directory does not exist'
		ERR="1"
		FATAL="1";
	fi
	
	if [ ! -d "$KERNEL_LIB_DIR" ]; then
		MSG="$MSG"$'\n	- Kernel module directory does not exist'
		ERR="1"
		FATAL="1";
	fi

	if [ ! -d "$KERNEL_DRM_DIR" ]; then
		MSG="$MSG"$'\n	- Kernel DRM directory does not exist'
		ERR="1";
	fi
	
	if [ ! -d "$XF86_GL_DIR" ]; then
		MSG="$MSG"$'\n	- XFree86 GL library directory does not exist'
		ERR="1";
	fi	
	
	if [ ! -d "$XF86_DRI_DIR" ]; then
		MSG="$MSG"$'\n	- XFree86 DRI directory does not exist'
		ERR="1";
	fi		

	if [ ! -d "$XF86_DRV_DIR" ]; then
		MSG="$MSG"$'\n	- XFree86 driver directory does not exist'
		ERR="1";
	fi
	
	if [ ! -d "$XF86_EXT_DIR" ]; then
		MSG="$MSG"$'\n	- XFree86 extensions directory does not exist'
		ERR="1";
	fi	
	
	if [ ! -d "$XF86_OS_DIR" ]; then
		MSG="$MSG"$'\n	- XFree86 Linux OS directory does not exist'
		ERR="1";
	fi	
	
	# No error so return
	if [ "$ERR" == "0" ]; then
		return 0;
	fi
	
	# Get out if we have a fatal error that requires user to re-enter values
	if [ "$FATAL" == "1" ]; then
		MSG="$MSG"$'\n\nPlease make sure you have entered all information correctly.\n\nPress ENTER to review the information.'
		print_logo
		echo "$MSG"
		read KEY
		return -1;
	fi
	
	#Fix what we can
	MSG="$MSG"$'\n\nThe script can create these directories for you.\n\nPress ENTER to continue or CTRL-C to abort.'
	print_logo
	echo "$MSG"
	read KEY
	
	# Now we just create all directories no matter what ...
	mkdir -p $XF86_GL_DIR
	mkdir -p $XF86_DRI_DIR
	mkdir -p $XF86_DRV_DIR
	mkdir -p $XF86_EXT_DIR
	mkdir -p $XF86_OS_DIR
	mkdir -p $KERNEL_DRM_DIR
	
	return 0;
}

copy_files() {

	#####################################################################
	# This function copies files to their destination directories.
	#####################################################################
	
	echo "Installing files:"
	
	echo -n "	DRI XFree86 modules..."
	cd $DRV_NAME
	for FILE in *drv.o
	do
		mv -f $XF86_DRV_DIR/$FILE $XF86_DRV_DIR/dri-old.$FILE >& $LOGFILE_TMP;
	done
	for FILE in *dri.so
	do
		mv -f $XF86_DRI_DIR/$FILE $XF86_DRI_DIR/dri-old.$FILE >& $LOGFILE_TMP;
	done	
	cd ..
	cp -f $DRV_NAME/*drv.o $XF86_DRV_DIR
	cp -f $DRV_NAME/*dri.so $XF86_DRI_DIR	
	echo "done"
	
	echo -n "	kernel modules..."
	cd drm
	mkdir -p $KERNEL_DRM_DIR
	for FILE in *o
	do
		mv -f $KERNEL_DRM_DIR/$FILE $KERNEL_DRM_DIR/dri-old.$FILE >& $LOGFILE_TMP;
	done
	cd ..
	cp -f drm/$DRV_MODULE.o $KERNEL_DRM_DIR
	/sbin/depmod -a
	echo "done"
	
	echo -n "	GL & GLU libraries..."
	cd GL
	for FILE in *
	do
		mv -f $XF86_GL_DIR/$FILE $XF86_GL_DIR/dri-old.$FILE >& $LOGFILE_TMP;
		cp -f $FILE $XF86_GL_DIR
	done
	cd ..
	echo "done"
	
	echo -n "	core libraries..."
	cd core
	for FILE in libdri.a libglx.a libGLcore.a; do
		if [ -e $FILE ]; then
			mv -f $XF86_EXT_DIR/$FILE $XF86_EXT_DIR/dri-old.$FILE >& $LOGFILE_TMP
			cp -f $FILE $XF86_EXT_DIR;
		fi;
	done
	for FILE in libdrm.a; do
		if [ -e $FILE ]; then
			mv -f $XF86_OS_DIR/$FILE $XF86_OS_DIR/dri-old.$FILE >& $LOGFILE_TMP;
			cp -f $FILE $XF86_OS_DIR
		fi;
	done
	cd ..
	echo "done"

	if [ -e extras/extras.sh ]; then
		echo -n "	Copying extra files..."
		extras/extras.sh $XF86_DIR
		echo "done"
	fi
}

restore_files () {

	print_logo
	echo "Restoring files..."
	
	echo -n "	XFree86 modules..."
	cd $DRV_NAME
	for FILE in *drv.o
	do
		mv -f $XF86_DRV_DIR/dri-old.$FILE $XF86_DRV_DIR/$FILE >& $LOGFILE_TMP;
	done
	for FILE in *dri.so
	do
		mv -f $XF86_DRI_DIR/dri-old.$FILE $XF86_DRI_DIR/$FILE >& $LOGFILE_TMP;
	done	
	cd ..
	echo "done"
	
	echo -n "	kernel modules..."
	cd drm
	for FILE in *o
	do
		mv -f $KERNEL_DRM_DIR/dri-old.$FILE $KERNEL_DRM_DIR/$FILE >& $LOGFILE_TMP;
	done
	cd ..
	/sbin/depmod -a
	echo "done"
	
	echo -n "	system libraries..."
	cd GL
	for FILE in *
	do
		mv -f $XF86_GL_DIR/dri-old.$FILE $XF86_GL_DIR/$FILE >& $LOGFILE_TMP;
	done
	cd ..
	echo "done"
	
	echo -n "	core libraries..."
	mv -f $XF86_EXT_DIR/dri-old.libdri.a $XF86_EXT_DIR/libdri.a >& $LOGFILE_TMP;
	mv -f $XF86_EXT_DIR/dri-old.libglx.a $XF86_EXT_DIR/libglx.a >& $LOGFILE_TMP;
	mv -f $XF86_EXT_DIR/dri-old.libGLcore.a $XF86_EXT_DIR/libGLcore.a >& $LOGFILE_TMP;
	mv -f $XF86_OS_DIR/dri-old.libdrm.a $XF86_OS_DIR/libdrm.a >& $LOGFILE_TMP;
	echo "done"
	
	echo ""
	echo "Completed restoring files."
}

update_config() {

	#####################################################################
	# This function updates the system configuration.
	#####################################################################
	
	echo ""
	echo "Updating configuration:"

	echo -n "	Running ldconfig..."
	grep "$XF86_DIR" /etc/ld.so.conf >& $LOGFILE_TMP
	if [ $? != 0 ]; then
		echo "$XF86_DIR/lib" >> /etc/ld.so.conf
		/sbin/ldconfig >& $LOGFILE_TMP
		if [ $? != 0 ]; then
			echo "ERROR";
			ERR=1
		else
			echo "done";
		fi
	fi
	cat $LOGFILE_TMP >> $LOGFILE

	if [ ! "$X_RUNNING" == "1" ]; then
	
		# Only try and update kernel modules if X server is not running

		for MOD in $DRV_MODULE
		do
			echo -n "	Removing old kernel module \"$MOD\"..."
			/sbin/modprobe -r $MOD >& $LOGFILE_TMP

			if [ $? != 0 ]; then
				echo "ERROR"
				ERR=1;
			else
				echo "done";
			fi
	
			cat $LOGFILE_TMP >> $LOGFILE
		
			echo -n "	Inserting new kernel module \"$MOD\"..."
			/sbin/modprobe agpgart >& $LOGFILE_TMP
			/sbin/modprobe $MOD >& $LOGFILE_TMP
		
			if [ $? != 0 ]; then
				echo "ERROR"
				ERR=1;
			else
				echo "done";
			fi
	
			cat $LOGFILE_TMP >> $LOGFILE;
		done;
	fi
	
	if [ "$ERR" == "1" ]; then
		echo ""
		echo "There were errors updating the system configuration."
		echo "See the $LOGFILE file for more information.";
	fi

	rm $LOGFILE_TMP
}

check_config() {

	#####################################################################
	# This function checks the system configuration.
	#####################################################################
	
	echo ""
	echo -n "Checking configuration..."
	
	# Fix potential libGL problems
	LIBGL1=`ldd $XF86_DIR/bin/glxinfo | grep libGL.so.1 | awk -F" " '{ printf "%s",$3 }'`
	LIBGL=`echo $LIBGL1 | sed -e 's/\.1//'`
	if [ "$LIBGL" != "$XF86_GL_DIR/libGL.so" ]; then
		echo ""
		echo -n "	second copy of DRI libraries found in "
		echo `echo $LIBGL1 | sed -e 's/libGL.so.1//'`
		
		echo -n "	libraries have been backed up to old.* in "
		echo `echo $LIBGL1 | sed -e 's/libGL.so.1//'`
		echo ""
		
		mv $LIBGL1 `echo $LIBGL1 | sed -e 's/libGL.so.1/old.libGL.so.1/'`
		mv $LIBGL  `echo $LIBGL | sed -e 's/libGL.so/old.libGL.so/'`
		ln -s $XF86_GL_DIR/libGL.so.1 $LIBGL1;
		ln -s $XF86_GL_DIR/libGL.so $LIBGL;
	fi

	# Make sure libGL and libGLU have correct links
	rm -f $XF86_GL_DIR/libGL.so
	rm -f $XF86_GL_DIR/libGL.so.1
	ln -s $XF86_GL_DIR/libGL.so.1.2 $XF86_GL_DIR/libGL.so
	ln -s $XF86_GL_DIR/libGL.so.1.2 $XF86_GL_DIR/libGL.so.1

	rm -f $XF86_GL_DIR/libGLU.so
	rm -f $XF86_GL_DIR/libGLU.so.1
	ln -s $XF86_GL_DIR/libGLU.so.1.3 $XF86_GL_DIR/libGLU.so;
	ln -s $XF86_GL_DIR/libGLU.so.1.3 $XF86_GL_DIR/libGLU.so.1;
	
	echo "done"
}

###########################################################
# MAIN SCRIPT
###########################################################

# Check if pkginfo file exists
if [ ! -e "pkginfo" ]; then
	echo "Could not locate 'pkginfo' file. Aborting."
	exit 127;
fi

# Check if we are running as root
if [ `whoami` != "root" ] && [ `whoami` != "ROOT" ]; then
	echo "You must be root to install the DRI drivers."
	exit 127;
fi

# Check if ed is installed
which ed &> /dev/null
if [ "$?" != "0" ]; then
	echo "Could not located 'ed' editor. Aborting."
	exit 127;
fi

### FIXME: We should check for matching architectures here!!! ###

# Figure out if we should restore files
if [ "$OPTION" == "restore" ]; then
	
	print_logo
	echo "This will restore your previous files."
	echo ""
	echo "XFree86 Dir       : $XF86_DIR"
	echo "Kernel Module Dir : $KERNEL_LIB_DIR"
	echo ""
	echo "Press ENTER to restore files or C to change defaults."
	read KEY
	
	if [ "$KEY" == "C" ] || [ "$KEY" == "c" ]; then
		print_logo
		echo "Enter new values and then press ENTER."
		echo ""
		echo -n "XFree86 Dir       : "
		read XF86_DIR
		echo -n "Kernel Module Dir : "
		read KERNEL_LIB_DIR
		echo ""
		echo "Press ENTER to restore files."
		read KEY;
	fi

	set_values	
	restore_files
	echo "";
	exit 0;
fi

# Print X is running message
ps -C X > /dev/null
if [ $? == 0 ]; then
	X_RUNNING=1
	print_logo
	echo "WARNING: YOUR X SERVER SEEMS TO BE RUNNING!"
	echo ""
	echo "The script can not update your kernel modules while the X server is running."
	echo ""
	echo "You can do one of the following:"
	echo ""
	echo "1. Log out of your X session now and then run this script."
	echo ""
	echo "2. Run the script now and restart your computer after the installation."
	echo "   If you exit your X session now you will not have to restart."
	echo ""
	echo "Press ENTER to continue or CTRL-C to exit."
	read KEY ;
else
	X_RUNNING=0;
fi

# Do misc stuff
rm $LOGFILE
touch $LOGFILE

# Setup the defaults values
set_values

# Print a welcome message
print_logo
echo "Welcome to the DRI Driver Installation Script"
echo ""
echo "The package you downloaded is for the following driver: "
echo ""
echo "Driver Name    : $DRV_NAME"
echo "Description    : $DRV_DESC"
echo "Architecture   : $DRV_ARCH"
echo "Build Date     : $DRV_DATE"
echo "Kernel Module  : $DRV_MODULE"
echo ""
echo "Optional Information"
echo ""
echo "Driver Version      : $DRV_VERSION"
echo "Special Description : $DRV_BUILD_DESC"
echo ""
echo "Press ENTER to continue or CTRL-C to exit."
read KEY

# Determine XFree86 Directory and Kernel Module directory from user input
ERR=-1;
while [ "$ERR" == "-1" ]; do

	# Determine XFree86 directory
	print_logo
	echo "The script will need to copy the DRI XFree86 driver modules to"
	echo "your XFree86 directory."
	echo ""
	echo "The script will use the following XFree86 directory:"
	echo ""
	echo " $XF86_DIR"
	echo ""
	echo "If this is correct press ENTER, press C to change or CTRL-C to exit."
	read KEY

	if [ "$KEY" == "C" ] || [ "$KEY" == "c" ]; then
		print_logo
		echo "Please enter the XFree86 directory you would like to use."
		echo ""
		echo "Press ENTER when done or CTRL-C to abort."
		echo ""
		echo -n "Directory: "
		read XF86_DIR ;
	fi

	# Determine Kernel module directory
	print_logo
	echo "The script also needs to copy the DRM kernel modules to your"
	echo "kernel module directory."
	echo ""
	echo "Please note that only 2.4.x kernels are supported right now."
	echo ""
	echo "Kernel Version   : $KERNEL_VER"
	echo "Module Directory : $KERNEL_LIB_DIR"
	echo ""
	echo "If this is correct press ENTER, press C to change or CTRL-C to exit."
	read KEY

	if [ "$KEY" == "C" ] || [ "$KEY" == "c" ]; then
		print_logo
		echo "Please enter your kernel module directory."
		echo ""
		echo "Press ENTER when done or CTRL-C to abort."
		echo ""
		echo -n "Directory: "
		read KERNEL_LIB_DIR ;
	fi

	# Determine paths from user input or defaults
	set_values
	
	# Check if values are good
	check_values
	ERR="$?";
done

# Compile the kernel modules
print_logo
echo "The script will now compile the DRM kernel modules for your machine."
echo ""
echo "Press ENTER to continue or CTRL-C to exit."
read KEY

echo ""
echo -n "Compiling..."
cd drm
make -f Makefile.linux $DRV_MODULE.o >& ../$LOGFILE_TMP
if [ $? != 0 ]; then
	cat ../$LOGFILE_TMP >> ../$LOGFILE
	cd ..
	echo ""
	echo "ERROR: Kernel modules did not compile"
	echo ""
	echo "The DRI drivers can not be installed without the latest kernel modules."
	echo "Installation will be aborted. See the $LOGFILE file for information on"
	echo "what went wrong."
	echo ""
	exit 127;
else
	echo "done";
fi
cat ../$LOGFILE_TMP >> ../$LOGFILE
cd ..

# Print a last message
print_logo
echo "The script is now ready to complete the installation."
echo ""
echo "Press ENTER to continue or CTRL-C to exit."
read KEY

# Copy files, update config, check config and fix problems
print_logo

copy_files
update_config
check_config

echo ""
echo "Press ENTER to continue."
read KEY

# Print last message
print_logo
echo "The DRI installation is complete."
echo ""
echo "Restart your X server to try the new DRI drivers."
echo ""
echo "If you have problems with the DRI after upgrading your drivers"
echo "please visit the DRI website and read the Help and FAQ section."
echo "The FAQ contains solutions to many common problems."
echo ""
echo "Report any bugs, problems and comments on the dri-devel mailing list."
echo ""
echo "Thank you for using the DRI."
echo ""
