<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:admin="http://webns.net/mvcb/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:html="http://www.w3.org/1999/html" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>Ross Burton</title><link>http://www.burtonini.com/blog</link><description>A potted account of Ross' life</description><language>en</language><ttl>60</ttl><dc:creator>Ross Burton</dc:creator><admin:generatorAgent rdf:resource="http://pyblosxom.sourceforge.net/"/><admin:errorReportsTo rdf:resource="mailto:ross@burtonini.com"/><item><title>Xrandr 1.2</title><guid isPermaLink="false">computers/randr-2007-02-06-17-50</guid><link>http://www.burtonini.com/blog/computers/randr-2007-02-06-17-50</link><description>Since I got my 20&quot; widescreen monitor in the summer, I discovered how bad X's support for resizing displays is. ...</description><content:encoded><![CDATA[    <p>
      Since I got my 20" widescreen monitor in the summer, I discovered how bad
      X's support for resizing displays is.  I wanted to have the ability to
      plug my laptop into the 20" display in the office and expand the desktop
      to 1680x1050, or remove the 20" display and shrink the desktop back down
      to the native resolution of 1024x768.  It turns out that a number of
      factors were stopping this, and the only way to do it would have been to
      restart X.  Because of this I ended up using the display at 1024x768 when
      I did use it, but mostly I stayed on the sofa.
    </p>
    <p>
      Then I heard about <tt>xrandr</tt> 1.2, the all-singing all-dancing
      revision of the X Resize and Rotate extension.  Basically, it would solve
      my problem, and as luck would have it my laptop has an Intel chipset and
      the people hacking on it work at Intel.  Yesterday after lots of poking I
      finally made it all work for this.  This involved a lot of poking and a
      little black magic.
    </p>
    <p>
      The first step is getting an X server new enough.  First, you'll need to
      update some X protocol headers.  We'll start with the easy ones that have
      had releases (grab the latest release you can find):
    </p>
    <ul>
      <li>xproto</li>
      <li>glproto</li>
      <li>inputproto</li>
    </ul>
    <p>
      Then you'll need to update various other bits of X:
    </p>
    <ul>
      <li>libXi</li>
      <li>libdrm</li>
    </ul>
    <p>
      Once this is done and X still works, it's time to brave the perilous world
      of git. If you've never used git before, it's quite simple for this.  Go
      to <a href="http://gitweb.freedesktop.org/">the git browser</a> and find
      the module you want to check out.  Click on it, and you'll see two URLs:
      you want the <tt>anongit</tt> one.  Do <tt>git clone [url]</tt>, and then
      if I've specified a branch other than master, <tt>cd</tt> into the
      directory and do <tt>git checkout [branch]</tt>.  For example:
    </p>
    <pre>git clone git://anongit.freedesktop.org/git/xorg/driver/xf86-video-intel
cd xf86-video-intel
git checkout modesetting</pre>
    <p>
      You'll need to grab:
    </p>
    <ul>
      <li>xorg/proto/x11proto</li>
      <li>xorg/proto/randrproto</li>
      <li>xorg/lib/libXrandr</li>
      <li>xorg/app/xrandr</li>
      <li>xorg/xserver (randr-1.2-for-server-1.2)</li>
      <li>xorg/driver/xf86-video-intel (modesetting)</li>
    </ul>
    <p>
      Build it all in that order.  The order is important as if you build the
      Intel driver against randr 1.0 instead of 1.2, it won't do what you want.
      By now you should have an X that looks no different.  But...
    </p>
    <pre>$ xrandr
Screen 0: minimum 320 x 240, current 1024 x 768, maximum 1680 x 1050
VGA disconnected 0mm x 0mm
LVDS connected 1024x768+0+0 246mm x 185mm
   1024x768       50.0 +   60.0*    40.0  
   800x600        60.3  
   640x480        60.0     59.9  
TV disconnected 0mm x 0mm</pre>
    <p>
      Now that is clever.  Here you can see that I don't have anything connected
      via VGA, my LVDS (no idea what this stands for, but it means the laptop's
      panel) has a preferred mode of 1024x768 (thats what the * means), and I
      have nothing connected to the TV output (because Lenovo didn't wire it
      up). Now if I plug something into the VGA and run <tt>xrandr -s 0</tt>
      (select default screen size), the external display should power on.
      Xrandr doesn't try to be too clever, it will leave that to desktop
      daemons, but by default it will try and make something appear on all of
      the connected displays.  In this case, my 20" TFT gets a clone of my
      laptop panel, at 1024x768.
    </p>
    <p>
      That is no good though, I want to turn off the laptop panel (as I'll be
      shutting the laptop) and switch the external display to 1680x1050.  This
      is where the black magic starts...  Currently the Intel driver cannot
      resize the physical framebuffer in memory after X has started, so it
      defaults to a framebuffer of 1200x1024 (IIRC).  That isn't big enough to
      hold 1680x1050.  Also the Intel driver doesn't detect any modes from the
      TFT.  This may be Dell being stupid, or the EDID parser in the driver
      being too restrictive, I don't know.  Luckily we can still use modelines
      in <tt>xorg.conf</tt> so I added this:
    </p>
    <pre>Section "Monitor"
        Identifier "Dell TFT"
        # This is a standard modeline for 1680x1050 at 60Hz
        Modeline "1680x1050" 149.00  1680 1760 1944 2280  1050 1050 1052 1089
EndSection
        
Section "Screen"
        Identifier      "Screen"
        Device          "Intel"
        Monitor         "Monitor"
        # This says that when using a monitor on the output called VGA, use the
        # settings in the monitor "Dell TFT"
        Option "monitor-VGA" "Dell TFT"
        DefaultDepth    24
        SubSection "Display"
                Depth 24
                # This tells the screen to allocate a frame buffer up to
                # 1680x1050.
                Virtual 1680 1050
        EndSubSection
EndSection</pre>
    <p>
      With this, everything just works.  If I <tt>xrandr</tt> with various
      displays plugged in I can see what they support and can switch modes.  To
      make everything nice and easy I wrote a small script that I bound to an
      unused function key:
    </p>
<pre>if xrandr -q | grep -q  "VGA connected"; then
  xrandr --output LVDS --off --output VGA --mode 1680x1050
else
  xrandr --output VGA --off --output LVDS --mode 1024x768
fi</pre>
    <p>
      (thanks to Eric for pointing out that I don't need to use the hex values).
      Simple!  As you can see the new xrandr is <em>very</em> powerful.  If you
      want to do Xinerama-style dual screen you can do that too: xrandr 1.2
      encompasses that behaviour.
    </p>
    <p>
      The final thing to point out is how glad I am that GNOME seems to handle
      the screen resizing like this so nicely already.  When the desktop shrinks
      Metacity moves windows so they are visible, and when the desktop expands
      the panel applets on the right stay on the right instead of sitting in the
      middle.  The script I run when I change screens does more than I pasted
      here: it changes the wallpaper to match the aspect ratio, and also changes
      the fonts.
    </p>
    <p>
      I hope this has made sense, I know there are a few people out there who
      were waiting for me to test this before they gave it a go.  If anything is
      too vague, leave a comment and I'll expand it.  I should also mention that
      I've got Ubuntu Edgy packages for everything here in <a
      href="http://burtonini.com/debian/">my repository</a>.
    </p>
    <p>
      <small>NP: <cite>Animal Magic</cite>, Bonobo</small>
    </p>
]]></content:encoded><dc:date>2007-02-06T17:50:00Z</dc:date></item></channel></rss>