Pivot

Found myself bored one day on my vacation and thought, hey, I can switch the orientation of my screen, why the heck don’t my software behave the way I want? My screen is a Samsung SyncMaster 215TW and it’s very nice. Actually, this automatic switching of orientation did work when I was toying with it in windows, all I had to to was to install a 36MB package plus a 78MB package for it to switch the orientation in windows. EXCELLENT. (Samsung, you guys suck)

So, how hard can it be for someone who hasn’t gotten the slightest clue about this crap to fix this in linux?

Fairly trivial for this extremely ugly solution, first of all I had to enable randr support for my nvidida card by inserting option "randrrotation" "true" in /etc/X11/xorg.conf for my graphics card. Second, I wanted to know what information was available to me about my monitor. I grabbed ddccontrol and probed for my little monitor.

$ ddccontrol -p
thumper:~# ddccontrol -p
ddccontrol version 0.4.2
Copyright 2004-2005 Oleg I. Vdovikin (oleg@cs.msu.su)
Copyright 2004-2006 Nicolas Boichat (nicolas@boichat.ch)
This program comes with ABSOLUTELY NO WARRANTY.
You may redistribute copies of this program under the terms of the GNU General Public License.

Probing for available monitors..........
Detected monitors :
 - Device: pci:04:00.0-1
   DDC/CI supported: Yes
   Monitor Name: Samsung SyncMaster 215TW (DVI)
   Input type: Digital
  (Automatically selected)
Reading EDID and initializing DDC/CI at bus pci:04:00.0-1...

EDID readings:
        Plug and Play ID: SAM0214 [Samsung SyncMaster 215TW (DVI)]
        Input type: Digital

= Samsung SyncMaster 215TW (DVI)
> Color settings
        > Brightness and Contrast
                > id=magicbright, name=Magic Bright Mode, address=0xdc, delay=-1ms, type=2
                  Possible values:
                        > id=text - name=Text, value=1
                        > id=internet - name=Internet, value=2
                        > id=game - name=Game, value=3
                        > id=sport - name=Sport, value=4
                        > id=entertain - name=Entertain, value=5
                        > id=custom - name=Custom, value=6
                  supported, value=1, maximum=6
                > id=brightness, name=Brightness, address=0x10, delay=-1ms, type=0
                  supported, value=11, maximum=100
                > id=contrast, name=Contrast, address=0x12, delay=-1ms, type=0
                  supported, value=63, maximum=100
        > Color maximum level
                > id=red, name=Red maximum level, address=0x16, delay=-1ms, type=0
                  supported, value=50, maximum=100
                > id=green, name=Green maximum level, address=0x18, delay=-1ms, type=0
                  supported, value=50, maximum=100
                > id=blue, name=Blue maximum level, address=0x1a, delay=-1ms, type=0
                  supported, value=50, maximum=100
        > Various color settings
                > id=colorpreset, name=Color Preset, address=0xe0, delay=-1ms, type=2
                  Possible values:
                        > id=normal - name=Normal, value=3
                        > id=custom - name=Custom, value=0
                        > id=warm - name=Warm, value=1
                        > id=cool - name=Cool, value=2
                  supported, value=3, maximum=3
> Others
        > Restore defaults
                > id=defaults, name=Restore Factory Defaults, address=0x4, delay=2000ms, type=1
                  Possible values:
                        > id=default - name=Restore Factory Defaults, value=1
                  supported, value=3, maximum=3
                > id=defaultluma, name=Restore Brightness and Contrast, address=0x5, delay=2000ms, type=1
                  Possible values:
                        > id=default - name=Restore Brightness and Contrast, value=1
                  supported, value=3, maximum=3
                > id=defaultcolor, name=Restore Factory Default Color, address=0x8, delay=2000ms, type=1
                  Possible values:
                        > id=default - name=Restore Factory Default Color, value=1
                  supported, value=3, maximum=3
                > id=settings, name=Settings, address=0xb0, delay=1000ms, type=1
                  Possible values:
                        > id=default - name=Settings, value=1
                  supported, value=0, maximum=2
        > OSD
                > id=osd2, name=On Screen Display (Samsung), address=0xf5, delay=-1ms, type=2
                  Possible values:
                        > id=disable - name=Disable, value=1
                        > id=enable - name=Enable, value=0
                  supported, value=0, maximum=2
        > Input settings
                > id=autosource, name=Autoselect Input Source, address=0xe2, delay=-1ms, type=2
                  Possible values:
                        > id=auto - name=Automatic, value=0
                        > id=manual - name=Manual, value=1
                  supported, value=0, maximum=2
                > id=inputsource, name=Input Source Select, address=0x60, delay=-1ms, type=2
                  Possible values:
                        > id=analog - name=Analog, value=1
                        > id=digital - name=Digital, value=3
                  supported, value=3, maximum=3
        > Power control
                > id=dpms, name=DPMS Control, address=0xd6, delay=-1ms, type=2
                  Possible values:
                        > id=on - name=On, value=1
                        > id=standby - name=Standby, value=4
                  supported, value=1, maximum=4
                > id=power, name=Power control, address=0xe1, delay=-1ms, type=2
                  Possible values:
                        > id=off - name=Off, value=0
                        > id=on - name=On, value=1
                  supported, value=1, maximum=1

Ok, so apparently there’s a lot of knobs and gauges available in the database, but not what I needed. Fine, I dump all values in landscape mode and compare them to the values I get when in portrait mode with ddccontrol -d pci:04:00.0-1 and after switching around a couple of times finally decided that Control 0xf8: +/1/1 C [???] was the orientation value.

So a quick and rather ugly script was born

#!/bin/sh
dev=pci:04:00.0-1
ctr=0xf8
while sleep 1s; do
        val=$(ddccontrol -r $ctr -f $dev 2>/dev/null | awk '/^Control/{FS="/";split($3,m);print m[2]}')
        if (( val == 0 )); then
                echo "normal" >/tmp/orientation
        elif (( val == 1 )); then
                echo "left" >/tmp/orientation
        fi
done

I start this as root and quickly forget about it. I run this script as my user

#!/bin/sh
while sleep 1s; do
        [[ -f /tmp/orientation ]] && xrandr -o $(cat /tmp/orientation)
done

Now, whenever I turn my screen, X follows. Sadly ion3 doesn’t know, and frankly, I don’t know if it should care, about my current orientation.

2 Responses to “Pivot”

  1. cowbutt says:

    I just re-invented your wheel for my Lenovo L220x:

    #!/bin/sh
    while [ true ]; do
            ORIENTATION=`nice ddccontrol -b /usr/local/share/ddccontrol-db-minimal -r 0xaa pci:01:00.0-1 2>/dev/null | grep Control | awk '{print $8}'`
            if [ "$ORIENTATION" = "Landscape]" -a "$LAST" != "normal" ]; then
                    xrandr --orientation normal
                    LAST="normal"
            fi
            if [ "$ORIENTATION" = "Portrait]" -a "$LAST" != "left" ]; then
                    xrandr --orientation left
                    LAST="left"
            fi      
            sleep 3s
    done
    

    ddccontrol does seem to be a bit CPU-hungry, hence the nice and the caching of the last orientation to avoid running xrandr unnecessarily. I have a minimal copy of options.xml and LEN1151.xml in usr/local/share/ddccontrol-db-minimal/ so that no more XML is parsed than necessary.

  2. knirch says:

    Good idea to cache the orientation, and I’m quite amazed about your googling skills or bad luck that made you end up here. I wasn’t aware the page got indexed :)

Leave a Reply