Exemplo n.º 1
0
def stopTouchApp():
    '''Stop the current application by leaving the main loop'''
    if pymt_evloop is None:
        return
    if pymt_evloop.status != 'started':
        return
    pymt_logger.info('Base: Leaving application in progress...')
    pymt_evloop.close()
Exemplo n.º 2
0
def stopTouchApp():
    '''Stop the current application by leaving the main loop'''
    if pymt_evloop is None:
        return
    if pymt_evloop.status != 'started':
        return
    pymt_logger.info('Base: Leaving application in progress...')
    pymt_evloop.close()
Exemplo n.º 3
0
    def init_gl(self):
        version = glGetString(GL_VERSION)
        pymt_logger.info('Window: OpenGL version <%s>' % str(version))

        line_smooth = pymt.pymt_config.getint('graphics', 'line_smooth')
        if line_smooth:
            if line_smooth == 1:
                hint = GL_FASTEST
            else:
                hint = GL_NICEST
            glHint(GL_LINE_SMOOTH_HINT, hint)
            glEnable(GL_LINE_SMOOTH)
Exemplo n.º 4
0
    def init_gl(self):
        version = glGetString(GL_VERSION)
        pymt_logger.info("Window: OpenGL version <%s>" % str(version))

        line_smooth = pymt.pymt_config.getint("graphics", "line_smooth")
        if line_smooth:
            if line_smooth == 1:
                hint = GL_FASTEST
            else:
                hint = GL_NICEST
            glHint(GL_LINE_SMOOTH_HINT, hint)
            glEnable(GL_LINE_SMOOTH)
Exemplo n.º 5
0
def css_reload():
    pymt_logger.debug('CSS: Reloading CSS in progress')
    pymt_sheet.reset()
    for callback, args in _css_sources[:]:
        callback(*args, _reload=True)
    Cache.remove('pymt.css')
    for r in _css_widgets.copy():
        o = r()
        if o is None:
            _css_widgets.remove(r)
            continue
        o.reload_css()
    pymt_logger.info('CSS: CSS Reloaded')
Exemplo n.º 6
0
        def __init__(self, device, args):
            super(HIDInputTouchProvider, self).__init__(device, args)
            self.input_fn = None
            self.default_ranges = dict()

            # split arguments
            args = args.split(',')
            if not args:
                pymt_logger.error(
                    'HIDInput: No filename pass to HIDInput configuration')
                pymt_logger.error(
                    'HIDInput: Use /dev/input/event0 for example')
                return None

            # read filename
            self.input_fn = args[0]
            pymt_logger.info('HIDInput: Read event from <%s>' % self.input_fn)

            # read parameters
            for arg in args[1:]:
                if arg == '':
                    continue
                arg = arg.split('=')

                # ensure it's a key = value
                if len(arg) != 2:
                    pymt_logger.error(
                        'HIDInput: invalid parameter %s, not in key=value format.'
                        % arg)
                    continue

                # ensure the key exist
                key, value = arg
                if key not in HIDInputTouchProvider.options:
                    pymt_logger.error('HIDInput: unknown %s option' % key)
                    continue

                # ensure the value
                try:
                    self.default_ranges[key] = int(value)
                except ValueError:
                    pymt_logger.error(
                        'HIDInput: invalid value %s for option %s' %
                        (key, value))
                    continue

                # all good!
                pymt_logger.info('HIDInput: Set custom %s to %d' %
                                 (key, int(value)))
Exemplo n.º 7
0
 def do_check(self, *largs, **kwargs):
     timer = time() - self.timer_no_activity
     step = -1
     for x in self.ramp:
         if timer >= x:
             step += 1
     if self.step != step:
         if step == -1:
             pymt_logger.info('Sleep: activity detected, wake up.')
         else:
             pymt_logger.info('Sleep: %ds inactivity detected. Reduce FPS to '
                              '%.4f' % (self.ramp[step], 1. / float(self.sleep[step])))
         self.step = step
     if step >= 0:
         sleep(self.sleep[step])
Exemplo n.º 8
0
 def do_check(self, *largs, **kwargs):
     timer = time() - self.timer_no_activity
     step = -1
     for x in self.ramp:
         if timer >= x:
             step += 1
     if self.step != step:
         if step == -1:
             pymt_logger.info('Sleep: activity detected, wake up.')
         else:
             pymt_logger.info(
                 'Sleep: %ds inactivity detected. Reduce FPS to '
                 '%.4f' % (self.ramp[step], 1. / float(self.sleep[step])))
         self.step = step
     if step >= 0:
         sleep(self.sleep[step])
Exemplo n.º 9
0
        def __init__(self, device, args):
            super(MTDTouchProvider, self).__init__(device, args)
            self._device = None
            self.input_fn = None
            self.default_ranges = dict()

            # split arguments
            args = args.split(',')
            if not args:
                pymt_logger.error('MTD: No filename pass to MTD configuration')
                pymt_logger.error('MTD: Use /dev/input/event0 for example')
                return None

            # read filename
            self.input_fn = args[0]
            pymt_logger.info('MTD: Read event from <%s>' % self.input_fn)

            # read parameters
            for arg in args[1:]:
                if arg == '':
                    continue
                arg = arg.split('=')

                # ensure it's a key = value
                if len(arg) != 2:
                    pymt_logger.error('MTD: invalid parameter %s, not in key=value format.' % arg)
                    continue

                # ensure the key exist
                key, value = arg
                if key not in MTDTouchProvider.options:
                    pymt_logger.error('MTD: unknown %s option' % key)
                    continue

                # ensure the value
                try:
                    self.default_ranges[key] = int(value)
                except ValueError:
                    pymt_logger.error('MTD: invalid value %s for option %s' % (key, value))
                    continue

                # all good!
                pymt_logger.info('MTD: Set custom %s to %d' % (key, int(value)))
