#!/bin/bash

#Just thought I'd warn you - this is Junker specific
if [ "$0" = "/usr/local/bin/MyX" ] ; then
	echo "WARNING - it is MyMyX you are using.  Some syntax may be different!!!"
fi

#(C) 2001 Dion Bonner, Junker Systems
#
#Released under the GNU General Public Licence Version 2
#
#
#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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
#A full copy of the GNU General Public license can be found in the help file
#that came with this script - select help from the window manager menu, or view the file MyMyX.hlp with your favorite file viewer.
#
#
#MyMyX is a window manager selection shell script.
#
#I would like to give some credit to Eric Gillespie, who modified an X init script and wrote MyX.  I then decided to roll my own, to teach me Bourne shell script.
#
#Thanks to Eric Gillespie for the idea of no disk writes using the back ticks.
#
#I'll admit that that IDEA wasn't totally of my own creation.
#Also thanks for the display case statement help - [0-9]

#I have had fun writing MyMyX and I have learned a lot about unix commands and
#BASH in the process.
#MyMyX version history

#0.01 - First version - no command line support, users entered input through
#read
#
#0.02 - Some tidying up done on the code
#
#0.1  - Messy command line options added using ifs - they were long and clunky
#
#0.7 Complete rewrite - warrents a MAJOR version number hike. 
#The whole way command line options are processed changed - shorter and tidier
#
#0.71 Nice looking dialog boxes added
#
#0.72 The code was revamped and tidied up,  Cut the script size down by half
#and made entering command line options easier, and certain combinations had
#bugs squashed on them.  It also used less variables.
#
#Also, dialog help screen entered
#
#0.721 X gets checked for, dialog gets checked for - safer.  Window Managers
#are also checked for existance.
#
#0.73 Checks for screensize
#
#28-6-2001 - fixed help and cancel button bug - it was just a silly piece of
#code writing on my part...
#
#28-8-2001 - Provided condition check to check if X 4 or X 3 is present.
#Thanks to Eric for telling me about the file difference.  
#Please note that this checks for a file called XFree86, which is not in <4.
#If you are running a 4.x X system, with a 3.3.6 (or less) server, please
#specify the parameter "-x 3" at the command line.  The help file and the
#manpage will provide more info on this.
#
# - Added no force parameter to override force (for no reason in particular)
#
# - Added x parameter to specify different X server version
#
# - Backtitles removed so that script now runs under BSD's dialog
#
# - Still haven't fixed grep code to fall back properly 
#
#

#Things to do or done - kind of a log
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#* write install script to build script to order (hard)

# 26-03-2001 - added code to check if X is running, but it is bad.  I may need
# some help with this.
#
# 19-04-2001 - stopped disk writes - thanks to Eric Gillespie for the idea of
# how to do it.
#
#Display number selection has also been added.
#
#30-06-2001 - made display number checking insurance code more portable, and less ps specific
#
# 21-9-2001 - version 0.75 added support for whiptail, fallback to both and ability to switch between dialog and whiptail
#This was totally typed up in vim - Vi IMproved
#looks cool with it's syntax highlighting

#Approx 415 lines of proper code

#Insert extra parameters you want to pass to the X server in the quotes on the
#next line
export meh=""


#export mymenutitle="MyMyX Window Manager Selection for `whoami`"

#######################
#Cleans up before exit#
#######################
#I know it's not too logical having this at the start, but it needs to be
#accessible from any function really, and it's not good to use functions before
#they are defined.

function cleanup()
{
	unset meh
	unset HeLpPath
	unset force
	unset dialogcols
	unset dialogrows
	unset mymenutitle
	unset holder
	unset WinMgr
	unset BpP
	unset dmenuheight
	unset mycols
	unset myrows
	unset xver
	unset yn
	unset dotsperinch
	exit	
}

#Cleanup on some of the kill signals so as not to leave loose ends...
trap "cleanup" 1 2 15 

#Setting screen size to feed to dialog program
if [ "`which stty`" ] ; then
	export mycols=`stty size | cut -d' ' -f2`
	export myrows=`stty size | cut -d' ' -f1`
	else	
	echo "No stty - going to 80x24 screen"
	export mycols='80'
	export myrows='24'
fi


##############################
#Default to 80x25 screen mode#
##############################

