Practical use of X.Org metamodes with emulators and manipulation of dual screens.


I've always been a user of at least 2 monitors on my desktops, which by the way is a minority in the grand scheme of things.  My main screen is either a CRT or DFP and the second screen is a NTSC television coming off the s-video output of the card.  Since I use my desktop computer as an entertainment device as well, this is a great way to setup my system so that I can watch videos or play emulators on the analog television display.

The contemporary X windows system along with the video card driver allows you to do things like put full screen videos on your second monitor, or run full screen OpenGL rendered application like games or emulators on the second monitor.  You can also choose which monitor you want the vertical blanking signal to synchronize to to prevent tearing.

I use Nvidia graphic cards with Nvidia proprietary drivers, so if you are using something else the environment variables specified in this article may be different.

IMHO, the first thing to understand with multi monitors under X is how to master the xorg.conf metamodes and the xrandr utility. I'm not going to go into great detail about how to setup xorg.conf files, suffice to say that in the Screen sections you make an Option line like this to define how the 2 monitors are setup.  Note that this setup is actually independent of how you setup your screens with the nvidia-settings utility which is provided with their binary driver:

Option "metamodes" "TV-0: 800x600 +1280+0, DFP-1: 1280x1024_60 +0+0; DFP-1: 1280x1024 +0+0,NULL; TV-0: 800x600 +1280+0,NULL"

Let's dissect this starting at the opening double-quote up to the first semi-colon, this means that I want the first mode to be my DFP at 1280x1024, and to the right of it I want my TV with a display resolution of 800x600.  Understand? For the next mode I want only the DFP at 1280x1024 and I want the TV off (NULL).  For the 3rd and final mode I want only the TV to the right at 800x600 and the DFP off (NULL).  I think if you look carefully you can see this is fairly obvious how the modes are constructed.  The +0+0 and +1280+0 are offsets which means for example "to the right by 1280 and down by 0", which makes logical sense since the DFP is 1280 pixels wide so I want the TV to start where the DFP ends..  Easy!

Now if you run xrandr without any options you'll see something like this depending on the metamodes you setup:

$ xrandr
Screen 0: minimum 320 x 240, current 2080 x 1024, maximum 2080 x 1024
default connected 2080x1024+0+0 0mm x 0mm
   2080x1024      50.0*
   1280x1024      51.0 
   640x480        52.0 
   320x240        53.0 
   1920x480       54.0 
   2080x600       55.0

Now you can test the modes like this:

$ xrandr -s 0
$ xrandr -s 1

and so on..  Each "-s x" are the modes in order from the list.

Note, the 2080x600 mode corresponds to the TV only at 800x600.  It's shown as 2080x600 because the 1280 offset "to the right" is also included.

So now that we know how to manipulate the X server modes, how can we use this in a practical way?  Well, I enjoy using my television to run Mame and other emulators, so in order to do that I made a script like this for Mame:

#!/bin/bash
GAME=$1
export SDL_VIDEO_FULLSCREEN_HEAD=1
export __GL_SYNC_DISPLAY_DEVICE="TV-0"
export __GL_SYNC_TO_VBLANK=1
mame -effect none -switchres ${GAME}

The script gets run like "./script gamename"  Since I'm using the SDL_VIDEO_FULLSCREEN_HEAD=1 environment variable, the TV fullscreen metamode gets selected automatically.  Here's another example with the Stella Atari 2600 emulator:

#!/bin/bash
export SDL_VIDEO_FULLSCREEN_HEAD=1
export __GL_SYNC_DISPLAY_DEVICE="TV-0"
export __GL_SYNC_TO_VBLANK=1
xrandr -s 5
stella &
xrandr -s 0

This one is a bit of a hack and might have some unnecessary stuff in it, but it does work.  Stella refuses to go fullscreen on my TV unless I first switch to a TV only metamode "-s 5", run stella, the switch back to a dual screen metamode "-s 0".

Here's another example but for the Mess emulator:

#!/bin/bash
export SDL_VIDEO_FULLSCREEN_HEAD=1
export __GL_SYNC_DISPLAY_DEVICE="TV-0"
export __GL_SYNC_TO_VBLANK=1
cd /home/xxxx/emulators/sdlmess0143/
./mess -effect none -switchres

Note the difference for the Mess emulator, I run it as-is without specifying a ROM image.  If you've ever used Mess before you know why.  After Mess starts you select the system and then the software.

Note in the above examples I'm setting some Nvidia specific OpenGL environment variables to control the vertical sync since I hate tearing.

Anyway, this article gives 3 different but similar examples of what you can do with X server metamodes and card/driver specific environment variables and features.  You could get creative and implement mplayer or vlc in a similar way, although it's not really necessary, but I suppose it's all up to the way each user wants to control his/her screens.