#!/bin/bash

# Copyright Jean-Philippe Guillemin <jp.guillemin@free.fr>. 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. Please take a look at http://www.gnu.org/copyleft/gpl.htm

# This script :
# - probes for videocard, monitor and keyboard
# - ask for runlevel
# - writes a configured Xorg config file.



# Version 1.0 - 30/08/2005
#  * Added Xdialog support
# Version 1.1 - 27/09/2005
#  * Fixed bug in call to discover causing glibc error message
# Version 1.2 - 16/10/2005
#  * Fixed bug when 2 video cards are detected by discover
# Version 1.3 - 22/10/2005
#  * Improved/secured tempdir management
# Version 2.0 - 29/12/2005
#  * Monitor probing with edid/X-configure
# Version 2.1 - 17/06/2006
#  * Removed discover support
# Version 2.2 - 17/06/2006
#  * Improved modules detection
# Version 3.2 - 29/09/2006
#  * Ported to Xorg 7.x
# Version 3.3 - 08/04/2007
#  * Compositor aware
# Version 3.4 - 18/04/2007
#  * Silent mode
# Version 4.0 - 02/10/2007
#  * Synaptics and modeline improvements
# Version 4.1 - 15/04/2008
#  * Bug fix
# Version 4.1 - 15/04/2008
#  * added latvian and improved russian keyboard support
# Version 5.0 - 14/03/2009
#  * adapted for new Xorg server, thanks to Michael Verret and Gerard Montponey for their contribution ;)
# Version 5.0 - 11/03/2010
#  * no more need to care about drivers, so let's go :)
# Version 5.1 - 16/05/2010
#  * added some vesa tweeks
# Version 7.2 - Sun May 20 16:19:30 CEST 2012
#  * evdev er ...
# Version 8.0 - Sun Jan 24 10:59:22 CET 2016
#  * conf.d era ...

# Take a look at "Xdialog" and use it instead of "dialog" in case X is running
if [[ "$DISPLAY" && "$(which Xdialog 2>&1 | grep -v "which: no")" ]]; then
	dialog="Xdialog --wrap --left"
else
	dialog="dialog"
fi

# Path needs to be extended in case you're only half a root :)
export PATH="${PATH}:/usr/sbin:/sbin"

# Translations only work with utf8 locales
if [ ! `echo $LANG | grep -i utf` ]; then
	LANG=en_US
fi

# Gettext internationalization
export TEXTDOMAIN="videoconfig"
export TEXTDOMAINDIR="/usr/share/locale"
. gettext.sh

# create the tmpdir directory
export tmpdir="$(mktemp -d -p /tmp temp.XXXXXXXX)"