if [ "$mycols" = "" ] ; then
	echo "Couldn't get screen size from stty - defaulting to 80x25"
	export mycols='80'
	export myrows='24'
fi

if [ "$myrows" = "" ] ; then
	echo "Couldn't get screen size from stty - defaulting to 80x25"
	export myrows='24'
	export mycols='80'
fi
########################
#Checks if X is running#
########################

#Am I being run from inside X?
if [ "$DISPLAY" != "" ] ; then
	echo "ERROR!"
	echo
	echo "You seem to be running MyMyX from within X or you are on a
	remote connection"
	echo "The DISPLAY environment variable is set!"
	echo 
	echo "This script should be run from a console" 
	cleanup	
fi

##################################
#Checks if startx actually exists#
##################################

if [ "`which startx`" ] ; then
	:
	else
	echo "I can't find the startx script in your path"
	echo "MyMyX needs the startx script to start X"
	echo
	echo "Bye."
	cleanup
fi

#Check for XFree 4 and the new -depth parameter - read notes at the start of
#the file regarding this!!!

if [ "`which XFree86`" ] ; then
	export xver='4'	
	else
#Note that 3 meaning less than 4	
	export xver='3'
fi

#This checks for whiptail and dialog.  Dialog being the default, as whiptail
#support isn't quite fixed yet.  There will be some bottlenecks

if [ "`which dialog`" ] ; then
	export dialogHaNdler='dialog' 
	else
	if [ "`which whiptail`" ] ; then
		export dialogHaNdler='whiptail'
	else
	clear
	echo "You do not seem to have dialog or whiptail on your system.  You must install" 
	echo "dialog or whiptail and have one of them in the path before you can use MyMyX"
	echo
	echo "A non dialog based version will be available soon..."
	cleanup 
	
fi
fi
################
#Checks for cut#
################

if [ `which cut` ] ; then
	:
	else
	echo "You do not have cut in your path!"
	echo "Because of this, display detection will not work, and some things will complain bitterly.  "
	echo "The script will still run, but some features will not work. "
	echo

	#No cut == no automatically got video modes!  I have duplicated here.
	
	export mycols='80'
	export myrows='24'
	echo "Do you want to continue? (Y\N)"
	read yn
	case $yn in
		[Yy]) export myrows='24'
		export mycols='80' ;;
		[Nn]) cleanup ;;
		
		esac
	unset yn
fi
#Check for fgrep - if fgrep is not there, fall back to grep...if nogrep...barf
if [ `which fgrep` ] ; then
	:
	else
	
	if [ `which grep` ] ; then
	alias fgrep='grep'
	else
	echo "Grep does not appear to be present!  Without grep, auto detection will not work, and some things will complain bitterly.  The
	script will still run, but some things will not work. "
	echo
	echo "Do you want to continue? (Y\N)"
	read yn
	case $yn in
		[Yy]) : ;;
		[Nn]) cleanup ;;
			