Exemplo n.º 10
0
class OSCServer(_OSCServer):
    def __init__(self, **kwargs):
        kwargs.setdefault('ipAddr', '127.0.0.1')
        kwargs.setdefault('port', 9001)
        super(OSCServer, self).__init__()
        self.ipAddr = kwargs.get('ipAddr')
        self.port = kwargs.get('port')

    def run(self):
        self.haveSocket = False
        # create socket
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

        # fix trouble if python leave without cleaning well the socket
        # not needed under windows, he can reuse addr even if the socket
        # are in fin2 or wait state.
        if os.name in ['posix', 'mac'] and hasattr(socket, 'SO_REUSEADDR'):
            self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

        # try to bind the socket, retry if necessary
        while not self.haveSocket and self.isRunning:
            try:
                self.socket.bind((self.ipAddr, self.port))
                self.socket.settimeout(0.5)
                self.haveSocket = True

            except socket.error, e:
                error, message = e.args

                # special handle for EADDRINUSE
                if error == errno.EADDRINUSE:
                    pymt_logger.error(
                        'OSC: Address %s:%i already in use, retry in 2 second'
                        % (self.ipAddr, self.port))
                else:
                    pymt_logger.exception(e)
                self.haveSocket = False

                # sleep 2 second before retry
                time.sleep(2)

        pymt_logger.info('OSC: listening for Tuio on %s:%i' %
                         (self.ipAddr, self.port))

        while self.isRunning:
            try:
                message = self.socket.recv(65535)
                self._queue_message(message)
            except Exception, e:
                if type(e) == socket.timeout:
                    continue
                pymt_logger.error('OSC: Error in Tuio recv()')
                pymt_logger.exception(e)
                return 'no data arrived'
Exemplo n.º 11
0
        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:
                pymt_logger.info('ProbeSysfs: found device: %s at %s' % (
                                 device.name, device.device))

                # must ignore ?
                if self.match:
                    if not re.match(self.match, device.name, re.IGNORECASE):
                        pymt_logger.warning('ProbeSysfs: device not match the'
                                            ' rule in config, ignoring.')
                        continue

                devicename = self.device % dict(name=device.device.split(os.path.sep)[-1])

                provider = TouchFactory.get(self.provider)
                if provider is None:
                    pymt_logger.info('ProbeSysfs: unable to found provider %s' %
                                     self.provider)
                    pymt_logger.info('ProbeSysfs: fallback on hidinput')
                    provider = TouchFactory.get('hidinput')
                if provider is None:
                    pymt_logger.critical('ProbeSysfs: no input provider found'
                                         ' to handle this device !')
                    continue

                instance = provider(devicename, '%s,%s' % (device.device,
                                                           ','.join(self.args)))
                if instance:
                    pymt.pymt_providers.append(instance)
Exemplo n.º 12
0
def _screenshot():
    import os
    import pygame
    from OpenGL.GL import glReadBuffer, glReadPixels, GL_RGB, GL_UNSIGNED_BYTE, GL_FRONT
    win = getWindow()
    glReadBuffer(GL_FRONT)
    data = glReadPixels(0, 0, win.width, win.height, GL_RGB, GL_UNSIGNED_BYTE)
    surface = pygame.image.fromstring(str(buffer(data)), win.size, 'RGB', True)
    filename = None
    for i in xrange(9999):
        path = os.path.join(os.getcwd(), 'screenshot%04d.jpg' % i)
        if not os.path.exists(path):
            filename = path
            break
    if filename:
        try:
            pygame.image.save(surface, filename)
            pymt_logger.info('KeyBinding: Screenshot saved at %s' % filename)
        except:
            pymt_logger.exception('KeyBinding: Unable to take a screenshot')
    else:
        pymt_logger.warning('KeyBinding: Unable to take screenshot, no more slot available')
Exemplo n.º 13
0
def _screenshot():
    import os
    import pygame
    from OpenGL.GL import glReadBuffer, glReadPixels, GL_RGB, GL_UNSIGNED_BYTE, GL_FRONT
    win = getWindow()
    glReadBuffer(GL_FRONT)
    data = glReadPixels(0, 0, win.width, win.height, GL_RGB, GL_UNSIGNED_BYTE)
    surface = pygame.image.fromstring(str(buffer(data)), win.size, 'RGB', True)
    filename = None
    for i in xrange(9999):
        path = os.path.join(os.getcwd(), 'screenshot%04d.jpg' % i)
        if not os.path.exists(path):
            filename = path
            break
    if filename:
        try:
            pygame.image.save(surface, filename)
            pymt_logger.info('KeyBinding: Screenshot saved at %s' % filename)
        except:
            pymt_logger.exception('KeyBinding: Unable to take a screenshot')
    else:
        pymt_logger.warning(
            'KeyBinding: Unable to take screenshot, no more slot available')
Exemplo n.º 14
0
def LetThemKnowTheTruth(x):
    pymt_logger.critical("You have MP3 Files!  Those suck!  Convert them to ogg and delete them!")
    pymt_logger.info("btw, if you want to implement an mp3 handler, xelapond would be very appreciative:)")
    print x
    del x #Kill the mp3 file