##################################################################
function writeconf(){

# ServerFlags section:
cat << EOF >  /etc/X11/xorg.conf.d/10-server-flags.conf
Section "ServerFlags"
#	Option		"NoTrapSignals"
#	Option		"DontVTSwitch"
	Option 		"DontZap"		"off"
#	Option		"DontZoom"
#	Option		"DisableVidModeExtension"
#	Option		"AllowNonLocalXvidtune"
#	Option		"DisableModInDev"
#	Option		"AllowNonLocalModInDev"
#	Option      "blank time"		"10"		# 10 minutes
#	Option      "standby time"		"20"
#	Option      "suspend time"		"30"
#	Option		"off time"			"60"
#	Option		"EstimateSizesAggresively" "0"
#	Option		"AutoEnableDevices"	"false"
#	Option		"AutoAddDevices"	"false"
#	Option		"AllowEmptyInput"	"false"
#	Option		"AccelMethod"		"exa"	
EndSection

EOF
	
# InputClass section:

cat << EOF > /etc/X11/xorg.conf.d/90-keyboard-layout.conf
Section "InputClass"
	Identifier "keyboard-all"
	MatchIsKeyboard "on"
	MatchDevicePath "/dev/input/event*"
	Driver "evdev"
	Option "XkbLayout" "$xkblayout"
	Option "XkbVariant" "$xkbvariant"
	Option "XkbOptions" "$xkboptions"
EndSection
EOF

# Device section:

if [ "$USEVESA" == "yes" ] ; then
cat << EOF > /etc/X11/xorg.conf.d/30-devices.conf
Section "Device"
	Identifier     "Videocard1"
#   VendorName  "Unknown Vendor"
# 	BoardName   ""
 	Driver     "vesa"
#   BusID       ""
 	Option "RenderAccel" "false"
# 	Option "XaaNoOffscreenPixmaps" "on"
EndSection

EOF

fi

if [ "$compositor" == "$(eval_gettext 'No')" ] ; then

cat << EOF >  /etc/X11/xorg.conf.d/20-compositor.conf
Section "Extensions"
        Option "Composite" "disable"
EndSection

EOF

else
cat << EOF >  /etc/X11/xorg.conf.d/20-compositor.conf
Section "Extensions"
        Option "Composite" "enable"
EndSection

EOF
fi

## DRI section:
#cat << EOF >>  /etc/X11/xorg.conf

## DRI            ( DRI-specific configuration )
##_______________________________________________________________________

#Section "dri"
## Access to OpenGL ICD is allowed for all users:
    #Mode		0666
## Access to OpenGL ICD is restricted to a specific user group:
##    Group		100    # users
#EndSection
#EOF

}



 
##################################################################
# Converts keyboard map from kmap (/usr/share/kbd/keymaps) to xkb (/etc/X11/xkb)
function xkbconvert(){

# Probing the keymap

  key="$(grep "^[[:space:]]*\/usr\/bin\/loadkeys" /etc/rc.d/rc.keymap \
    | sed -e 's/^.*loadkeys *\([^\.]*\)\(\.map\)*$/\1/')"



	# We convert keymap into XkbLayout  -- The fields are  keymap | XkbLayout | XkbOptions

	cat << "EOF" | grep "^$key|.*|.*" \
	  | sed -e "s/^.*|\(.*\)|\(.*\)|\(.*\)/\1|\2|\3/" > $tmpdir/xkb
ANSI-dvorak|dvorak||
al|al||
am|am||
ar|ar||
azerty|fr||
az|az||
be-latin1|be||
bg-cp1251|bg||
bg-cp855|bg||
bg_bds-cp1251|bg||
bg_bds-utf8|bg||
bg_pho-cp1251|bg||
bg_pho-utf8|bg||
br-abnt2|br||
br-abnt|br||
br-latin1-abnt2|br||
br-latin1-us|br||
brdk|brdk||
by|by||
by|by||
cf|ca_enhanced||
croat|hr||
cz-cp1250|cz||
cz-lat2-prog|cz||
cz-lat2|cz||
cz-us-qwertz|cz_qwerty||
cz|cz||
de-latin1-nodeadkeys|de||
de-latin1|de||
de_CH-latin1|de_CH||
de|de||
dk-latin1|dk||
dk|dk||
dvorak-l|dvorak||
dvorak-r|dvorak||
dvorak|dvorak||
es-cp850|es||
es|es||
fi-latin1|fi-latin1||
fi-latin9|fi-latin9||
fi|fi||
fr-latin0|fr-latin0||
fr-latin1|fr-latin1||
fr-latin9|fr-latin9||
fr-pc|fr||
fr_CH-latin1|fr_CH||
fr_CH|fr_CH||
fr|fr||
gr-pc|us,el|grp:alt_shift_toggle|
gr|us,el|grp:alt_shift_toggle|
hu|hu||
il|us,il|grp:alt_shift_toggle|
il-heb|us,il-heb|grp:alt_shift_toggle|
il-phonetic|us,il-phonetic|grp:alt_shift_toggle|
is-latin1-us|us,is|grp:alt_shift_toggle|
is-latin1|is||
it-ibm|it||
it2|it||
it|it||
jp106|jp||
lt.baltic|lt_std||
lt.l4|lt_std||
lt|lt_std||
lt|lt||
lv|lv||
lv-latin7|lv||
mk-cp1251|mk||
mk-utf|mk||
mk0|mk||
mk|mk||
nl2|nl|
nl|nl||
nl|nl||
no-latin1|no||
no|no||
pl2|pl2||
pl|pl||
pt-latin1|pt||
pt-latin9|pt||
ro_win|ro_microsoft||
ru-cp1251|ru|grp:switch,grp:alt_shift_toggle,grp_led:scroll|
ru-ms|us,ru(winkeys)|grp:switch,grp:alt_shift_toggle,grp_led:scroll|
ru-yawerty|ru||
ru1|us,ru(winkeys)|grp:switch,grp:alt_shift_toggle,grp_led:scroll|
ru2|us,ru(winkeys)|grp:switch,grp:alt_shift_toggle,grp_led:scroll|
ru3|us,ru(winkeys)|grp:switch,grp:alt_shift_toggle,grp_led:scroll|
ru4|us,ru(winkeys)|grp:switch,grp:alt_shift_toggle,grp_led:scroll|
ru_win|us,ru(winkeys)|grp:switch,grp:alt_shift_toggle,grp_led:scroll|
ru|us,ru(winkeys)|grp:switch,grp:alt_shift_toggle,grp_led:scroll|
se-fi-ir209|se_FI||
se-fi-lat6|se_FI||
se-ir209|se_SE||
se-lat6|se_SE||
sg-latin1-lk450|sg||
sg-latin1|de_CH||
sg|de_CH||
sk-prog-qwerty|sk_qwerty||
sk-prog-qwertz|sk_qwerty||
sk-prog-qwertz|sk||
sk-qwerty|sk_qwerty||
sk-qwertz|sk_qwerty||
slovene|si||
sr-cy|sry||
sv-latin1|se||
syr|syr||
tel|tel||
th_pat|th_pat||
th_tis|th_tis||
th|th||
tj|tj||
tml|tml||
tr_f-latin5|tr_f||
tr_q-latin5|tr||
tralt|tr||
tralt|tr||
trq|tr||
ua-utf-ws|ua||
ua-utf|ua||
ua-ws|ua||
ua|ua||
ua|ua||
uk|gb||
us-acentos|us||
us|us||
uz|uz||
vn|vn||
wangbe2|fr||
wangbe|fr||
fr-dvorak-bepo|fr|grp:alt_shift_toggle|bepo
fr-dvorak-bepo-utf8|fr|grp:alt_shift_toggle|bepo
EOF
	
	xkblayout="$(sed -e "s/^\(.*\)|.*|.*$/\1/" $tmpdir/xkb)"
	xkboptions="terminate:ctrl_alt_bksp"
	specialxkboptions="$(sed -e "s/^.*|\(.*\)|.*$/\1/" $tmpdir/xkb)"
	[ "${specialxkboptions}" ] && xkboptions="${xkboptions},${specialxkboptions}"
	xkbvariant="$(sed -e "s/^.*|.*|\(.*\)$/\1/" $tmpdir/xkb)"
	
	rm -f $tmpdir/xkb
	# Fall back to keymap if no xkb maping available
	if [ ! "$xkblayout" ]; then
	  xkblayout="$key"
	fi

}

