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