Exemplo n.º 15
0
        def _thread_run(self, **kwargs):
            input_fn = kwargs.get('input_fn')
            queue = kwargs.get('queue')
            device = kwargs.get('device')
            drs = kwargs.get('default_ranges').get
            touches = {}
            touches_sent = []
            point = {}
            l_points = {}

            # prepare some vars to get limit of some component
            range_min_position_x = 0
            range_max_position_x = 2048
            range_min_position_y = 0
            range_max_position_y = 2048
            range_min_pressure = 0
            range_max_pressure = 255
            invert_x = int(bool(drs('invert_x', 0)))
            invert_y = int(bool(drs('invert_y', 0)))
            reset_touch = False

            def process(points):
                actives = points.keys()
                for args in points.itervalues():
                    tid = args['id']
                    try:
                        touch = touches[tid]
                    except KeyError:
                        touch = LinuxWacomTouch(device, tid, args)
                        touches[touch.id] = touch
                    if touch.sx == args['x'] and touch.sy == args[
                            'y'] and tid in touches_sent:
                        continue
                    touch.move(args)
                    if tid not in touches_sent:
                        queue.append(('down', touch))
                        touches_sent.append(tid)
                    queue.append(('move', touch))

                for tid in touches.keys()[:]:
                    if tid not in actives:
                        touch = touches[tid]
                        if tid in touches_sent:
                            queue.append(('up', touch))
                            touches_sent.remove(tid)
                        del touches[tid]

            def normalize(value, vmin, vmax):
                return (value - vmin) / float(vmax - vmin)

            # open the input
            fd = open(input_fn, 'rb')

            # get the controler name (EVIOCGNAME)
            device_name = fcntl.ioctl(fd, EVIOCGNAME + (256 << 16),
                                      " " * 256).split('\x00')[0]
            pymt_logger.info('LinuxWacomTouch: using <%s>' % device_name)

            # get abs infos
            bit = fcntl.ioctl(fd, EVIOCGBIT + (EV_MAX << 16), ' ' * sz_l)
            bit, = struct.unpack('Q', bit)
            for x in xrange(EV_MAX):
                # preserve this, we may want other things than EV_ABS
                if x != EV_ABS:
                    continue
                # EV_ABS available for this device ?
                if (bit & (1 << x)) == 0:
                    continue
                # ask abs info keys to the devices
                sbit = fcntl.ioctl(fd, EVIOCGBIT + x + (KEY_MAX << 16),
                                   ' ' * sz_l)
                sbit, = struct.unpack('Q', sbit)
                for y in xrange(KEY_MAX):
                    if (sbit & (1 << y)) == 0:
                        continue
                    absinfo = fcntl.ioctl(
                        fd, EVIOCGABS + y + (struct_input_absinfo_sz << 16),
                        ' ' * struct_input_absinfo_sz)
                    abs_value, abs_min, abs_max, abs_fuzz, \
                        abs_flat, abs_res = struct.unpack('iiiiii', absinfo)
                    if y == ABS_X:
                        range_min_position_x = drs('min_position_x', abs_min)
                        range_max_position_x = drs('max_position_x', abs_max)
                        pymt_logger.info('LinuxWacomTouch: ' +
                                         '<%s> range position X is %d - %d' %
                                         (device_name, abs_min, abs_max))
                    elif y == ABS_Y:
                        range_min_position_y = drs('min_position_y', abs_min)
                        range_max_position_y = drs('max_position_y', abs_max)
                        pymt_logger.info('LinuxWacomTouch: ' +
                                         '<%s> range position Y is %d - %d' %
                                         (device_name, abs_min, abs_max))
                    elif y == ABS_PRESSURE:
                        range_min_pressure = drs('min_pressure', abs_min)
                        range_max_pressure = drs('max_pressure', abs_max)
                        pymt_logger.info('LinuxWacomTouch: ' +
                                         '<%s> range pressure is %d - %d' %
                                         (device_name, abs_min, abs_max))

            # read until the end
            point = {}
            changed = False
            touch_id = 0
            touch_x = 0
            touch_y = 0
            touch_pressure = 0
            while fd:

                data = fd.read(struct_input_event_sz)
                if len(data) < struct_input_event_sz:
                    break

                # extract each event
                for i in xrange(len(data) / struct_input_event_sz):
                    ev = data[i * struct_input_event_sz:]

                    # extract timeval + event infos
                    tv_sec, tv_usec, ev_type, ev_code, ev_value = \
                            struct.unpack('LLHHi', ev[:struct_input_event_sz])

                    if ev_type == EV_SYN and ev_code == SYN_REPORT:
                        if touch_id in l_points:
                            p = l_points[touch_id]
                        else:
                            p = dict()
                            l_points[touch_id] = p
                        p['id'] = touch_id
                        if reset_touch is False:
                            p['x'] = touch_x
                            p['y'] = touch_y
                            p['pressure'] = touch_pressure
                        if self.mode == 'pen' and touch_pressure == 0 and not reset_touch:
                            del l_points[touch_id]
                        if changed:
                            if not 'x' in p:
                                reset_touch = False
                                continue
                            process(l_points)
                            changed = False
                        if reset_touch:
                            l_points.clear()
                            reset_touch = False
                            process(l_points)
                        point = {}
                    elif ev_type == EV_MSC and ev_code == MSC_SERIAL:
                        touch_id = ev_value
                    elif ev_type == EV_ABS and ev_code == ABS_X:
                        val = normalize(ev_value, range_min_position_x,
                                        range_max_position_x)
                        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
Exemplo n.º 16
0
def runTouchApp(widget=None, slave=False):
    '''Static main function that starts the application loop.
    You got some magic things, if you are using argument like this :

    :Parameters:
        `<empty>`
            To make dispatching work, you need at least one
            input listener. If not, application will leave.
            (MTWindow act as an input listener)

        `widget`
            If you pass only a widget, a MTWindow will be created,
            and your widget will be added on the window as the root
            widget.

        `slave`
            No event dispatching are done. This will be your job.

        `widget + slave`
            No event dispatching are done. This will be your job, but
            we are trying to get the window (must be created by you before),
            and add the widget on it. Very usefull for embedding PyMT
            in another toolkit. (like Qt, check pymt-designed)

    '''

    global pymt_evloop

    # Ok, we got one widget, and we are not in slave mode
    # so, user don't create the window, let's create it for him !
    ### Not needed, since we always create window ?!
    #if not slave and widget:
    #    global pymt_window
    #    from ui.window import MTWindow
    #    pymt_window = MTWindow()

    # Instance all configured input
    for key, value in pymt.pymt_config.items('input'):
        pymt_logger.debug('Base: Create provider from %s' % (str(value)))

        # split value
        args = str(value).split(',', 1)
        if len(args) == 1:
            args.append('')
        provider_id, args = args
        provider = TouchFactory.get(provider_id)
        if provider is None:
            pymt_logger.warning('Base: Unknown <%s> provider' % \
                                str(provider_id))
            continue

        # create provider
        p = provider(key, args)
        if p:
            pymt_providers.append(p)

    pymt_evloop = TouchEventLoop()

    # add postproc modules
    for mod in pymt_postproc_modules.values():
        pymt_evloop.add_postproc_module(mod)

    # add main widget
    if widget and getWindow():
        getWindow().add_widget(widget)

    # start event loop
    pymt_logger.info('Base: Start application main loop')
    pymt_evloop.start()

    # we are in a slave mode, don't do dispatching.
    if slave:
        return

    # in non-slave mode, they are 2 issues
    #
    # 1. if user created a window, call the mainloop from window.
    #    This is due to glut, it need to be called with
    #    glutMainLoop(). Only FreeGLUT got a gluMainLoopEvent().
    #    So, we are executing the dispatching function inside
    #    a redisplay event.
    #
    # 2. if no window is created, we are dispatching event lopp
    #    ourself (previous behavior.)
    #
    try:
        if pymt_window is None:
            _run_mainloop()
        else:
            pymt_window.mainloop()
    finally:
        stopTouchApp()
