Some further error handling regarding Xinerama
[grml-x.git] / grml-x
1 #!/bin/zsh
2 # Filename:      grml-x
3 # Purpose:       wrapper for startx on grml [providing new xconfiguration tool]
4 # Authors:       grml-team (grml.org), (c) Michael Prokop <mika@grml.org>
5 # Bug-Reports:   see http://grml.org/bugs/
6 # License:       This file is licensed under the GPL v2.
7 # Latest change: Don Jul 12 02:53:42 CEST 2007 [mika]
8 ################################################################################
9
10 # debugging {{{
11 # usage: DEBUG=1 grml-x ..... 2>/tmp/grml-x-debug.log
12   if [[ $DEBUG -gt 0 ]]; then
13       setopt xtrace
14   fi
15 # }}}
16
17 # functions and color {{{
18   # use colors only if not booted with nocolor bootoption
19   if ! grep -q nocolor /proc/cmdline ; then
20      autoload colors ; colors
21      [ -r /etc/grml_colors ] && . /etc/grml_colors
22   fi
23
24   # some functions like getBootParam
25   if [ -r /etc/grml/script-functions -a -r /etc/grml/sh-lib ] ; then
26      source /etc/grml/script-functions
27      source /etc/grml/sh-lib
28   else
29     echo 'Error: sourcing function files failed. Exiting.'
30     exit 1
31   fi
32
33   check4root &>/dev/null && ROOT='1' || ROOT=''
34 # }}}
35
36 # set variables  {{{
37   PROGRAMNAME=${0##*/}
38   HWINFO='/usr/sbin/hwinfo'
39   DATE=$(date)
40   [ -n "$XINITRC" ] || XINITRC="$HOME/.xinitrc"
41
42   # temporary files
43   HWINFO_TMP="/tmp/hwinfo.$$"
44   MONITORINFO="/tmp/monitorinfo.$$"
45   MOUSEINFO="/tmp/mouse.$$"
46
47   if [ -r /etc/sysconfig/keyboard ] ; then
48     source /etc/sysconfig/keyboard
49   else
50     XKEYBOARD='us'
51   fi
52
53   XSERVER="Xorg"
54   XCONFIG='/etc/X11/xorg.conf'
55   KEYBOARD="# Driver      \"kbd\"
56 #         Option      \"XkbRules\"   \"xfree86\"
57 #         Option      \"XkbRules\"   \"xorg\"
58 #         Option      \"XkbModel\"   \"pc105\"
59 #         Option      \"XkbLayout\"  \"${XKEYBOARD},us\"
60 #         Option      \"XkbVariant\" \"nodeadkeys\""
61
62   # check for font path
63   if [ -d /usr/share/fonts/X11 ] ; then
64      XFONTS="        FontPath     \"/usr/share/fonts/X11/misc\"
65         FontPath     \"/usr/share/fonts/X11/100dpi/:unscaled\"
66         FontPath     \"/usr/share/fonts/X11/75dpi/:unscaled\"
67         FontPath     \"/usr/share/fonts/X11/Type1\"
68         FontPath     \"/usr/share/fonts/X11/100dpi\"
69         FontPath     \"/usr/share/fonts/X11/75dpi\""
70   fi
71   # /usr/X11R6/lib/X11/fonts exists nearly everywhere, assume
72   # /usr/X11R6/lib/X11/fonts as valid font path only if fonts.dir
73   # exists for "misc"
74   if [ -r /usr/X11R6/lib/X11/fonts/misc/fonts.dir ] ; then
75       XFONTS="$XFONTS
76         FontPath     \"/usr/X11R6/lib/X11/fonts/Type1\"
77         FontPath     \"/usr/X11R6/lib/X11/fonts/misc:unscaled\"
78         FontPath     \"/usr/X11R6/lib/X11/fonts/misc\"
79         FontPath     \"/usr/X11R6/lib/X11/fonts/75dpi:unscaled\"
80         FontPath     \"/usr/X11R6/lib/X11/fonts/75dpi\"
81         FontPath     \"/usr/X11R6/lib/X11/fonts/100dpi:unscaled\"
82         FontPath     \"/usr/X11R6/lib/X11/fonts/100dpi\""
83   fi
84 # }}}
85
86 # make sure we don't leave any temp files {{{
87 bailout() {
88   rm -f "$HWINFO_TMP" "$MONITORINFO" "$MOUSEINFO"
89   [ -n "$1" ] && EXIT="$1" || EXIT="1"
90   print "$bg[black]$fg[red]${bold_color}Exiting...${reset_color}">&2
91   exit "$EXIT"
92 }
93
94 trap bailout 1 2 3 15
95 # }}}
96
97 # warn if running as user root {{{
98   if [ -n "$ROOT" ] ; then
99      if [ -r /etc/grml_cd ] ; then
100         print "$bg[black]$fg[red]${bold_color}Warning: Please do not run grml-x as user root.${reset_color}"
101         print "$bg[black]$fg[red]${bold_color}Running grml-x as user root is *not* supported!${reset_color}"
102         print "$bg[black]$fg[red]${bold_color}Switch to user grml or run su - grml -c 'grml-x ...' instead.${reset_color}"
103         print ''
104      else
105         print "$bg[black]$fg[red]${bold_color}Warning: Please do not run X.org as user root!${reset_color}"
106         print "$bg[black]$fg[red]${bold_color}As soon as you have a working $XCONFIG please use startx instead of grml-x.${reset_color}"
107         print ''
108      fi
109   fi
110   fstabuser=$(grep ':x:1000:' /etc/passwd)
111   fstabuser=${fstabuser%%[:]*}
112 # }}}
113
114 # usage information {{{
115 usage()
116 {
117   if [[ $1 != '' ]] ; then echo 1>&2 "\n$1" ; fi
118   print "$bg[black]$fg[red]$bold_color"
119   print 1>&2 "
120 Usage: $PROGRAMNAME
121        $PROGRAMNAME [-options] windowmanager
122
123 Usage examples:
124   $PROGRAMNAME wmii
125   $PROGRAMNAME fluxbox
126   $PROGRAMNAME openbox
127   $PROGRAMNAME -force -nostart fluxbox
128   $PROGRAMNAME -nosynaptics fluxbox
129   $PROGRAMNAME -nosync fluxbox
130   $PROGRAMNAME -noddc wmii
131   $PROGRAMNAME -xinerama -composite wmii
132   $PROGRAMNAME -module radeon -mode 1024x768 -vsync 60 openbox
133   XINITRC=~/.xinitrc $PROGRAMNAME openbox
134   $PROGRAMNAME -display 8 openbox
135
136 More information on grml-x can be found in the manual page: man grml-x
137
138 Report bugs, send wishes and feedback to the grml team:
139 http://grml.org/bugs/ - contact (at) grml.org
140 "
141   print "${reset_color}"
142   exit 2
143 }
144 # }}}
145
146 # writehwinfo {{{
147 writehwinfo()
148 {
149    if [ -n "$ROOT" ] ; then
150      su - $fstabuser -c "$HWINFO > $HWINFO_TMP"
151    else
152      $HWINFO > $HWINFO_TMP
153    fi
154 }
155 # }}}
156
157 # monitor {{{
158 monitor()
159 {
160   sudo $HWINFO --monitor > $MONITORINFO
161 }
162 # }}}
163
164 # mode {{{
165 mode()
166 {
167    [ -r "$MONITORINFO" ] || monitor # get monitor settings
168    modes=$(perl -e 'while (<STDIN>) {if (/  Resolution:/) { s/.*\s+(\d+x\d+).*/$1/; print} }' < $MONITORINFO |
169 sort -nur | perl -ne 's/\s+/ /; s/(\d+x\d+)/"$1"/; print')
170
171    if [ -n "$XINERAMA" ] ; then
172
173       print "$fg[green]
174
175 Option for $fg[yellow]Xinerama$fg[green] found, please use xrandr inside X.org for your further configuration!
176 Trying to identify monitors now..."
177
178       # make sure we have information from 2 monitors:
179       # - first one from 'hwinfo --monitor'      => $MONITORINFO
180       # - second one from 'hwinfo --framebuffer' => $FRAMEBUFFER
181       FRAMEBUFFER=$(hwinfo --framebuffer | grep 'Mode 0x.* bits' | head -1)
182       if [ -z "$FRAMEBUFFER" ] ; then
183          print "$fg[red]
184 Fatal: could not identify two monitors - no chance to
185        set up multihead using Xinerama - sorry. :-(
186
187 Please run grml-x without the -xinerama option to start
188 X anyway (dropping support for Xinerama of course) and
189 contact grml developers if you have any further useful
190 information.                  => http://grml.org/bugs/
191 "
192          bailout 10
193       fi
194
195       # check whether we can read the $MONITORINFO file
196       if ! [ -r "$MONITORINFO" ] ; then
197          print "$fg[red]
198 Fatal: could not identify monitor - no chance to
199        set up multihead using Xinerama - sorry. :-(
200 "
201          bailout 11
202       else
203          # Currently we only know that it works with current intel driver,
204          # so inform user about that:
205          if [[ "$MODULE" != "intel" ]] ; then
206             print "$fg[red]
207
208 Warning: using a non-intel driver - trying Xinerama setup anyway.
209 If it worked please contact grml developers providing information
210 about your setup so we can adjust grml-x according!
211
212       -> http://grml.org/contact/
213
214 Sleeping for 10 seconds now... Will continue then...
215 Just press Ctrl-C to cancel operation.
216 "
217             sleep 10
218          fi
219
220          # now calculate Virtual size for use with Xinerama
221          HORIZ_RES1="$(grep 'Max. Resolution:' $MONITORINFO | sed 's/    Max\. Resolution: \(.*\)x\(.*\)/\1/')"
222          VERIZ_RES1="$(grep 'Max. Resolution:' $MONITORINFO | sed 's/    Max\. Resolution: \(.*\)x\(.*\)/\2/')"
223          # it might happen that we don't have a Max Resolution in hwinfo output :-/
224          # fall back to a generic value then...
225          # TODO: check out how to get resolution of external monitor from console
226          if [ -z "$HORIZ_RES1" ] ; then
227             HORIZ_RES1="1024"
228             VERIZ_RES1="768"
229          fi
230
231          # get maximum of output
232          HORIZ_RES2="$(echo $FRAMEBUFFER | grep 'Mode 0x' | sed 's/  Mode 0x.*: \(.*\)x.*/\1/'| sort -u | head -1)"
233          VERIZ_RES2="$(echo $FRAMEBUFFER | grep 'Mode 0x' | sed 's/  Mode 0x.*x\(.*\) (.*/\1/' | sort -u | head -1)"
234
235          if [ -n "$HORIZ_RES1" -a -n "$VERIZ_RES1" -a -n "$HORIZ_RES2" -a -n "$VERIZ_RES2" ] ; then
236             if [ "$(echo $VERIZ_RES1" - "$VERIZ_RES2 | bc -l)" -eq 0 ] ; then
237             VERIZ_RESULT="$VERIZ_RES1"
238             elif [ "$VERIZ_RES1" -gt "$VERIZ_RES2" ] ; then
239                VERIZ_RESULT="$VERIZ_RES1"
240             else
241                VERIZ_RESULT="$VERIZ_RES2"
242             fi
243
244             HORIZ_RESULT=$(echo $HORIZ_RES1 + $HORIZ_RES2 | bc -l)
245
246             # important: keep newline for appropriate placing below $MODES!
247             if [ -n "$HORIZ_RESULT" ] ; then
248                VIRTUAL="
249                 Virtual $HORIZ_RESULT $VERIZ_RES1"
250             fi
251          fi
252        fi
253    fi
254
255    if [[ -n $NODDC ]] ; then
256      MODES="Modes \"1024x768\" \"800x600\" \"640x480\"  \"1600x1200\" \"1280x1024\" \"1280x960\"$VIRTUAL"
257    elif [[ "$modes" == "\"1024x768\" " || -z $modes ]] ; then
258      MODES="# Modes \"1024x768\" \"800x600\" \"640x480\"  \"1600x1200\" \"1280x1024\" \"1280x960\"$VIRTUAL"
259    else
260      MODES="# Modes $modes$VIRTUAL"
261    fi
262 }
263 # }}}
264
265 # sync - get hsync/vsync settings {{{
266 sync()
267 {
268    [ -r "$MONITORINFO" ] || monitor # get monitor settings
269    vsyncval=$(awk '/Vert. Sync Range:/{print $4}' $MONITORINFO | sed 's/-/.0 - / ; s/$/.0/' | head -1)
270    hsyncval=$(awk '/Hor. Sync Range:/{print $4}'  $MONITORINFO | sed 's/-/.0 - / ; s/$/.0/' | head -1)
271    if [ -z $vsyncval ] ; then
272      vsyncval='50.0 - 60.0'
273    fi
274    if [ -z $hsyncval ] ; then
275      hsyncval='28.0 - 96.0'
276    fi
277 }
278 # }}}
279
280 # mouse {{{
281 mouse()
282 {
283    sudo $HWINFO --mouse > $MOUSEINFO
284
285    # SynPS/2 Synaptics TouchPad
286    if grep -q 'Device:.*Synaptics' "$MOUSEINFO" ; then
287     if [[ "$SYNAPTICS" == "yes" ]] ; then # check for '-nosynaptics'-option
288      MOUSEDRIVER='synaptics'
289      SYNMOUSE='InputDevice    "Synaptics"  "AlwaysCore"'
290      SYNMOUSEDETAIL="
291 Section \"InputDevice\"
292   Driver        \"synaptics\"
293   Identifier    \"Synaptics\"
294   Option        \"Device\"        \"/dev/psaux\"
295   Option        \"Protocol\"      \"auto-dev\"
296   Option        \"LeftEdge\"      \"1700\"
297   Option        \"RightEdge\"     \"5300\"
298   Option        \"TopEdge\"       \"1700\"
299   Option        \"BottomEdge\"    \"4200\"
300   Option        \"FingerLow\"     \"25\"
301   Option        \"FingerHigh\"    \"30\"
302   Option        \"ZAxisMapping\"   \"4 5\"
303   Option        \"MaxTapTime\"    \"180\"
304   Option        \"MaxTapMove\"    \"220\"
305   Option        \"VertScrollDelta\" \"100\"
306   Option        \"MinSpeed\"      \"0.06\"
307   Option        \"MaxSpeed\"      \"0.12\"
308   Option        \"AccelFactor\" \"0.0010\"
309 #  Option       \"SHMConfig\"     \"on\"
310 #  Option       \"Repeater\"      \"/dev/ps2mouse\"
311 EndSection
312 "
313     else
314      MOUSEDRIVER='mouse'
315      SYNMOUSEDETAIL=""
316      SYNMOUSE='# No synaptics touchpad detected.'
317     fi
318    else
319
320     # AlpsPS/2 ALPS TouchPad (with Synapticsdriver)
321     if grep -q 'Device:.*ALPS' "$MOUSEINFO" ; then
322      if [[ "$SYNAPTICS" == "yes" ]] ; then # check for '-nosynaptics'-option
323       MOUSEDRIVER='synaptics'
324       SYNMOUSE='InputDevice    "Synaptics"  "AlwaysCore"'
325       SYNMOUSEDETAIL="
326 Section \"InputDevice\"
327   Driver        \"synaptics\"
328   Identifier    \"Synaptics\"
329   Option        \"Device\"        \"/dev/psaux\"
330   Option        \"Protocol\"      \"auto-dev\"
331   Option        \"LeftEdge\"      \"120\"
332   Option        \"RightEdge\"     \"850\"
333   Option        \"TopEdge\"       \"120\"
334   Option        \"BottomEdge\"    \"650\"
335   Option        \"FingerLow\"     \"14\"
336   Option        \"FingerHigh\"    \"15\"
337   Option        \"ZAxisMapping\"   \"4 5\"
338   Option        \"MaxTapTime\"    \"180\"
339   Option        \"MaxTapMove\"    \"50\"
340   Option        \"MaxDoubleTapTime\"    \"100\"
341   Option        \"VertScrollDelta\" \"20\"
342   Option        \"HorizScrollDelta\" \"20\"
343   Option        \"MinSpeed\"      \"0.3\"
344   Option        \"MaxSpeed\"      \"2.00\"
345   Option        \"AccelFactor\" \"0.030\"
346   Option        \"UpDownScrolling\" \"1\"
347   Option        \"EmulateMiddleButtonTime\" \"75\"
348   Option        \"CircularScrolling\" \"1\"
349   Option        \"CircScrollDelta\" \"0.1\"
350   Option        \"CircScrollTrigger\" \"8\"
351 #  Option       \"SHMConfig\"     \"on\"
352 #  Option       \"Repeater\"      \"/dev/ps2mouse\"
353 EndSection
354 "
355      else
356       MOUSEDRIVER='mouse'
357       SYNMOUSEDETAIL=""
358       SYNMOUSE='# No alps touchpad detected.'
359      fi
360     else
361       SYNMOUSE='# No synaptics/alps touchpad present.'
362     fi
363    fi
364
365    # USB-PS/2 Optical Mouse
366    if [ -n "$USE_USB" ] ; then
367      USBMOUSE='InputDevice    "USB Mouse"     "CorePointer"'
368      USBMOUSEDETAIL="
369 Section \"InputDevice\"
370         Identifier      \"USB Mouse\"
371         Driver          \"mouse\"
372         Option          \"Device\"                \"/dev/input/mice\"
373         Option          \"Protocol\"              \"auto\"
374         Option          \"ZAxisMapping\"          \"4 5\"
375         Option          \"Buttons\"               \"5\"
376         Option          \"SendCoreEvents\"        \"true\"
377 EndSection
378 "
379    else
380      USBMOUSE='# InputDevice    "USB Mouse"     "CorePointer"'
381      USBMOUSEDETAIL=''
382    fi
383
384    if grep -q 'Device:.*Serial' "$MOUSEINFO" ; then
385      SERIAL='yes'
386      SERMOUSE='InputDevice    "Serial Mouse"     "CorePointer"'
387      SERMOUSEDETAIL="
388 Section \"InputDevice\"
389         Identifier  \"Serial Mouse\"
390         Driver      \"mouse\"
391         Option      \"Device\" \"/dev/ttyS0\"
392         Option      \"Protocol\" \"Microsoft\"
393         Option      \"Emulate3Buttons\" \"true\"
394         Option      \"Emulate3Timeout\" \"70\"
395         Option      \"SendCoreEvents\"  \"true\"
396 EndSection
397 "
398    else
399      SERMOUSE='# No serial mouse detected.'
400      SERMOUSEDETAIL=''
401    fi
402
403    # ImExPS/2 Logitech Explorer Mouse
404    # "PS2++ Logitech MX Mouse"
405    if [ -n "$USE_PS2" ] ; then
406       PS2='yes'
407       PS2MOUSE='InputDevice    "PS/2 Mouse"    "CorePointer"'
408       PS2MOUSEDETAIL="
409 Section \"InputDevice\"
410         Identifier  \"PS/2 Mouse\"
411         Driver      \"mouse\"
412         Option      \"Device\" \"/dev/input/mice\"
413         # Option      \"Device\" \"/dev/psaux\"
414         Option      \"Protocol\" \"PS/2\"
415         Option      \"Emulate3Buttons\" \"true\"
416         Option      \"Emulate3Timeout\" \"70\"
417         Option      \"SendCoreEvents\"  \"true\"
418 EndSection
419 "
420      else
421       PS2MOUSE='# InputDevice    "PS/2 Mouse"    "CorePointer"'
422       PS2MOUSEDETAIL=''
423      fi
424
425      EVDEV_MOUSE="
426 # Section \"InputDevice\"
427 #         Identifier      \"Generic Mouse\"
428 #         Driver          \"evdev\"
429 #         Option          \"Device\"                \"/dev/input/mice\"
430 #         Option          \"Protocol\"              \"auto\"
431 #         Option          \"ZAxisMapping\"          \"4 5\"
432 #         Option          \"Buttons\"               \"5\"
433 #         Option          \"SendCoreEvents\"        \"true\"
434 # EndSection
435 "
436
437    MOUSE="        $USBMOUSE
438         $PS2MOUSE
439         $SYNMOUSE
440         $SERMOUSE"
441 }
442 # }}}
443
444 # commandline parsing {{{
445 parse_options()
446 {
447    zparseopts -K -- module:=o_module help=o_help noddc=o_noddc nosync=o_nosync \
448                     vsync:=o_vsync hsync:=o_hsync mode:=o_mode force=o_force display:=o_display   \
449                     nostart=o_nostart nodpms=o_nodpms nosynaptics=o_nosynaptics nousb=o_nousb \
450                     nops2=o_nops2 genmouse=o_genmouse novref=o_novref nohsync=o_nohsync \
451                     fallback=o_fallback usb=o_usb ps2=o_ps2 composite=o_composite \
452                     xinerama=o_xinerama
453
454    if [[ $# == 0 || "$o_help" != "" || "$1" == '-h' || "$1" == '--help' ]]; then
455       usage
456    fi
457
458    if [[ "$o_force" != "" ]]; then
459       FORCE='yes'
460    fi
461
462    if [[ "$o_fallback" != "" ]]; then
463       FALLBACK="yes"
464       if [ -r /etc/X11/xorg.conf.example ] ; then
465          sudo cp /etc/X11/xorg.conf.example $XCONFIG
466          print "$bold_color$fg[blue]Copying /etc/X11/xorg.conf.example to $XCONFIG as requested via fallback option."
467       else
468          echo 'Error: /etc/X11/xorg.conf.example not readable, exiting.'
469          exit 1
470       fi
471    fi
472
473    if [[ "$o_nodpms" != "" ]]; then
474       DPMS='Option       "DPMS"      "false"'
475    else
476       DPMS='Option       "DPMS"      "true"'
477    fi
478
479    if [[ "$o_noddc" != "" ]]; then
480       NODDC="yes"
481    fi
482
483    if [[ "$o_vsync" != "" ]]; then
484       FORCE="yes"
485    fi
486
487    if [[ "$o_hsync" != "" ]]; then
488       FORCE="yes"
489    fi
490
491    if [[ "$o_nousb" != "" ]]; then
492       echo 'Warning: option -nousb is deprecated.'>&2
493    fi
494
495    if [[ "$o_usb" != "" ]]; then
496       USE_USB='yes'
497    fi
498
499    if [[ "$o_nops2" != "" ]]; then
500       echo 'Warning: optino -nops2 is deprecatedË™'>&2
501    fi
502
503    if [[ "$o_ps2" != "" ]]; then
504       USE_PS2='yes'
505    fi
506
507    if [[ "$o_genmouse" != "" ]]; then
508       GENERICMOUSE='yes'
509    fi
510
511    if [[ "$o_nosynaptics" != "" ]]; then
512       SYNAPTICS='no'
513    else
514       SYNAPTICS='yes'
515    fi
516
517    if [[ "$o_nostart" != "" ]]; then
518       NOSTART="yes"
519    fi
520
521    DISPLAY=$o_display[2]
522
523    eval WINDOWMANAGER=\${$#}
524
525    if [[ "$XKEYBOARD" == de ]] ; then
526       KEYBOARD="$KEYBOARD
527 #         Option      \"XkbVariant\" \"nodeadkeys\""
528    fi
529
530    if [ -n "$FORCE" -o ! -r "$XCONFIG" -a -z "$FALLBACK" ] ; then
531      print -n "$bold_color$fg[blue]Gathering hardware information...$fg[red]"
532
533      sync # get hsync/vsync
534
535      if [ -z "$o_hsync" ] ; then
536        o_hsync=(-hsync "$hsyncval")
537        HSYNC=$o_hsync[2]
538        HORIZSYNC="        HorizSync    $HSYNC"
539      else
540        o_hsync=(-hsync "$o_hsync[2]")
541        HSYNC=$o_hsync[2]
542        HORIZSYNC="        HorizSync    $HSYNC"
543      fi
544
545      if [ -z "$o_vsync" ] ; then
546        o_vsync=(-vsync "$vsyncval")
547        VSYNC=$o_vsync[2]
548        VERTISYNC="        VertRefresh  $VSYNC"
549      else
550        o_vsync=(-vsync "$o_vsync[2]")
551        VSYNC=$o_vsync[2]
552        VERTISYNC="        VertRefresh  $VSYNC"
553      fi
554
555      if [[ "$o_nosync" != "" ]]; then
556         HORIZSYNC="#       HorizSync   28.0 - 96.0  # deactivated via -nosync option of grml-x"
557         VERTISYNC="#       VertRefresh 50.0 - 60.0  # deactivated via -nosync option of grml-x"
558      fi
559
560      if [[ "$o_nohsync" != "" ]]; then
561         HORIZSYNC="#       HorizSync   28.0 - 96.0  # deactivated via -nohsync option of grml-x"
562      fi
563
564      if [[ "$o_novref" != "" ]]; then
565         VERTISYNC="#       VertRefresh 50.0 - 60.0  # deactivated via -novref option of grml-x"
566      fi
567
568      if [[ "$o_xinerama" != "" ]]; then
569         XINERAMA=1
570      fi
571
572      if [[ "$o_composite" != "" ]]; then
573         COMPOSITE="Section \"Extensions\"
574     Option \"Composite\" \"Enable\"
575 EndSection"
576      else
577         COMPOSITE="#Section \"Extensions\"
578 #    Option \"Composite\" \"Enable\"
579 #EndSection"
580      fi
581
582      # write hwinfo stuff
583      writehwinfo
584
585      # monitor stuff
586      MONITOR=$(awk '/monitor.1:/{print $3}' $HWINFO_TMP)
587      [[ $MONITOR != 'ddc' ]] && NODDC=yes
588
589      # module handling
590      MODULE=$o_module[2]
591      if [ -z "$MODULE" ] ; then
592        MODULE="$(getBootParam xmodule 2>/dev/null)"
593        if [ -z "$MODULE" ] ; then
594          MODULE=$(grep 'XFree86 v4 Server Module:' "${HWINFO_TMP}" | head -1 | awk '{print $5}')
595          if [ -z "$MODULE" ] ; then
596            MODULE='vesa'
597          fi
598          # hwinfo >=13.28 reports driver 'intel' instead of i810
599          if [[ "$MODULE" == 'intel' ]] ; then
600             [ -r /usr/lib/xorg/modules/drivers/intel_drv.so ] || MODULE='i810'
601          fi
602        fi
603      else
604        FORCE="yes"
605      fi
606
607      mouse    # get mouse settings
608      VGA=$(lspci | grep VGA | sed 's/.*compatible controller: //' | head -1)
609
610      MODE=$o_mode[2]
611      if [ -z $MODE ] ; then
612        B_MODE="$(getBootParam xmode 2>/dev/null)"
613        if [ -n "$B_MODE" ] ; then
614          MODES="Modes \"$B_MODE\""
615          FORCE="yes"
616        fi
617        if [ -z "$MODES" ] ; then
618           mode # get available modes
619        fi
620      else
621        MODES="Modes \"$MODE\""
622        FORCE="yes"
623      fi
624
625      print "$fg[green]done$reset_color"
626      print "$bg[black]$fg[white]$bold_color"
627      print "$fg[green]Specified windowmanager is $fg[yellow]$WINDOWMANAGER"
628      print "$fg[green]Video is $fg[yellow]$VGA$fg[green] using $bg[black]$fg[yellow]${XSERVER}$fg[cyan](${MODULE})$fg[green] Server"
629      [[ -z $HSYNC ]] && [[ -z $VSYNC ]] && print "$fg[green]Monitor is $fg[yellow]$MONITOR"
630      [[ -z $HSYNC ]] && [[ -n $VSYNC ]] && print "$fg[green]Monitor is $fg[yellow]$MONITOR$fg[green], VSYNC: $fg[yellow]$VSYNC"
631      [[ -z $VSYNC ]] && [[ -n $HSYNC ]] && print "$fg[green]Monitor is $fg[yellow]$MONITOR$fg[green], HSYNC: $fg[yellow]$HSYNC"
632      [[ -n $VSYNC ]] && [[ -n $HSYNC ]] && print "$fg[green]Monitor is $fg[yellow]$MONITOR$fg[green], HSYNC: $fg[yellow]$HSYNC $fg[green]VSYNC: $fg[yellow]$VSYNC"
633      [[ -n $modes ]] && print "$fg[green]Using default X.org modes."
634      [[ -z $modes ]] && print "$fg[green]Using Mode: $fg[yellow]$MODE"
635      print "${reset_color}"
636    fi
637 }
638 parse_options $*
639 # }}}
640
641 # check for requirements {{{
642 requirements()
643 {
644 if ! [ -x $(which hwinfo) ] ; then
645   print "$bg[black]$fg[red]${bold_color}Error: hwinfo not found in path.${reset_color}
646 Note:  run 'aptitude install hwinfo' on systems running debian.
647 Exiting.${reset_color}"
648   exit -1
649 fi
650
651 if ! [[ -d /sys ]] ; then
652   print "$bg[black]$fg[red]${bold_color}Error: mounted /sys required (for hwinfo).${reset_color}
653 You may want to add the following line to your /etc/fstab:
654
655   sysfs /sys sysfs defaults 0 0
656
657 or just run 'mount /sys'. Exiting.${reset_color}"
658   exit -1
659 fi
660 }
661 requirements
662 # }}}
663
664 # xconfig {{{
665 xconfig() {
666 cat << EOX
667 ################################################################################
668 # Filename:      $XCONFIG
669 # Purpose:       config file for xserver - generated by grml-x
670 # Bug-Reports:   see http://grml.org/bugs/
671 # Latest change: ${DATE}
672 # See also:
673 #   /usr/share/doc/xserver-xorg/   and
674 #   http://wiki.x.org/wiki/Home    and
675 #   http://ftp.x.org/pub/X11R7.0/doc/html/index.html for information on Xorg
676
677 # Refer to the xorg.conf man page and to
678 # http://ftp.x.org/pub/X11R7.0/doc/html/xorg.conf.5.html
679 # for details about the format of this file.
680 #
681 # See http://wiki.debian.org/XStrikeForce/FAQ for information
682 # regarding Xorg packages within Debian.
683 #
684 # If you would like this file to be automatically reconfigured by debian,
685 # run the following command:
686 #   sudo dpkg-reconfigure -phigh xserver-xorg
687 ################################################################################
688
689 Section "ServerLayout"
690         Identifier     "XServer Configured"
691         Screen      0  "Screen0" 0 0
692         # InputDevice    "Keyboard0"     "CoreKeyboard"
693         # InputDevice    "Generic Mouse" "CorePointer"
694 $MOUSE
695 EndSection
696
697 Section "ServerFlags"
698         Option "AllowMouseOpenFail"  "true"  # allows the server to start up even if the mouse does not work
699         Option "DontVTSwitch"        "false" # allow switching between virtual terminal
700         # Option "DontZap"             "true"  # disable <Crtl><Alt><BS> (server abort)
701         # Option "DontZoom"            "true"  # disable <Crtl><Alt><KP_+>/<KP_-> (resolution switching)
702 EndSection
703
704 Section "Files"
705         # More information:  http://ftp.x.org/pub/X11R7.0/doc/html/fonts.html
706 $XFONTS
707         # FontPath     "/usr/share/fonts/ttf/western"
708         # FontPath     "/usr/share/fonts/ttf/decoratives"
709         FontPath     "/usr/share/fonts/truetype/ttf-bitstream-vera"
710         FontPath     "/usr/share/fonts/latex-ttf-fonts"
711         FontPath     "/var/lib/defoma/x-ttcidfont-conf.d/dirs/TrueType"
712 EndSection
713
714 # Modules - see /usr/X11R6/lib/modules/fonts and /usr/X11R6/lib/modules/extensions
715 Section "Module"
716         Load  "dbe"       # double buffer extension
717         Load  "dri"       # direct rendering
718         Load  "glx"       # 3D layer / GLX extension
719         Load  "type1"     # type1 font module
720         Load  "freetype"  # freetype fonts rendering
721         Load  "extmod"    # some commonly used server extensions (e.g. shape extension)
722         Load  "record"    # recording extension
723         Load  "evdev"     # generic input handling driver on Linux
724         # Load  "vbe"       # Vesa BIOS Extension
725         # Load  "i2c"       # I2C bus
726         # Load  "int10"     # initialize graphics cards via int10 call to the BIOS
727         # Load  "v4l"       # Video for Linux
728         ## Deprecated/unneeded modules with Xorg >=7.0:
729         # Load  "speedo"    # font module (does not exist anymore)
730         # Load  "ddc"       # ddc probing of monitor (automatically loaded)
731         # Load  "GLcore"    # render OpenGL in software (automatically loaded)
732         # Load  "bitmap"    # bitmap fonts (automatically loaded)
733 # Valid entries - see /usr/lib/xorg/modules/[extensions/]
734 # afb bitmap cfb cfb16 cfb24 cfb32 cw damage dbe ddc dri drm extmod fb
735 # fbdevhw freetype GLcore glx i2c int10 int10 layer mfb pcidata rac ramdac
736 # record scanpci shadow shadowfb type1 vbe vgahw xaa xf1bpp xf24_32bpp xf4bpp
737 # xf8_16bpp xf8_32bpp xtrap
738 EndSection
739
740 # If you'd like to switch the positions of your capslock and control keys, use:
741 # Option "XkbOptions" "ctrl:swapcaps"
742 # Or if you just want both to be control, use:
743 # Option "XkbOptions" "ctrl:nocaps"
744 # More information: http://ftp.x.org/pub/X11R7.0/doc/html/XKB-Config.html
745 # Section "InputDevice"
746 #         Identifier  "Keyboard0"
747 #         Option      "CoreKeyboard"
748 #         $KEYBOARD
749 #         # Option      "XkbOptions" "ctrl:swapcaps,grp:alt_shift_toggle,grp_led:scroll,compose:menu"
750 # EndSection
751
752 # More information: http://ftp.x.org/pub/X11R7.0/doc/html/mouse.html
753 ${USBMOUSEDETAIL}${PS2MOUSEDETAIL}${SERMOUSEDETAIL}${SYNMOUSEDETAIL}${EVDEV_MOUSE}
754 Section "Monitor"
755         Identifier   "Monitor0"
756 #       ModelName    "Old Monitor (no DDC)"
757         $DPMS
758 #       HorizSync    28.0 - 78.0 # Warning: This may fry very old Monitors
759 #       HorizSync    28.0 - 96.0 # Warning: This may fry old Monitors
760 $HORIZSYNC
761 #       VertRefresh  50.0 - 76.0 # Very conservative. May flicker.
762 #       VertRefresh  50.0 - 60.0 # Extreme conservative. Will flicker. TFT default.
763 $VERTISYNC
764 # Need more information?
765 #  http://xtiming.sourceforge.net/cgi-bin/xtiming.pl
766 #  http://en.tldp.org/HOWTO/XFree86-Video-Timings-HOWTO/
767 EndSection
768
769 Section "Device"
770         ### Available Driver options are:
771         ## sw_cursor is needed for some ati and radeon cards
772         # Option     "sw_cursor"
773         # Option     "hw_cursor"
774         # Option     "NoAccel"
775         # Option     "ShowCache"
776         # Option     "ShadowFB"
777         # Option     "UseFBDev"
778         # Option     "Rotate"
779         ## xorg + nvidia:
780         # Option "RenderAccel" "true"
781         # Option "AllowGLXWithComposite" "true"
782         Identifier  "Card0"
783         # The following line is auto-generated by grml-x
784         Driver      "$MODULE"
785         VendorName  "All"
786         BoardName   "All"
787         ## Workaround for drivers (for example radeon) which might send output to wrong device:
788         # Option "MonitorLayout" "LVDS, AUTO"
789         # Option "MonitorLayout" "LVDS, CRT"
790         # Option "MonitorLayout" "NONE, STV"
791         # Option "MonitorLayout" "LVDS"
792         ## Specify BusID:
793         # BusID       "PCI:1:0:0"
794 EndSection
795
796 Section "Screen"
797         Identifier "Screen0"
798         Device     "Card0"
799         Monitor    "Monitor0"
800         DefaultColorDepth 16
801         SubSection "Display"
802                 Depth     1
803                 $MODES
804         EndSubSection
805         SubSection "Display"
806                 Depth     4
807                 $MODES
808         EndSubSection
809         SubSection "Display"
810                 Depth     8
811                 $MODES
812         EndSubSection
813         SubSection "Display"
814                 Depth     15
815                 $MODES
816         EndSubSection
817         SubSection "Display"
818                 Depth     16
819                 $MODES
820         EndSubSection
821         SubSection "Display"
822                 Depth     24
823                 $MODES
824         EndSubSection
825         SubSection "Display"
826                 Depth     32
827                 $MODES
828         EndSubSection
829 EndSection
830
831 # Make sure you have the relevant Debian packages on your system
832 # to be able to use DRI (libgl1-mesa-dri for example)
833 Section "DRI"
834         Mode 0666
835 EndSection
836
837 $COMPOSITE
838
839 ## END OF FILE #################################################################
840 EOX
841 }
842 # }}}
843
844 # writeit {{{
845 writeit() {
846     XCONFTMP="/tmp/xconfig.$$"
847     xconfig > $XCONFTMP
848     # we do not want to have two CorePointers, deactivate one therefore
849     if grep -Eq '^[[:space:]]+InputDevice[ ]+"USB Mouse"[ ]+"CorePointer"' $XCONFTMP ; then
850        if grep -Eq '^[[:space:]]+InputDevice[ ]+"PS/2 Mouse"[ ]+"CorePointer"' $XCONFTMP ; then
851           sed -i 's|InputDevice.*PS/2.*CorePointer|# & # deactivated to avoid two CorePointers|' $XCONFTMP
852        fi
853     fi
854     [ -f $XCONFIG ] && sudo mv -f $XCONFIG $XCONFIG.old
855     sudo mv $XCONFTMP $XCONFIG
856     sudo chown root.root $XCONFIG
857     sudo chmod 644 $XCONFIG
858 }
859 # }}}
860
861 # writeconfig {{{
862 function writeconfig
863 {
864   if [[ ! -f $XCONFIG ]] ; then
865     print -n "$bold_color$fg[blue]Creating $XCONFIG: $fg[red]"
866     writeit && print "$fg[green]done$reset_color"
867   else
868     if [ -z "$FORCE" -a -z "$FALLBACK" ] ; then
869        print "$bold_color$fg[blue]Notice: $XCONFIG exists already.
870 Use the force-option (-force) to force creation.
871 $fg[red]"
872     fi
873   fi
874   if [[ -n "$FORCE" ]] ; then
875     print "$bold_color$fg[blue]Force-switch or manual option(s) detected:"
876     print -n "\-> Moving eventual existing $XCONFIG to ${XCONFIG}.old: $fg[red]"
877     writeit && print "$fg[green]done$reset_color"
878   fi
879 }
880 # }}}
881
882 # runit {{{
883 function runit
884 {
885   writeconfig
886   if [ -z "$NOSTART" ] ; then
887     print "$reset_color"
888     if [ -x /etc/init.d/xorg-common ] ; then
889       sudo /etc/init.d/xorg-common start
890     else
891       if [ -x /etc/init.d/xfree86-common ] ; then
892         sudo /etc/init.d/xfree86-common start
893       fi
894     fi
895     print ""
896     if [ -z "$DISPLAY" ] ; then
897       print "$bold_color$fg[green]Now trying to run startx.$reset_color"
898       startx $XINITRC -- $XOPTS
899     else
900       print "$bold_color$fg[green]Now trying to run startx on display $DISPLAY.$reset_color"
901       startx $XINITRC -- :$DISPLAY $XOPTS
902     fi
903   else
904     print "$bold_color$fg[blue]Not running startx as requested via option.$reset_color"
905   fi
906   return 1
907 }
908 # }}}
909
910 # failed {{{
911 function failed
912 {
913   print "$fg[red]"
914   if [ -z "$ROOT" ] ; then
915     if [[ $(tty) == /dev/pts/* ]] ; then
916       print "It seems you are running $PROGRAMNAME from inside GNU screen.
917 Notice that this might fail if running as user grml!
918 Please exit screen and try to run $PROGRAMNAME again."
919     fi
920   fi
921   print "Run the following commands for getting information on your hardware:
922   hwinfo --gfxcard
923   discover -v --data-path=xfree86/server/device/driver display
924   xdebconfigurator -c -d -i -x
925   get-edid | parse-edid
926
927 Do you want to go the debian way of life? Run:
928   aptitude install xorg read-edid mdetect hwinfo xdebconfigurator
929   dpkg-reconfigure -phigh xserver-xorg
930
931 Problems with the module used for X? Try to load another one or
932 fall back to module vesa:
933   $PROGRAMNAME -module radeon ...
934   $PROGRAMNAME -module vesa  ...
935
936 Do you want to deactivate a present synaptics touchpad? Run:
937   $PROGRAMNAME -nosynaptics ...
938
939 Your monitor is very old and/or does not support DDC-probing?
940   $PROGRAMNAME -noddc ...
941
942 Do you want to create a x configuration file but do not start X?
943   $PROGRAMNAME -nostart ...
944
945 Monitor frequency too high or too low? Just specify hsync/vsync manually:
946   $PROGRAMNAME -hsync 30-65 ...
947   $PROGRAMNAME -hsync 30-65 -vsync 50-60 ...
948
949 Want to adjust the resolution? Use the mode-switch:
950   $PROGRAMNAME -mode 1024x768 ...
951   $PROGRAMNAME -mode '1280x1024 1024x768' ...
952
953 Problems? Use vesa with resolution 1024x768:
954   $PROGRAMNAME -module vesa -mode 1024x768 ...
955
956 Still problems with X? Use the fallback option:
957   $PROGRAMNAME -fallback ...
958
959 To adjust resolution while running X execute:
960   xrandr -s '1024x768'
961
962 More information on grml-x can be found in the manual page: man grml-x
963
964 Report bugs, send wishes and feedback to the grml team:
965 http://grml.org/bugs/ - contact (at) grml.org
966 "
967 print -n "$reset_color"
968 }
969 # }}}
970
971 # cleanup {{{
972 cleanup()
973 {
974   rm -f $HWINFO_TMP
975   rm -f $MONITORINFO
976   rm -f $MOUSEINFO
977   rm -f $XCONFTMP
978 }
979 cleanup
980 # }}}
981
982 # xinitrc {{{
983   if ! [ -x "$(which $WINDOWMANAGER)" ] ; then
984      print "$bg[black]$fg[red]${bold_color}Fatal: windowmanager $fg[blue]$WINDOWMANAGER$fg[red] not executable, startx won' work.${reset_color}">&2
985      bailout
986   fi
987   if [ -w "$XINITRC" ] ; then
988     sed -i "s|^[^#]*exec.*|  exec $WINDOWMANAGER|g" $XINITRC
989     runit || failed
990   else
991     echo -e "#!/bin/sh\n  exec $WINDOWMANAGER" >> $XINITRC
992     runit || failed
993   fi
994 # }}}
995
996 ## END OF FILE #################################################################
997 # vim:foldmethod=marker expandtab ai ft=zsh