Created
May 29, 2012 18:00
-
-
Save inean/2829771 to your computer and use it in GitHub Desktop.
A class to interact with Harmattan compositor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from os import getpid | |
class HarmattanCompositor(object): | |
# Atoms | |
XA_ATOM = 4 | |
XA_STRING = 31 | |
XA_WINDOW = 33 | |
# Contants | |
PropModeReplace, \ | |
PropModePrepend, \ | |
PropModeAppend = xrange(0, 3) | |
def __init__(self): | |
# C types | |
try: | |
import ctypes as c | |
except ImportError: | |
sys.exit(1) | |
# store ctypes modules | |
self.c = c | |
@property | |
@cached | |
def xlib(self): | |
"""Load Xlib library and setup required methods properly""" | |
# load library | |
xlib, c = self.c.cdll.LoadLibrary('/usr/lib/libX11.so.6'), self.c | |
# XInterAtom | |
xlib.XInternAtom.argtypes = [ | |
c.c_void_p, c.c_char_p, c.c_int | |
] | |
# XChangeProperty | |
xlib.XChangeProperty.argtypes = [ | |
c.c_void_p, c.c_long, c.c_int, c.c_int, c.c_int, | |
c.c_int, c.c_char_p, c.c_int | |
] | |
# XGetWindowProperty | |
xlib.XGetWindowProperty.argtypes = [ | |
c.c_void_p, c.c_long, c.c_int, c.c_int, c.c_int, c.c_int, | |
c.c_int, c.c_void_p, c.c_void_p, c.c_void_p, c.c_void_p, c.POINTER(c.POINTER(c.c_ulong))] | |
#XSetTransientForHint | |
xlib.XSetTransientForHint.argtypes = [ | |
c.c_void_p, c.c_long, c.c_long | |
] | |
# define a data Union class and store on xlib | |
class data(c.Union): | |
_fields_ = [("i", c.c_int, 32), ("s", c.c_char * 4)] | |
setattr(xlib, "data", data) | |
return xlib | |
@cached | |
def _get_display(self): | |
"""get display""" | |
return self.xlib.XOpenDisplay(None) | |
@cached | |
def _get_root(self): | |
return self.xlib.XDefaultRootWindow(self._get_display()) | |
@cached | |
def _get_data(self, value): | |
"""Create a data object required as by XChangeProperty""" | |
data, c = self.xlib.data(), self.c | |
attr = 'i' if isinstance(value, (int, long,)) else 's' | |
setattr(data, attr, value) | |
return c.cast(c.pointer(data), c.c_char_p) | |
@cached | |
def _get_atom(self, atom): | |
"""Get atom specified by atom string""" | |
return self.xlib.XInternAtom(self._get_display(), atom, False) | |
def _change_property(self, child, atom, ptype, psize, mode, data, dlen): | |
"""Invoke XChangeProperty""" | |
self.xlib.XChangeProperty( | |
self._get_display(), child, | |
self._get_atom(atom), ptype, | |
psize, mode, data, dlen) | |
def _get_property(self, atom): | |
"""Call XGetWindowProperty""" | |
# init return vars | |
c = self.c | |
type_ret = c.c_int() | |
format_ret = c.c_int() | |
nitems_ret = c.c_ulong() | |
bytes_after_ret = c.c_ulong() | |
winp = c.pointer(c.c_ulong()) | |
# invoke | |
retval = self.xlib.XGetWindowProperty( | |
self._get_display(), | |
self._get_root(), | |
self._get_atom(atom), | |
0, 0x7fffffff, False, self.XA_WINDOW, | |
c.byref(type_ret), c.byref(format_ret), c.byref(nitems_ret), | |
c.byref(bytes_after_ret), c.byref(winp)) | |
# return requested values | |
return not retval, winp | |
def splash_window(self, wm_class, image): | |
retval, compositor = self._get_property("_NET_SUPPORTING_WM_CHECK") | |
if retval and compositor: | |
c = self.c | |
# create_string_buffer adds missing NUL | |
buff = "%d\0%s\0%s\0\0" %(getpid(), wm_class, image,) | |
buff = c.create_string_buffer(buff) | |
data = c.cast(buff, c.POINTER(c.c_char)) | |
# invoke | |
self._change_property( | |
compositor.contents.value, "_MEEGO_SPLASH_SCREEN", | |
self.XA_STRING, 8, self.PropModeReplace, data, len(buff)) | |
# flush | |
self.xlib.XFlush(self._get_display()) | |
self.xlib.XFree(compositor) | |
def stack_window(self, parent_id, child_id): | |
"""Stack child_id to parent_id""" | |
# Notify that we want a stacked window | |
self._change_property( | |
child_id, | |
"_MEEGOTOUCH_WM_INVOKED_BY", self.XA_WINDOW, | |
self.PropModeReplace, 32, self._get_data(parent_id), 1 | |
) | |
# for task switcher view stacking | |
self.xlib.XSetTransientForHint( | |
self._get_display(), child_id, parent_id) | |
def set_window_type(self, child_id, wtype): | |
"""Append wtype as window type""" | |
self._change_property( | |
child_id, | |
"_NET_WM_WINDOW_TYPE", self.XA_ATOM, 32, | |
self.PropModeAppend, self._get_data(self._get_atom(wtype)), 1 | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
for a valid @cached decorator see memoize: http://wiki.python.org/moin/PythonDecoratorLibrary#Memoize