Ubuntu Multi-monitor Setup
January 15, 2011
My current computing platform is a ThinkPad T61p running Ubuntu. I recently picked up a Mini Dock and a pair of 24" Samsung monitors. This post describes how I got the multi-monitor setup working.
The ThinkPad has an NVidia Quadro FX 570M GPU. Your best reference for configuring dual displays on Linux with NVidia GPUs is the NVidia Linux driver README
There are a number of ways to get multiple monitors working on an X server. I decided to use NVidia's proprietary TwinView approach. Under TwinView, X thinks there's one large display space, and the NVidia driver divides this up into multiple monitors.
The easiest way to get this working is to install the Ubuntu
nvidia-settings package and fiddle with the GUI application it
installs under the System > Administration menu. The problem is that
there doesn't seem to be a way to clearly switch between two modes when
I'm docked (the two external displays) or un-docked (the laptop's
panel). Luckily, like most things in Linux, we can fix things up with a
bit of scripting.
nv-control-dpy utility gives us the functionality we need to
dynamically control our display configuration. This utility is actually
just a sample program that NVidia distributes with the driver source to
illustrate how to use their API. We can build
nv-control-dpy from the
the Ubuntu source package. The following instructions are based on a a
post to the Ubuntu forums
site, but have been
tweaked to work on Ubuntu 10.10.
sudo apt-get install build-essential libxext-dev libx11-dev cd mkdir nvidia-source cd nvidia-source/ apt-get source nvidia-settings cd nvidia-settings-*/ cd src/libXNVCtrl make cd ../../samples make
At this point I got a compile error when compiling
nv-control-events.c:705: error: ‘NV_CTRL_FLATPANEL_DITHERING_MODE’ undeclared here (not in a function)
I didn't need this particular program; however, running
nv-control-dpy as suggested in the Ubuntu forums post didn't work
either. The solution was to edit
nv-control-events.c and comment out
the offending line:
make again, and you should find
nv-control-dpy in the
_out/Linux_x86_64 directory. I suggest you copy it
Switching Display Modes
X detects the installed displays when it starts. This can be a challenge for
laptop users whose display configuration changes depending on whether
or not they're docked. The way I've handled this is to remove all
TwinView-related settings from
MetaModes, etc.), and to set things up dynamically at runtime.
Suppose we've rebooted our laptop un-docked. X will be unaware of our
external displays. We can remedy this by running
--probe-dpys. On my system the output is as follows:
Using NV-CONTROL extension 1.24 on :0.0 Connected Display Devices: DFP-0 (0x00010000): LEN Display Device Probed Information: number of GPUs: 1 display devices on GPU-0 (Quadro FX 570M): CRT-0 (0x00000001): Samsung SyncMaster DFP-0 (0x00010000): LEN DFP-1 (0x00020000): Samsung SyncMaster
To the NVidia driver,
DFP-0 refers to the laptops attached panel,
CRT-0 is the external monitor connected to the dock's VGA port
DFP-1 is the external monitor connected to the dock's DVI port.
Now that the driver sees the new displays, we have to "associate" them
(I'm not exactly sure what that means, but we have to do it for things
to work.) If you look at the output of
you'll notice that each display has an associated hexadecimal number. To
associated multiple displays, you have to call
--set-associated-dpys X, where
X is the result of or-ing these
numbers together. On my system the proper command is
Now we must create a "meta mode" that describes a configuration that incorporates the external displays. In my case, I want them displayed side-by-side, with the internal laptop display disabled. Here is the appropriate setting:
nv-control-dpy --add-metamode "DFP-0: NULL, CRT-0: nvidia-auto-select +0+0, DFP-1: nvidia-auto-select +1920+0"
Refer to the NVidia documentation for a full treatment of meta modes.
Finally, we use the
xrandr utility to switch between configurations.
xrandr is not directly aware of meta modes, but we can switch based on
the fact that one of the configurations has a display resolution of
1920x1200 and the other a resolution of 3840x1200:
xrandr -s 3840x1200
Tying It All Together
I put the required commnds together in a shell script that toggles the display configuration:
#!/bin/sh nv-control-dpy --probe-dpys nv-control-dpy --set-associated-dpys 0x00030001 nv-control-dpy --add-metamode "DFP-0: NULL, CRT-0: nvidia-auto-select +0+0, DFP-1: nvidia-auto-select +1920+0" if xrandr | grep 'current 1920'; then xrandr -s 3840x1200 else xrandr -s 1920x1200 fi
In Gnome, you can bind this to a keystroke by running System > Preferences > Keyboard Shortcuts. Click Add, and specify the shell script with a name and the full path to the script, and click Apply. Finally, bind the new shortcut to a key. (I used `Ctrl-Alt-```.)