pastebin.ch - Xlib

Subject
Xlib
Author
xlq
Description
Open a window with libX11 (Xlib)
Posted on
Thu, 04 Mar 2010 17:47:07 +0100
Content
from ctypes import *
import ctypes.util
import sys, weakref
 
libX11_name = ctypes.util.find_library("X11")
if not libX11_name:
    raise Exception("libX11 not found")
 
X11 = ctypes.CDLL(libX11_name)
Xwrap = ctypes.CDLL('./libXwrap.so')
 
XID = c_ulong
P_XDisplay = c_void_p
XGC = c_void_p
XWindow = XID
XTime = c_ulong
Bool = c_int
XDrawable = XID
XAtom = XID
XColormap = XID
XStatus = c_int
 
class XKeyEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('window', XWindow),
        ('root', XWindow),
        ('subwindow', XWindow),
        ('time', XTime),
        ('x', c_int),
        ('y', c_int),
        ('x_root', c_int),
        ('y_root', c_int),
        ('state', c_uint),
        ('keycode', c_uint),
        ('same_screen', Bool),
    ]
 
class XButtonEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('window', XWindow),
        ('root', XWindow),
        ('subwindow', XWindow),
        ('time', XTime),
        ('x', c_int),
        ('y', c_int),
        ('x_root', c_int),
        ('y_root', c_int),
        ('state', c_uint),
        ('button', c_uint),
        ('same_screen', Bool),
    ]
 
class XMotionEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('window', XWindow),
        ('root', XWindow),
        ('subwindow', XWindow),
        ('time', XTime),
        ('x', c_int),
        ('y', c_int),
        ('x_root', c_int),
        ('y_root', c_int),
        ('state', c_uint),
        ('is_hint', c_byte),
        ('same_screen', Bool),
    ]
 
class XCrossingEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('window', XWindow),
        ('root', XWindow),
        ('subwindow', XWindow),
        ('time', XTime),
        ('x', c_int),
        ('y', c_int),
        ('x_root', c_int),
        ('y_root', c_int),
        ('mode', c_int),
        ('detail', c_int),
        ('same_screen', Bool),
        ('focus', Bool),
        ('state', c_uint),
    ]
 
class XFocusChangeEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('window', XWindow),
        ('mode', c_int),
        ('detail', c_int),
    ]
 
class XKeymapEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('window', XWindow),
        ('key_vector', c_byte * 32),
    ]
 
class XExposeEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('window', XWindow),
        ('x', c_int),
        ('y', c_int),
        ('width', c_int),
        ('height', c_int),
        ('count', c_int),
    ]
 
class XGraphicsExposeEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('drawable', XDrawable),
        ('x', c_int),
        ('y', c_int),
        ('width', c_int),
        ('height', c_int),
        ('count', c_int),
        ('major_code', c_int),
        ('minor_code', c_int),
    ]
 
class XNoExposeEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('drawable', XDrawable),
        ('major_code', c_int),
        ('minor_code', c_int),
    ]
 
class XVisibilityEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('window', XWindow),
        ('state', c_int),
    ]
 
class XCreateWindowEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('parent', XWindow),
        ('window', XWindow),
        ('x', c_int),
        ('y', c_int),
        ('width', c_int),
        ('height', c_int),
        ('border_width', c_int),
        ('override_redirect', Bool),
    ]
 
class XDestroyWindowEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('event', XWindow),
        ('window', XWindow),
    ]
 
class XUnmapEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('event', XWindow),
        ('window', XWindow),
        ('from_configure', Bool),
    ]
 
class XMapEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('event', XWindow),
        ('window', XWindow),
        ('override_redirect', Bool),
    ]
 
class XMapRequestEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('parent', XWindow),
        ('window', XWindow),
    ]
 
class XReparentEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('event', XWindow),
        ('window', XWindow),
        ('parent', XWindow),
        ('x', c_int),
        ('y', c_int),
        ('override_redirect', Bool),
    ]
 
class XConfigureEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('event', XWindow),
        ('window', XWindow),
        ('x', c_int),
        ('y', c_int),
        ('width', c_int),
        ('height', c_int),
        ('border_width', c_int),
        ('above', XWindow),
        ('override_redirect', Bool),
    ]
 
class XGravityEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('event', XWindow),
        ('window', XWindow),
        ('x', c_int),
        ('y', c_int),
    ]
 
class XResizeRequestEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('window', XWindow),
        ('width', c_int),
        ('height', c_int),
    ]
 
class XConfigureRequestEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('parent', XWindow),
        ('window', XWindow),
        ('x', c_int),
        ('y', c_int),
        ('width', c_int),
        ('height', c_int),
        ('border_width', c_int),
        ('above', XWindow),
        ('detail', c_int),
        ('value_mask', c_ulong),
    ]
 
class XCirculateEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('event', XWindow),
        ('window', XWindow),
        ('place', c_int),
    ]
 
class XCirculateRequestEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('parent', XWindow),
        ('window', XWindow),
        ('place', c_int),
    ]
 
class XPropertyEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('window', XWindow),
        ('atom', XAtom),
        ('time', XTime),
        ('state', c_int),
    ]
 
class XSelectionClearEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('window', XWindow),
        ('selection', XAtom),
        ('time', XTime),
    ]
 
class XSelectionRequestEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('owner', XWindow),
        ('requestor', XWindow),
        ('selection', XAtom),
        ('target', XAtom),
        ('property', XAtom),
        ('time', XTime),
    ]
 
class XSelectionEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('requestor', XWindow),
        ('selection', XAtom),
        ('target', XAtom),
        ('property', XAtom),
        ('time', XTime),
    ]
 
class XColormapEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('window', XWindow),
        ('colormap', XColormap),
        ('new', Bool),
        ('state', c_int),
    ]
 
class XClientMessageEvent_data(Union):
    _fields_ = [
        ('b', c_byte * 20),
        ('s', c_short * 10),
        ('l', c_long * 5),
    ]
 
class XClientMessageEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('window', XWindow),
        ('message_type', XAtom),
        ('format', c_int),
        ('data', XClientMessageEvent_data),
    ]
 
class XMappingEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('window', XWindow),
        ('request', c_int),
        ('first_keycode', c_int),
        ('count', c_int),
    ]
 
class XErrorEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('display', P_XDisplay),
        ('resourceid', XID),
        ('serial', c_ulong),
        ('error_code', c_ubyte),
        ('request_code', c_ubyte),
        ('minor_code', c_ubyte),
    ]
 
class XAnyEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('window', XWindow),
    ]
 
class XGenericEvent(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('extension', c_int),
        ('evtype', c_int),
    ]
 
class XGenericEventCookie(Structure):
    _fields_ = [
        ('type', c_int),
        ('serial', c_ulong),
        ('send_event', Bool),
        ('display', P_XDisplay),
        ('extension', c_int),
        ('evtype', c_int),
        ('cookie', c_uint),
        ('data', c_void_p),
    ]
 
class XEvent(Union):
    _fields_ = [
        ('type', c_int),
	    ('xany', XAnyEvent),
	    ('xkey', XKeyEvent),
	    ('xbutton', XButtonEvent),
	    ('xmotion', XMotionEvent),
	    ('xcrossing', XCrossingEvent),
	    ('xfocus', XFocusChangeEvent),
	    ('xexpose', XExposeEvent),
	    ('xgraphicsexpose', XGraphicsExposeEvent),
	    ('xnoexpose', XNoExposeEvent),
	    ('xvisibility', XVisibilityEvent),
	    ('xcreatewindow', XCreateWindowEvent),
	    ('xdestroywindow', XDestroyWindowEvent),
	    ('xunmap', XUnmapEvent),
	    ('xmap', XMapEvent),
	    ('xmaprequest', XMapRequestEvent),
	    ('xreparent', XReparentEvent),
	    ('xconfigure', XConfigureEvent),
	    ('xgravity', XGravityEvent),
	    ('xresizerequest', XResizeRequestEvent),
	    ('xconfigurerequest', XConfigureRequestEvent),
	    ('xcirculate', XCirculateEvent),
	    ('xcirculaterequest', XCirculateRequestEvent),
	    ('xproperty', XPropertyEvent),
	    ('xselectionclear', XSelectionClearEvent),
	    ('xselectionrequest', XSelectionRequestEvent),
	    ('xselection', XSelectionEvent),
	    ('xcolormap', XColormapEvent),
	    ('xclient', XClientMessageEvent),
	    ('xmapping', XMappingEvent),
	    ('xerror', XErrorEvent),
	    ('xkeymap', XKeymapEvent),
	    ('xgeneric', XGenericEvent),
	    ('xcookie', XGenericEventCookie),
        ('pad', c_long * 24),
    ]
 
# Event numbers
KeyPress = 2
KeyRelease = 3
ButtonPress = 4
ButtonRelease = 5
MotionNotify = 6
EnterNotify = 7
LeaveNotify = 8
FocusIn = 9
FocusOut = 10
KeymapNotify = 11
Expose = 12
GraphicsExpose = 13
NoExpose = 14
VisibilityNotify = 15
CreateNotify = 16
DestroyNotify = 17
UnmapNotify = 18
MapNotify = 19
MapRequest = 20
ReparentNotify = 21
ConfigureNotify = 22
ConfigureRequest = 23
GravityNotify = 24
ResizeRequest = 25
CirculateNotify = 26
CirculateRequest = 27
PropertyNotify = 28
SelectionClear = 29
SelectionRequest = 30
SelectionNotify = 31
ColormapNotify = 32
ClientMessage = 33
MappingNotify = 34
GenericEvent = 35
 