esac
unset yn
fi
fi
#################################
#Displays non-dialog help screen#
#################################
function helpscreen()
{
echo "Quick help screen"
echo "~~~~~~~~~~~~~~~~~"
echo "MyMyX - An X Window manager and bit depth picker for unix."
echo "Based on, but does not contain any code from Eric's script MyX"
echo
echo "Contributors:"
echo
echo "Eric Gillespie help, teaching me some scripting, where I got the idea"
echo "And of course, me who wrote the code"
echo
echo "Command line options"
echo "~~~~~~~~~~~~~~~~~~~~"
echo "MyMyX <client> <bitdepth> <display number> mode=rowsxcols"
echo 
echo "Client is the window manager to start, bit depth is the bit depth to start up in, mode is the size of your screen - you don't need to specify this unless you want to."
echo
echo "Parameters which are needed to continue, and not given at the command line, the script will prompt you for them."

echo 
echo "You can type 'MyMyX -h' for this screen"
echo
echo "Each Window Manager is assigned with a label and this is what you enter   for client.  This is usually the first letter of the window manager's name."
echo "For a list of window managers and labels, type MyMyX -l"
echo
echo "For bit depth you specifiy the bits per pixel that you want.  Ie 8, 16, 24"
echo
echo "If you don't enter any parameters at the command line, you will get a menu that you can enter them into.  If you haven't used this script  before, it     would be easier to use the menu"
echo
echo "Aditional Options:"
echo
echo "-f 			Skips confirmation screen"
echo
echo "mode			Size of screen to adjust the sizes of the dialogs"
echo "eg MyMyX mode=80x25 would set the dialogs to resize for an 80x25 screen."
echo
echo "Usually, you don't need to specify a screen size as these are picked up automatically by the program."
echo
echo ":<displaynumber>		This will specify the display number to run X on if you want to specify one.  The format is MyMyX :1 to start X on display 1"

}
##############################################
#Displays window manager list at command line#
##############################################
function wm_list()
{
	echo
	echo "G GNOME"
	echo "O Openwindows"
	echo "M MWM - Motif"
	echo "F FVWM"
	echo "L AnotherLevel"
	echo "I ICEWM"
	echo "W WindowMaker"
	echo "A Afterstep"
	echo "4 B4Step"
	echo "B Blackbox"
	echo "9 9wm"
	echo "E Equinox"
	echo "E2 Enlightenment"
	echo "Q QVWM"
	echo "FL fluxbox"
	echo "S Sawmill"
	echo "P Pwm"
	echo "12 wmG"
	echo "T TWM"
	echo "K KDE"
	echo "C CTWM"
	echo "2 FLWM"
	echo "1 Bogus Openstep Workspace MANager"
	echo "X XFCE"
	echo "3 EPIwm"
	echo "N Just an XTERM"
	echo
	echo "The label is to the left of the client's name"
	cleanup
	
}

#################################################################
#Does some safety stuff.  Not yet finished, as I am not bothered#
#################################################################
function vars()
{
	export mY_WinMgr_backup=$WinMgr
	export mY_BpP_backup=$BpP
	unset WinMgr
	unset BpP
}
#Check if X is running on the current display.  No awk here :)
function checkdisp ()
{
	#Should I do another test here for distnum or not bother?
	#No distnum could produce unexpected results in error handling...
#nasty!
if [ "`ps ax | sed s/[0-9]:/notneeded/ | grep X | grep $dispnum | grep -v MyMyX | grep -v grep`" != "" ] ; then

#What's going on here?
$dialogHaNdler --title "Warning" --yesno "There is already an X server running
on that display - choose another?" 9 40
echo $?
case $? in
	1) echo "Bye"
	cleanup  ;; 
	0) export oldDiSp=$dispnum
	export dispnum=$($dialogHaNdler --title "New Display" --radiolist "Please select new display number" 17 42 8 ":1" "Display 1" off ":2" "Display 2" off ":3" "Display 3" off ":4" "Display 4" off ":5" "Display 5" off ":6" "Display 6" off ":7" "Display 7" off "C" "Continue" off 2>&1 1> $(tty) )
#
#And here?!!!
if [ "$?" = "1" ] ; then 
	cleanup
fi


#if [ "$?" > "1" ] ; then 
#	cleanup
#fi
#
#case $? in
#	1) cleanup ;;
#	255) cleanup ;;	
#esac

#if [ "$dispnum" = "C" ] ; then
#	export dispnum=$oldDiSp
#	noconfirm
#fi

esac
fi
}

########################
#This actually starts X#
########################

function noconfirm()
{
checkdisp

#Code to check for X 4.x and compensate, should work (hopefully)
#Thanks to Eric for this :)
#Only problem being, if user is using X 4 and a 3 or lower server.
#Manual parameters have been put in to solve this
	if [ "$xver" = "4" ] ; then
		startx -- $dispnum -depth $BpP $meh
		else
		startx -- $dispnum -bpp $BpP $meh
	fi
	cleanup 
	
}
###################################################
#Checks for force parameter and confirms if needbe#
###################################################
function usure()
{
if [ "$force" = "yes" ]
then
	noconfirm
fi
$dialogHaNdler --title "Confirmation" --yesno "Window Manager will be $WinMgr at $BpP bits on display $dispnum Are you sure?" 9 40
case $? in
	0) noconfirm ;;
	1) cleanup ;;	
esac
}

#Checks if the window manager requested is actually on the system

function checkforwm()
{
if [ "`which $WinMgr`" ] ; then
	usure
	else

	$dialogHaNdler --title "Warning" --yesno "The window manager cannot be found.  Do you want to continue anyway?" 7 40

	case $? in
		1) unset WinMgr
		cleanup ;;
		
		0) usure ;;
		255) unset WinMgr
		cleanup ;;
		
	esac