Exemplo n.º 17
0
        def _thread_run(self, **kwargs):
            input_fn = kwargs.get('input_fn')
            queue = kwargs.get('queue')
            device = kwargs.get('device')
            drs = kwargs.get('default_ranges').get
            touches = {}
            touches_sent = []
            point = {}
            l_points = {}

            # prepare some vars to get limit of some component
            range_min_position_x    = 0
            range_max_position_x    = 2048
            range_min_position_y    = 0
            range_max_position_y    = 2048
            range_min_pressure      = 0
            range_max_pressure      = 255
            invert_x                = int(bool(drs('invert_x', 0)))
            invert_y                = int(bool(drs('invert_y', 0)))
            reset_touch             = False

            def process(points):
                actives = points.keys()
                for args in points.itervalues():
                    tid = args['id']
                    try:
                        touch = touches[tid]
                    except KeyError:
                        touch = LinuxWacomTouch(device, tid, args)
                        touches[touch.id] = touch
                    if touch.sx == args['x'] and touch.sy == args['y'] and tid in touches_sent:
                        continue
                    touch.move(args)
                    if tid not in touches_sent:
                        queue.append(('down', touch))
                        touches_sent.append(tid)
                    queue.append(('move', touch))

                for tid in touches.keys()[:]:
                    if tid not in actives:
                        touch = touches[tid]
                        if tid in touches_sent:
                            queue.append(('up', touch))
                            touches_sent.remove(tid)
                        del touches[tid]

            def normalize(value, vmin, vmax):
                return (value - vmin) / float(vmax - vmin)

            # open the input
            fd = open(input_fn, 'rb')

            # get the controler name (EVIOCGNAME)
            device_name = fcntl.ioctl(fd, EVIOCGNAME + (256 << 16), " " * 256).split('\x00')[0]
            pymt_logger.info('LinuxWacomTouch: using <%s>' % device_name)

            # get abs infos
            bit = fcntl.ioctl(fd, EVIOCGBIT + (EV_MAX << 16), ' ' * sz_l)
            bit, = struct.unpack('Q', bit)
            for x in xrange(EV_MAX):
                # preserve this, we may want other things than EV_ABS
                if x != EV_ABS:
                    continue
                # EV_ABS available for this device ?
                if (bit & (1 << x)) == 0:
                    continue
                # ask abs info keys to the devices
                sbit = fcntl.ioctl(fd, EVIOCGBIT + x + (KEY_MAX << 16), ' ' * sz_l)
                sbit, = struct.unpack('Q', sbit)
                for y in xrange(KEY_MAX):
                    if (sbit & (1 << y)) == 0:
                        continue
                    absinfo = fcntl.ioctl(fd, EVIOCGABS + y +
                                          (struct_input_absinfo_sz << 16),
                                          ' ' * struct_input_absinfo_sz)
                    abs_value, abs_min, abs_max, abs_fuzz, \
                        abs_flat, abs_res = struct.unpack('iiiiii', absinfo)
                    if y == ABS_X:
                        range_min_position_x = drs('min_position_x', abs_min)
                        range_max_position_x = drs('max_position_x', abs_max)
                        pymt_logger.info('LinuxWacomTouch: ' +
                            '<%s> range position X is %d - %d' % (
                            device_name, abs_min, abs_max))
                    elif y == ABS_Y:
                        range_min_position_y = drs('min_position_y', abs_min)
                        range_max_position_y = drs('max_position_y', abs_max)
                        pymt_logger.info('LinuxWacomTouch: ' +
                            '<%s> range position Y is %d - %d' % (
                            device_name, abs_min, abs_max))
                    elif y == ABS_PRESSURE:
                        range_min_pressure = drs('min_pressure', abs_min)
                        range_max_pressure = drs('max_pressure', abs_max)
                        pymt_logger.info('LinuxWacomTouch: ' +
                            '<%s> range pressure is %d - %d' % (
                            device_name, abs_min, abs_max))

            # read until the end
            point = {}
            changed = False
            touch_id = 0
            touch_x = 0
            touch_y = 0
            touch_pressure = 0
            while fd:

                data = fd.read(struct_input_event_sz)
                if len(data) < struct_input_event_sz:
                    break

                # extract each event
                for i in xrange(len(data) / struct_input_event_sz):
                    ev = data[i * struct_input_event_sz:]

                    # extract timeval + event infos
                    tv_sec, tv_usec, ev_type, ev_code, ev_value = \
                            struct.unpack('LLHHi', ev[:struct_input_event_sz])

                    if ev_type == EV_SYN and ev_code == SYN_REPORT:
                        if touch_id in l_points:
                            p = l_points[touch_id]
                        else:
                            p = dict()
                            l_points[touch_id] = p
                        p['id'] = touch_id
                        if reset_touch is False:
                            p['x'] = touch_x
                            p['y'] = touch_y
                            p['pressure'] = touch_pressure
                        if self.mode == 'pen' and touch_pressure == 0 and not reset_touch:
                            del l_points[touch_id]
                        if changed:
                            if not 'x' in p:
                                reset_touch = False
                                continue
                            process(l_points)
                            changed = False
                        if reset_touch:
                            l_points.clear()
                            reset_touch = False
                            process(l_points)
                        point = {}
                    elif ev_type == EV_MSC and ev_code == MSC_SERIAL:
                        touch_id = ev_value
                    elif ev_type == EV_ABS and ev_code == ABS_X:
                        val = normalize(ev_value,
                            range_min_position_x, range_max_position_x)
                        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
