#!/bin/bash
# This script is used to download, manage and build the git repositories that
# make up the X server and many of it's related modules. The script takes
# one of three arguements
#
# init:		Download the git repositories for the first time (git clone)
# update:	Update the git repositories (git pull)
# build:	Build all modules
#
# The script uses a file in the current directory called built.successful
# to track what has already been successfully built and installed. If you
# want to force the rebuilding of a module, edit this file. This is to
# cut down on the time needed to restart a build if one module fails

# Prefix to install X 
PREFIX="/opt/gfx-test"

# Use the systems xkbcomp instead of compiling your own
USE_SYS_XKB=yes

# Which drm kernel modules to build. linux-core for Linux of course. BSD
# uses bsd-core
drmcore=linux-core

# List of input modules
input="xf86-input-mouse xf86-input-keyboard xf86-input-synaptics"

# List of graphics drivers to build
drivers="xf86-video-intel xf86-video-ati xf86-video-radeonhd"

# List of git repositories to download and manage
REPOS="\
git://git.freedesktop.org/git/xorg/util/macros \
git://git.freedesktop.org/git/xorg/proto/x11proto \
git://git.freedesktop.org/git/xorg/proto/damageproto \
git://git.freedesktop.org/git/xorg/proto/xextproto \
git://git.freedesktop.org/git/xorg/proto/fontsproto \
git://git.freedesktop.org/git/xorg/proto/videoproto \
git://git.freedesktop.org/git/xorg/proto/renderproto \
git://git.freedesktop.org/git/xorg/proto/inputproto \
git://git.freedesktop.org/git/xorg/proto/xf86vidmodeproto \
git://git.freedesktop.org/git/xorg/proto/xf86dgaproto \
git://git.freedesktop.org/git/xorg/proto/xf86driproto \
git://git.freedesktop.org/git/xorg/proto/xcmiscproto \
git://git.freedesktop.org/git/xorg/proto/scrnsaverproto \
git://git.freedesktop.org/git/xorg/proto/bigreqsproto \
git://git.freedesktop.org/git/xorg/proto/resourceproto \
git://git.freedesktop.org/git/xorg/proto/compositeproto \
git://git.freedesktop.org/git/xorg/proto/evieproto \
git://git.freedesktop.org/git/xorg/proto/dri2proto \
git://git.freedesktop.org/git/xorg/lib/libxtrans \
git://git.freedesktop.org/git/xorg/lib/libX11 \
git://git.freedesktop.org/git/xorg/lib/libXext \
git://git.freedesktop.org/git/xorg/lib/libxkbfile \
git://git.freedesktop.org/git/xorg/lib/libfontenc \
git://git.freedesktop.org/git/xorg/lib/libXfont \
git://git.freedesktop.org/git/xorg/lib/libXfixes \
git://git.freedesktop.org/git/xorg/lib/libXdamage \
git://git.freedesktop.org/git/xorg/lib/libXv \
git://git.freedesktop.org/git/xorg/lib/libXvMC \
git://git.freedesktop.org/git/xorg/lib/libXxf86vm \
git://git.freedesktop.org/git/xorg/proto/dri2proto \
git://git.freedesktop.org/git/xorg/proto/glproto \
git://git.freedesktop.org/git/xorg/lib/libpciaccess \
git://git.freedesktop.org/git/pixman \
git://git.freedesktop.org/git/xcb/proto \
git://git.freedesktop.org/git/xcb/pthread-stubs \
git://git.freedesktop.org/git/xcb/libxcb \
git://git.freedesktop.org/git/xorg/proto/randrproto \
git://git.freedesktop.org/git/mesa/drm \
git://git.freedesktop.org/git/mesa/mesa \
git://git.freedesktop.org/git/xorg/xserver \
git://git.freedesktop.org/git/xorg/driver/xf86-input-mouse \
git://git.freedesktop.org/git/xorg/driver/xf86-input-keyboard \
git://git.freedesktop.org/git/xorg/driver/xf86-input-synaptics \
git://git.freedesktop.org/git/xorg/driver/xf86-video-intel \
git://git.freedesktop.org/git/xorg/driver/xf86-video-radeonhd \
"

# Names of the git modules once checked out
modules="\
fontsproto \
x11proto \
xextproto \
videoproto \
renderproto \
inputproto \
damageproto \
xf86vidmodeproto \
xf86dgaproto \
xf86driproto \
xcmiscproto \
scrnsaverproto \
bigreqsproto \
resourceproto \
compositeproto \
resourceproto \
evieproto \
libxtrans \
proto \
pthread-stubs \
libxcb \
libX11 \
libXext \
libxkbfile \
libfontenc \
libXfont \
libXv \
libXvMC \
libXxf86vm \
libXfixes \
libXdamage \
dri2proto \
glproto \
libpciaccess \
pixman \
randrproto"