# Event masks
NoEventMask = 0
KeyPressMask = 1 << 0
KeyReleaseMask = 1 << 1
ButtonPressMask = 1 << 2
ButtonReleaseMask = 1 << 3
EnterWindowMask = 1 << 4
LeaveWindowMask = 1 << 5
PointerMotionMask = 1 << 6
PointerMotionHintMask = 1 << 7
Button1MotionMask = 1 << 8
Button2MotionMask = 1 << 9
Button3MotionMask = 1 << 10
Button4MotionMask = 1 << 11
Button5MotionMask = 1 << 12
ButtonMotionMask = 1 << 13
KeymapStateMask = 1 << 14
ExposureMask = 1 << 15
VisibilityChangeMask = 1 << 16
StructureNotifyMask = 1 << 17
ResizeRedirectMask = 1 << 18
SubstructureNotifyMask = 1 << 19
SubstructureRedirectMask = 1 << 20
FocusChangeMask = 1 << 21
PropertyChangeMask = 1 << 22
ColormapChangeMask = 1 << 23
OwnerGrabButtonMask = 1 << 24
 
def declare(lib, ret, name, *args):
    f = getattr(lib, name)
    f.argtypes = args
    f.restype = ret
 
declare(X11, P_XDisplay, 'XOpenDisplay', c_char_p)
declare(X11, c_int, 'XCloseDisplay', P_XDisplay)
declare(X11, XWindow, 'XCreateSimpleWindow', P_XDisplay, XWindow,
  c_int, c_int, c_uint, c_uint,
  c_uint, c_ulong, c_ulong)
declare(X11, c_int, 'XDestroyWindow', P_XDisplay, XWindow)
declare(X11, c_int, 'XMapWindow', P_XDisplay, XWindow)
declare(X11, c_int, 'XUnmapWindow', P_XDisplay, XWindow)
declare(X11, c_int, 'XNextEvent', P_XDisplay, POINTER(XEvent))
declare(X11, XAtom, 'XInternAtom', P_XDisplay, c_char_p, Bool)
declare(X11, XStatus, 'XSetWMProtocols', P_XDisplay, XWindow, POINTER(XAtom), c_int)
declare(X11, c_int, 'XSelectInput', P_XDisplay, XWindow, c_long)
 
declare(Xwrap, c_int, 'Xw_DefaultScreen', P_XDisplay)
declare(Xwrap, XGC, 'Xw_DefaultGC', P_XDisplay, c_int)
declare(Xwrap, XWindow, 'Xw_RootWindow', P_XDisplay, c_int)
declare(Xwrap, c_ulong, 'Xw_BlackPixel', P_XDisplay, c_int)
declare(Xwrap, c_ulong, 'Xw_WhitePixel', P_XDisplay, c_int)
 
class Display(object):
    def __init__(self, name=None):
        self.open = False
        self._d = X11.XOpenDisplay(None)
        if not self._d:
            raise Exception("Cannot open display: %s" % name)
        self.wm_delete_window = X11.XInternAtom(
          self._d,
          "WM_DELETE_WINDOW",
          False)
        self.open = True
 
    def close(self):
        if self.open:
            X11.XCloseDisplay(self._d)
            self.open = False
 
    def __del__(self):
        if self.open:
            sys.stderr.write("WARNING: Display wasn't closed")
            self.close()
 
    def run(self):
        """Run event loop"""
        e = XEvent()
        while True:
            X11.XNextEvent(self._d, pointer(e))
            print "Event type %d" % e.type
            if e.type == ClientMessage:
                if e.xclient.data.l[0] == self.wm_delete_window:
                    # Close window
                    return
 
class Window(object):
    def __init__(self, display, x=10, y=10, width=300, height=300):
        self.open = False
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.display = weakref.ref(display)
        self._s = Xwrap.Xw_DefaultScreen(display._d)
        self._gc = Xwrap.Xw_DefaultGC(display._d, self._s)
        self._w = X11.XCreateSimpleWindow(
          display._d,
          Xwrap.Xw_RootWindow(display._d, self._s),
          x, y, width, height, 1,
          Xwrap.Xw_BlackPixel(display._d, self._s), # border
          Xwrap.Xw_WhitePixel(display._d, self._s), # background
        )
        atom = XAtom(display.wm_delete_window)
        if not X11.XSetWMProtocols(
          display._d,
          self._w,
          pointer(atom),
          1
        ):
            raise Exception("XSetWMProtocols failed")
        X11.XSelectInput(display._d, self._w,
          ExposureMask | KeyPressMask | StructureNotifyMask
          | PointerMotionMask | ButtonPressMask | ButtonReleaseMask)
 
        self.open = True
 
    def show(self):
        X11.XMapWindow(self.display()._d, self._w)
 
    def hide(self):
        X11.XUnmapWindow(self.display()._d, self._w)
 
    def close(self):
        if self.open:
            X11.XDestroyWindow(self.display()._d, self._w)
            self.open = False
 
    def __del__(self):
        if self.open:
            sys.stderr.write("WARNING: Window wasn't closed")
            self.close()
 
 
d = Display()
w = Window(d)
w.show()
d.run()
w.close()
d.close()
 
Don't email to hereI'm now supporting the experiment spamschlucker.org too :)