|
|
|
#!/bin/bash
|
|
|
|
#
|
|
|
|
# CDM: The Console Display Manager
|
|
|
|
#
|
|
|
|
# Copyright (C) 2009-2011, Daniel J Griffiths <ghost1227@archlinux.us>
|
|
|
|
# Thanks to:
|
|
|
|
#
|
|
|
|
# Andrwe beta-testing and submitting the fix for the all
|
|
|
|
# important X incrementation function
|
|
|
|
# brisbin33 code cleanup
|
|
|
|
# tigrmesh finding a critical issue with the gnome-session handler
|
|
|
|
# Profjim several incredibly useful patches
|
|
|
|
# lambchops468 consolekit and hibernation patches
|
|
|
|
# CasperVector Massive rearchitecturing and code sanitation
|
|
|
|
#
|
|
|
|
# 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., 51 Franklin Street, Fifth Floor, Boston,
|
|
|
|
# MA 02110-1301, USA.
|
|
|
|
|
|
|
|
name=$(basename "$0")
|
|
|
|
longname='Console Display Manager'
|
|
|
|
ver='0.6'
|
|
|
|
|
|
|
|
trap '' SIGINT SIGTSTP
|
|
|
|
|
|
|
|
# Helper functions.
|
|
|
|
|
|
|
|
warn() { printf ' \033[01;33m*\033[00m '; echo "$name: $*" > /dev/stderr; }
|
|
|
|
error() { printf ' \033[01;31m*\033[00m '; echo "$name: $*" > /dev/stderr; }
|
|
|
|
exitnormal() { exit 0; }
|
|
|
|
exiterror() { sleep 1; exit 1; }
|
|
|
|
yesno()
|
|
|
|
{
|
|
|
|
[ -z "$1" ] && return 1
|
|
|
|
|
|
|
|
case "$1" in
|
|
|
|
[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) return 0;;
|
|
|
|
[Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) return 1;;
|
|
|
|
*) warn "\`$1' is not a valid argument for \`yesno'; using \`no' for now."
|
|
|
|
esac
|
|
|
|
}
|
|
|
|
|
|
|
|
# Source cdm configurations.
|
|
|
|
|
|
|
|
if [[ -n "$1" ]]; then
|
|
|
|
if [[ -f "$1" ]]
|
|
|
|
then
|
|
|
|
source "$1"
|
|
|
|
else
|
|
|
|
error "config file \`$1' does not exist."
|
|
|
|
exiterror
|
|
|
|
fi
|
|
|
|
elif [[ -f "$HOME/.cdmrc" ]]; then
|
|
|
|
source "$HOME/.cdmrc"
|
|
|
|
elif [[ -f /etc/cdmrc ]]; then
|
|
|
|
source /etc/cdmrc
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Default options.
|
|
|
|
|
|
|
|
binlist=${binlist:-()}
|
|
|
|
namelist=${namelist:-()}
|
|
|
|
flaglist=${flaglist:-()}
|
|
|
|
dialogrc=${dialogrc:-}
|
|
|
|
countfrom=${countfrom:-0}
|
|
|
|
display=${display:-0}
|
|
|
|
xtty=${xtty:-7}
|
|
|
|
locktty=${locktty:-no}
|
|
|
|
serverargs=${serverargs:-'-nolisten tcp'}
|
|
|
|
consolekit=${consolekit:-yes}
|
|
|
|
cktimeout=${cktimeout:-30}
|
|
|
|
|
|
|
|
# Offer all available sessions in /etc/X11/Sessions,
|
|
|
|
# if binlist if not explicitly set in cdmrc.
|
|
|
|
|
|
|
|
if [[ "${#binlist[@]}" == 0 ]]; then
|
|
|
|
binlist=($(ls /etc/X11/Sessions))
|
|
|
|
flaglist=($(sed 's/[[:digit:]]\+/X/g' <<< ${!flaglist[*]}))
|
|
|
|
namelist=(${binlist[@]^})
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Generate the main menu.
|
|
|
|
menu=()
|
|
|
|
for ((count = 0; count < ${#namelist[@]}; count++)); do
|
|
|
|
menu=("${menu[@]}" "$((count+countfrom))" "${namelist[${count}]}")
|
|
|
|
done
|
|
|
|
|
|
|
|
# Override dialog display if only one option is available.
|
|
|
|
if [[ "$count" == 1 ]]; then
|
|
|
|
binindex=0
|
|
|
|
else
|
|
|
|
# Display selection dialog.
|
|
|
|
binindex=$(
|
|
|
|
DIALOGRC="$dialogrc" dialog --colors --stdout \
|
|
|
|
--backtitle "${longname} v${ver}" \
|
|
|
|
--ok-label ' Select ' --cancel-label ' Exit ' \
|
|
|
|
--menu 'Select session' 0 0 0 "${menu[@]}"
|
|
|
|
)
|
|
|
|
if [[ $? != 0 ]]; then
|
|
|
|
clear
|
|
|
|
exitnormal
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Run $bin according to its flag.
|
|
|
|
let binindex-=countfrom
|
|
|
|
bin="${binlist[${binindex}]}"
|
|
|
|
case ${flaglist[$binindex]} in
|
|
|
|
# *C*onsole programs.
|
|
|
|
[Cc])
|
|
|
|
clear
|
|
|
|
# If $bin is a login shell, it might `exec' cdm again, causing an endless
|
|
|
|
# loop. To solve this problem, export $CDM_SPAWN when `exec'ing $bin and
|
|
|
|
# only let the shell automatically `exec' cdm when $CDM_SPAWN is not set.
|
|
|
|
# See also the example shell profile file shipped with the cdm package.
|
|
|
|
CDM_SPAWN=$$ exec $bin
|
|
|
|
;;
|
|
|
|
|
|
|
|
# *X* programs.
|
|
|
|
[Xx])
|
|
|
|
clear
|
|
|
|
|
|
|
|
# If X is already running and locktty=yes, activate it,
|
|
|
|
# otherwise increment.
|
|
|
|
if $(yesno locktty); then
|
|
|
|
# Activate existing X session.
|
|
|
|
if xdpyinfo -display ":$display.0" &> /dev/null; then
|
|
|
|
chvt "$((display+xtty))"
|
|
|
|
exitnormal
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
# Get the first empty display.
|
|
|
|
display=0
|
|
|
|
while ((display < 7)); do
|
|
|
|
if dpyinfo=$(xdpyinfo -display ":$display.0" 2>&1 1>/dev/null) ||
|
|
|
|
# Display is in use by another user.
|
|
|
|
[[ "$dpyinfo" == 'No protocol specified'* ]]
|
|
|
|
then
|
|
|
|
let display+=1
|
|
|
|
else
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
serverargs=":${display} $serverargs vt$((xtty+display))"
|
|
|
|
|
|
|
|
$(yesno consolekit) && launchflags="-c -t $cktimeout"
|
|
|
|
if ! eval cdm-xlaunch $launchflags -- $bin -- $serverargs; then
|
|
|
|
warn "\`cdm-xlaunch' exited unsuccessfully."
|
|
|
|
exiterror
|
|
|
|
fi
|
|
|
|
;;
|
|
|
|
|
|
|
|
*)
|
|
|
|
error "unknown flag: \`${flaglist[$binindex]}'."
|
|
|
|
exiterror
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|