MAKE="make -j$((`grep ^processor /proc/cpuinfo | wc -l`*2))" 

# Report and error and exit the script
die()
{
	echo FATAL: $@
	exit -1
}


# Clone the git repositories
init()
{
	for repo in $REPOS; do
		echo "Cloning $repo";
		git clone $repo;
	done
	cd macros
	echo "Building macros"
	./autogen.sh --prefix="$PREFIX" || die Failed to configure macros
	($MAKE) || die Failed to build macros
	make install || die Failed to install macros
	cd ..
}

# Update the git repositories
update_modules()
{
	for module in $modules; do
		cd $module
		git pull
		cd ..
	done
}

# Check if we have already built and installed a module.
check_already_built()
{
	BUILT=`grep ^$1 built.successful 2> /dev/null`
	if [ "$BUILT" != "" ]; then
		return 1
	fi

	return 0
}

build ()
{
	export ACLOCAL="aclocal -I$PREFIX/share/aclocal"
	export PKG_CONFIG_PATH="$PREFIX/lib/pkgconfig"

# build core modules
	for i in $modules; do

		check_already_built $i
		if [ $? -eq 1 ]; then
			echo Already built $i, skipping
			continue
		fi

		cd $i
		echo "Building $i"
		./autogen.sh --prefix="$PREFIX" || \
			echo Failed to configure $i.
		$MAKE || die Failed to build $i
		make install || die Failed to install $i

		cd ..
		echo $i >> built.successful
	done

# build drm
	check_already_built drm
	if [ $? -eq 0 ]; then
		cd drm
		./autogen.sh --prefix="$PREFIX" || \
			die Failed to configure drm
		($MAKE) || die Failed to build drm
		make -C $drmcore || die Failed to build drm $drmcore
		make install || die Failed to install drm $drmcore
		cd ..
		echo drm >> built.successful
	else
		echo Already built drm, skipping
	fi

#build mesa
	check_already_built mesa
	if [ $? -eq 0 ]; then
		cd mesa
		./autogen.sh --prefix=$PREFIX \
				--with-driver=dri \
				--disable-glut || \
			die Failed to configure mesa

		($MAKE) || die Failed to build mesa
		make install || die Failed to install mesa
		mkdir -p $PREFIX/bin
		install -m755 progs/xdemos/{glxinfo,glxgears} $PREFIX/bin/
		cd ..
		echo mesa >> built.successful
	else
		echo Already built mesa, skipping
	fi

#build xserver
	check_already_built xserver
	if [ $? -eq 0 ]; then

		if [ "$USE_SYS_XKB" = "yes" ]; then
			XSERVER_EXTRA=--with-xkb-path=/usr/share/X11/xkb
		fi
		cd xserver
		./autogen.sh --prefix=$PREFIX $XSERVER_EXTRA --enable-builtin-fonts || \
			die Failed to configure xserver
		($MAKE) || die Failed to build xserver
		make install || die Failed to install xserver
		chown root $PREFIX/bin/Xorg;
		chmod +s $PREFIX/bin/Xorg

		if [ "$USE_SYS_XKB" = "yes" ]; then
			ln -s /usr/bin/xkbcomp $PREFIX/bin/xkbcomp
		fi

		cd ..
		echo xserver >> built.successful
	else
		echo Already built xserver, skipping
	fi

#build input modules
	for i in $input; do
		check_already_built $i
		if [ $? -eq 1 ]; then
			echo Already built $i, skipping
			continue
		fi

		cd $i
		./autogen.sh --prefix=$PREFIX || \
			die Failed to configure $i
		($MAKE) || die Failed to build $i
		make install || die Failed to install $i
		cd ..
		echo $i >> built.successful
	done

#build drivers
	for i in $drivers; do
		check_already_built $i
		if [ $? -eq 1 ]; then
			echo Already built $i, skipping
			continue
		fi

		cd $i
		./autogen.sh --prefix=$PREFIX || \
			die Failed to configure $i
		($MAKE) || die Failed to build $i
		make install || Failed to install $i
		cd ..
		echo $i >> built.successful
	done
}

case "$1" in 
	init)
		init
		;;
	build)
		build
		;;
	update)
		update_modules
		;;
	*)
		echo "Usage: $0 init | build | update"
		exit 3
esac
