def probe(self): inputs = get_inputs(self.input_path) inputs = [x for x in inputs if x.has_capability(ABS_MT_POSITION_X)] for device in inputs: Logger.info('ProbeSysfs: found device: %s at %s' % ( device.name, device.device)) # must ignore ? if self.match: if not match(self.match, device.name, IGNORECASE): Logger.warning('ProbeSysfs: device not match the' ' rule in config, ignoring.') continue d = device.device devicename = self.device % dict(name=d.split(sep)[-1]) provider = MotionEventFactory.get(self.provider) if provider is None: Logger.info('ProbeSysfs: unable to found provider %s' % self.provider) Logger.info('ProbeSysfs: fallback on hidinput') provider = MotionEventFactory.get('hidinput') if provider is None: Logger.critical('ProbeSysfs: no input provider found' ' to handle this device !') continue instance = provider(devicename, '%s,%s' % (device.device, ','.join(self.args))) if instance: from kivy.base import EventLoop EventLoop.add_input_provider(instance)
def probe(self): global EventLoop from kivy.base import EventLoop inputs = get_inputs(self.input_path) Logger.debug('ProbeSysfs: using probesysfs!') use_mouse = self.should_use_mouse() if not self.select_all: inputs = [x for x in inputs if x.has_capability(ABS_MT_POSITION_X) and (use_mouse or not x.is_mouse)] for device in inputs: Logger.debug('ProbeSysfs: found device: %s at %s' % ( device.name, device.device)) # must ignore ? if self.match: if self.use_regex: if not match(self.match, device.name, IGNORECASE): Logger.debug('ProbeSysfs: device not match the' ' rule in config, ignoring.') continue else: if self.match not in device.name: continue Logger.info('ProbeSysfs: device match: %s' % device.device) d = device.device devicename = self.device % dict(name=d.split(sep)[-1]) provider = MotionEventFactory.get(self.provider) if provider is None: Logger.info('ProbeSysfs: unable to found provider %s' % self.provider) Logger.info('ProbeSysfs: fallback on hidinput') provider = MotionEventFactory.get('hidinput') if provider is None: Logger.critical('ProbeSysfs: no input provider found' ' to handle this device !') continue instance = provider(devicename, '%s,%s' % ( device.device, ','.join(self.args))) if instance: EventLoop.add_input_provider(instance)
def _get_provider_map(self): """Iterates through all registered input provider names and finds the respective MotionEvent subclass for each. Returns a dict of MotionEvent subclasses mapped to their provider name. """ provider_map = {} for input_provider in MotionEventFactory.list(): if not hasattr(providers, input_provider): continue p = getattr(providers, input_provider) for m in p.__all__: event = getattr(p, m) if issubclass(event, MotionEvent): provider_map[event] = input_provider return provider_map
done = self._touch_handler(msg, wParam, lParam) if msg >= WM_MOUSEMOVE and msg <= WM_MOUSELAST: done = self._mouse_handler(msg, wParam, lParam) if not done: return windll.user32.CallWindowProcW(self.old_windProc, hwnd, msg, wParam, lParam) return 1 # this on pushes WM_TOUCH messages onto our event stack def _touch_handler(self, msg, wParam, lParam): touches = (TOUCHINPUT * wParam)() windll.user32.GetTouchInputInfo(HANDLE(lParam), wParam, pointer(touches), sizeof(TOUCHINPUT)) for i in xrange(wParam): self.touch_events.appendleft(touches[i]) return True # filter fake mouse events, because touch and stylus # also make mouse events def _mouse_handler(self, msg, wparam, lParam): info = windll.user32.GetMessageExtraInfo() # its a touch or a pen if (info & PEN_OR_TOUCH_MASK) == PEN_OR_TOUCH_SIGNATURE: if info & PEN_EVENT_TOUCH_MASK: return True MotionEventFactory.register('wm_touch', WM_MotionEventProvider)
point['x'] = val elif ev_code == ABS_MT_POSITION_Y: val = 1. - normalize(ev_value, range_min_position_y, range_max_position_y) if invert_y: val = 1. - val point['y'] = val elif ev_code == ABS_MT_ORIENTATION: point['orientation'] = ev_value elif ev_code == ABS_MT_BLOB_ID: point['blobid'] = ev_value elif ev_code == ABS_MT_PRESSURE: point['pressure'] = normalize(ev_value, range_min_pressure, range_max_pressure) elif ev_code == ABS_MT_TOUCH_MAJOR: point['size_w'] = ev_value elif ev_code == ABS_MT_TOUCH_MINOR: point['size_h'] = ev_value def update(self, dispatch_fn): # dispatch all event from threads try: while True: event_type, touch = self.queue.popleft() dispatch_fn(event_type, touch) except: pass MotionEventFactory.register('hidinput', HIDInputMotionEventProvider)
return QUERYSYSTEMGESTURE_WNDPROC if msg == WM_TOUCH: done = self._touch_handler(msg, wParam, lParam) if msg >= WM_MOUSEMOVE and msg <= WM_MOUSELAST: done = self._mouse_handler(msg, wParam, lParam) if not done: return windll.user32.CallWindowProcW(self.old_windProc, hwnd, msg, wParam, lParam) return 1 # this on pushes WM_TOUCH messages onto our event stack def _touch_handler(self, msg, wParam, lParam): touches = (TOUCHINPUT * wParam)() windll.user32.GetTouchInputInfo(HANDLE(lParam), wParam, pointer(touches), sizeof(TOUCHINPUT)) for i in xrange(wParam): self.touch_events.appendleft(touches[i]) return True # filter fake mouse events, because touch and stylus # also make mouse events def _mouse_handler(self, msg, wparam, lParam): info = windll.user32.GetMessageExtraInfo() # its a touch or a pen if (info & PEN_OR_TOUCH_MASK) == PEN_OR_TOUCH_SIGNATURE: if info & PEN_EVENT_TOUCH_MASK: return True MotionEventFactory.register("wm_touch", WM_MotionEventProvider)
val = 1. - val touch_x = val changed = True elif ev_type == EV_ABS and ev_code == ABS_Y: val = 1. - normalize(ev_value, range_min_position_y, range_max_position_y) if invert_y: val = 1. - val touch_y = val changed = True elif ev_type == EV_ABS and ev_code == ABS_PRESSURE: touch_pressure = normalize(ev_value, range_min_pressure, range_max_pressure) changed = True elif ev_type == EV_ABS and ev_code == ABS_MISC: if ev_value == 0: reset_touch = True def update(self, dispatch_fn): # dispatch all event from threads try: while True: event_type, touch = self.queue.popleft() dispatch_fn(event_type, touch) except: pass MotionEventFactory.register('linuxwacom', LinuxWacomMotionEventProvider)
if not done: return windll.user32.CallWindowProcW(self.old_windProc, hwnd, msg, wParam, lParam) return 1 # this on pushes WM_TOUCH messages onto our event stack def _touch_handler(self, msg, wParam, lParam): touches = (TOUCHINPUT * wParam)() windll.user32.GetTouchInputInfo(HANDLE(lParam), wParam, pointer(touches), sizeof(TOUCHINPUT)) for i in xrange(wParam): self.touch_events.appendleft(touches[i]) return True # filter fake mouse events, because touch and stylus # also make mouse events def _mouse_handler(self, msg, wparam, lParam): info = windll.user32.GetMessageExtraInfo() # its a touch or a pen if (info & PEN_OR_TOUCH_MASK) == PEN_OR_TOUCH_SIGNATURE: if info & PEN_EVENT_TOUCH_MASK: return True MotionEventFactory.register('wm_touch', WM_MotionEventProvider)
report_dict["Libraries"] = report report = [] title("Configuration") s = StringIO() from kivy.config import Config ConfigParser.write(Config, s) report.extend(s.getvalue().split("\n")) report_dict["Configuration"] = report report = [] title("Input availability") from kivy.input.factory import MotionEventFactory for x in MotionEventFactory.list(): report.append(x) report_dict["InputAvailablity"] = report report = [] """ title('Log') for x in pymt_logger_history.history: report.append(x.message) """ title("Environ") for k, v in os.environ.items(): report.append("%s = %s" % (k, v)) report_dict["Environ"] = report report = []
if not match(self.match, device.name, IGNORECASE): Logger.debug('ProbeSysfs: device not match the' ' rule in config, ignoring.') continue else: if self.match not in device.name: continue Logger.info('ProbeSysfs: device match: %s' % device.device) d = device.device devicename = self.device % dict(name=d.split(sep)[-1]) provider = MotionEventFactory.get(self.provider) if provider is None: Logger.info('ProbeSysfs: unable to found provider %s' % self.provider) Logger.info('ProbeSysfs: fallback on hidinput') provider = MotionEventFactory.get('hidinput') if provider is None: Logger.critical('ProbeSysfs: no input provider found' ' to handle this device !') continue instance = provider(devicename, '%s,%s' % ( device.device, ','.join(self.args))) if instance: EventLoop.add_input_provider(instance) MotionEventFactory.register('probesysfs', ProbeSysfsHardwareProbe)
self.hwnd = windll.user32.GetActiveWindow() # inject our own wndProc to handle messages # before window manager does self.new_windProc = WNDPROC(self._pen_wndProc) self.old_windProc = SetWindowLong_wrapper(self.hwnd, GWL_WNDPROC, self.new_windProc) def update(self, dispatch_fn): while True: try: etype, x, y = self.pen_events.pop() except: break if etype == "begin": self.uid += 1 self.pen = WM_Pen(self.device, self.uid, [x, y]) elif etype == "update": self.pen.move([x, y]) elif etype == "end": self.pen.update_time_end() dispatch_fn(etype, self.pen) def stop(self): self.pen = None SetWindowLong_wrapper(self.hwnd, GWL_WNDPROC, self.old_windProc) MotionEventFactory.register("wm_pen", WM_PenProvider)
def __init__(self, device, id, args): super(Tuio2dObjMotionEvent, self).__init__(device, id, args) def depack(self, args): self.is_touch = True if len(args) < 5: self.sx, self.sy = args[0:2] self.profile = ("pos",) elif len(args) == 9: self.fid, self.sx, self.sy, self.a, self.X, self.Y = args[:6] self.A, self.m, self.r = args[6:9] self.Y = -self.Y self.profile = ("markerid", "pos", "angle", "mov", "rot", "motacc", "rotacc") else: self.fid, self.sx, self.sy, self.a, self.X, self.Y = args[:6] self.A, self.m, self.r, width, height = args[6:11] self.Y = -self.Y self.profile = ("markerid", "pos", "angle", "mov", "rot", "rotacc", "acc", "shape") if self.shape is None: self.shape = ShapeRect() self.shape.width = width self.shape.height = height self.sy = 1 - self.sy super(Tuio2dObjMotionEvent, self).depack(args) # registers TuioMotionEventProvider.register("/tuio/2Dcur", Tuio2dCurMotionEvent) TuioMotionEventProvider.register("/tuio/2Dobj", Tuio2dObjMotionEvent) MotionEventFactory.register("tuio", TuioMotionEventProvider)
# python for android do * 1000. pressure = joy.get_axis(2) / 1000. radius = joy.get_axis(3) / 1000. # new touche ? if pressed and jid not in touches: self.uid += 1 touch = AndroidMotionEvent(self.device, self.uid, [x, y, pressure, radius]) touches[jid] = touch dispatch_fn('begin', touch) # update touch elif pressed: touch = touches[jid] # avoid same touch position if (touch.sx == x and touch.sy == y and touch.pressure == pressure): continue touch.move([x, y, pressure, radius]) dispatch_fn('update', touch) # disapear elif not pressed and jid in touches: touch = touches[jid] touch.move([x, y, pressure, radius]) touch.update_time_end() dispatch_fn('end', touch) touches.pop(jid) MotionEventFactory.register('android', AndroidMotionEventProvider)
def depack(self, args): self.is_touch = True if len(args) < 5: self.sx, self.sy = args[0:2] self.profile = ('pos', ) elif len(args) == 9: self.fid, self.sx, self.sy, self.a, self.X, self.Y = args[:6] self.A, self.m, self.r = args[6:9] self.Y = -self.Y self.profile = ('markerid', 'pos', 'angle', 'mov', 'rot', 'motacc', 'rotacc') else: self.fid, self.sx, self.sy, self.a, self.X, self.Y = args[:6] self.A, self.m, self.r, width, height = args[6:11] self.Y = -self.Y self.profile = ('markerid', 'pos', 'angle', 'mov', 'rot', 'rotacc', 'acc', 'shape') if self.shape is None: self.shape = ShapeRect() self.shape.width = width self.shape.height = height self.sy = 1 - self.sy super(Tuio2dObjMotionEvent, self).depack(args) # registers TuioMotionEventProvider.register('/tuio/2Dcur', Tuio2dCurMotionEvent) TuioMotionEventProvider.register('/tuio/2Dobj', Tuio2dObjMotionEvent) MotionEventFactory.register('tuio', TuioMotionEventProvider)
_instance.lock.acquire() _instance.uid += 1 # create a touch touch = MacMotionEvent(_instance.device, _instance.uid, args) _instance.lock.release() # create event _instance.queue.append(('begin', touch)) # store touch touches[data_id] = touch else: touch = touches[data_id] # check if he really moved if data.normalized.position.x == touch.sx and \ data.normalized.position.y == touch.sy: continue touch.move(args) _instance.queue.append(('update', touch)) # delete old touchs for tid in list(touches.keys())[:]: if tid not in actives: touch = touches[tid] touch.update_time_end() _instance.queue.append(('end', touch)) del touches[tid] return 0 MotionEventFactory.register('mactouch', MacMotionEventProvider)
if invert_x: val = 1. - val touch_x = val changed = True elif ev_type == EV_ABS and ev_code == ABS_Y: val = 1. - normalize(ev_value, range_min_position_y, range_max_position_y) if invert_y: val = 1. - val touch_y = val changed = True elif ev_type == EV_ABS and ev_code == ABS_PRESSURE: touch_pressure = normalize(ev_value, range_min_pressure, range_max_pressure) changed = True elif ev_type == EV_ABS and ev_code == ABS_MISC: if ev_value == 0: reset_touch = True def update(self, dispatch_fn): # dispatch all event from threads try: while True: event_type, touch = self.queue.popleft() dispatch_fn(event_type, touch) except: pass MotionEventFactory.register('linuxwacom', LinuxWacomMotionEventProvider)
if ev_value == -1: point['delete'] = True # force process of changes here, as the slot can be # reused. _changes.add(_slot) process([l_points[x] for x in _changes]) _changes.clear() continue else: point['id'] = ev_value else: # unrecognized command, ignore. continue _changes.add(_slot) # push all changes if _changes: process([l_points[x] for x in _changes]) _changes.clear() def update(self, dispatch_fn): # dispatch all event from threads try: while True: event_type, touch = self.queue.popleft() dispatch_fn(event_type, touch) except: pass MotionEventFactory.register('mtdev', MTDMotionEventProvider)
elif len(args) == 9: self.fid, self.sx, self.sy, self.a, self.X, self.Y = args[:6] self.A, self.m, self.r = args[6:9] self.Y = -self.Y self.profile = ('markerid', 'pos', 'angle', 'mov', 'rot', 'motacc', 'rotacc') else: self.fid, self.sx, self.sy, self.a, self.X, self.Y = args[:6] self.A, self.m, self.r, width, height = args[6:11] self.Y = -self.Y self.profile = ('markerid', 'pos', 'angle', 'mov', 'rot', 'rotacc', 'acc', 'shape') if self.shape is None: self.shape = ShapeRect() self.shape.width = width self.shape.height = height self.sy = 1 - self.sy super(Tuio2dObjMotionEvent, self).depack(args) # registers TuioListener.register('/tuio/2Dcur', Tuio2dCurMotionEvent) TuioListener.register('/tuio/2Dobj', Tuio2dObjMotionEvent) MotionEventFactory.register('tuio', TuioListener) #tu = TuioListener(None, '192.168.1.100:3333') #tu.start() #while 1 == 1: # tu.update() # time.sleep(.2)
if ev_value == -1: point["delete"] = True # force process of changes here, as the slot can be # reused. _changes.add(_slot) process([l_points[x] for x in _changes]) _changes.clear() continue else: point["id"] = ev_value else: # unrecognized command, ignore. continue _changes.add(_slot) # push all changes if _changes: process([l_points[x] for x in _changes]) _changes.clear() def update(self, dispatch_fn): # dispatch all event from threads try: while True: event_type, touch = self.queue.popleft() dispatch_fn(event_type, touch) except: pass MotionEventFactory.register("mtdev", MTDMotionEventProvider)
# inject our own wndProc to handle messages # before window manager does self.new_windProc = WNDPROC(self._pen_wndProc) self.old_windProc = SetWindowLong_wrapper( self.hwnd, GWL_WNDPROC, self.new_windProc) def update(self, dispatch_fn): while True: try: etype, x, y = self.pen_events.pop() except: break if etype == 'begin': self.uid += 1 self.pen = WM_Pen(self.device, self.uid, [x, y]) elif etype == 'update': self.pen.move([x, y]) elif etype == 'end': self.pen.update_time_end() dispatch_fn(etype, self.pen) def stop(self): self.pen = None SetWindowLong_wrapper(self.hwnd, GWL_WNDPROC, self.old_windProc) MotionEventFactory.register('wm_pen', WM_PenProvider)
pass def process_frame(self, frame): events = [] touches = self.touches available_uid = [] for hand in frame.hands: for finger in hand.fingers: #print hand.id(), finger.id(), finger.tip() uid = '{0}:{1}'.format(hand.id, finger.id) available_uid.append(uid) position = finger.tip_position args = (position.x, position.y, position.z) if uid not in touches: touch = LeapFingerEvent(self.device, uid, args) events.append(('begin', touch)) touches[uid] = touch else: touch = touches[uid] touch.move(args) events.append(('update', touch)) for key in touches.keys()[:]: if key not in available_uid: events.append(('end', touches[key])) del touches[key] return events # registers MotionEventFactory.register('leapfinger', LeapFingerEventProvider)
# inject our own wndProc to handle messages # before window manager does self.new_windProc = WNDPROC(self._pen_wndProc) self.old_windProc = SetWindowLong_wrapper(self.hwnd, GWL_WNDPROC, self.new_windProc) def update(self, dispatch_fn): while True: try: etype, x, y = self.pen_events.pop() except: break if etype == 'begin': self.uid += 1 self.pen = WM_Pen(self.device, self.uid, [x, y]) elif etype == 'update': self.pen.move([x, y]) elif etype == 'end': self.pen.update_time_end() dispatch_fn(etype, self.pen) def stop(self): self.pen = None SetWindowLong_wrapper(self.hwnd, GWL_WNDPROC, self.old_windProc) MotionEventFactory.register('wm_pen', WM_PenProvider)
cur = self.current_drag if cur: if (button in ( 'left', 'scrollup', 'scrolldown', 'scrollleft', 'scrollright') and not ('ctrl' in modifiers) or (self.disable_multitouch or 'multitouch_sim' not in cur.profile or not cur.multitouch_sim)): self.remove_touch(cur) self.current_drag = None else: cur.update_graphics(EventLoop.window, True) if self.alt_touch: self.remove_touch(self.alt_touch) self.alt_touch = None return True def update(self, dispatch_fn): '''Update the mouse provider (pop event from the queue)''' try: while True: event = self.waiting_event.popleft() dispatch_fn(*event) except IndexError: pass # registers MotionEventFactory.register('mouse', MouseMotionEventProvider)
y = 1. - (joy.get_axis(1) * 32768. / h) pressure = joy.get_axis(2) radius = joy.get_axis(3) # new touche ? if pressed and jid not in touches: self.uid += 1 touch = AndroidMotionEvent(self.device, self.uid, [x, y, pressure, radius]) touches[jid] = touch dispatch_fn('begin', touch) # update touch elif pressed: touch = touches[jid] # avoid same touch position if touch.sx == x and touch.sy == y \ and touch.pressure == pressure: #print 'avoid moving.', touch.uid, x, y, pressure, radius continue touch.move([x, y, pressure, radius]) dispatch_fn('update', touch) # disapear elif not pressed and jid in touches: touch = touches[jid] touch.move([x, y, pressure, radius]) touch.update_time_end() dispatch_fn('end', touch) touches.pop(jid) MotionEventFactory.register('android', AndroidMotionEventProvider)
# extract timeval + event infos infos = struct.unpack('LLHHi', ev[:struct_input_event_sz]) if is_multitouch: process_as_multitouch(*infos) else: process_as_mouse_or_keyboard(*infos) def update(self, dispatch_fn): # dispatch all events from threads dispatch_queue = self.dispatch_queue n = len(dispatch_queue) for name, args in dispatch_queue[:n]: if name == 'mouse_pos': Window.mouse_pos = args elif name == 'key_down': if not Window.dispatch('on_key_down', *args): Window.dispatch('on_keyboard', *args) elif name == 'key_up': Window.dispatch('on_key_up', *args) del dispatch_queue[:n] try: while True: event_type, touch = self.queue.popleft() dispatch_fn(event_type, touch) except: pass MotionEventFactory.register('hidinput', HIDInputMotionEventProvider)
class Tuio2dBlbMotionEvent(TuioMotionEvent): '''A 2dBlb TUIO object. # FIXME 3d shape are not supported /tuio/2Dobj set s i x y a X Y A m r /tuio/2Dblb set s x y a w h f X Y A m r ''' def __init__(self, device, id, args): super(Tuio2dBlbMotionEvent, self).__init__(device, id, args) def depack(self, args): self.is_touch = True self.sx, self.sy, self.a, self.X, self.Y, sw, sh, sd, \ self.A, self.m, self.r = args self.Y = -self.Y self.profile = ('pos', 'angle', 'mov', 'rot', 'rotacc', 'acc', 'shape') if self.shape is None: self.shape = ShapeRect() self.shape.width = sw self.shape.height = sh self.sy = 1 - self.sy super(Tuio2dBlbMotionEvent, self).depack(args) # registers TuioMotionEventProvider.register('/tuio/2Dcur', Tuio2dCurMotionEvent) TuioMotionEventProvider.register('/tuio/2Dobj', Tuio2dObjMotionEvent) TuioMotionEventProvider.register('/tuio/2Dblb', Tuio2dBlbMotionEvent) MotionEventFactory.register('tuio', TuioMotionEventProvider)
'opencv', 'opencv.cv', 'opencv.highgui', 'cython', ): testimport(x) title('Configuration') s = StringIO() from kivy.config import Config ConfigParser.write(Config, s) report.extend(s.getvalue().split('\n')) title('Input availability') from kivy.input.factory import MotionEventFactory for x in MotionEventFactory.list(): report.append(x) ''' title('Log') for x in pymt_logger_history.history: report.append(x.message) ''' title('Environ') for k, v in os.environ.iteritems(): report.append('%s = %s' % (k, v)) title('Options') for k, v in kivy.kivy_options.iteritems(): report.append('%s = %s' % (k, v))
x = joy.get_axis(0) * 32768.0 / w y = 1.0 - (joy.get_axis(1) * 32768.0 / h) pressure = joy.get_axis(2) radius = joy.get_axis(3) # new touche ? if pressed and jid not in touches: self.uid += 1 touch = AndroidMotionEvent(self.device, self.uid, [x, y, pressure, radius]) touches[jid] = touch dispatch_fn("begin", touch) # update touch elif pressed: touch = touches[jid] # avoid same touch position if touch.sx == x and touch.sy == y and touch.pressure == pressure: # print 'avoid moving.', touch.uid, x, y, pressure, radius continue touch.move([x, y, pressure, radius]) dispatch_fn("update", touch) # disapear elif not pressed and jid in touches: touch = touches[jid] touch.move([x, y, pressure, radius]) touch.update_time_end() dispatch_fn("end", touch) touches.pop(jid) MotionEventFactory.register("android", AndroidMotionEventProvider)
# special case, if button is all, then remove all the current mouses. if button == 'all': for cur in self.touches.values()[:]: self.remove_touch(cur) self.current_drag = None width, height = EventLoop.window.system_size rx = x / float(width) ry = 1. - y / float(height) cur = self.find_touch(rx, ry) if (button in ('left', 'scrollup', 'scrolldown') or self.disable_multitouch) and cur and not ('ctrl' in modifiers): self.remove_touch(cur) self.current_drag = None if self.alt_touch: self.remove_touch(self.alt_touch) self.alt_touch = None return True def update(self, dispatch_fn): '''Update the mouse provider (pop event from the queue)''' try: while True: event = self.waiting_event.popleft() dispatch_fn(*event) except IndexError: pass # registers MotionEventFactory.register('mouse', MouseMotionEventProvider)
y = 1.0 - (joy.get_axis(1) * 32768.0 / h) # python for android do * 1000. pressure = joy.get_axis(2) / 1000.0 radius = joy.get_axis(3) / 1000.0 # new touche ? if pressed and jid not in touches: self.uid += 1 touch = WintabMotionEvent(self.device, self.uid, [x, y, pressure, radius]) touches[jid] = touch dispatch_fn("begin", touch) # update touch elif pressed: touch = touches[jid] # avoid same touch position if touch.sx == x and touch.sy == y and touch.pressure == pressure: continue touch.move([x, y, pressure, radius]) dispatch_fn("update", touch) # disapear elif not pressed and jid in touches: touch = touches[jid] touch.move([x, y, pressure, radius]) touch.update_time_end() dispatch_fn("end", touch) touches.pop(jid) MotionEventFactory.register("Wintab", WintabMotionEventProvider)