Finally: T41p, radeon, and DVI hotplug

Maybe I'm just an idiot, but I've never been able to use the open-source radeon driver with my T41p.  The main reason being that the radeon driver seemed doomed to permanent suckage when it came to using my external 1600×1200 DVI flat panel.  Sure, I could boot up with the lid closed and the DVI plugged in and then reboot when moving to the couch to use the integrated display, but come on, that's ridiculous.

Recent versions of the evil fglrx driver seemed to solve my problem with the dynamic –enable-monitor flag.  I wrote a little script that took the output of –query-monitor and stuffed it into –enable-monitor.  This meant any time I switched configs, I could just run that script and it would enable whatever monitors were connected.  I could then use xrandr to change the resolution to what I wanted and be happy.

Ubuntu Gutsy Gibbon promised to make this all better.  However, when I upgraded, the new display settings tool didn't seem to do much for me.  It detected my external flat panel as the laptop display and I couldn't make it do anything with minimal work.  So, I restored my xorg.conf with the fglrx settings and went back to what I had.  However, fglrx in Gutsy seemed to break my ability to suspend, which is something I had just gotten used to.

This afternoon, I sat down determined to put some more time into the new bits and see if I could make something work.  First, I moved my xorg.conf file away (to a safe hiding spot) and restarted X.  I then went into the display config tool and forced the laptop display to 1400×1050.  It didn't show my external monitor, so I saved the settings and restarted.  When I got back in, my external display showed up, model undetected, but present.  So, I configured the model and resolution, saved, and restarted.  I got nothing.  The login screen showed in 1400×1050 on the internal display, and an offset 1600×1200 on the external, but after login the external display went black and I just had the internal display.

From there, I opened up a terminal to run the command-line xrandr program.  Wow, has that changed!  It now shows me connected monitors, resolutions, etc:

Screen 0: minimum 320 x 200, current 1600 x 1200, maximum 1600 x 1200
VGA-0 disconnected (normal left inverted right)
DVI-0 connected 1600×1200+0+0 (normal left inverted right) 367mm x 275mm
   1600×1200      60.0*+   59.9  
   1280×1024      75.0     59.9  
   1152×864       74.8  
   1024×768       75.1     60.0  
   800×600        75.0     60.3  
   640×480        75.0     60.0  
   720×400        70.1  
LVDS connected (normal left inverted right)
   1400×1050      50.0 +
   1280×1024      59.9  
   1280×960       59.9  
   1280×800       60.0  
   1280×768       60.0  
   1024×768       60.0     59.9  
   800×600        60.3     59.9  
   640×480        59.9     59.4  
S-video disconnected (normal left inverted right)

 Playing around a little, I noticed that I could turn on and off either display, by doing:

$ xrandr –output DVI-0 –off
$ xrandr –output DVI-0 –auto
$ xrandr –output LVDS –off
$ xrandr –output LVDS –auto

The current resolution would switch to 1400×1050 when the LVDS output was enabled (its maximum) and 1600×1200 when the LVDS output was disabled (the DVI-0 maximum).  This is perfect!  All I need is for this to happen when the lid ACPI event triggers.  If the lid is open, enable LVDS.  If it's closed, disable LVDS.  For both cases, "auto" mode for DVI-0 should be fine.  So, I wrote the following script:

 #!/bin/bash

. /usr/share/acpi-support/power-funcs
. /usr/share/acpi-support/policy-funcs
. /etc/default/acpi-support

do_it() {
    STATE=$(cat /proc/acpi/button/lid/*/state | awk '{print $2}'Smilie: ;)
    
    if [ "$STATE" = "closed" ]; then
        echo Setting LVDS off
        xrandr –output LVDS –off
    else
        echo Setting LVDS on
        xrandr –output LVDS –auto
    fi
    
    echo Setting DVI auto
    xrandr –output DVI-0 –auto
}

# Give the displays a chance to settle
sleep 2

for x in /tmp/.X11-unix/*; do
    displaynum=`echo $x | sed s#/tmp/.X11-unix/X##`
    getXuser;
    if [ x"$XAUTHORITY" != x"" ]; then
        export DISPLAY=":$displaynum"
    do_it
    fi
done

Next, I created a /etc/acpi/local/lid.sh.pre file to call my script and marked it executable (you could put the above in the lid.sh.pre itself, of course).  I copied the display setting code from /etc/acpi/lid.sh.  This ensures that DISPLAY is set appropriately so that xrandr will work correctly.

Now, when I cycle my lid (or press the little sunken button myself for testing) the display output and resolution switch automagically.  Not only that, but I can even suspend my machine again Smilie: :)

I would have really hoped that Gutsy would bring this level of polish with it.  Maybe it did and I'm just completely inept, but I didn't find any mention of it working flawlessly in the first page of a google search, so I assume I'm not alone here. 

Category(s): Linux

Comments are closed.