~ubuntu-branches/debian/stretch/electrum/stretch

« back to all changes in this revision

Viewing changes to gui/kivy/tools/.buildozer/android/platform/python-for-android/dist/kivy/python-install/lib/python2.7/site-packages/kivy/input/providers/mactouch.py

  • Committer: Package Import Robot
  • Author(s): Tristan Seligmann
  • Date: 2016-04-04 03:02:39 UTC
  • mfrom: (1.1.10)
  • Revision ID: package-import@ubuntu.com-20160404030239-0szgkio8yryjv7c9
Tags: 2.6.3-1
* New upstream release.
  - Drop backported install-wizard-connect.patch.
* Add Suggests: python-zbar and update the installation hint to suggest
  apt-get instead of pip (closes: #819517).
* Bump Standards-Version to 3.9.7 (no changes).
* Update Vcs-* links.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
'''
 
2
Native support of MultitouchSupport framework for MacBook (MaxOSX platform)
 
3
===========================================================================
 
4
'''
 
5
 
 
6
__all__ = ('MacMotionEventProvider', )
 
7
 
 
8
import ctypes
 
9
import threading
 
10
import collections
 
11
import os
 
12
from kivy.input.provider import MotionEventProvider
 
13
from kivy.input.factory import MotionEventFactory
 
14
from kivy.input.motionevent import MotionEvent
 
15
from kivy.input.shape import ShapeRect
 
16
 
 
17
if 'KIVY_DOC' not in os.environ:
 
18
    CFArrayRef = ctypes.c_void_p
 
19
    CFMutableArrayRef = ctypes.c_void_p
 
20
    CFIndex = ctypes.c_long
 
21
 
 
22
    dll = '/System/Library/PrivateFrameworks/' + \
 
23
        'MultitouchSupport.framework/MultitouchSupport'
 
24
    MultitouchSupport = ctypes.CDLL(dll)
 
25
 
 
26
    CFArrayGetCount = MultitouchSupport.CFArrayGetCount
 
27
    CFArrayGetCount.argtypes = [CFArrayRef]
 
28
    CFArrayGetCount.restype = CFIndex
 
29
 
 
30
    CFArrayGetValueAtIndex = MultitouchSupport.CFArrayGetValueAtIndex
 
31
    CFArrayGetValueAtIndex.argtypes = [CFArrayRef, CFIndex]
 
32
    CFArrayGetValueAtIndex.restype = ctypes.c_void_p
 
33
 
 
34
    MTDeviceCreateList = MultitouchSupport.MTDeviceCreateList
 
35
    MTDeviceCreateList.argtypes = []
 
36
    MTDeviceCreateList.restype = CFMutableArrayRef
 
37
 
 
38
    class MTPoint(ctypes.Structure):
 
39
        _fields_ = [('x', ctypes.c_float),
 
40
                    ('y', ctypes.c_float)]
 
41
 
 
42
    class MTVector(ctypes.Structure):
 
43
        _fields_ = [('position', MTPoint),
 
44
                    ('velocity', MTPoint)]
 
45
 
 
46
    class MTData(ctypes.Structure):
 
47
        _fields_ = [
 
48
            ('frame', ctypes.c_int),
 
49
            ('timestamp', ctypes.c_double),
 
50
            ('identifier', ctypes.c_int),
 
51
            # Current state (of unknown meaning).
 
52
            ('state', ctypes.c_int),
 
53
            ('unknown1', ctypes.c_int),
 
54
            ('unknown2', ctypes.c_int),
 
55
            # Normalized position and vector of the touch (0 to 1)
 
56
            ('normalized', MTVector),
 
57
            # The area of the touch.
 
58
            ('size', ctypes.c_float),
 
59
            ('unknown3', ctypes.c_int),
 
60
            # The following three define the ellipsoid of a finger.
 
61
            ('angle', ctypes.c_float),
 
62
            ('major_axis', ctypes.c_float),
 
63
            ('minor_axis', ctypes.c_float),
 
64
            ('unknown4', MTVector),
 
65
            ('unknown5_1', ctypes.c_int),
 
66
            ('unknown5_2', ctypes.c_int),
 
67
            ('unknown6', ctypes.c_float), ]
 
68
 
 
69
    MTDataRef = ctypes.POINTER(MTData)
 
70
 
 
71
    MTContactCallbackFunction = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int,
 
72
                                                 MTDataRef, ctypes.c_int,
 
73
                                                 ctypes.c_double, ctypes.c_int)
 
74
 
 
75
    MTDeviceRef = ctypes.c_void_p
 
76
 
 
77
    MTRegisterContactFrameCallback = \
 
78
        MultitouchSupport.MTRegisterContactFrameCallback
 
79
    MTRegisterContactFrameCallback.argtypes = \
 
80
        [MTDeviceRef, MTContactCallbackFunction]
 
81
    MTRegisterContactFrameCallback.restype = None
 
82
 
 
83
    MTDeviceStart = MultitouchSupport.MTDeviceStart
 