Exemplo n.º 18
0
        def _thread_run(self, **kwargs):
            input_fn = kwargs.get('input_fn')
            queue = kwargs.get('queue')
            device = kwargs.get('device')
            drs = kwargs.get('default_ranges').get
            touches = {}
            touches_sent = []
            point = {}
            l_points = {}

            def process(points):
                for args in points:
                    tid = args['id']
                    try:
                        touch = touches[tid]
                    except KeyError:
                        touch = MTDTouch(device, tid, args)
                        touches[touch.id] = touch
                    touch.move(args)
                    action = 'move'
                    if tid not in touches_sent:
                        action = 'down'
                        touches_sent.append(tid)
                    if 'delete' in args:
                        action = 'up'
                        del args['delete']
                        touches_sent.remove(tid)
                    queue.append((action, touch))

            def normalize(value, vmin, vmax):
                return (value - vmin) / float(vmax - vmin)

            # open mtdev device
            _fn = self.input_fn
            _slot = 0
            _device = Device(_fn)
            _changes = set()

            # prepare some vars to get limit of some component
            ab = _device.get_abs(MTDEV_ABS_POSITION_X)
            range_min_position_x    = drs('min_position_x', ab.minimum)
            range_max_position_x    = drs('max_position_x', ab.maximum)
            pymt_logger.info('MTD: <%s> range position X is %d - %d' %
                             (_fn, range_min_position_x, range_max_position_x))

            ab = _device.get_abs(MTDEV_ABS_POSITION_Y)
            range_min_position_y    = drs('min_position_y', ab.minimum)
            range_max_position_y    = drs('max_position_y', ab.maximum)
            pymt_logger.info('MTD: <%s> range position Y is %d - %d' %
                             (_fn, range_min_position_y, range_max_position_y))

            ab = _device.get_abs(MTDEV_ABS_TOUCH_MAJOR)
            range_min_major         = drs('min_touch_major', ab.minimum)
            range_max_major         = drs('max_touch_major', ab.maximum)
            pymt_logger.info('MTD: <%s> range touch major is %d - %d' %
                             (_fn, range_min_major, range_max_major))

            ab = _device.get_abs(MTDEV_ABS_TOUCH_MINOR)
            range_min_minor         = drs('min_touch_minor', ab.minimum)
            range_max_minor         = drs('max_touch_minor', ab.maximum)
            pymt_logger.info('MTD: <%s> range touch minor is %d - %d' %
                             (_fn, range_min_minor, range_max_minor))

            range_min_pressure      = drs('min_pressure', 0)
            range_max_pressure      = drs('max_pressure', 255)
            pymt_logger.info('MTD: <%s> range pressure is %d - %d' %
                             (_fn, range_min_pressure, range_max_pressure))

            while _device:
                # idle as much as we can.
                while _device.idle(1000):
                    continue

                # got data, read all without redoing idle
                while True:
                    data = _device.get()
                    if data is None:
                        break

                    # set the working slot
                    if data.type == MTDEV_TYPE_EV_ABS and \
                       data.code == MTDEV_CODE_SLOT:
                        _slot = data.value
                        continue

                    # fill the slot
                    if not _slot in l_points:
                        l_points[_slot] = dict()
                    point = l_points[_slot]
                    ev_value = data.value
                    ev_code = data.code
                    if ev_code == MTDEV_CODE_POSITION_X:
                        point['x'] = normalize(ev_value,
                            range_min_position_x, range_max_position_x)
                    elif ev_code == MTDEV_CODE_POSITION_Y:
                        point['y'] = 1. - normalize(ev_value,
                            range_min_position_y, range_max_position_y)
                    elif ev_code == MTDEV_CODE_PRESSURE:
                        point['pressure'] = normalize(ev_value,
                            range_min_pressure, range_max_pressure)
                    elif ev_code == MTDEV_CODE_TOUCH_MAJOR:
                        point['size_w'] = normalize(ev_value,
                            range_min_major, range_max_major)
                    elif ev_code == MTDEV_CODE_TOUCH_MINOR:
                        point['size_h'] = normalize(ev_value,
                            range_min_minor, range_max_minor)
                    elif ev_code == MTDEV_CODE_TRACKING_ID:
                        if ev_value == -1:
                            point['delete'] = True
                        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()
