Saturday, November 13, 2010

Fedora and Screen Resolution: Pt2

Turns out, the xrandr info is not persistent across reboots. The obvious solution was to add the needed lines to the /etc/rc.local, but xrandr will only execute if the X engine is online. The solution was to create a script and drop into the X window systems initialization sequence:
cat /etc/X11/xinit/xinitrc.d/setres.sh
#!/bin/sh
xrandr --newmode "1280x1024" 108.88 1280 1360 1496 1712 1024 1025 1028 1060 -HSync +Vsync
xrandr --addmode VGA-0 "1280x1024"
xrandr -s "1280x1024"
Notice the scripts path.

Fedora and Screen Resolution

For the last few revisions of Fedora, I've had problems with getting my physical systems to behave at the desired screen resolution. The problem is the way the video drivers attempt to detect them monitor-- it is assumed that the display hardware is an LCD. Unfortunately, some of my physical systems still use CRT's. Why? Because they work.

I don't know exactly when the change occurred, but starting with F13, my system always booted to 1024x768. Back in the day, we'd use system-config-display to set the proper resolution, but it is no longer a default component, and has become unreliable. Instead, we should use the less intuitive xrandr. So, here's what it takes to override the default resolution.

First, determine what xrandr sees. From within an X desktop environment, open a terminal window.
xrandr -q
Screen 0: minimum 320 x 200, current 1024 x 768, maximum 2944 x 1024
VGA-0 connected 1024x768+0+0 (normal left inverted right x axis y axis) 0mm x 0mm
  1024x768     60.0*
  800x600       60.3
  640x480       59.9
It knows that Screen 0 (the monitor) is capable of 2944x1024. For some reason, VGA-0 (the video card) is defaulting to 1024x768 as indicated by the asterisk.

Second, we need to configure more video modes. This requires that we feed xrandr a huge amount of information we don't have. Luckily, gtf knows what we need. Let's try to bump the resolution up one notch to 1152x864 with 60Hz refresh rate.
# gtf 1152 864 60
# 1152x864 @ 60.00 Hz (GTF) hsync: 53.70 kHz; pclk: 81.62 MHz
Modeline "1152x864_60.00" 81.62 1152 1216 1336 1520 864 865 868 895 -HSync +Vsync
We need the second line to feed to xrandr:
xrandr --newmode "1152x864_60.00" \
  81.62 1152 1216 1336 1520 864 865 868 895 -HSync +Vsync

xrandr -q
Screen 0: minimum 320 x 200, current 1024 x 768, maximum 2944 x 1024
VGA-0 connected 1024x768+0+0 (normal left inverted right x axis y axis) 0mm x 0mm
  1024x768     60.0*
  800x600       60.3
  640x480       59.9
  1152x864_60.00 (0x7e)   81.6MHz
    h: width 1152 start 1216 end 1336 total 1520 skew 0 clock 53.7KHz
    v: height 864 start 865 end 868 total 895 clock 60.0Hz
Our new mode has been staged, now it has to be connected to a video card, and activated:
xrandr --addmode VGA-0 "1152x864_60.00"
xrandr -q
Screen 0: minimum 320 x 200, current 1024 x 768, maximum 2944 x 1024
VGA-0 connected 1024x768+0+0 (normal left inverted right x axis y axis) 0mm x 0mm
  1024x768     60.0*
  800x600       60.3
  640x480       59.9
  1152x864_60.00   60.0
xrandr -s "1152x864_60.00"
xrandr -q
Screen 0: minimum 320 x 200, current 1152 x 864, maximum 2944 x 1024
VGA-0 connected 1152x864+0+0 (normal left inverted right x axis y axis) 0mm x 0mm
  1024x768     60.0
  800x600       60.3
  640x480       59.9
  1152x864_60.00   60.0*
If you're lucky, you can still see your video output!

Oddly, it would seem the part in quotes is completely arbitrary, but GNOME's desktop resolution utility needs that field to be in the 1234x567 format. The real headache is trying to determine the available resolutions and scan rates. If you really feel daring you can pump all the possibilities into the list and try them until you find one you like. Here's the list:
for J in `elinks http://bunger.us/rez.xml`; do \
  X=`echo $J | cut -dx -f1`; Y=`echo $J | cut -dx -f2`;\
  for K in 60 75 80 120; do \
    gtf $X $Y $K | grep Modeline; \
done; done
And here's the sledgehammer that populates the list:
for J in `elinks http://bunger.us/rez.xml`; do \
  X=`echo $J | cut -dx -f1`; Y=`echo $J | cut -dx -f2`;\
  for K in 60 75 80 120; do \
    L=`gtf $X $Y $K | grep Modeline | cut -d\  -f4-99`;\
    M=`echo $L | cut -d\  -f1`; \
    xrandr --newmode $L; xrandr --addmode VGA-0 $M;\
done; done