fi
}
#####################################
#Displays window manager menu dialog#
#####################################
function choosewm()
{
export dialogrows=$(($myrows-5))
export dialogcols=$(($mycols-5))
export dmenuheight=$(($dialogrows-6))

export holder=$($dialogHaNdler --title "Select Window Manager" --menu "Use cursor pad keys to select window manager" "$dialogrows" "$dialogcols" "$dmenuheight" "1" "Bogus Openstep Workspace MANager" 12 wmG 2 FLWM 3 Epiwm 4 B4Step 9 9WM A Afterstep B Blackbox C CTWM "E" "Equinox" "E2" "Enlightenment" F FVWM "F2" "Fvwm2" "Fl" "Fluxbox" G GNOME I ICEWM K KDE L AnotherLevel M MWM O OpenWindows P PWM Q QVWM S Sawfish T TWM W WindowMaker X XFCE "X1" "WM2" "R" "Rat Poison" "H" "Help" "ex" "Exit" 2>&1 1> $(tty) ) 
#Check for cancel button push

if [ "$?" = "255" ] ; then
	cleanup
	
fi

#Check for any special parameters
case $holder in
	0) cleanup ;;
	H) unset holder
	help
	unset WinMgr
	#rm -f ~/menu.tmp
	unset holder 

	choosewm ;;
	ex) unset holder
	cleanup
	cleanup ;;
esac

if [ "$?" = "0" ] ; then
	if [ "$holder" = "" ] ; then
		cleanup
	fi
fi

#If it doesn't get caught by any of those conditions, then leave it to the
#parser
check
}

function help()
{
#Just making sure that helpfile is in same directory before starting
export HeLpPath=`which $0`'.hlp'	
if [ -e "/usr/local/bin/MyMyX.hlp" ] ; then

	if [ "$dialogHaNdler" = "whiptail" ] ; then
	$dialogHaNdler --textbox --title "Help Screen" $HeLpPath 22 77 
else
	$dialogHaNdler --cr-wrap --title "Help Screen" --textbox $HeLpPath 22 77
fi 

else
	$dialogHaNdler --title "Sorry" --msgbox "Help file not readable" 7 40
fi
}
################################
#Get bit depth off of the user #
################################
function bits()
{
#Displays radio list
export holder=$($dialogHaNdler --title "Bit depth" --radiolist "Select bit depth" 15 40 5 \
	"8"  "8  bits per pixel" off \
	"15" "15 bits per pixel" off \
	"16" "16 bits per pixel" on \
	"24" "24 bits per pixel" off \
	"32" "32 bits per pixel" off 2>&1 1> $(tty) )
#Checks for cancel button push
if [ "$?" = "1" ] ; then
	cleanup
fi
#Checks parameter
check
}

#Obviously there is a nine display limit here - sorry :p~~~
#I don't actually need a function here - it could be put in check :-(
function disp ()
{
	case $holder in
		:[0-9]) export dispnum=$holder ;;
	esac
}