Exemplo n.º 19
0
        def _thread_run(self, **kwargs):
            input_fn = kwargs.get('input_fn')
            queue = kwargs.get('queue')
            device = kwargs.get('device')
            drs = kwargs.get('default_ranges').get
            touches = {}
            touches_sent = []
            point = {}
            l_points = []

            # prepare some vars to get limit of some component
            range_min_position_x    = 0
            range_max_position_x    = 2048
            range_min_position_y    = 0
            range_max_position_y    = 2048
            range_min_pressure      = 0
            range_max_pressure      = 255
            invert_x                = int(bool(drs('invert_x', 0)))
            invert_y                = int(bool(drs('invert_y', 0)))

            def process(points):
                actives = [args['id'] for args in points]
                for args in points:
                    tid = args['id']
                    try:
                        touch = touches[tid]
                        if touch.sx == args['x'] and touch.sy == args['y']:
                            continue
                        touch.move(args)
                        if tid not in touches_sent:
                            queue.append(('down', touch))
                            touches_sent.append(tid)
                        queue.append(('move', touch))
                    except KeyError:
                        touch = HIDTouch(device, tid, args)
                        touches[touch.id] = touch

                for tid in touches.keys()[:]:
                    if tid not in actives:
                        touch = touches[tid]
                        if tid in touches_sent:
                            queue.append(('up', touch))
                            touches_sent.remove(tid)
                        del touches[tid]

            def normalize(value, vmin, vmax):
                return (value - vmin) / float(vmax - vmin)

            # open the input
            fd = open(input_fn, 'rb')

            # get the controler name (EVIOCGNAME)
            device_name = fcntl.ioctl(fd, EVIOCGNAME + (256 << 16), " " * 256).split('\x00')[0]
            pymt_logger.info('HIDTouch: using <%s>' % device_name)

            # get abs infos
            bit = fcntl.ioctl(fd, EVIOCGBIT + (EV_MAX << 16), ' ' * sz_l)
            bit, = struct.unpack('Q', bit)
            for x in xrange(EV_MAX):
                # preserve this, we may want other things than EV_ABS
                if x != EV_ABS:
                    continue
                # EV_ABS available for this device ?
                if (bit & (1 << x)) == 0:
                    continue
                # ask abs info keys to the devices
                sbit = fcntl.ioctl(fd, EVIOCGBIT + x + (KEY_MAX << 16), ' ' * sz_l)
                sbit, = struct.unpack('Q', sbit)
                for y in xrange(KEY_MAX):
                    if (sbit & (1 << y)) == 0:
                        continue
                    absinfo = fcntl.ioctl(fd, EVIOCGABS + y +
                                          (struct_input_absinfo_sz << 16),
                                          ' ' * struct_input_absinfo_sz)
                    abs_value, abs_min, abs_max, abs_fuzz, \
                        abs_flat, abs_res = struct.unpack('iiiiii', absinfo)
                    if y == ABS_MT_POSITION_X:
                        range_min_position_x = drs('min_position_x', abs_min)
                        range_max_position_x = drs('max_position_x', abs_max)
                        pymt_logger.info('HIDTouch: ' +
                            '<%s> range position X is %d - %d' % (
                            device_name, abs_min, abs_max))
                    elif y == ABS_MT_POSITION_Y:
                        range_min_position_y = drs('min_position_y', abs_min)
                        range_max_position_y = drs('max_position_y', abs_max)
                        pymt_logger.info('HIDTouch: ' +
                            '<%s> range position Y is %d - %d' % (
                            device_name, abs_min, abs_max))
                    elif y == ABS_MT_PRESSURE:
                        range_min_pressure = drs('min_pressure', abs_min)
                        range_max_pressure = drs('max_pressure', abs_max)
                        pymt_logger.info('HIDTouch: ' +
                            '<%s> range pressure is %d - %d' % (
                            device_name, abs_min, abs_max))

            # read until the end
            while fd:

                data = fd.read(struct_input_event_sz)
                if len(data) < struct_input_event_sz:
                    break

                # extract each event
                for i in xrange(len(data) / struct_input_event_sz):
                    ev = data[i * struct_input_event_sz:]

                    # extract timeval + event infos
                    tv_sec, tv_usec, ev_type, ev_code, ev_value = \
                            struct.unpack('LLHHi', ev[:struct_input_event_sz])

                    # sync event
                    if ev_type == EV_SYN:
                        if ev_code == SYN_MT_REPORT:
                            if 'id' not in point:
                                continue
                            l_points.append(point)
                        elif ev_code == SYN_REPORT:
                            process(l_points)
                            l_points = []

                    elif ev_type == EV_MSC and ev_code in (MSC_RAW, MSC_SCAN):
                        pass

                    else:
                        # compute multitouch track
                        if ev_code == ABS_MT_TRACKING_ID:
                            point = {}
                            point['id'] = ev_value
                        elif ev_code == ABS_MT_POSITION_X:
                            val = normalize(ev_value,
                                range_min_position_x, range_max_position_x)
                            if invert_x:
                                val = 1. - val
                            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
Exemplo n.º 20
0
            def stop(self):
                super(LoaderPygame, self).stop()
                self.worker.stop()

            def run(self, *largs):
                while self._running:
                    try:
                        parameters = self._q_load.pop()
                    except:
                        time.sleep(0.1)
                        continue
                    self.worker.do(self._load, parameters)

        Loader = LoaderPygame()
        pymt_logger.info('Loader: using <pygame> as thread loader')

    except:

        #
        # Default to the clock loader
        #

        class LoaderClock(LoaderBase):
            '''Loader implementation using a simple Clock()'''
            def start(self):
                super(LoaderClock, self).start()
                getClock().schedule_interval(self.run, 0.0001)

            def stop(self):
                super(LoaderClock, self).stop()
Exemplo n.º 21
0
    Thanks for the support to Buchsenhausen, Innsbruck, Austria.
'''

import OSC
import socket, os, time, errno, sys
from threading import Lock
from pymt.logger import pymt_logger
try:
    # multiprocessing support is not good on window
    if sys.platform in ('win32', 'cygwin'):
        raise
    use_multiprocessing = True
    from multiprocessing import Process, Queue, Value
    import multiprocessing.synchronize
    pymt_logger.info('OSC: using <multiprocessing> for socket')
except:
    use_multiprocessing = False
    from threading import Thread
    pymt_logger.info('OSC: using <thread> for socket')

# globals
outSocket = 0
oscThreads = {}
oscLock = Lock()

if use_multiprocessing:

    def _readQueue(thread_id=None):
        global oscThreads
        for id in oscThreads:
Exemplo n.º 22
0
def runTouchApp(widget=None, slave=False):
    '''Static main function that starts the application loop.
    You got some magic things, if you are using argument like this :

    :Parameters:
        `<empty>`
            To make dispatching work, you need at least one
            input listener. If not, application will leave.
            (MTWindow act as an input listener)

        `widget`
            If you pass only a widget, a MTWindow will be created,
            and your widget will be added on the window as the root
            widget.

        `slave`
            No event dispatching are done. This will be your job.

        `widget + slave`
            No event dispatching are done. This will be your job, but
            we are trying to get the window (must be created by you before),
            and add the widget on it. Very usefull for embedding PyMT
            in another toolkit. (like Qt, check pymt-designed)

    '''

    global pymt_evloop

    # Ok, we got one widget, and we are not in slave mode
    # so, user don't create the window, let's create it for him !
    ### Not needed, since we always create window ?!
    #if not slave and widget:
    #    global pymt_window
    #    from ui.window import MTWindow
    #    pymt_window = MTWindow()

    # Instance all configured input
    for key, value in pymt.pymt_config.items('input'):
        pymt_logger.debug('Base: Create provider from %s' % (str(value)))

        # split value
        args = str(value).split(',', 1)
        if len(args) == 1:
            args.append('')
        provider_id, args = args
        provider = TouchFactory.get(provider_id)
        if provider is None:
            pymt_logger.warning('Base: Unknown <%s> provider' % \
                                str(provider_id))
            continue

        # create provider
        p = provider(key, args)
        if p:
            pymt_providers.append(p)

    pymt_evloop = TouchEventLoop()

    # add postproc modules
    for mod in pymt_postproc_modules.values():
        pymt_evloop.add_postproc_module(mod)

    # add main widget
    if widget and getWindow():
        getWindow().add_widget(widget)

    # start event loop
    pymt_logger.info('Base: Start application main loop')
    pymt_evloop.start()

    # we are in a slave mode, don't do dispatching.
    if slave:
        return

    # in non-slave mode, they are 2 issues
    #
    # 1. if user created a window, call the mainloop from window.
    #    This is due to glut, it need to be called with
    #    glutMainLoop(). Only FreeGLUT got a gluMainLoopEvent().
    #    So, we are executing the dispatching function inside
    #    a redisplay event.
    #
    # 2. if no window is created, we are dispatching event lopp
    #    ourself (previous behavior.)
    #
    try:
        if pymt_window is None:
            _run_mainloop()
        else:
            pymt_window.mainloop()
    finally:
        stopTouchApp()
Exemplo n.º 23
0
    Thanks for the support to Buchsenhausen, Innsbruck, Austria.
'''

