#!/bin/bash
# -*- mode: shell-script; coding: UTF-8 -*-
# 
# Build Xvnc with Xorg 7.4 or 7.5
#

set -e

PREFIX=
MAKE="make"
PARALLEL_MAKE=0
XORG_VERSION=7.5
XONLY=0
CFGHOST=
SRCDIR=`dirname $0`/../..

modules="dri2proto \
    libpthread-stubs \
    glproto \
    xf86vidmodeproto \
    xextproto \
    xproto \
    kbproto \
    inputproto \
    xcmiscproto \
    bigreqsproto \
    fixesproto \
    damageproto \
    xf86driproto \
    randrproto \
    renderproto \
    scrnsaverproto \
    resourceproto \
    fontsproto \
    videoproto \
    compositeproto \
    xineramaproto \
    libdrm \
    libXau \
    xtrans \
    libXdmcp \
    libX11 \
    libXext \
    libXxf86vm \
    libICE \
    libSM \
    libXt \
    libXmu \
    libXfixes \
    libXdamage \
    libXi \
    libxkbfile \
    libfontenc \
    libXfont \
    libpciaccess \
    pixman"

init()
{
    update_modules

    pushd xorg
    tar jxf ~/.tigervnc-xorg-$XORG_VERSION/util-macros.tar.bz2
    pushd util-macros-*
    echo "Building macros"
    ./configure --prefix=${PREFIX}
    ($MAKE install)
    popd

    pushd xserver

	patch -p1 < $SRCDIR/unix/xserver18.patch
    for all in `find $SRCDIR/contrib/xorg/xorg-$XORG_VERSION-patches/ -type f |grep '.*\.patch$'`; do
	echo Applying $all
	patch -p1 < $all
    done

    popd
    popd
}