84
    MTDeviceStart.argtypes = [MTDeviceRef, ctypes.c_int]
 
85
    MTDeviceStart.restype = None
 
86
 
 
87
else:
 
88
    MTContactCallbackFunction = lambda x: None
 
89
 
 
90
 
 
91
class MacMotionEvent(MotionEvent):
 
92
    '''MotionEvent representing a contact point on the touchpad. Supports pos
 
93
    and shape profiles.
 
94
    '''
 
95
 
 
96
    def depack(self, args):
 
97
        self.is_touch = True
 
98
        self.shape = ShapeRect()
 
99
        self.sx, self.sy = args[0], args[1]
 
100
        self.shape.width = args[2]
 
101
        self.shape.height = args[2]
 
102
        self.profile = ('pos', 'shape')
 
103
        super(MacMotionEvent, self).depack(args)
 
104
 
 
105
    def __str__(self):
 
106
        return '<MacMotionEvent id=%d pos=(%f, %f) device=%s>' \
 
107
            % (self.id, self.sx, self.sy, self.device)
 
108
 
 
109
_instance = None
 
110
 
 
111
 
 
112
class MacMotionEventProvider(MotionEventProvider):
 
113
 
 
114
    def __init__(self, *largs, **kwargs):
 
115
        global _instance
 
116
        if _instance is not None:
 
117
            raise Exception('Only one MacMotionEvent provider is allowed.')
 
118
        _instance = self
 
119
        super(MacMotionEventProvider, self).__init__(*largs, **kwargs)
 
120
 
 
121
    def start(self):
 
122
        # global uid
 
123
        self.uid = 0
 
124
        # touches will be per devices
 
125
        self.touches = {}
 
126
        # lock needed to access on uid
 
127
        self.lock = threading.Lock()
 
128
        # event queue to dispatch in main thread
 
129
        self.queue = collections.deque()
 
130
 
 
131
        # ok, listing devices, and attach !
 
132
        devices = MultitouchSupport.MTDeviceCreateList()
 
133
        num_devices = CFArrayGetCount(devices)
 
134
        for i in range(num_devices):
 
135
            device = CFArrayGetValueAtIndex(devices, i)
 
136
            # create touch dict for this device
 
137
            data_id = str(device)
 
138
            self.touches[data_id] = {}
 
139
            # start !
 
140
            MTRegisterContactFrameCallback(device, self._mts_callback)
 
141
            MTDeviceStart(device, 0)
 
142
 
 
143
    def update(self, dispatch_fn):
 
144
        # dispatch all event from threads
 
145
        try:
 
146
            while True:
 
147
                event_type, touch = self.queue.popleft()
 
148
                dispatch_fn(event_type, touch)
 
149
        except:
 
150
            pass
 
151
 
 
152
    def stop(self):
 
153
        # i don't known how to stop it...
 
154
        pass
 
155
 
 
156
    @MTContactCallbackFunction
 
157
    def _mts_callback(device, data_ptr, n_fingers, timestamp, frame):
 
158
        global _instance
 
159
        devid = str(device)
 
160
 
 
161
        # XXX create live touch, we get one case that
 
162
        # the device announced by macosx don't match the device
 
163
        # in _mts_callback....
 
164
        if not devid in _instance.touches:
 
165
            _instance.touches[devid] = {}
 
166
 
 
167
        touches = _instance.touches[devid]
 
168
        actives = []
 
169
 
 
170
        for i in range(n_fingers):
 
171
            # get pointer on data
 
172
            data = data_ptr[i]
 
173
 
 
174
            # add this touch as an active touch
 
175
            actives.append(data.identifier)
 
176
 
 
177
            # extract identifier
 
178
            data_id = data.identifier
 
179
 
 
180
            # prepare argument position
 
181
            norm_pos = data.normalized.position
 
182
            args = (norm_pos.x, norm_pos.y, data.size)
 
183
 
 
184
            if not data_id in touches:
 
185
                # increment uid
 
186
                _instance.lock.acquire()
 
187
                _instance.uid += 1
 
188
                # create a touch
 
189
                touch = MacMotionEvent(_instance.device, _instance.uid, args)
 
190
                _instance.lock.release()
 
191
                # create event
 
192
                _instance.queue.append(('begin', touch))
 
193
                # store touch
 
194
                touches[data_id] = touch
 
195
            else:
 
196
                touch = touches[data_id]
 
197
                # check if he really moved
 
198
                if data.normalized.position.x == touch.sx and \
 
199
                   data.normalized.position.y == touch.sy:
 
200
                    continue
 
201
                touch.move(args)
 
202
                _instance.queue.append(('update', touch))
 
203
 
 
204
        # delete old touchs
 
205
        for tid in list(touches.keys())[:]:
 
206
            if tid not in actives:
 
207
                touch = touches[tid]
 
208
                touch.update_time_end()
 
209
                _instance.queue.append(('end', touch))
 
210
                del touches[tid]
 
211
 
 
212
        return 0
 
213
 
 
214
MotionEventFactory.register('mactouch', MacMotionEventProvider)