import OSC
import socket, os, time, errno, sys
from threading import Lock
from pymt.logger import pymt_logger
try:
    # multiprocessing support is not good on window
    if sys.platform in ('win32', 'cygwin'):
        raise
    use_multiprocessing = True
    from multiprocessing import Process, Queue, Value
    import multiprocessing.synchronize
    pymt_logger.info('OSC: using <multiprocessing> for socket')
except:
    use_multiprocessing = False
    from threading import Thread
    pymt_logger.info('OSC: using <thread> for socket')

# globals
outSocket      = 0
oscThreads     = {}
oscLock        = Lock()

if use_multiprocessing:
    def _readQueue(thread_id=None):
        global oscThreads
        for id in oscThreads:
            if thread_id is not None:
Exemplo n.º 24
0
        def _thread_run(self, **kwargs):
            input_fn = kwargs.get('input_fn')
            queue = kwargs.get('queue')
            device = kwargs.get('device')
            drs = kwargs.get('default_ranges').get
            touches = {}
            touches_sent = []
            point = {}
            l_points = []

            # prepare some vars to get limit of some component
            range_min_position_x = 0
            range_max_position_x = 2048
            range_min_position_y = 0
            range_max_position_y = 2048
            range_min_pressure = 0
            range_max_pressure = 255
            invert_x = int(bool(drs('invert_x', 0)))
            invert_y = int(bool(drs('invert_y', 0)))

            def process(points):
                actives = [args['id'] for args in points]
                for args in points:
                    tid = args['id']
                    try:
                        touch = touches[tid]
                        if touch.sx == args['x'] and touch.sy == args['y']:
                            continue
                        touch.move(args)
                        if tid not in touches_sent:
                            queue.append(('down', touch))
                            touches_sent.append(tid)
                        queue.append(('move', touch))
                    except KeyError:
                        touch = HIDTouch(device, tid, args)
                        touches[touch.id] = touch

                for tid in touches.keys()[:]:
                    if tid not in actives:
                        touch = touches[tid]
                        if tid in touches_sent:
                            queue.append(('up', touch))
                            touches_sent.remove(tid)
                        del touches[tid]

            def normalize(value, vmin, vmax):
                return (value - vmin) / float(vmax - vmin)

            # open the input
            fd = open(input_fn, 'rb')

            # get the controler name (EVIOCGNAME)
            device_name = fcntl.ioctl(fd, EVIOCGNAME + (256 << 16),
                                      " " * 256).split('\x00')[0]
            pymt_logger.info('HIDTouch: using <%s>' % device_name)

            # get abs infos
            bit = fcntl.ioctl(fd, EVIOCGBIT + (EV_MAX << 16), ' ' * sz_l)
            bit, = struct.unpack('Q', bit)
            for x in xrange(EV_MAX):
                # preserve this, we may want other things than EV_ABS
                if x != EV_ABS:
                    continue
                # EV_ABS available for this device ?
                if (bit & (1 << x)) == 0:
                    continue
                # ask abs info keys to the devices
                sbit = fcntl.ioctl(fd, EVIOCGBIT + x + (KEY_MAX << 16),
                                   ' ' * sz_l)
                sbit, = struct.unpack('Q', sbit)
                for y in xrange(KEY_MAX):
                    if (sbit & (1 << y)) == 0:
                        continue
                    absinfo = fcntl.ioctl(
                        fd, EVIOCGABS + y + (struct_input_absinfo_sz << 16),
                        ' ' * struct_input_absinfo_sz)
                    abs_value, abs_min, abs_max, abs_fuzz, \
                        abs_flat, abs_res = struct.unpack('iiiiii', absinfo)
                    if y == ABS_MT_POSITION_X:
                        range_min_position_x = drs('min_position_x', abs_min)
                        range_max_position_x = drs('max_position_x', abs_max)
                        pymt_logger.info('HIDTouch: ' +
                                         '<%s> range position X is %d - %d' %
                                         (device_name, abs_min, abs_max))
                    elif y == ABS_MT_POSITION_Y:
                        range_min_position_y = drs('min_position_y', abs_min)
                        range_max_position_y = drs('max_position_y', abs_max)
                        pymt_logger.info('HIDTouch: ' +
                                         '<%s> range position Y is %d - %d' %
                                         (device_name, abs_min, abs_max))
                    elif y == ABS_MT_PRESSURE:
                        range_min_pressure = drs('min_pressure', abs_min)
                        range_max_pressure = drs('max_pressure', abs_max)
                        pymt_logger.info('HIDTouch: ' +
                                         '<%s> range pressure is %d - %d' %
                                         (device_name, abs_min, abs_max))

            # read until the end
            while fd:

                data = fd.read(struct_input_event_sz)
                if len(data) < struct_input_event_sz:
                    break

                # extract each event
                for i in xrange(len(data) / struct_input_event_sz):
                    ev = data[i * struct_input_event_sz:]

                    # extract timeval + event infos
                    tv_sec, tv_usec, ev_type, ev_code, ev_value = \
                            struct.unpack('LLHHi', ev[:struct_input_event_sz])

                    # sync event
                    if ev_type == EV_SYN:
                        if ev_code == SYN_MT_REPORT:
                            if 'id' not in point:
                                continue
                            l_points.append(point)
                        elif ev_code == SYN_REPORT:
                            process(l_points)
                            l_points = []

                    elif ev_type == EV_MSC and ev_code in (MSC_RAW, MSC_SCAN):
                        pass

                    else:
                        # compute multitouch track
                        if ev_code == ABS_MT_TRACKING_ID:
                            point = {}
                            point['id'] = ev_value
                        elif ev_code == ABS_MT_POSITION_X:
                            val = normalize(ev_value, range_min_position_x,
                                            range_max_position_x)
                            if invert_x:
                                val = 1. - val
                            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