update_modules()
{
    if [ -d xorg ]; then rm -rf xorg; fi
    if [ -d xorg.build ]; then rm -rf xorg.build; fi
    mkdir xorg
    pushd xorg
    $SRCDIR/contrib/xorg/download-xorg-$XORG_VERSION
    for module in ${modules}; do
        tar jxf ~/.tigervnc-xorg-$XORG_VERSION/${module}.tar.bz2
    done

    [ -r ~/.tigervnc-xorg-$XORG_VERSION/Mesa.tar.bz2 ] && \
        tar jxf ~/.tigervnc-xorg-$XORG_VERSION/Mesa.tar.bz2
    [ -r ~/.tigervnc-xorg-$XORG_VERSION/Mesa.tar.gz ] && \
        tar zxf ~/.tigervnc-xorg-$XORG_VERSION/Mesa.tar.gz

    tar jxf ~/.tigervnc-xorg-$XORG_VERSION/freetype.tar.bz2
    tar jxf ~/.tigervnc-xorg-$XORG_VERSION/xorg-server.tar.bz2
    cp -r $SRCDIR/unix/xserver xserver
    cp -r xorg-server-1.*/* xserver
    popd
}


build ()
{
    if [ $XONLY -eq 0 ]; then

    # Build VNC
    echo "*** Building VNC ***"
    cmake -G"Unix Makefiles" ${1+"$@"} -DBUILD_STATIC=1 $SRCDIR
    $MAKE

    # Build Xorg
    echo "*** Building Xorg ***"
    pushd xorg

    # build freetype
    echo "*** Building freetype ***"
    pushd freetype-*
    ./configure ${CFGHOST} --prefix=${PREFIX} --enable-static --disable-shared
    if [ $? -ne 0 ]; then
	echo "Failed to configure freetype."
	exit
    fi
    $MAKE install
    popd

    for module in ${modules}; do
        extraoptions=""
        cd ${module}-*
        echo ======================
        echo configuring ${module}
        echo ======================
        if [ "${module}" = "libX11" ]; then
            extraoptions="${extraoptions} --without-xcb --disable-specs"
        fi
        if [ "${module}" = "libSM" ]; then
            extraoptions="${extraoptions} --without-libuuid"
        fi
        if [ "${module}" = "pixman" ]; then
            extraoptions="${extraoptions} --disable-gtk"
        fi
	if [ "${module}" = "libXfont" ]; then
	    extraoptions="${extraoptions} --with-freetype-config=${PREFIX}/bin/freetype-config"
	fi
        OLD_CFLAGS=${CFLAGS}
        OLD_CXXFLAGS=${CXXFLAGS}
        CFLAGS=${CFLAGS}' -fPIC'
        CXXFLAGS=${CXXFLAGS}' -fPIC'
        export CFLAGS CXXFLAGS
        ./configure ${CFGHOST} --prefix="${PREFIX}" ${extraoptions} --enable-static --disable-shared
        CFLAGS=${OLD_CFLAGS}
        CXXFLAGS=${OLD_CXXFLAGS}
        export CFLAGS CXXFLAGS
        echo ======================
        echo building ${module}
        echo ======================
        if [ $? -ne 0 ]; then
                echo "Failed to configure ${module}."
                exit
        fi
        $MAKE install
        cd ..
    done

    # build mesa
    echo "*** Building Mesa ***"
    pushd Mesa-*
    ./configure ${CFGHOST} --prefix=${PREFIX} --disable-driglx-direct --with-dri-drivers=swrast --with-driver=dri --disable-glut --without-demos
    if [ $? -ne 0 ]; then
	echo "Failed to configure Mesa."
	exit
    fi
    $MAKE
    $MAKE install
    popd

    popd

    fi # XONLY

    # build xserver
    echo "*** Building xserver ***"
    pushd xorg/xserver
    autoreconf -fiv
    XORGCFGFLAGS="--disable-dri --enable-dri2 --disable-composite --disable-xinerama --disable-xvfb --disable-xnest --disable-xorg --disable-dmx --disable-xwin --disable-xephyr --disable-kdrive --disable-config-dbus --disable-config-hal --disable-config-udev --with-sha1=libgcrypt SHA1_LIB=-lcrypto --disable-shared --enable-static ${XORGCFGFLAGS}"
    ./configure ${CFGHOST} --prefix=${PREFIX} ${XORGCFGFLAGS}
    if [ $? -ne 0 ]; then
	echo "Failed to configure X server."
	exit
    fi
    $MAKE TIGERVNC_SRCDIR=$SRCDIR install
    popd
}

rebuild ()
{
    # Build VNC
    echo "*** Building VNC ***"
    $MAKE ${1+"$@"}

    # build xserver
    echo "*** Building xserver ***"
    pushd xorg/xserver
    $MAKE TIGERVNC_SRCDIR=$SRCDIR install ${1+"$@"}
    popd
}


usage ()
{
    echo "Usage: $0  init [-version <7.4 | 7.5>]"
    echo
    echo "       $0  build [-version <7.4 | 7.5>]"
    echo "       [additional CMake flags]"
    echo
    echo "       $0  rebuild [additional make options]"
    echo
    echo "       $0  update [-version <7.4 | 7.5>]"
    echo
    exit 1
}

if [ -x '/usr/bin/getconf' -a "$PARALLEL_MAKE" = "1" ]; then
    MAKE_PARALLEL=`/usr/bin/getconf _NPROCESSORS_ONLN 2>&1`
    [ "$MAKE_PARALLEL" -gt 1 ] && MAKE="$MAKE -j$MAKE_PARALLEL"
fi

while [ $# -gt 0 ]
do
    case "$1" in
	init)       MODE=init                ;;
	build)      MODE=build               ;;
	xbuild)     MODE=build;  XONLY=1     ;;
	rebuild)    MODE=rebuild             ;;
	update)     MODE=update              ;;
	-parallel)  PARALLEL_MAKE=1;         ;;
	-srcdir)    SRCDIR=$2;        shift  ;;
	*)          break                    ;;
    esac
    shift
done

pushd $SRCDIR
SRCDIR=`pwd`
echo "*** Using TigerVNC source tree at $SRCDIR ***"
popd

if [ "`pwd`" = "$SRCDIR/unix" ]; then
    cd $SRCDIR
fi

if [ "$PREFIX" = "" ]; then
    PREFIX=`pwd`/xorg.build
fi

if [ "$MODE" = "build" ]; then
    if [ ! -d ./xorg.build/syslib ]; then
	mkdir -p ./xorg.build/syslib
    fi

    for i in "$@"; do
	case "$i" in
	    CC=*)        CC=`echo $i | sed s/^CC=//g`  ;;
	    CXX=*)       CXX=`echo $i | sed s/^CXX=//g`  ;;
	    CFLAGS=*)    CFLAGS=`echo $i | sed s/^CFLAGS=//g`  ;;
	    CXXFLAGS=*)  CXXFLAGS=`echo $i | sed s/^CXXFLAGS=//g`  ;;
	    LDFLAGS=*)   LDFLAGS=`echo $i | sed s/^LDFLAGS=//g`  ;;
	esac
    done
    if [ "$CC" = "" ]; then
	CC=gcc
    fi
    if [ "$CXX" = "" ]; then
	CXX=g++
    fi
    if [ "$CFLAGS" = "" ]; then
	CFLAGS=-O3
    fi
    if [ "$CXXFLAGS" = "" ]; then
	CXXFLAGS=-O3
    fi
    CFLAGS="$CFLAGS -fPIC"
    CXXFLAGS="$CXXFLAGS -fPIC"
    LDFLAGS="$LDFLAGS -static-libgcc -L`pwd`/xorg.build/syslib"
    echo CC = $CC
    echo CXX = $CXX
    echo CFLAGS = $CFLAGS
    echo CXXFLAGS = $CXXFLAGS
    echo LDFLAGS = $LDFLAGS
    if [[ $CFLAGS = *-m32* ]]; then
	CFGHOST="--host i686-pc-linux-gnu"
    fi
    STATICLIBS='libcrypto.a libz.a'
    for lib in $STATICLIBS; do
	if [ -f ./xorg.build/syslib/$lib ]; then
	    rm -f ./xorg.build/syslib/$lib
	fi
    done
    IS64BIT=`echo -e "#ifdef __x86_64__\nis64bit_yes\n#else\nis64bit_no\n#endif" | $CC $CFLAGS -E - | grep is64bit`
    STATICLIBDIR=
    case $IS64BIT in
	is64bit_yes)
	    if [ -d /usr/lib64 ]; then STATICLIBDIR=lib64;
	    else STATICLIBDIR=lib; fi
	    ;;
	is64bit_no)
	    if [ -d /usr/lib32 ]; then STATICLIBDIR=lib32;
	    else STATICLIBDIR=lib; fi
	    ;;
	*)
	    echo "Cannot determine whether compiler output is 64-bit or 32-bit.  Are you using GCC?"
	    exit 1
	    ;;
    esac
    for lib in $STATICLIBS; do
	if [ -f /usr/$STATICLIBDIR/$lib ]; then
	    ln -fs /usr/$STATICLIBDIR/$lib ./xorg.build/syslib
	else
	    if [ -f /$STATICLIBDIR/$lib ]; then
		ln -fs /$STATICLIBDIR/$lib ./xorg.build/syslib
	    else
		DYLIB=`echo $lib | sed s/\\\.a/\\.so/g`
		if [ -f /usr/$STATICLIBDIR/$DYLIB -o -f /$STATICLIBDIR/$DYLIB ]; then
		    echo WARNING: Cannot find suitable $lib.  Xvnc will depend on $DYLIB.
		fi
	    fi
	fi
    done
fi

export ACLOCAL="aclocal -I ${PREFIX}/share/aclocal"
export PKG_CONFIG_PATH="${PREFIX}/lib/pkgconfig:${PREFIX}/share/pkgconfig"

case "$MODE" in
    init)       init                 ;;
    build)
	export CFLAGS CXXFLAGS LDFLAGS
	build ${1+"$@"};
	;;
    rebuild)    rebuild ${1+"$@"}    ;;
    update)     update               ;;
    *)          usage                ;;
esac
