startx.cpp revision ac57ed83
1XCOMM!SHELL_CMD
2
3XCOMM
4XCOMM This is just a sample implementation of a slightly less primitive
5XCOMM interface than xinit.  It looks for XINITRC and XSERVERRC environment
6XCOMM variables, then user .xinitrc and .xserverrc files, and then system
7XCOMM xinitrc and xserverrc files, else lets xinit choose its default.
8XCOMM The system xinitrc should probably do things like check for
9XCOMM .Xresources files and merge them in, start up a window manager, and
10XCOMM pop a clock and several xterms.
11XCOMM
12XCOMM Site administrators are STRONGLY urged to write nicer versions.
13XCOMM
14
15xinitdir=XINITDIR
16xterm=XTERM
17xserver=XSERVER
18xinit=XINIT
19bundle_id_prefix=BUNDLE_ID_PREFIX
20xauth=XAUTH
21bindir=__bindir__
22libexecdir=__libexecdir__
23mk_cookie=MK_COOKIE
24has_cookie_maker=HAS_COOKIE_MAKER
25
26unset SESSION_MANAGER
27
28if [ "$(uname -s)" = "Darwin" ] ; then
29
30    XCOMM Check for /usr/bin/X11 and BINDIR in the path, if not add them.
31    XCOMM This allows startx to be placed in a place like /usr/bin or /usr/local/bin
32    XCOMM and people may use X without changing their PATH.
33    XCOMM Note that we put our own bin directory at the front of the path, and
34    XCOMM the standard system path at the back, since if you are using the Xorg
35    XCOMM server there's a pretty good chance you want to bias the Xorg clients
36    XCOMM over the old system's clients.
37
38    case $PATH in
39        *:$bindir | *:$bindir:* | $bindir:*) ;;
40        *) PATH=$bindir:$PATH ;;
41    esac
42
43    XCOMM Now the "old" compiled path
44    oldbindir=/usr/X11R6/bin
45
46    if [ -d "$oldbindir" ] ; then
47        case $PATH in
48            *:$oldbindir | *:$oldbindir:* | $oldbindir:*) ;;
49            *) PATH=$PATH:$oldbindir ;;
50        esac
51    fi
52
53    XCOMM Bourne shell does not automatically export modified environment variables
54    XCOMM so export the new PATH just in case the user changes the shell
55    export PATH
56fi
57
58userclientrc=$HOME/.xinitrc
59[ -f "${XINITRC}" ] && userclientrc="${XINITRC}"
60sysclientrc=XINITDIR/xinitrc
61
62userserverrc=$HOME/.xserverrc
63[ -f "${XSERVERRC}" ] && userserverrc="${XSERVERRC}"
64sysserverrc=$xinitdir/xserverrc
65defaultclient=$xterm
66defaultserver=$xserver
67defaultclientargs=""
68defaultserverargs="-noretro"
69defaultdisplay=""
70clientargs=""
71serverargs=""
72vtarg=""
73
74
75if [ "$(uname -s)" = "Darwin" ] ; then
76
77    if [ "$X11_PREFS_DOMAIN" = "" ] ; then
78        export X11_PREFS_DOMAIN=$bundle_id_prefix".X11"
79    fi
80
81    XCOMM Initialize defaults (this will cut down on "safe" error messages)
82    if ! defaults read $X11_PREFS_DOMAIN cache_fonts > /dev/null 2>&1 ; then
83        defaults write $X11_PREFS_DOMAIN cache_fonts -bool true
84    fi
85
86    if ! defaults read $X11_PREFS_DOMAIN no_auth > /dev/null 2>&1 ; then
87        defaults write $X11_PREFS_DOMAIN no_auth -bool false
88    fi
89
90    if ! defaults read $X11_PREFS_DOMAIN nolisten_tcp > /dev/null 2>&1 ; then
91        defaults write $X11_PREFS_DOMAIN nolisten_tcp -bool true
92    fi
93
94    if ! defaults read $X11_PREFS_DOMAIN enable_iglx > /dev/null 2>&1 ; then
95        defaults write $X11_PREFS_DOMAIN enable_iglx -bool false
96    fi
97
98    XCOMM First, start caching fonts
99    if [ "$(defaults read $X11_PREFS_DOMAIN cache_fonts)" = 1 ] ; then
100        if [ -x $bindir/font_cache ] ; then
101            $bindir/font_cache
102        elif [ -x $bindir/font_cache.sh ] ; then
103            $bindir/font_cache.sh
104        elif [ -x $bindir/fc-cache ] ; then
105            $bindir/fc-cache
106        fi
107    fi
108
109    if [ -x $libexecdir/privileged_startx ] ; then
110	XCOMM Don't push this into the background because it can cause
111	XCOMM a race to create /tmp/.X11-unix
112	$libexecdir/privileged_startx
113    fi
114
115    if [ "$(defaults read $X11_PREFS_DOMAIN no_auth)" = 0 ] ; then
116        enable_xauth=1
117    else
118        enable_xauth=0
119    fi
120
121    if [ "$(defaults read $X11_PREFS_DOMAIN nolisten_tcp)" = 1 ] ; then
122        defaultserverargs="$defaultserverargs -nolisten tcp"
123    else
124        defaultserverargs="$defaultserverargs -listen tcp"
125    fi
126
127    if [ "$(defaults read $X11_PREFS_DOMAIN enable_iglx)" = 1 ] ; then
128        defaultserverargs="$defaultserverargs +iglx +extension GLX"
129    else
130        defaultserverargs="$defaultserverargs -iglx"
131    fi
132
133    XCOMM The second check is the real one.  The first is to hopefully avoid
134    XCOMM needless syslog spamming.
135    if defaults read $X11_PREFS_DOMAIN 2> /dev/null | grep -q 'dpi' && defaults read $X11_PREFS_DOMAIN dpi > /dev/null 2>&1 ; then
136        defaultserverargs="$defaultserverargs -dpi $(defaults read $X11_PREFS_DOMAIN dpi)"
137    fi
138
139else
140    enable_xauth=1
141fi
142
143XCOMM Automatically determine an unused $DISPLAY
144d=0
145while true ; do
146    [ -e "/tmp/.X$d-lock" -o -S "/tmp/.X11-unix/X$d" ] || break
147    d=$(($d + 1))
148done
149defaultdisplay=":$d"
150unset d
151
152whoseargs="client"
153while [ "$1" != "" ]; do
154    case "$1" in
155    XCOMM '' required to prevent cpp from treating "/*" as a C comment.
156    /''*|\./''*)
157	if [ "$whoseargs" = "client" ]; then
158	    if [ "$client" = "" ] && [ "$clientargs" = "" ]; then
159		client="$1"
160	    else
161		clientargs="$clientargs $1"
162	    fi
163	else
164	    if [ "$server" = "" ] && [ "$serverargs" = "" ]; then
165		server="$1"
166	    else
167		serverargs="$serverargs $1"
168	    fi
169	fi
170	;;
171    --)
172	whoseargs="server"
173	;;
174    *)
175	if [ "$whoseargs" = "client" ]; then
176	    clientargs="$clientargs $1"
177	else
178	    XCOMM display must be the FIRST server argument
179	    if [ "$serverargs" = "" ] && @@
180		 expr "$1" : ':[0-9][0-9]*$' > /dev/null 2>&1; then
181		display="$1"
182	    else
183		serverargs="$serverargs $1"
184	    fi
185	fi
186	;;
187    esac
188    shift
189done
190
191XCOMM process client arguments
192if [ "$client" = "" ]; then
193    client=$defaultclient
194
195    XCOMM For compatibility reasons, only use startxrc if there were no client command line arguments
196    if [ "$clientargs" = "" ]; then
197        if [ -f "$userclientrc" ]; then
198            client=$userclientrc
199        elif [ -f "$sysclientrc" ]; then
200            client=$sysclientrc
201        fi
202    fi
203fi
204
205XCOMM if no client arguments, use defaults
206if [ "$clientargs" = "" ]; then
207    clientargs=$defaultclientargs
208fi
209
210XCOMM process server arguments
211if [ "$server" = "" ]; then
212    server=$defaultserver
213
214if [ "$(uname -s)" = "Linux" ] ; then
215    XCOMM When starting the defaultserver start X on the current tty to avoid
216    XCOMM the startx session being seen as inactive:
217    XCOMM "https://bugzilla.redhat.com/show_bug.cgi?id=806491"
218    tty=$(tty)
219    if expr "$tty" : '/dev/tty[0-9][0-9]*$' > /dev/null; then
220        tty_num=${tty#/dev/tty}
221        vtarg="vt$tty_num -keeptty"
222    fi
223fi
224
225    XCOMM For compatibility reasons, only use xserverrc if there were no server command line arguments
226    if [ "$serverargs" = "" ] && [ "$display" = "" ]; then
227	if [ -f "$userserverrc" ]; then
228	    server=$userserverrc
229	elif [ -f "$sysserverrc" ]; then
230	    server=$sysserverrc
231	fi
232    fi
233fi
234
235XCOMM if no server arguments, use defaults
236if [ "$serverargs" = "" ]; then
237    serverargs=$defaultserverargs
238fi
239
240XCOMM if no vt is specified add vtarg (which may be empty)
241have_vtarg="no"
242for i in $serverargs; do
243    if expr "$i" : 'vt[0-9][0-9]*$' > /dev/null; then
244        have_vtarg="yes"
245    fi
246done
247if [ "$have_vtarg" = "no" ]; then
248    serverargs="$serverargs $vtarg"
249fi
250
251XCOMM if no display, use default
252if [ "$display" = "" ]; then
253    display=$defaultdisplay
254fi
255
256if [ "$enable_xauth" = 1 ] ; then
257    if [ "$XAUTHORITY" = "" ]; then
258        XAUTHORITY=$HOME/.Xauthority
259        export XAUTHORITY
260    fi
261
262    removelist=
263
264    XCOMM set up default Xauth info for this machine
265    hostname="$(uname -n)"
266
267    authdisplay=${display:-:0}
268    if [ -n "$has_cookie_maker" ] && [ -n "$mk_cookie" ] ; then
269        mcookie=$($mk_cookie)
270    else
271        if [ -r /dev/urandom ]; then
272            mcookie=$(dd if=dev/urandom bs=16 count=1 2>/dev/null | hexdump -e \\"%08x\\")
273        else
274            mcookie=$(dd if=/dev/random bs=16 count=1 2>/dev/null | hexdump -e \\"%08x\\")
275        fi
276    fi
277    if [ "$mcookie" = "" ]; then
278        echo "Couldn't create cookie"
279        exit 1
280    fi
281    dummy=0
282
283    XCOMM create a file with auth information for the server. ':0' is a dummy.
284    xserverauthfile=$HOME/.serverauth.$$
285    trap "rm -f '$xserverauthfile'" HUP INT QUIT ILL TRAP BUS TERM
286    xauth -q -f "$xserverauthfile" << EOF
287add :$dummy . $mcookie
288EOF
289
290    case "$(uname -s)" in
291    CYGWIN*|Darwin)
292        xserverauthfilequoted=$(echo ${xserverauthfile} | sed "s/'/'\\\\''/g")
293        serverargs=${serverargs}" -auth '"${xserverauthfilequoted}"'"
294        ;;
295    *)
296        serverargs=${serverargs}" -auth "${xserverauthfile}
297        ;;
298    esac
299
300    XCOMM now add the same credentials to the client authority file
301    XCOMM if '$displayname' already exists do not overwrite it as another
302    XCOMM server may need it. Add them to the '$xserverauthfile' instead.
303    for displayname in $authdisplay $hostname$authdisplay; do
304        authcookie=$(xauth list "$displayname" @@
305        | sed -n 's/.*'"$displayname"'[[:space:]*].*[[:space:]*]//p' 2>/dev/null);
306        if [ "z${authcookie}" = "z" ] ; then
307            $xauth -q << EOF
308add $displayname . $mcookie
309EOF
310        removelist="$displayname $removelist"
311        else
312            dummy=$(($dummy+1));
313            $xauth -q -f "$xserverauthfile" << EOF
314add :$dummy . $authcookie
315EOF
316        fi
317    done
318fi
319
320case "$(uname -s)" in
321CYGWIN_NT*|Darwin)
322    eval $xinit \"$client\" $clientargs -- \"$server\" $display $serverargs
323    ;;
324*)
325    $xinit "$client" $clientargs -- "$server" $display $serverargs
326    ;;
327esac
328retval=$?
329
330if [ "$enable_xauth" = 1 ] ; then
331    if [ "$removelist" != "" ]; then
332        $xauth remove $removelist
333    fi
334    if [ "$xserverauthfile" != "" ]; then
335        rm -f "$xserverauthfile"
336    fi
337fi
338
339XCOMM various machines need special cleaning up
340if [ "$(uname -s)" = "Linux" ]; then
341    if command -v deallocvt > /dev/null 2>&1; then
342        deallocvt
343    fi
344fi
345
346if [ "$(uname -s)" = "SunOS" ]; then
347    kbd_mode -a
348fi
349
350exit $retval
351