##################################################################
#Checks parameters inside parameter holder variable - main parser#
##################################################################
function check () 
{
case $holder in
	-w) export dialogHaNdler='whiptail' ;;
	-W) export dialogHaNdler='whiptail' ;;
	-d) export dialogHaNdler='dialog' ;;
	-D) export dialogHaNdler='dialog' ;;
	X1) export WinMgr='wm2' ;;
	x1) export WinMgr='wm2' ;;
	[Nn]) export WinMgr='xterm' ;;
	1) export WinMgr='bowman' ;;
	12) export WinMgr='wmG' ;;
	2) export WinMgr='flwm' ;;
	4) export WinMgr='B4Step' ;;
	9) export WinMgr='9wm' ;;
	[Aa]) export WinMgr='afterstep' ;;
	[Bb]) export WinMgr='blackbox' ;;
	[Cc]) export WinMgr='ctwm' ;;
	[Ee]) export WinMgr='starteq' ;;
	e2) export WinMgr='enlightenment' ;;
	E2) export WinMgr='enlightenment' ;;
	[Ff]) export WinMgr='fvwm' ;;
	F2) export WinMgr='fvwm2' ;;
	f2) export WinMgr='fvwm2' ;;
	[Gg]) export WinMgr='gnome-session' ;;
	[Ii]) export WinMgr='icewm-gnome' ;;
	[Kk]) export WinMgr='startkde' ;;
	[Ll]) export WinMgr='AnotherLevel' ;;
	[Mm]) export WinMgr='mwm' ;;
	[Oo]) export WinMgr='olwm' ;;
	[Pp]) export WinMgr='pwm' ;;
	[Qq]) export WinMgr='qvwm' ;;
	fl) export WinMgr='fluxbox' ;;
	fL) export WinMgr='fluxbox' ;;
	Fl) export WinMgr='fluxbox' ;;
	FL) export WinMgr='fluxbox' ;;
	[Ss]) export WinMgr='sawfish' ;;
	[Tt]) export WinMgr='twm' ;;
	[Ww]) export WinMgr='wmaker' ;;
	[Xx]) export WinMgr='/etc/X11/xfce/xinitrc' ;;
	3) export WinMgr='epiwm' ;;
	i) export WinMgr='icewm' ;;
	[Rr]) export WinMgr='ratpoison' ;;
	8) export BpP='8' ;;
	16) export BpP='16' ;;
	15) export BpP='15' ;;
	24) export BpP='24' ;;
	32) export BpP='32' ;;
	-dpi) dpifunction ;;
*) modes
disp
esac
#Insurance code :p~~
if [ "$dispnum" = "" ] ; then
	export dispnum=':0' 
fi
}
###############################
#Get manually set screen sizes#
###############################
#I'm not exactly proud of this code
function modes ()
{
#not trying to look like a leet kiddie here, just trying to avoid bumping into
#things.
export tHewoRd=`echo $holder | cut -d'=' -f1`
export tHenum=`echo $holder | cut -d'=' -f2`

# Boy, do I need a lexical scanner
case $tHewoRd in
mode) if [ "$tHenum" != "" ] ; then
	tHecols=`echo $tHenum | cut -d'x' -f1`
	tHerows=`echo $tHenum | cut -d'x' -f2`
	
	if [ "thecols" > 0 ] ; then
		if [ "therows" > 0 ] ; then
	
			if [ "$tHecols" != "" ] ; then
				if [ "tHerows" != "" ] ; then
					export mycols=$tHecols
					export myrows=$tHerows
					unset tHerows
					unset tHecols
					fi
				fi
			fi
		fi
	fi
esac
}
##################################################################
#Check command line for parameters to make script do silly things# 
##################################################################
while [ "$1" != "" ] ; do
	case $1 in
		-meh) shift
		export meh=$1 ;;
		-f) export force='yes' ;;
		-F) export force='yes' ;;
		-nf) unset force ;;
		-h) helpscreen 
		cleanup ;;
		-l) wm_list ;;
		-L) wm_list ;;
		-x) shift
		if [ "$1" = "3" ] ; then
			export xver='3' 
			else
				if [ "$1" = "4" ] ; then
				export xver='4' 
				else
					export holder=$1
					check
		fi 
		fi ;;
		*) export holder=$1 
		check ;;
	esac
	shift
done

#Checks if window manager is not set by this stage.  If so, get it
if [ "$WinMgr" = "" ] ; then
	choosewm
fi
#Checks if bit depth is not set by this stage.  If so, get it
if [ "$BpP" = "" ] ; then
	bits
fi
#Checks if bit depth and wm is set by this stage.  If not, get it
if [ "$BpP" != "" ] ; then
	if [ "$WinMgr" != "" ] ; then
	checkforwm
	fi
fi

#Gee, we passed all the way through the algorithms without doing anything
if [ "$WinMgr" = "" ] ; then
	if [ `which $dialogHaNdler` ] ; then
	:
	else
	echo "The dialog program you set ($dialogHaNdler) was not found - that is a possible reason for the following error:"
	echo
	fi
	echo "Winmgr not set"
	cleanup
fi
if [ "$BpP" = "" ] ; then
	if [ `which $dialogHaNdler` ] ; then
	:
	else
	echo "The dialog program you set ($dialogHaNdler) was not found - that is a possible reason for the following error:"
	echo
	fi

	echo "bits not set"
	cleanup
fi

echo "How did I get here?"
