summaryrefslogtreecommitdiff
path: root/spnav.py
blob: 4f1ff6b84bb9fc66467205b60581695e5229d002 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
from ctypes import cdll, c_int, c_uint, c_void_p, py_object, byref, Structure, Union, pythonapi

# OMG CALLING CPYTHON FUNCTIONS FROM INSIDE PYTHON
pythonapi.PyCObject_AsVoidPtr.restype = c_void_p
pythonapi.PyCObject_AsVoidPtr.argtypes = [py_object]

libspnav = cdll.LoadLibrary('libspnav.so')

SPNAV_EVENT_ANY = 0
SPNAV_EVENT_MOTION = 1
SPNAV_EVENT_BUTTON = 2

class spnav_event_motion(Structure):
    _fields_ = [('type', c_int),
                ('x', c_int),
                ('y', c_int),
                ('z', c_int),
                ('rx', c_int),
                ('ry', c_int),
                ('rz', c_int),
                ('period', c_uint),
                ('data', c_void_p)]

class spnav_event_button(Structure):
    _fields_ = [('type', c_int),
                ('press', c_int),
                ('bnum', c_int)]

class spnav_event(Union):
    _fields_ = [('type', c_int),
                ('motion', spnav_event_motion),
                ('button', spnav_event_button) ]

    def __str__(self):
        if self.type == SPNAV_EVENT_ANY:
            return 'SPNAV_EVENT_ANY'
        elif self.type == SPNAV_EVENT_MOTION:
            m = self.motion
            return 'SPNAV_EVENT_MOTION t(%d,%d,%d) r(%d,%d,%d)' % (m.x, m.y, m.z, m.rx, m.ry, m.rz)
        elif self.type == SPNAV_EVENT_BUTTON:
            if self.button.press:
                state = 'down'
            else:
                state = 'up'
            return 'SPNAV_EVENT_BUTTON %d %s' % (self.button.bnum, state)
    
def spnav_open():
    if libspnav.spnav_open() == -1:
        raise Exception('failed to connect to the space navigator daemon')

def spnav_x11_open(display, window):
    display_ptr = pythonapi.PyCObject_AsVoidPtr(display)
    if libspnav.spnav_x11_open(display_ptr, window) == -1:
        raise Exception('failed to connect to the space navigator daemon')

def spnav_x11_window(window):
    libspnav.spnav_x11_window(window)

def spnav_close():
    libspnav.spnav_close()

def spnav_fd():
    return libspnav.spnav_fd()

def spnav_wait_event():
    ev = spnav_event()
    ret = libspnav.spnav_wait_event(byref(ev))
    if ret:
        return ev
    else:
        raise Exception('non-zero return code from spnav_wait_event()')

def spnav_poll_event():
    ev = spnav_event()
    ret = libspnav.spnav_poll_event(byref(ev))
    if ret == 0:
        return None
    else:
        return ev

def spnav_remove_events(event_type):
    return libspnav.spnav_remove_events(event_type)

def spnav_x11_event(xevent):
    ev = spnav_event()
    ret = libspnav.spnav_x11_event(xevent, byref(ev))
    if ret == 0:
        return None
    else:
        return ev

if __name__ == '__main__':
    spnav_open()
    try:
        while True:
            ev = spnav_wait_event()
            print ev
    finally:
        spnav_close()