##################################################################
function updatefc(){
	# Update the X font indexes
	if [ -x /usr/bin/fc-cache ]; then
		for dir in /usr/share/fonts/* ; do touch $dir ; done
		/usr/bin/fc-cache 2>&1 1>/dev/null &
	fi
}


##################################################################
function updatemime(){
	# Update the X font indexes
	if [ -x /usr/bin/update-mime-database ]; then
		/usr/bin/update-mime-database /usr/share/mime 2>&1 1>/dev/null &
	fi
}

##################################################################
function updatescrollkeeper(){
	# Generate GNOME documentation
	if [ -x /usr/bin/scrollkeeper-update ]; then
		/usr/bin/scrollkeeper-update 2>&1 1>/dev/null &
	fi
}


     ########################################
########### HERE COMES THE SUN ####################
     ########################################




	
	if [ "$1" = "silent" ] ; then
		echo "$(eval_gettext 'Configuring the X server')"
		(
		USEVESA="no"
		[ "$( lspci | grep "VirtualBox Graphic" )" ] && USEVESA="yes"
		xkbconvert
		writeconf
		updatefc
		updatemime	
		sed -i "s/^id:.*:initdefault:$/id:4:initdefault:/" /etc/inittab
		) 2>&1 1>/dev/null
		exit
	fi
	
	

	# probe for monitor specs 
	clear
	[ "$( lspci | grep "VirtualBox Graphic" )" ] && USEVESA="yes"
	$dialog --infobox "$(eval_gettext 'Configuring the X server')..." 8 45
	sleep 1
	xkbconvert
	


	# Compositor support ?

	  $dialog \
	  --title "$(eval_gettext 'Compositor')" \
	  --icon "videoconfig" \
	  --menu \
	"$(eval_gettext 'Do you want to enable the compositor (transparency, shadows, ... it can be slow on some videocards) ?')\n\n" \
	14 75 3 \
	   "$(eval_gettext 'Yes')" "$(eval_gettext 'Enable the compositor')" \
	   "$(eval_gettext 'No')" "$(eval_gettext 'Disable the compositor')" 2> $tmpdir/compositor

	compositor=$(cat $tmpdir/compositor)
	rm -f $tmpdir/compositor

	writeconf
	updatefc
	updatemime

	# Runlevel 3 or 4 ?

	  $dialog --title "$(eval_gettext 'Login mode configuration')" --icon "videoconfig" --menu \
	"$(eval_gettext 'Select the login mode you want to enable on startup:')\n\n" \
	16 76 3 \
	   "$(eval_gettext 'Text')" "$(eval_gettext 'Text mode login - runlevel 3')" \
	   "$(eval_gettext 'Graphical')" "$(eval_gettext 'Graphical Xwindow login - runlevel 4')" \
	   "$(eval_gettext 'Skip')" "$(eval_gettext 'No change')" 2> $tmpdir/runlevel

	runlevel=$(cat $tmpdir/runlevel)
	rm -f $tmpdir/runlevel

	case $runlevel in
	  $(eval_gettext 'Text'))
		sed -i "s/^id:.*:initdefault:$/id:3:initdefault:/" /etc/inittab
		;;
	  $(eval_gettext 'Graphical'))
		sed -i "s/^id:.*:initdefault:$/id:4:initdefault:/" /etc/inittab
		;;
	  $(eval_gettext 'Skip'))
	    exit
		;;
	esac