Exemplo n.º 25
0
    '''
    for callback in __pymt_post_configuration:
        callback()


def pymt_register_post_configuration(callback):
    '''Register a function to be call when pymt_configure() will be called.

    .. warning::
        Internal use only.
    '''
    __pymt_post_configuration.append(callback)


# Start !
pymt_logger.info('PyMT v%s' % (__version__))

#: Global settings options for pymt
pymt_options = {
    'use_accelerate': True,
    'shadow_window': True,
    'window': ('pygame', 'glut'),
    'text': ('pil', 'cairo', 'pygame'),
    'video': ('gstreamer', 'pyglet'),
    'audio': (
        'pygame',
        'gstreamer',
    ),
    'image': ('pil', 'pygame'),
    'camera': ('opencv', 'gstreamer', 'videocapture'),
    'svg': ('squirtle', ),
Exemplo n.º 26
0
    def draw(self):
        """Draw a circle under every touches"""
        set_color(*self.touch_color)
        for touch in getCurrentTouches():
            drawCircle(pos=(touch.x, touch.y), radius=self.radius)


# Searching the best provider
MTWindow = None
if not "PYMT_DOC" in os.environ:
    if "pygame" in pymt.pymt_options["window"]:
        try:
            import win_pygame

            MTWindow = win_pygame.MTWindowPygame
            pymt_logger.info("Window: use Pygame as window provider.")
        except ImportError:
            pymt_logger.debug("Window: Unable to use Pygame as provider.")

    if MTWindow is None and "glut" in pymt.pymt_options["window"]:
        try:
            import win_glut

            MTWindow = win_glut.MTWindowGlut
            pymt_logger.info("Window: use GLUT as window provider.")
        except ImportError:
            pymt_logger.debug("Window: Unable to use GLUT as provider.")

    # No window provider ?
    if MTWindow is None:
        pymt_logger.critical("Window: No provider found (configuration is %s)" % str(pymt.pymt_options["window"]))
Exemplo n.º 27
0
    '''Call post-configuration of PyMT.
    This function must be called in case of you create yourself the window.
    '''
    for callback in __pymt_post_configuration:
        callback()

def pymt_register_post_configuration(callback):
    '''Register a function to be call when pymt_configure() will be called.

    .. warning::
        Internal use only.
    '''
    __pymt_post_configuration.append(callback)

# Start !
pymt_logger.info('PyMT v%s' % (__version__))

#: Global settings options for pymt
pymt_options = {
    'use_accelerate': True,
    'shadow_window': True,
    'window': ('pygame', 'glut'),
    'text': ('pil', 'cairo', 'pygame'),
    'video': ('gstreamer', 'pyglet' ),
    'audio': ('pygame', 'gstreamer', ),
    'image': ('pil', 'pygame'),
    'camera': ('opencv', 'gstreamer', 'videocapture'),
    'svg': ('squirtle',),
    'spelling': ('enchant', 'osxappkit',),
    'clipboard': ('pygame', 'dummy'),
}
Exemplo n.º 28
0
Arquivo: loader.py Projeto: bernt/pymt
            def stop(self):
                super(LoaderPygame, self).stop()
                self.worker.stop()

            def run(self, *largs):
                while self._running:
                    try:
                        parameters = self._q_load.pop()
                    except:
                        time.sleep(0.1)
                        continue
                    self.worker.do(self._load, parameters)

        Loader = LoaderPygame()
        pymt_logger.info('Loader: using <pygame> as thread loader')

    except:

        #
        # Default to the clock loader
        #

        class LoaderClock(LoaderBase):
            '''Loader implementation using a simple Clock()'''
            def start(self):
                super(LoaderClock, self).start()
                getClock().schedule_interval(self.run, 0.0001)

            def stop(self):
                super(LoaderClock, self).stop()
Exemplo n.º 29
0
    def draw(self):
        '''Draw a circle under every touches'''
        set_color(*self.touch_color)
        for touch in getCurrentTouches():
            drawCircle(pos=(touch.x, touch.y), radius=self.radius)


# Searching the best provider
MTWindow = None
if not 'PYMT_DOC' in os.environ:
    if 'pygame' in pymt.pymt_options['window']:
        try:
            import win_pygame
            MTWindow = win_pygame.MTWindowPygame
            pymt_logger.info('Window: use Pygame as window provider.')
        except ImportError:
            pymt_logger.debug('Window: Unable to use Pygame as provider.')

    if MTWindow is None and 'glut' in pymt.pymt_options['window']:
        try:
            import win_glut
            MTWindow = win_glut.MTWindowGlut
            pymt_logger.info('Window: use GLUT as window provider.')
        except ImportError:
            pymt_logger.debug('Window: Unable to use GLUT as provider.')

    # No window provider ?
    if MTWindow is None:
        pymt_logger.critical(
            'Window: No provider found (configuration is %s)' %