lauantai 2. tammikuuta 2010

Switching Nokia N900 into portrait mode

Currently there is no xrandr software installed on the Maemo plattform. But xrandr library is there so all you need is a little bit of python to take advantage of it. This is slightly based on https://launchpad.net/python-xrandr . If your python software needs xrandr support on N900 I think that library might be handy.

Anyways this is the code I used:


from ctypes import *
import os
import sys
from pprint import pprint

xlib = cdll.LoadLibrary("libX11.so.6")
rr = cdll.LoadLibrary("libXrandr.so.2")


display = xlib.XOpenDisplay(os.getenv("DISPLAY"))
screen = xlib.XDefaultScreen(display)
root = xlib.XDefaultRootWindow(display, screen)

class XRRScreenConfiguration(Structure):
pass
gsi = rr.XRRGetScreenInfo
gsi.restype = POINTER(XRRScreenConfiguration)
config = gsi(display, root)

current_time = c_ulong()
rr.XRRTimes.restpye = c_ulong
timestamp = rr.XRRTimes(display, screen, byref(current_time))

xccr = rr.XRRConfigCurrentRate
xccr.restype = c_int
rate = xccr(config)

rotation = c_ushort()
size = rr.XRRConfigCurrentConfiguration(config, byref(rotation))


rr.XRRSetScreenConfigAndRate(display,config,root,size,int(sys.argv[1]),rate,timestamp)

So copy that into something like rotate.py and run it like this
  • for portrait mode "python rotate.py 2"
  • for landscape mode "python rotate.py 1"
Portrait mode support is currently lacking but it might have its uses. For example browser currently supports it quite nicely. In the end, I think my Nokia N900 will still be mostly in landscape orientation. Anyways this has been a nice learning experience about python, n900 and xrandr.


Updated daemon version


This will rotate the screen automatically

from ctypes import *
import os
import sys
import time
from math import atan2
from pprint import pprint

xlib = cdll.LoadLibrary("libX11.so.6")
rr = cdll.LoadLibrary("libXrandr.so.2")

def get_rotation():
f = open("/sys/class/i2c-adapter/i2c-3/3-001d/coord", 'r' )
coords = [int(w) for w in f.readline().split()]
f.close()
return coords

print get_rotation()

def rotate(angle):
rr.XRRSetScreenConfigAndRate(display,config,root,size,angle,rate,timestamp)

display = xlib.XOpenDisplay(os.getenv("DISPLAY"))
screen = xlib.XDefaultScreen(display)
root = xlib.XDefaultRootWindow(display, screen)

class XRRScreenConfiguration(Structure):
pass

gsi = rr.XRRGetScreenInfo
gsi.restype = POINTER(XRRScreenConfiguration)
config = gsi(display, root)

current_time = c_ulong()
rr.XRRTimes.restpye = c_ulong
timestamp = rr.XRRTimes(display, screen, byref(current_time))

xccr = rr.XRRConfigCurrentRate
xccr.restype = c_int
rate = xccr(config)

rotation = c_ushort()
size = rr.XRRConfigCurrentConfiguration(config, byref(rotation))

while True:
[x,y,z] = get_rotation()
print x,y,z
if y < -500:
rotate(1)
elif y > 500:
rotate(4)

elif x < -500:
rotate(2)
elif x > 500:
rotate(8)

time.sleep(1)


This also has a bug that will reboot the phone in some situations. Probably related to software that will handle screen rotation also..

Ei kommentteja:

Lähetä kommentti