Xrandr 1.2
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.
Then I heard about xrandr 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.
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):
- xproto
- glproto
- inputproto
Then you'll need to update various other bits of X:
- libXi
- libdrm
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 the git browser and find the module you want to check out. Click on it, and you'll see two URLs: you want the anongit one. Do git clone [url], and then if I've specified a branch other than master, cd into the directory and do git checkout [branch]. For example:
git clone git://anongit.freedesktop.org/git/xorg/driver/xf86-video-intel cd xf86-video-intel git checkout modesetting
You'll need to grab:
- xorg/proto/x11proto
- xorg/proto/randrproto
- xorg/lib/libXrandr
- xorg/app/xrandr
- xorg/xserver (randr-1.2-for-server-1.2)
- xorg/driver/xf86-video-intel (modesetting)
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...
$ 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
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 xrandr -s 0 (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.
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 xorg.conf so I added this:
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
With this, everything just works. If I xrandr 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:
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
(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 very powerful. If you want to do Xinerama-style dual screen you can do that too: xrandr 1.2 encompasses that behaviour.
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.
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 my repository.
NP: Animal Magic, Bonobo
Otherwise, thanks for the excellent guide. I will be stealing your packages!
Thanks for the interesting insight into the new Xrandr!
having fun getting this working myself, permissions issues galore and it looks like I need to rebuild libglx, sigh...
[adamw@lenovo ~]$ xrandr
Screen 0: minimum 320 x 240, current 1680 x 1050, maximum 1680 x 1200
VGA connected 1680x1050+0+0 (normal left inverted right) 433mm x 271mm
...
LVDS connected 1280x800+0+0 (normal left inverted right) 261mm x 163mm
craaaazy. Thanks a lot for the guide, ross :)
Do you know how well it behaves with two monitors? I've got a 1280x1024 at work and 1440x900 at home (plus the 1280x800 in the laptop), i'll give it a try later and see what happens...
With more people trying this we'll be able to figure out if its the EDID parser in X which is broken, or my monitor.
I don't know if we have the same monitor but lately I've been using my Dell 2005FPW 20" widescreen 1680x1050 monitor turned on its side to portrait mode.
Does anyone know if sub-pixel aliasing (for Ubuntu specifically in my case) takes account of this rotation without having to manually change it from RGB to VRGB and back?
Analog VGA output
LVDS laptop integrated panel output
SDVO DVI/DMS-59 output
integrated TV output
SDVO TV output
DVO DVI output
DVO TV output
dave:
When you rotate a CRTC, the rotation should be reflected in the subpixel ordering field of the CRTC. Additionally, the compatibility RandR 1.0 output should report the rotated order if the compatibility RandR CRTC is the one rotated.
However, if you've got your laptop panel non-rotated, and your panel to the side rotated, don't expect your apps to do the right thing with their subpixel rendering on both (yet?)
Also, I was wrong. The driver doesn't rotate the RGB ordering it reports, apparently. It just tells what the monitor is, and the app gets to account for rotation/reflection.
Now it all works and I finally have a pleasant xinerama-like setup at work.
The only thing that annoys me now is that DRI no longer works. I have my laptop at 1024x768 and my external monitor at 1600x1200 which means that I need a Virtual 2624 1200 in xorg.conf. The intel driver complains "(EE) intel(0): Cannot support DRI with frame buffer width > 2048." Do you know (yes, you are my oracle) if there is a way around this, or if the hardware is limiting this?
i still have trouble compiling it to 1.2, but in the meantime it just ignores te xorg setup and clones the picture on the other screen with randr 1.1.
I'm running feisty and your repository seems to miss some debs in the feisty dir: If I only install the xrandr package the server still reports xrandr v1.1. If I also install xserver-xorg-core then I have to uninstall xserver-xorg-input-kbd and xserver-xorg-input-mouse (they conflict) but then the xserver doesn't start anymore because he can't find the keyboard/mouse.
I thought about using the packages from experimental or from Daniel Stone's edgy repository but wasn't sure if that's a good idea. Do you have a suggestion? Which packages do I actually need? Would this work with feisty?
I have -intel and -core from my feisty repository, and -kdb 1.1.0-0ubuntu1 -mouse 1.1.1-0ubuntu1. I should rebuild those at some point against the new server, or rebuild a server with a correct version.
Welcome to the bleeding edge. These packages will break your system. :)
Just found your site while searching for a solution ;) I just bought a subnotebook with an intel graphics chip. Now when I'm working at home I'd like to use my 21" tft. I'm using feisty but as of now I haven't found a working solution.
Now I'm wondering if your solution (including your packages) is working. Your statement "Welcome to the bleeding edge. These packages will break your system. :)" worries me a littel bit ;)
Any hints for me? ;) thanks
i somewhat new to linux and am trying to get my x60 working with an external monitor at 1280x1024. When reading your how-to, I'm not sure how to do a few things:
1) how to update xproto, glproto, inputproto,libXi, and libdrm. ..not sure how to update a protocal header
2)i'm also not sure how to "build" xorg/proto/x11proto etc.
many thanks,
tom
It's really frustrating to know that, just out of my reach, there is a soliution to the one problem that has me wanting to replace my ThinkPad T60 with a MacBook Pro.
What I finally came up with is this: (Make sure this doesn't line wrap; Only 3 lines.)
echo deb http://burtonini.com/debian/ feisty/|sudo tee -a /etc/apt/sources.list
sudo apt-key advanced --keyserver subkeys.pgp.net --recv-keys 0x510E0293
sudo apt-get -V install xrandr xserver-xorg-video-intel xserver-xorg-core
The -V will show you the versions to be installed. Make sure they correspond with the file names here: http://burtonini.com/debian/feisty/
After a reboot, the new intel driver and xrandr was working:
~$ xrandr
Screen 0: minimum 320 x 200, current 1600 x 1200, maximum 1600 x 1600
VGA connected 1600x1200+0+0 (normal left inverted right) 367mm x 275mm
1600x1200 60.0*+ 59.9
1280x1024 59.9
640x480 60.0
LVDS connected 1024x768+0+0 (normal left inverted right) 286mm x 214mm
1024x768 60.0*+ 50.0
800x600 60.3
640x480 60.0 59.9
TMDS-1 disconnected (normal left inverted right)
TV disconnected (normal left inverted right)
I'd expect that replacing feisty with edgy would work for those not on the bleeding (now released as stable) edge.
Now I just have to figure out what to do with it! I want to get into a dual desktop situation... I'll follow up if I figure it out.
I hope that helps Tom Harris and anyone else who was confused like me.
Thank you for your quick randr 1.2 "howto". I install everything from your depots, and got it quite a bit working. Config: laptop panel 1280x800 + External 1680x1050; intel 855gm. Unfortunatly, I noticed a few annoying problms:
1. Is it possible to get the FIRST output to the LVDS panel, and to handle the external screen as an extension ? What would be the VIRTUAL config needed ?
2. Subpixel hinting on the external screen is very bad; xrandr --verbose shows "Subpixel: Unknown" for the external panel. Is it possible to force/fix it ?
3. The "man xrandr" page is quite poor; is there a more complete documentation/manual for xrandr 1.2 somewhere ?
Again: thank you very much,
Felix
One small problem - when the xserver first starts, both displays are always enabled. Normally when I have the external screen plugged in, the laptop display won't turn on at all when X starts.
Is it possible to keep one display off at startup?
Regarding Sean's comment above, I've found that my "best practices" involve leaving the external unplugged at startup, and then changing screens. To do so otherwise, with my Dell 2005FPW, will query the screen resolution of the 2005FPW (1680x1050) and will set the maximum screen area to 1680x1680 instead of 2048x2048. Starting up with nothing attached gives me the full range of options, and I've just created an alias that turns the external on and the laptop screen off.
Somewhere you said "If you want to do Xinerama-style dual screen you can do that too: xrandr 1.2 encompasses that behaviour"
How can I do this with a monitor using 1024x768 (laptop) and the other one using 1440x900 (external LCD)?
I have been trying... but not success till now
Going from VGA to LVDS mostly works. In the other direction the gnome-terminals always die. Some other clients live, others come up in a bad state.
Some times the session dies and goes back to a login screen on a switch.
Any ideas?
Are you running the standard feisty libxrandr and GTk+?
Here is what the segfault looks like on a client
#0 init_xinerama_support (screen=<value optimized out>) at gdkscreen-x11.c:617
#1 0xb7c06090 in _gdk_x11_screen_size_changed (screen=0x80680d0,
event=0xbffdb618) at gdkscreen-x11.c:753
#2 0xb7bf85d9 in gdk_event_translate (display=0x8065098, event=0x80695f8,
xevent=0xbffdb618, return_exposes=0) at gdkevents-x11.c:1825
#3 0xb7bf9cfb in _gdk_events_queue (display=0x8065098) at gdkevents-x11.c:2252
#4 0xb7bfa0ff in gdk_event_dispatch (source=0x806cec0, callback=0,
user_data=0x0) at gdkevents-x11.c:2312
#5 0xb78a7df2 in g_main_context_dispatch () from /usr/lib/libglib-2.0.so.0
#6 0xb78aadcf in ?? () from /usr/lib/libglib-2.0.so.0
Looks kind of like its in gdkscreen. Does it make sense that xinerama is being called?
IMHO the XRandR in conjunction with the intel driver make dual-screening stupidly simple.
I tried to find the feisty packages in your repository but I didnt find any x package...
Do I miss something?
thank you
That said, Gutsy has been out for a long time now, and has everything working (the packages were rebuilds of Gutsy packages).
Hi Ross,
I have Xrandr 1.2 version, when I give Xrandr -q or xrand -query
I get following output::::
# xrandr --query
SZ: Pixels Physical Refresh
0 1600 x 1200 ( 310mm x 231mm ) 69 68 67
1 1280 x 1024 ( 310mm x 231mm ) 80 79 78
2 1024 x 768 ( 310mm x 231mm ) 105 104 103
3 800 x 600 ( 310mm x 231mm ) 133 132 131
4 1400 x 1050 ( 310mm x 231mm ) 75 60
5 1280 x 960 ( 310mm x 231mm ) 85 60
6 1152 x 864 ( 310mm x 231mm ) 75
7 1152 x 768 ( 310mm x 231mm ) 55
8 928 x 696 ( 310mm x 231mm ) 60
9 896 x 672 ( 310mm x 231mm ) 60
10 832 x 624 ( 310mm x 231mm ) 75
11 700 x 525 ( 310mm x 231mm ) 75 60
12 640 x 512 ( 310mm x 231mm ) 75 60
13 640 x 480 ( 310mm x 231mm ) 85 75 73 60
14 720 x 400 ( 310mm x 231mm ) 85
15 640 x 400 ( 310mm x 231mm ) 85
16 576 x 432 ( 310mm x 231mm ) 75
17 640 x 350 ( 310mm x 231mm ) 85
18 576 x 384 ( 310mm x 231mm ) 55
19 512 x 384 ( 310mm x 231mm ) 85 75 70 60 87
20 416 x 312 ( 310mm x 231mm ) 75
21 400 x 300 ( 310mm x 231mm ) 85 75 72 60 56
22 320 x 240 ( 310mm x 231mm ) 85 75 73 60
23 360 x 200 ( 310mm x 231mm ) 85
24 320 x 200 ( 310mm x 231mm ) 85
25 320 x 175 ( 310mm x 231mm ) 85
Current rotation - normal
Current reflection - none
Rotations possible - normal
Reflections possible - none
Thus, I am unable to know which mode is currently connected(i.e VGA, LVSD, DVI etc.)
Basically I want to simulate turning on and off of my Monitor.
I am doing
$ xrandr –output VGA-0 –off
but, its not working.
Any help in this respect is greatly appreciated.
- Sam
Hi Ross,
I have Xrandr 1.2 version, when I give Xrandr -q or xrand -query
I get following output::::
# xrandr --query
SZ: Pixels Physical Refresh
0 1600 x 1200 ( 310mm x 231mm ) 69 68 67
1 1280 x 1024 ( 310mm x 231mm ) 80 79 78
2 1024 x 768 ( 310mm x 231mm ) 105 104 103
3 800 x 600 ( 310mm x 231mm ) 133 132 131
4 1400 x 1050 ( 310mm x 231mm ) 75 60
5 1280 x 960 ( 310mm x 231mm ) 85 60
6 1152 x 864 ( 310mm x 231mm ) 75
7 1152 x 768 ( 310mm x 231mm ) 55
8 928 x 696 ( 310mm x 231mm ) 60
9 896 x 672 ( 310mm x 231mm ) 60
10 832 x 624 ( 310mm x 231mm ) 75
11 700 x 525 ( 310mm x 231mm ) 75 60
12 640 x 512 ( 310mm x 231mm ) 75 60
13 640 x 480 ( 310mm x 231mm ) 85 75 73 60
14 720 x 400 ( 310mm x 231mm ) 85
15 640 x 400 ( 310mm x 231mm ) 85
16 576 x 432 ( 310mm x 231mm ) 75
17 640 x 350 ( 310mm x 231mm ) 85
18 576 x 384 ( 310mm x 231mm ) 55
19 512 x 384 ( 310mm x 231mm ) 85 75 70 60 87
20 416 x 312 ( 310mm x 231mm ) 75
21 400 x 300 ( 310mm x 231mm ) 85 75 72 60 56
22 320 x 240 ( 310mm x 231mm ) 85 75 73 60
23 360 x 200 ( 310mm x 231mm ) 85
24 320 x 200 ( 310mm x 231mm ) 85
25 320 x 175 ( 310mm x 231mm ) 85
Current rotation - normal
Current reflection - none
Rotations possible - normal
Reflections possible - none
Thus, I am unable to know which mode is currently connected(i.e VGA, LVSD, DVI etc.)
Basically I want to simulate turning on and off of my Monitor.
I am doing
$ xrandr –output VGA-0 –off
but, its not working.
Any help in this respect is greatly appreciated.
- Sam