Ejemplo n.º 1
0
class KeyboardOutputDevice:

    device = None

    def isConnected(self):
        return self.device is not None

    def __init__(self, deviceName='LilyFrog'):

        print 'Open keyboard output device.'
        self.device = UInput(name=deviceName)

    def stop(self):

        if self.isConnected():
            print 'Close keyboard output device.'
            self.device.close()
            self.device = None

    def pressKeyString(self, keystr):

        # print 'pressKeyString => %s' % keystr

        if not len(keystr): return

        scancodes = []

        for keychr in keystr:

            if keychr in KeyChrToCodeMap:

                scancode = KeyChrToCodeMap[keychr]
                scancodes.extend(scancode)

            else:
                raise ValueError('Invalid key string value \'%s\'!' % keychr)

        self.pressKeys(scancodes)

    def pressKeys(self, scancodes):

        if not len(scancodes): return

        for scancode in scancodes:

            isShiftRequired = isinstance(scancode, list)

            if not isShiftRequired:

                self.device.write(EV_KEY, scancode, KeyEvent.key_down)
                self.device.write(EV_KEY, scancode, KeyEvent.key_up)

            else:

                self.device.write(EV_KEY, KEY_LEFTSHIFT, KeyEvent.key_down)
                self.device.write(EV_KEY, scancode[0], KeyEvent.key_down)
                self.device.write(EV_KEY, scancode[0], KeyEvent.key_up)
                self.device.write(EV_KEY, KEY_LEFTSHIFT, KeyEvent.key_up)

        self.device.syn()
Ejemplo n.º 2
0
def main(argv):
    thumb_board = identify_thumb_board()
    if thumb_board is None:
        print("could not find a Thumb Keyboard")
        return 1
    print(
        "binding to %s (%x %x)" %
        (thumb_board.path, thumb_board.info.vendor, thumb_board.info.product))

    alias_map = AliasMap(open("halfquerty-v2.bin", "rb").read())
    event_buffer = CircleBuffer(5)
    print("forward_aliases", alias_map.forward_aliases)
    print("alias_target_keys", alias_map.alias_target_keys)

    try:
        ui = UInput()
        for event in thumb_board.read_loop():
            if event.type == ecodes.EV_KEY:
                process_ev(
                    event_buffer,
                    alias_map.forward_aliases,
                    event,
                    ui,
                    alias_map.alias_target_keys,
                )
    except KeyboardInterrupt as e:
        return 0
    except Exception as e:
        print(full_stack())
    finally:
        ui.close()
        return 1
Ejemplo n.º 3
0
class EvdevWriter(Writer):

    def __init__(self):
        self.event_to_ecode_translator = EventToEcodeTranslator()
        self.ui = UInput()

    def write_iterable(self, events_iterable):
        for event in events_iterable:
            if isinstance(event, list):
                self.write_combo(event)
            else:
                self.__buffer_event(event)
        self.ui.syn()

    def write_event(self, event):
        self.__buffer_event(event)
        self.ui.syn()

    def __buffer_event(self, event):
        ecode = self.event_to_ecode_translator.translate(event)
        self.ui.write(ecodes.EV_KEY, ecode, 1)
        self.ui.write(ecodes.EV_KEY, ecode, 0)

    def write_combo(self, events):
        for event in events:
            ecode = self.event_to_ecode_translator.translate(event)
            self.ui.write(ecodes.EV_KEY, ecode, 1)
            self.ui.syn()
        for event in reversed(events):
            ecode = self.event_to_ecode_translator.translate(event)
            self.ui.write(ecodes.EV_KEY, ecode, 0)
            self.ui.syn()

    def close(self):
        self.ui.close()
Ejemplo n.º 4
0
class KeyboardOutputDevice:

    device = None

    def isConnected(self):
        return self.device is not None

    def __init__(self, deviceName='LilyFrog'):

        print 'Open keyboard output device.'
        self.device = UInput(name=deviceName)

    def stop(self):

        if self.isConnected():
            print 'Close keyboard output device.'
            self.device.close()
            self.device = None
            
    def pressKeyString(self, keystr):
        
        # print 'pressKeyString => %s' % keystr

        if not len(keystr): return

        scancodes = []

        for keychr in keystr:

            if keychr in KeyChrToCodeMap:

                scancode = KeyChrToCodeMap[keychr]
                scancodes.extend(scancode)

            else: raise ValueError('Invalid key string value \'%s\'!' % keychr)

        self.pressKeys(scancodes)

    def pressKeys(self, scancodes):

        if not len(scancodes): return

        for scancode in scancodes:

            isShiftRequired = isinstance(scancode, list)

            if not isShiftRequired:

                self.device.write(EV_KEY, scancode, KeyEvent.key_down)
                self.device.write(EV_KEY, scancode, KeyEvent.key_up)

            else:

                self.device.write(EV_KEY, KEY_LEFTSHIFT, KeyEvent.key_down)
                self.device.write(EV_KEY, scancode[0],   KeyEvent.key_down)
                self.device.write(EV_KEY, scancode[0],   KeyEvent.key_up)
                self.device.write(EV_KEY, KEY_LEFTSHIFT, KeyEvent.key_up)

        self.device.syn()
Ejemplo n.º 5
0
    def execute(self):
        print "Executing " + e.KEY[self.macroKey] + " macro."
        ui = UInput()

        for i in range(len(self.keySequence)):
            ui.write(e.EV_KEY, self.keySequence[i], self.keyState[i]);
        ui.syn()
        ui.close()
Ejemplo n.º 6
0
class Keyboard:
    def __init__(self):
        self.uinput = UInput()

    def close(self):
        self.uinput.close()

    def send_key(self, js_keycode, state):
        self.uinput.write(ecodes.EV_KEY, js_map[js_keycode], 1 if state else 0)
        self.uinput.syn()
Ejemplo n.º 7
0
class Keyboard(object):
    def __init__(self):
        self.ui = UInput()

    def press(self, key):
        self.ui.write(e.EV_KEY, key, 1)
        self.ui.write(e.EV_KEY, key, 0)
        self.ui.syn()

    def __del__(self):
        self.ui.close()
Ejemplo n.º 8
0
class vjoy(object):
    """ send virtual joystick data to linux event system   """
    def __init__(self, can_id):
        self.can_id = can_id
        axis_cap = AbsInfo(-32700, 32700, 0, 0, 0, 0)
        self._ev = UInput(
            name='vjoy',
            events={
                ecodes.EV_ABS: [(ecodes.ABS_X, axis_cap),
                                (ecodes.ABS_Y, axis_cap),
                                (ecodes.ABS_Z, axis_cap)],
                ecodes.EV_KEY:
                [ecodes.BTN_TRIGGER, ecodes.BTN_TOP, ecodes.BTN_TOP2]
            })

    def __enter__(self):
        return self

    def __exit__(self, type, value, tb):
        self._ev.close()

    def signal(self, x, y, z, b0, b1, b2):
        self._ev.write(ecodes.EV_ABS, ecodes.ABS_X, x)
        self._ev.write(ecodes.EV_ABS, ecodes.ABS_Y, y)
        self._ev.write(ecodes.EV_ABS, ecodes.ABS_Z, z)
        self._ev.write(ecodes.EV_KEY, ecodes.BTN_TRIGGER, b0)
        self._ev.write(ecodes.EV_KEY, ecodes.BTN_TOP, b1)
        self._ev.write(ecodes.EV_KEY, ecodes.BTN_TOP2, b2)
        self._ev.syn()

    def process_can_data(self, msg):
        #print(msg)
        if (msg.mid == (0x180 + self.can_id)):
            # convert axis data to signed
            abs_x = (msg[0] - 256) if (msg[0] > 127) else msg[0]
            abs_y = (msg[1] - 256) if (msg[1] > 127) else msg[1]
            abs_z = (msg[2] - 256) if (msg[2] > 127) else msg[2]
            # flip y
            abs_y = -abs_y
            # rescale from -100..100 to -32700..32700:
            abs_x = abs_x * 327
            abs_y = abs_y * 327
            abs_z = abs_z * 327
            # fetch buttons
            b0 = 1 if (msg[5] & 32) else 0
            b1 = 1 if (msg[5] & 1) else 0
            b2 = 1 if (msg[5] & 8) else 0
            # debug data
            print(" X: " + str(abs_x) + " Y: " + str(abs_y) + " Z: " +
                  str(abs_z) + " B0: " + str(b0) + " B1: " + str(b1) +
                  " B2: " + str(b2))
            # send data
            self.signal(abs_x, abs_y, abs_z, b0, b1, b2)
Ejemplo n.º 9
0
class Device(object):
    def __init__(self):
        self.ui = UInput()

    def send(self, data):
        for d in data:
            self.ui.write(e.EV_KEY, keydict[d], 1)
            self.ui.syn()
            self.ui.write(e.EV_KEY, keydict[d], 0)
            self.ui.syn()

    def close(self):
        self.ui.close()
Ejemplo n.º 10
0
 def trigger_display_switch (self):
     ''' Trigger super+p twice '''
     ui = UInput()
     ui.write(e.EV_KEY, e.KEY_LEFTMETA, 1)
     ui.syn()
     time.sleep(1)
     ui.write(e.EV_KEY, e.KEY_P, 1)
     ui.write(e.EV_KEY, e.KEY_P, 0)
     ui.write(e.EV_KEY, e.KEY_P, 1)
     ui.write(e.EV_KEY, e.KEY_P, 0)
     ui.write(e.EV_KEY, e.KEY_LEFTMETA, 0)
     ui.syn()
     ui.close()
Ejemplo n.º 11
0
class PointerWatcher(Thread):
    def __init__(self):
        Thread.__init__(self)
        self.ui = UInput()
        self.devices = []
        self.running = True
        self.device_search()

    def device_search(self):
        devices_list = []
        files = []
        for (dirpath, dirnames, filenames) in walk(INPUTDIR):
            files.extend(filenames)
            break
        for f in files:
            try:
                dev = InputDevice(path.join(INPUTDIR, f))
                if dev.name == "W WirelessUSB":
                    devices_list.append(dev)
            except (IOError, OSError, TypeError):
                pass
        self.devices = {dev.fd: dev for dev in devices_list}

    def run(self):
        c = 0
        if len(self.devices) > 0:
            while self.running:
                r, w, x = select(self.devices, [], [])
                for fd in r:
                    try:
                        for event in self.devices[fd].read():
                            if event.code == ecodes.KEY_UP and event.value == 1:
                                self.ui.write(ecodes.EV_KEY, ecodes.KEY_DOWN, 1)
                                self.ui.write(ecodes.EV_KEY, ecodes.KEY_DOWN, 0)
                                self.ui.write(ecodes.EV_KEY, ecodes.KEY_LEFT, 1)
                                self.ui.write(ecodes.EV_KEY, ecodes.KEY_LEFT, 0)
                                self.ui.syn()
                                c += 1
                            elif event.code == ecodes.KEY_DOWN and event.value == 1:
                                self.ui.write(ecodes.EV_KEY, ecodes.KEY_UP, 1)
                                self.ui.write(ecodes.EV_KEY, ecodes.KEY_UP, 0)
                                self.ui.write(ecodes.EV_KEY, ecodes.KEY_RIGHT, 1)
                                self.ui.write(ecodes.EV_KEY, ecodes.KEY_RIGHT, 0)
                                self.ui.syn()
                                c -= 1
                    except IOError:
                        self.running = False
                        break
        self.ui.close()
Ejemplo n.º 12
0
def call(k, conf=False):
    if conf:
        keys = defns._k[k]
    else:
        keys = defns.default[k]
    try:
        ui = UInput()
        for key in keys:
            ui.write(defns.k["EV_KEY"], defns.k["KEY_" + key.upper()], 1)
        defns._k[k].reverse()
        for key in keys:
            ui.write(defns.k["EV_KEY"], defns.k["KEY_" + key.upper()], 0)
        ui.syn()
        ui.close()
    except err:
        print "Not enough permissions. Are you root?"
Ejemplo n.º 13
0
def call(k, conf=False):
    if conf:
        keys = defns._k[k]
    else:
        keys = defns.default[k]
    try:
        ui = UInput()
        for key in keys:
            ui.write(defns.k["EV_KEY"], defns.k["KEY_" + key.upper()], 1)
        defns._k[k].reverse()
        for key in keys:
            ui.write(defns.k["EV_KEY"], defns.k["KEY_" + key.upper()], 0)
        ui.syn()
        ui.close()
    except err:
        print "Not enough permissions. Are you root?"
Ejemplo n.º 14
0
class App(object):
    _logger = logging.getLogger('evdev_mt_a')

    def __init__(self, hardware_version):
        logging.basicConfig(level=LOGGING_LEVEL, **LOGGING_FORMATS)
        self.electrodes = electrodes_by_hardware_version(hardware_version)
        self.electrodes.init()

        ev_multitouch = {
            ecodes.EV_ABS: [
                (ecodes.ABS_MT_POSITION_X, (0, 0,
                                            self.electrodes.grid_sizes[0])),
                (ecodes.ABS_MT_POSITION_Y, (0, 0,
                                            self.electrodes.grid_sizes[1])),
            ]
        }
        self.ui_multitouch = UInput(ev_multitouch,
                                    name='capacitive_electrodes',
                                    version=0x3)

    def __loop__(self):
        self._logger.info('loop')
        while True:
            self.electrodes.update()

            if self.electrodes.get_newly_touched(
            ) or self.electrodes.get_newly_released():
                touched = self.electrodes.get_touched()
                for i in touched:
                    self.ui_multitouch.write(ecodes.EV_ABS,
                                             ecodes.ABS_MT_POSITION_X,
                                             i.grid_indexes[0])
                    self.ui_multitouch.write(ecodes.EV_ABS,
                                             ecodes.ABS_MT_POSITION_Y,
                                             i.grid_indexes[1])
                    self.ui_multitouch.write(ecodes.EV_SYN,
                                             ecodes.SYN_MT_REPORT, 0)
                if not touched:
                    self.ui_multitouch.write(ecodes.EV_SYN,
                                             ecodes.SYN_MT_REPORT, 0)
                self._logger.info('send multitouch_a[%d] report', len(touched))
                self.ui_multitouch.syn()

            time.sleep(0.01)

    def __exit__(self):
        self.ui_multitouch.close()
Ejemplo n.º 15
0
def writeWord(word):
    listOfLetters = list(word)
    
    
    ui = UInput()
    
    for letter in listOfLetters:
        if letter.isupper():
            letter = letter.lower()
            case = 'upper'
        else:
            case = 'lower'

        writeUiCase(letter, ui, case)

    ui.syn()
    ui.close()
Ejemplo n.º 16
0
def call(vals):
    """
  The call function receives a list of keys to be pressed and loops over
  them switching them to pressed state, then loops over the reversed list
  unpressing them. That way it can process key combinations.
  """
    try:
        ui = UInput()
        for k in vals:
            ui.write(ecodes["EV_KEY"], ecodes["KEY_" + keys[k]], 1)
        vals.reverse()
        for k in vals:
            ui.write(ecodes["EV_KEY"], ecodes["KEY_" + keys[k]], 0)
        ui.syn()
        ui.close()
    except err:
        print "Not enough permissions. Are you root?"
Ejemplo n.º 17
0
def call(vals):
    '''
  The call function receives a list of keys to be pressed and loops over
  them switching them to pressed state, then loops over the reversed list
  unpressing them. That way it can process key combinations.
  '''
    try:
        ui = UInput()
        for k in vals:
            ui.write(ecodes["EV_KEY"], ecodes["KEY_" + keys[k]], 1)
        vals.reverse()
        for k in vals:
            ui.write(ecodes["EV_KEY"], ecodes["KEY_" + keys[k]], 0)
        ui.syn()
        ui.close()
    except err:
        print "Not enough permissions. Are you root?"
Ejemplo n.º 18
0
class MouseWatcher(Thread):
    def __init__(self, listener=MouseListener()):
        Thread.__init__(self)
        self.m = PyMouse()
        self.ui = UInput()
        self.devices = []
        self.running = True
        self.lastPosition = None
        self.device_search()
        self.listener = listener

    def stop(self):
        print "Desligando mouse."
        self.running = False

    def device_search(self):
        devices_list = []
        files = []
        for (dirpath, dirnames, filenames) in walk(INPUTDIR):
            files.extend(filenames)
            break
        for f in files:
            try:
                dev = InputDevice(path.join(INPUTDIR, f))
                keymap = dev.capabilities().get(1)
                if ecodes.BTN_MOUSE in keymap and ecodes.BTN_LEFT in keymap:
                    devices_list.append(dev)
            except (IOError, OSError, TypeError):
                pass
        self.devices = {dev.fd: dev for dev in devices_list}

    def run(self):
        while self.running:
            r,w,x = select(self.devices, [], [])
            for fd in r:
                if not self.running:
                    break
                for event in self.devices[fd].read():
                    if event.type == ecodes.EV_KEY and event.value == 1:
                        self.lastPosition = self.m.position()
                        if self.listener.__class__ != MouseListener:
                            self.listener.call_me(self.lastPosition)
        self.ui.close()
Ejemplo n.º 19
0
class KeyboardSimuThread(Thread):
    def __init__(self, thNo):
        Thread.__init__(self)
        self.thNo = thNo
        self.ui = UInput()
        self.keep_running = True
        self.waitingOnKey = True
        self.key = ecodes.KEY_Q

    #
    def run(self):
        print "KeyboardSimuThread Started!"
        while self.keep_running:
            if self.waitingOnKey == False:
                #print "Buzzer " + str(self.thNo)
                #self.ui.write_event(InputEvent(1, 200, ecodes.EV_KEY, self.key, 1)) does not work in Blender
                self.ui.write(ecodes.EV_KEY, self.key, 1)  #Press key down
                self.ui.syn()
                time.sleep(
                    0.3
                )  #Hold it down for 300ms so that Blender is able to read it
                self.ui.write(ecodes.EV_KEY, self.key, 0)  #Relase
                self.ui.syn()

                self.waitingOnKey = True  #Now we can send a new key
                #If another key of this buzzer had been pressed it will not be taken in concideration
                # before waitingOnKey is set to True. So 300ms after last key was pressed
            time.sleep(0.1)

        self.ui.close()
        print "KeyboardSimuThread terminated!"

    def simulateKey(self, key):
        #If the thread is waiting for a key we send it, otherwise we ignore it because the thread is already managing one key
        if self.waitingOnKey == True:
            self.key = key
            self.waitingOnKey = False

    # Each thread runs until explicitly signaled to stop
    def signal(self):
        print "KeyboardSimuThread will terminate!"
        self.keep_running = False
Ejemplo n.º 20
0
class VirtualJoystick(object):
    def __init__(self, top_rpm, top_wheel):
        e = ecodes
        cap = {
                e.EV_ABS: [  (e.ABS_X,
                              AbsInfo(value=top_wheel, min=0, max=top_wheel*2, fuzz=0, flat=15, resolution=0)),
                             (e.ABS_Y,
                              AbsInfo(value=128, min=0, max=255, fuzz=0, flat=15, resolution=0)),
                             (e.ABS_Z,
                              AbsInfo(value=top_rpm, min=0, max=top_rpm*2, fuzz=0, flat=15, resolution=0)),
                             ],
                e.EV_KEY: [e.BTN_JOYSTICK,
                            e.BTN_THUMB,
                            e.BTN_THUMB2,
                            e.BTN_TOP,
                            e.BTN_TOP2,
                            e.BTN_PINKIE,
                            e.BTN_BASE,
                            e.BTN_BASE2,
                            e.BTN_BASE3,
                            e.BTN_BASE4,
                            e.BTN_BASE5,
                            e.BTN_BASE6],
               }
        self.joystick = UInput(cap, name='gpad-bike')

    def __del__(self):
        self.joystick.close()

    def set_wheel(self, value):
        self.set_axis(ecodes.ABS_X, value)

    def set_rpm(self, value):
        self.set_axis(ecodes.ABS_Z, value)

    def set_axis(self, axis, value):
        #value = 255
        self.joystick.write(ecodes.EV_ABS, axis, value)
        self.joystick.syn()

    def write(self, etype, code, value):
        self.joystick.write(etype, code, value)
Ejemplo n.º 21
0
async def generate_kb_input(keys=None):
    if not keys:
        raise ValueError("Can't iterate over nothing")
    ui = UInput()
    for k in keys:
        if isinstance(k, str) and ',' in k:
            for state in [1, 0]:
                for kk in k.split(','):
                    kk = e.__getattribute__('KEY_' + kk)
                    print("SENDING KEY", kk)
                    ui.write(e.EV_KEY, kk, state)
                ui.syn()
        else:
            if isinstance(k, str):
                k = e.__getattribute__('KEY_' + k)
            print("SENDING KEY", k)
            ui.write(e.EV_KEY, k, 1)
            ui.write(e.EV_KEY, k, 0)
            ui.syn()
    ui.close()
Ejemplo n.º 22
0
class KbdOutput(object):
    def __init__(self):
        self.ui = UInput()
        logging.info('Creating uinput device: ' + to_str(self.ui))

    def __enter__(self):
        return self

    def press(self, key):
        self.ui.write(e.EV_KEY, keycode(key), etype.KEY_PRESS)

    def release(self, key):
        self.ui.write(e.EV_KEY, keycode(key), etype.KEY_RELEASE)

    def sync(self):
        self.ui.syn()

    def close(self):
        self.ui.close()

    def __exit__(self, exc_type, exc_value, traceback):
        logging.info('Closing uinput device: ' + to_str(self.ui))
        self.close()
Ejemplo n.º 23
0
class KeyHandler:

    def __init__(self, mod_mapping, key_mapping):
        self._ui = UInput()
        self._mod_mapping = mod_mapping
        self._key_mapping = key_mapping

    def chord_event(self, mods, virtual_mods, chord, value):
        chord_keys = self.map_chord(virtual_mods, chord)
        if value == 0:
            chord_keys = chord_keys + self.map_mods(mods)
        else:
            chord_keys = self.map_mods(mods) + chord_keys

        for key in chord_keys:
            self._ui.write(EV_KEY, key, value)
        self._ui.syn()

    def map_chord(self, virtual_mods, chord):
        frozen_vmods = frozenset(virtual_mods)
        if frozen_vmods not in self._key_mapping:
            return []
        current_mapping = self._key_mapping[frozen_vmods]
        frozen_chord = frozenset(chord)
        if frozen_chord not in current_mapping:
            return []
        return current_mapping[frozen_chord]

    def map_mods(self, keys):
        mods = []
        for key in keys:
            mods.append(self._mod_mapping[key])
        return mods

    def close(self):
        self._ui.close()
Ejemplo n.º 24
0
    def _kp_monitor_loop(self):
        """ Keypad monitoring loop, running in a thread and responsible for
        sending the evdev key events corresponding to key actions.

        Th uinput instance life-cycle is entirely managed in this method.
        """
        log = logging.getLogger('uinput')
        log.info('starting keypad monitor')

        dev = self.terminal.device
        try:
            keypad_map = dev.get_keypad_map()
        except AttributeError:
            keypad_map = [
                ecodes.KEY_NUMERIC_1,
                ecodes.KEY_NUMERIC_2,
                ecodes.KEY_NUMERIC_3,
                ecodes.KEY_NUMERIC_4,
                ecodes.KEY_NUMERIC_5,
                ecodes.KEY_NUMERIC_6,
                ecodes.KEY_NUMERIC_7,
                ecodes.KEY_NUMERIC_8,
                ecodes.KEY_NUMERIC_9,
                ecodes.KEY_NUMERIC_STAR,
                ecodes.KEY_NUMERIC_0,
                ecodes.KEY_NUMERIC_POUND,
            ]

        keypad_mask = 0
        for k in reversed(keypad_map):
            keypad_mask <<= 1
            if k is not None:
                keypad_mask |= 1

        cap = {
            ecodes.EV_KEY: [ecodes.KEY_PREVIOUS, ecodes.KEY_NEXT, ecodes.KEY_ESC, ecodes.KEY_OK]
        }
        ui = UInput(cap, name='ctrl-panel')
        log.info('uinput created')

        last_state = None
        self._kp_monitor_terminate = False

        while not self._kp_monitor_terminate:
            state = dev.get_keypad_state() & keypad_mask
            changes_mask = state if last_state is None else last_state ^ state
            if changes_mask:
                log.debug('change detected : state=%d last_state=%d', state, last_state)
                last_state = state
                for i, k in enumerate(keypad_map):
                    if k is not None and (changes_mask & 1):
                        key_state = state & 1
                        value = 1 if key_state else 0
                        ui.write(ecodes.EV_KEY, k, value)
                        log.info('EV_KEY event sent (code=%s, value=%d)', ecodes.keys[k], value)
                    state >>= 1
                    changes_mask >>= 1

                ui.syn()
                log.debug('sync event sent')

            time.sleep(0.1)

        ui.close()
        log.info('uinput closed')
Ejemplo n.º 25
0
class PPMDecoder(object):
    """Decodes the audio data into PPM pulse data, and then into uinput
    joystick events.
    """
    def __init__(self, rate):
        """
        Parameters
        ----------
        rate : int
            sample rate
        """
        self._rate = float(rate)
        self._lf = None
        self._threshold = 15000
        self._last_edge = None
        self._ch = None

        # Size in sampling intervals, of the frame space marker
        self._marker = int(2.0 * 0.0025 * self._rate)

        # Mapping of channels to events
        self._mapping = {0: ecodes.ABS_X,
                         1: ecodes.ABS_Y,
                         2: ecodes.ABS_Z,
                         3: ecodes.ABS_THROTTLE}

        events = [(v, (0, 255, 5, 0)) for v in self._mapping.values()]

        self._ev = UInput(name='ppmadapter',
                          events={
                               ecodes.EV_ABS: events,
                               ecodes.EV_KEY: {288: 'BTN_JOYSTICK'}
                          })

    def __enter__(self):
        return self

    def __exit__(self, type, value, tb):
        self._ev.close()

    def feed(self, data):
        """Feeds the decoder with a block of sample data.

        The data should be integer values, and should only be a single channel.

        Parameters
        ----------
        data : list
            sample data
        """
        sync_req = False
        for i in range(len(data)):
            this_edge = data[i] > self._threshold
            if self._last_edge is None:
                self._last_edge = this_edge
                continue

            if this_edge and not self._last_edge:
                # rising
                if self._lf is not None:
                    sync_req |= self.signal(i - self._lf)
            elif not this_edge and self._last_edge:
                # falling
                self._lf = i

            self._last_edge = this_edge

        if sync_req:
            self._ev.syn()

        if self._lf is not None:
            self._lf = self._lf - len(data)
            if self._lf < (-self._rate):
                print("Lost sync")
                self._ch = None
                self._lf = None

    def signal(self, w):
        """Process the detected signal.

        The signal is the number of sampling intervals between the falling
        edge and the rising edge.

        Parameters
        ----------
        w : int
            signal width

        Returns
        -------
        bool
            does uinput require sync
        """
        if w > self._marker:
            if self._ch is None:
                print("Got sync")
            self._ch = 0
            return False

        if self._ch is None or self._ch not in self._mapping:
            return False

        duration = float(w) / self._rate
        value = int((duration - 0.0007) * 1000 * 255)
        self._ev.write(ecodes.EV_ABS, self._mapping[self._ch], value)

        self._ch += 1

        return True
Ejemplo n.º 26
0
class PPMDecoder(object):
    """Decodes the audio data into PPM pulse data, and then into uinput
    joystick events.
    """
    def __init__(self, rate, average_length):
        """
        Parameters
        ----------
        rate : int
            sample rate
        average_length : int
            average of past channel values for smoothing, set to 1 if undesired
        """
        self.rate = float(rate)

        # Values that persist between windows so we can handle small windows
        # where not all the channels have been seen in a single window
        self.min_value = float("+inf")
        self.max_value = float("-inf")
        self.channel = 0
        self.previous_value = None
        self.pulse_start_time = 0
        self.samples_since_pulse = 0

        # Should be 2ms, but sometimes not quite
        self.start_pulse_length = 2.0 / 1000

        # Mapping of channels to events
        self.mapping = {
            0: ecodes.ABS_X,
            1: ecodes.ABS_Y,
            2: ecodes.ABS_Z,
            3: ecodes.ABS_THROTTLE,
            4: ecodes.ABS_RUDDER,
            5: ecodes.ABS_MISC,
        }

        # History of values (for averaging)
        self.history = {
            i: collections.deque(maxlen=average_length)
            for i in self.mapping.keys()
        }

        # Min/max values we'll output
        events = [(v, (0, -512, 512, 0)) for v in self.mapping.values()]

        self.ev = UInput(name='ppmadapter',
                         events={
                             ecodes.EV_ABS: events,
                             ecodes.EV_KEY: {
                                 288: 'BTN_JOYSTICK'
                             }
                         })

    def __enter__(self):
        return self

    def __exit__(self, type, value, tb):
        self.ev.close()

    def feed(self, data, plot=False, debug=False):
        """Feeds the decoder with a block of sample data.

        The data should be integer values, and should only be a single channel.

        Parameters
        ----------
        data : list
            Sample data
        plot : bool
            Whether to display data in a matplotlib plot or not
        """
        if plot:
            plot_start = np.zeros((len(data), ))
            plot_channels = {
                i: np.zeros((len(data), ))
                for i in self.mapping.keys()
            }

        # Process all audio samples
        for i in range(len(data)):
            # Hmm... maybe the problem was just that it needed to be negated?
            # This is what txppm does.
            current_value = -data[i]

            # Update extrema and threshold as a weighted average. In my case,
            # average ends up being close to 0, which then results in noise
            # triggering this. Thus, weight toward max.
            self.min_value = min(self.min_value, current_value)
            self.max_value = max(self.max_value, current_value)
            threshold = 1 / 4 * self.min_value + 3 / 4 * self.max_value

            # Keep track of the previous value for determining if between the
            # last sample and the current sample there was a rise
            if self.previous_value is None:
                self.previous_value = current_value
                continue

            # Detect rising edge: if the previous value is low and now it's
            # high
            rising = self.previous_value < threshold and current_value > threshold

            if rising:
                # Time when hitting threshold (measured in seconds)
                # See: https://github.com/nexx512/txppm/blob/master/software/ppm.c
                trigger_offset = (threshold - self.previous_value) / \
                    (current_value - self.previous_value) / self.rate
                trigger_time = self.samples_since_pulse / self.rate + trigger_offset
                pulse_length = trigger_time - self.pulse_start_time
                self.pulse_start_time = trigger_time

                # Start pulse
                if pulse_length > self.start_pulse_length:
                    self.channel = 0
                    self.pulse_start_time = trigger_offset
                    self.samples_since_pulse = 0

                    if plot:
                        plot_start[i] = threshold

                # Channel measurement
                else:
                    # If a channel we care about, save it. Note: still need to
                    # increment the channel even if not in mapping since we
                    # might care about non-consecutive channels (e.g. 1, 3, and
                    # 5).
                    if self.channel in self.mapping:
                        # txppm says "According to the spec, the pulse length
                        # ranges from 1..2ms"
                        value = pulse_length * 1000 - 1.5

                        # To enable averaging, add current value to queue but
                        # don't set it yet
                        self.history[self.channel].append(value)

                        if plot:
                            plot_channels[self.channel][i] = threshold

                    self.channel += 1

            self.samples_since_pulse += 1
            self.previous_value = current_value

        # Send joystick updates
        for ch, values in self.history.items():
            value = 0

            # Handle averaging
            if len(values) > 0:
                value = int(sum(values) / len(values) * 512)

            self.ev.write(ecodes.EV_ABS, self.mapping[ch], value)

            if debug:
                print("ch" + str(ch), "=", value)

        self.ev.syn()

        # Plot the audio data we received if desired
        if plot:
            # Plot negative since we negate when processing
            y = -np.array(list(data), dtype=np.float32)
            x = np.arange(0, len(y), 1)
            plt.plot(x, y, label="signal")
            plt.plot(x, plot_start, label="start")
            for ch, values in plot_channels.items():
                plt.plot(x, values, label="ch" + str(ch))
            plt.legend()
            plt.show()
Ejemplo n.º 27
0
class PointingTechnique:
    capabilities = {
        e.EV_REL: (e.REL_X, e.REL_Y),
        e.EV_KEY: (e.BTN_LEFT, e.BTN_RIGHT)
    }

    def __get_distance_to_target(self, pos):
        return math.dist([pos.x(), pos.y()],
                         [self.__target_pos.x(),
                          self.__target_pos.y()])

    def __is_in_target(self, pos):
        return self.__get_distance_to_target(pos) <= (self.__target.width() /
                                                      2)

    # Code based on:
    # https://en.wikipedia.org/wiki/Linear_interpolation
    # https://stackoverflow.com/questions/49173095/how-to-move-an-object-along-a-line-given-two-points#49173439
    def __move_to_target(self):
        if self.__moving or self.__is_in_target(self.__current_pos):
            return

        self.__moving = True

        n = self.__density  # The smaller n is the "faster" the mouse becomes
        x0, y0 = self.__current_pos.x(), self.__current_pos.y()
        x1, y1 = self.__target_pos.x(), self.__target_pos.y()
        x_t0, y_t0 = x0, y0

        for i in range(0, n):
            if self.__is_in_target(self.__current_pos):
                return

            t = i / n
            x_t = (1.0 - t) * x0 + t * x1
            y_t = (1.0 - t) * y0 + t * y1

            rel_x = int(x_t - x_t0)
            rel_y = int(y_t - y_t0)

            self.__device.write(e.EV_REL, e.REL_X, rel_x)
            self.__device.write(e.EV_REL, e.REL_Y, rel_y)
            self.__device.syn()

            x_t0, y_t0 = x_t, y_t

            time.sleep(0.01)
            QtWidgets.qApp.processEvents()

        self.__moving = False

    def __init__(self, target, threshold, density):
        self.__moving = False
        self.__device = UInput(self.capabilities)
        self.__target = target
        self.__target_pos = self.__target.geometry().center()
        self.__current_pos = None

        self.__threshold = threshold
        self.__density = density

    def __del__(self):
        self.__device.close()

    def filter(self, current_pos):
        self.__current_pos = current_pos

        threshold = int(self.__target.parent().width() * self.__threshold)
        if self.__get_distance_to_target(current_pos) < threshold:
            self.__move_to_target()
Ejemplo n.º 28
0
class EvPointer(object):

	def __init__(self):

		self.xdisplay = display.Display()
		screen = self.xdisplay.screen()
		self.screen_width = screen.width_in_pixels
		self.screen_height = screen.height_in_pixels
		self.xroot = screen.root
		pointer = self.xroot.query_pointer()

		self.position = MousePos(pointer.root_x, pointer.root_y)

		devices = [InputDevice(fn) for fn in list_devices()]
		self.pointer_devs = []
		self.keyboard_devs = []
		for device in devices:
			caps = device.capabilities()
			if ecodes.EV_REL in caps:
				self.pointer_devs.append(device)
			elif ecodes.EV_ABS in caps:
				self.pointer_devs.append(device)
			elif ecodes.EV_KEY in caps:
				self.keyboard_devs.append(device)

		self.queue = Queue()
		self.mainloop = Thread(target=self._mainloop, name='EvPointer mainloop')
		self.mainloop.start()
		self.stop = False
		self.hook_callback = None
		self.hook = Thread(target=self._hook, name='EvPointer hook loop')
		self.hook.start()

		caps = {
			ecodes.EV_REL: (
				ecodes.REL_X, ecodes.REL_Y, ecodes.REL_WHEEL, ecodes.REL_HWHEEL),
			ecodes.EV_KEY: (
				ecodes.BTN_LEFT, ecodes.BTN_RIGHT, ecodes.BTN_MIDDLE,
				ecodes.BTN_SIDE, ecodes.BTN_EXTRA)}
		self.uinput = UInput(caps, name='macpy pointer')

	def close(self):

		self.uinput.close()
		self.enqueue(None)
		if self.hook and self.hook.is_alive():
			self.stop = True

	def _hook(self):

		li = LibInput(ContextType.PATH)
		for device in self.pointer_devs:
			li.add_device(device.fn)

		for event in li.events:
			if self.stop:
				break

			mods = {
				'SHIFT': False,
				'ALTGR': False,
				'CTRL': False,
				'ALT': False,
				'META': False}
			active_mods = set()
			for device in self.keyboard_devs:
				active_mods |= set(device.active_keys())
			for key in active_mods:
				key = Key.from_ec(key)
				if key in Mods.SHIFT:
					mods['SHIFT'] = True
				elif key in Mods.CTRL:
					mods['CTRL'] = True
				elif key in Mods.ALT:
					mods['ALT'] = True
				elif key in Mods.META:
					mods['META'] = True

			if event.type == EventType.POINTER_MOTION:
				dx, dy = event.delta
				x = self.position.x + round(dx)
				y = self.position.y + round(dy)
				if x < 0:
					x = 0
				elif x > (self.screen_width - 1):
					x = self.screen_width - 1
				if y < 0:
					y = 0
				elif y > (self.screen_height - 1):
					y = self.screen_height - 1
				self.position = MousePos(x, y)
				if self.hook_callback:
					self.enqueue(self.hook_callback, PointerEventMotion(
						self.position.x, self.position.y, mods))
			elif event.type == EventType.POINTER_MOTION_ABSOLUTE:
				x, y = event.transform_absolute_coords(
					self.screen_width, self.screen_height)
				self.position = MousePos(round(x), round(y))
				if self.hook_callback:
					self.enqueue(self.hook_callback, PointerEventMotion(
						self.position.x, self.position.y, mods))
			elif event.type == EventType.POINTER_BUTTON:
				button = Key.from_ec(event.button)
				state = KeyState(event.button_state.value)
				if self.hook_callback:
					self.enqueue(self.hook_callback, PointerEventButton(
						self.position.x, self.position.y, button, state, mods))
			elif event.type == EventType.POINTER_AXIS:
				if event.has_axis(LIPAxis.SCROLL_VERTICAL):
					axis = mPAxis.VERTICAL
					value = event.get_axis_value(LIPAxis.SCROLL_VERTICAL)
				else:
					axis = mPAxis.HORIZONTAL
					value = event.get_axis_value(LIPAxis.SCROLL_HORIZONTAL)
				if self.hook_callback:
					self.enqueue(self.hook_callback, PointerEventAxis(
						self.position.x, self.position.y, value, axis, mods))

	def install_pointer_hook(self, callback, grab=False):

		self.hook_callback = callback

	def uninstall_pointer_hook(self):

		self.hook_callback = None

	def _mainloop(self):

		while True:
			method, args = self.queue.get()
			if method is None:
				break
			try:
				method(*args)
			except Exception as e:
				print(
					'Error in EvPointer mainloop: \n',
					''.join(traceback.format_exception(
						type(e), e, e.__traceback__)))
			self.queue.task_done()

	def enqueue(self, method, *args):

		self.queue.put_nowait((method, args))

	def _warp(self, x, y, relative=False):

		if relative:
			dx = x
			dy = y
		else:
			dx = x - self.position.x
			dy = y - self.position.y
		self.uinput.write(ecodes.EV_REL, ecodes.REL_X, dx)
		self.uinput.write(ecodes.EV_REL, ecodes.REL_Y, dy)
		self.uinput.syn()

	def warp(self, x, y, relative=False):

		self.enqueue(self._warp, x, y, relative)

	def _scroll(self, axis, value):

		if axis is mPAxis.VERTICAL:
			self.uinput.write(ecodes.EV_REL, ecodes.REL_WHEEL, -value)
		elif axis is mPAxis.HORIZONTAL:
			self.uinput.write(ecodes.EV_REL, ecodes.REL_HWHEEL, value)
		else:
			raise TypeError('Invalid axis type')
		self.uinput.syn()

	def scroll(self, axis, value):

		self.enqueue(self._scroll, axis, value)

	def _click(self, key, state=None):

		if state is None:
			self.uinput.write(ecodes.EV_KEY, key.ec.value, 1)
			self.uinput.write(ecodes.EV_KEY, key.ec.value, 0)
		elif state is KeyState.PRESSED:
			self.uinput.write(ecodes.EV_KEY, key.ec.value, 1)
		elif state is KeyState.RELEASED:
			self.uinput.write(ecodes.EV_KEY, key.ec.value, 0)
		self.uinput.syn()

	def click(self, key, state=None):

		self.enqueue(self._click, key)

	def get_button_state(self, button):

		active_keys = set()
		for dev in self.pointer_devs:
			active_keys |= set(dev.active_keys())
		if button.ec in active_keys:
			return KeyState.PRESSED
		else:
			return KeyState.RELEASED
Ejemplo n.º 29
0
class BaseDriver(ABC):
    @abstractmethod
    def __init__(self):
        self.create_node = True
        self.name = None
        self.input_dev = None
        self.capabilities = None
        self.vendor = None
        self.product = None
        self.version = None
        self.phys = None
        self.bustype = None
        self.auto_triggers = dict()

    def create(self):
        self.input_dev = UInput(self.capabilities,
                                self.name,
                                vendor=self.vendor,
                                product=self.product,
                                version=self.version,
                                phys=self.phys)

        return self

    # Central write handler
    # handles all kind of writes, single writes and auto triggers
    def write(self,
              config: Config,
              drivers,
              e_type=None,
              e_sub_type=None,
              value=None,
              meta=None,
              periodical=0,
              frequency=0,
              event=None):

        auto_trigger_button_pressed, auto_trigger_button_released, auto_trigger_button_toggle, auto_trigger_press_ongoing, no_auto_trigger = self._calculate_toggle_state(
            e_sub_type, periodical, value)

        # Normal state first which is 90% of all triggers hence needs to be processed first
        if no_auto_trigger:
            self.input_dev.write(e_type, int(e_sub_type), value)
            return self

        # Autotrigger states
        elif auto_trigger_button_pressed:
            if len(self.auto_triggers) == 0:
                asyncio.ensure_future(self._loop_periodical())
            elif e_sub_type in self.auto_triggers:
                return self
            self._register_auto_trigger(e_sub_type, e_type, frequency, value)
            self.input_dev.write(e_type, int(e_sub_type), value)

        elif auto_trigger_press_ongoing:
            return self

        elif auto_trigger_button_released:
            self._deregister_auto_trigger(e_sub_type)
            self.input_dev.write(e_type, int(e_sub_type), value)

        elif auto_trigger_button_toggle:
            self._toggle_auto_trigger(e_sub_type, e_type, frequency, value)

        else:
            self.input_dev.write(e_type, int(e_sub_type), value)

        return self

    # calculate the toggle states for the auto fire function
    def _calculate_toggle_state(self, e_sub_type, periodical, value):
        no_auto_trigger = periodical == 0
        auto_trigger_button_pressed = periodical == 1 and value == 1
        auto_trigger_button_released = periodical == 1 and value == 0
        auto_trigger_press_ongoing = periodical == 1 and value > 1 and e_sub_type in self.auto_triggers
        auto_trigger_button_toggle = periodical == 2 and value == 1
        return auto_trigger_button_pressed, auto_trigger_button_released, auto_trigger_button_toggle, auto_trigger_press_ongoing, no_auto_trigger

    def syn(self):
        self.input_dev.syn()
        return self

    def verify(self):
        self.input_dev.verify()
        return self

    def close(self):
        if self.input_dev is not None:
            self.input_dev.close()

    def transfer_dev_data(self):
        self.phys = self.input_dev.phys
        self.name = self.input_dev.name
        self.version = self.input_dev.version
        self.vendor = self.input_dev.vendor
        self.bustype = self.input_dev.bustype
        self.product = self.input_dev.product

    # periodic loop which triggers the autofire
    async def _loop_periodical(self):
        while len(self.auto_triggers) > 0:
            await asyncio.sleep(STD_DELAY)
            try:
                for key in self.auto_triggers:
                    now = datetime.now().microsecond
                    val = self.auto_triggers[key]
                    access_difference = round(
                        abs(now - val[LAST_ACCESSED]) / 1000)
                    if access_difference > val[FREQUENCY]:
                        val[LAST_ACCESSED] = now
                        val[TRIGGER]()
                        # 100ms delay because some emulators do not accept input which is lower than that
                        # between button up and button down
                        await asyncio.sleep(STD_DELAY)
                        val[TRIGGER_OFF]()
            # we would get somtimes a collection changed exception, we safely can ignore that
            # (race condition due to external delete and await in the loop
            except Exception as e:
                pass

    def _deregister_auto_trigger(self, e_sub_type):
        del self.auto_triggers[e_sub_type]

    # registers an auto trigger into our trigger dictionary
    def _register_auto_trigger(self, e_sub_type, e_type, frequency, value):
        self.auto_triggers[e_sub_type] = dict()
        self.auto_triggers[e_sub_type][FREQUENCY] = frequency
        self.auto_triggers[e_sub_type][TRIGGER] = lambda: self._button_down(
            e_type, e_sub_type, value)
        self.auto_triggers[e_sub_type][TRIGGER_OFF] = lambda: self._button_up(
            e_type, e_sub_type, value)
        self.auto_triggers[e_sub_type][LAST_ACCESSED] = datetime.now(
        ).microsecond

    # simulates a button down
    def _button_down(self, e_type, e_sub_type, value):
        self.input_dev.write(e_type, int(e_sub_type), value)
        self.syn()

    # simulates a button up
    def _button_up(self, e_type, e_sub_type, value):
        self.input_dev.write(e_type, int(e_sub_type), 0)
        self.syn()

    # toggles the auto triggers either on or off
    def _toggle_auto_trigger(self, e_sub_type, e_type, frequency, value):
        if e_sub_type in self.auto_triggers:
            del self.auto_triggers[e_sub_type]
        else:
            if len(self.auto_triggers) == 0:
                asyncio.ensure_future(self._loop_periodical())
            self._register_auto_trigger(e_sub_type, e_type, frequency, value)
Ejemplo n.º 30
0
def run_evdev():
    # Define the events that will be triggered by the custom xinput device that we will create
    pen_events = {
        # Defining a pressure sensitive pen tablet area with 2 stylus buttons and no eraser
        ecodes.EV_KEY:
        get_required_ecodes(),
        ecodes.EV_ABS: [
            #AbsInfo input: value, min, max, fuzz, flat, resolution
            (ecodes.ABS_X,
             AbsInfo(0, 0, args['pen']['max_x'], 0, 0,
                     args['pen']['resolution'])),
            (ecodes.ABS_Y,
             AbsInfo(0, 0, args['pen']['max_y'], 0, 0,
                     args['pen']['resolution'])),
            (ecodes.ABS_PRESSURE,
             AbsInfo(0, 0, args['pen']['max_pressure'], 0, 0, 0)),
            (ecodes.ABS_TILT_X,
             AbsInfo(0, 0, args['pen']['max_tilt_x'], 0, 0, 0)),
            (ecodes.ABS_TILT_Y,
             AbsInfo(0, 0, args['pen']['max_tilt_y'], 0, 0, 0)),
        ],
    }

    # Try to get a reference to the USB we need
    dev = usb.core.find(idVendor=args['<usb_vendor_id>'],
                        idProduct=args['<usb_product_id>'])
    if not dev:
        raise Exception(
            "Could not find device. The device may be unavailable or already open"
        )

    # Forcefully claim the interface from any other script that might have been using it
    for cfg in dev:
        for interface in cfg:
            if dev.is_kernel_driver_active(interface.index):
                dev.detach_kernel_driver(interface.index)
                usb.util.claim_interface(dev, interface.index)
                if not args['--quiet-mode']:
                    print("grabbed interface {}".format(interface.index))

    # The method needs to be called or otherwise the tablet may not be in the correct mode
    # and no output might be seen from the first endpoint after a tablet reboot
    read_tablet_info(dev)

    # Seems like we need to try and read atleast once from the second endpoint on the device
    # or else the output from the first endpoint may get blocked on a tablet reboot
    try:
        endpoint_1 = dev[0][(1, 0)][0]
        data = dev.read(endpoint_1.bEndpointAddress, endpoint_1.wMaxPacketSize)
    except:
        pass

    # Create a virtual pen in /dev/input/ so that it shows up as a XInput device
    global vpen
    vpen = UInput(events=pen_events, name=args['<xinput_name>'], version=0x3)

    # Get a reference to the end that the tablet's output will be read from
    usb_endpoint = dev[0][(0, 0)][0]

    xinput_map_to_display()

    # Read the tablet output in an infinite loop
    while True:
        try:
            # Read data from the USB
            data = dev.read(usb_endpoint.bEndpointAddress,
                            usb_endpoint.wMaxPacketSize)

            # Only calculate these values if the event is a pen event and not tablet event
            if data[1] in [128, 129, 130, 131, 132, 133]:
                # Calculate the values
                pen_x = (data[3] << 8) + (data[2])
                pen_y = (data[5] << 8) + data[4]
                pen_pressure = (data[7] << 8) + data[6]
                pen_tilt_x = data[10] >= 128 and (data[10] - 256) or data[10]
                pen_tilt_y = data[11] >= 128 and (data[11] - 256) or data[11]

                # Send data to the Xinput device so that cursor responds
                vpen.write(ecodes.EV_ABS, ecodes.ABS_X, pen_x)
                vpen.write(ecodes.EV_ABS, ecodes.ABS_Y, pen_y)
                vpen.write(ecodes.EV_ABS, ecodes.ABS_PRESSURE, pen_pressure)
                vpen.write(ecodes.EV_ABS, ecodes.ABS_TILT_X, pen_tilt_x)
                vpen.write(ecodes.EV_ABS, ecodes.ABS_TILT_Y, pen_tilt_y)

                if args['--print-calculated-data'] and not args['--quiet-mode']:
                    print("X {} Y {} PRESS {}          ".format(
                        pen_x,
                        pen_y,
                        pen_pressure,
                    ),
                          end='\r')

            # Reset any actions because this code means that nothing is happening
            if data[1] == 128:
                run_action('')

            # Pen click
            if data[1] == 129:
                run_action(args['actions'].get('pen_touch', ''))

            # Pen button 1
            if data[1] == 130:
                run_action(args['actions'].get('pen_button_1', ''))

            # Pen button 1 with pen touch
            if data[1] == 131:
                run_action(args['actions'].get('pen_button_1_touch', ''))

            # Pen button 2
            if data[1] == 132:
                run_action(args['actions'].get('pen_button_2', ''))

            # Pen button 2 with pen touch
            if data[1] == 133:
                run_action(args['actions'].get('pen_button_2_touch', ''))

            # Tablet buttons
            if data[1] == 224:
                global previous_tablet_btn
                if data[4]:
                    btn_index = int(math.log(data[4], 2))
                    if previous_tablet_btn != data[4] and args['actions'].get(
                            'tablet_buttons', ''):
                        run_action(
                            args['actions']['tablet_buttons'][btn_index])
                    previous_tablet_btn = btn_index
                else:
                    run_action('')
                    previous_tablet_btn = 0

            # Scrollbar
            if data[1] == 240:
                global previous_scrollbar_state
                scrollbar_state = data[5]

                if scrollbar_state:
                    if previous_scrollbar_state:
                        if scrollbar_state > previous_scrollbar_state:
                            run_action(args['actions'].get(
                                'tablet_scrollbar_increase', ''))
                        elif scrollbar_state < previous_scrollbar_state:
                            run_action(args['actions'].get(
                                'tablet_scrollbar_decrease', ''))

                    if scrollbar_state != previous_scrollbar_state and args[
                            'actions'].get('tablet_scrollbar', ''):
                        run_action(
                            args['actions']['tablet_scrollbar'][scrollbar_state
                                                                - 1])
                else:
                    run_action('')

                previous_scrollbar_state = scrollbar_state

            # Dispatch the evdev events
            vpen.syn()

            if args['--print-usb-data']:
                print_raw_data(data, 6)

        except usb.core.USBError as e:
            if e.args[0] == 19:
                vpen.close()
                raise Exception('Device has been disconnected')

            # The usb read probably timed out for this cycle. Thats ok
            data = None
Ejemplo n.º 31
0
class WebKeyboard(WebSocket):
    k_alnum_lc = "qwertyuiopasdfghjklzxcvbnm1234567890"
    k_al_uc = "QWERTYUIOPASDFGHJKLZXCVBNM"
    k_rest = {
        " ": {
            "key": "KEY_SPACE"
        },
        "!": {
            "key": "KEY_1",
            "mod": "KEY_LEFTSHIFT"
        },
        "@": {
            "key": "KEY_2",
            "mod": "KEY_LEFTSHIFT"
        },
        "#": {
            "key": "KEY_3",
            "mod": "KEY_LEFTSHIFT"
        },
        "$": {
            "key": "KEY_4",
            "mod": "KEY_LEFTSHIFT"
        },
        "%": {
            "key": "KEY_5",
            "mod": "KEY_LEFTSHIFT"
        },
        "^": {
            "key": "KEY_6",
            "mod": "KEY_LEFTSHIFT"
        },
        "&": {
            "key": "KEY_7",
            "mod": "KEY_LEFTSHIFT"
        },
        "*": {
            "key": "KEY_8",
            "mod": "KEY_LEFTSHIFT"
        },
        "(": {
            "key": "KEY_9",
            "mod": "KEY_LEFTSHIFT"
        },
        ")": {
            "key": "KEY_0",
            "mod": "KEY_LEFTSHIFT"
        },
        "-": {
            "key": "KEY_MINUS"
        },
        "_": {
            "key": "KEY_MINUS",
            "mod": "KEY_LEFTSHIFT"
        },
        "=": {
            "key": "KEY_EQUAL"
        },
        "+": {
            "key": "KEY_EQUAL",
            "mod": "KEY_LEFTSHIFT"
        },
        "[": {
            "key": "KEY_LEFTBRACE"
        },
        "{": {
            "key": "KEY_LEFTBRACE",
            "mod": "KEY_LEFTSHIFT"
        },
        "]": {
            "key": "KEY_RIGHTBRACE"
        },
        "}": {
            "key": "KEY_RIGHTBRACE",
            "mod": "KEY_LEFTSHIFT"
        },
        ";": {
            "key": "KEY_SEMICOLON"
        },
        ":": {
            "key": "KEY_SEMICOLON",
            "mod": "KEY_LEFTSHIFT"
        },
        "'": {
            "key": "KEY_APOSTROPHE"
        },
        "\"": {
            "key": "KEY_APOSTROPHE",
            "mod": "KEY_LEFTSHIFT"
        },
        "\\": {
            "key": "KEY_BACKSLASH"
        },
        "|": {
            "key": "KEY_BACKSLASH",
            "mod": "KEY_LEFTSHIFT"
        },
        ",": {
            "key": "KEY_COMMA"
        },
        "<": {
            "key": "KEY_COMMA",
            "mod": "KEY_LEFTSHIFT"
        },
        ".": {
            "key": "KEY_DOT"
        },
        ">": {
            "key": "KEY_DOT",
            "mod": "KEY_LEFTSHIFT"
        },
        "/": {
            "key": "KEY_SLASH"
        },
        "?": {
            "key": "KEY_SLASH",
            "mod": "KEY_LEFTSHIFT"
        },
        "`": {
            "key": "KEY_GRAVE"
        },
        "~": {
            "key": "KEY_GRAVE",
            "mod": "KEY_LEFTSHIFT"
        },
    }

    def connected(self):
        print(self.address, "connected")
        self.ui = UInput()

    def handle(self):
        print(self.data)

        self.key = self.mod = None
        # Set key value from valid KEY_s directly
        if "KEY_" in self.data:
            try:
                self.key = getattr(eco, self.data)
                self.key = self.data
            except (AttributeError):
                print("No such key " + self.data)
                pass
        # Set key value to alphanumeric lowercase
        elif self.data[0] in self.k_alnum_lc:
            self.key = "KEY_" + self.data[0].upper()
        # Set key value to alpha uppercase with modifier Shift key
        elif self.data[0] in self.k_al_uc:
            self.mod = "KEY_LEFTSHIFT"
            self.key = "KEY_" + self.data[0]
        # Set key value to one of k_rest with or without modifier Shift key
        elif self.data[0] in self.k_rest:
            self.key = self.k_rest[self.data[0]]["key"]
            if "mod" in self.k_rest[self.data[0]]:
                self.mod = self.k_rest[self.data[0]]["mod"]

        # Send recorded key to system along with modifier if available
        if self.key is not None:
            if self.mod is not None:
                self.ui.write(eco.EV_KEY, getattr(eco, self.mod), 1)
            self.ui.write(eco.EV_KEY, getattr(eco, self.key), 1)
            self.ui.write(eco.EV_KEY, getattr(eco, self.key), 0)
            self.ui.syn()
            if self.mod is not None:
                self.ui.write(eco.EV_KEY, getattr(eco, self.mod), 0)

        # Echo received data back to client
        self.send_message(self.data)

    def handle_close(self):
        print(self.address, "disconnected")
        self.ui.close()
Ejemplo n.º 32
0
        elif data[0] == 2:  # Tablet button actions
            # press types: 0 - up; 1 - down; 2 - hold
            press_type = 1
            if data[1] == 2:  # First button
                pressed = 0
            elif data[1] == 4:  # Second button
                pressed = 1
            elif data[3] == 44:  # Third button
                pressed = 2
            elif data[3] == 43:  # Fourth button
                pressed = 3
            else:
                press_type = 0
            key_codes = config["actions"]["tablet_buttons"][pressed].split("+")
            for key in key_codes:
                act = ecodes.ecodes[key]
                vbtn.write(ecodes.EV_KEY, act, press_type)
        # Flush
        vpen.syn()
        vbtn.syn()
    except usb.core.USBError as e:
        if e.args[0] == 19:
            vpen.close()
            raise Exception("Device has been disconnected")
    except KeyboardInterrupt:
        vpen.close()
        vbtn.close()
        sys.exit("\nDriver terminated successfully.")
    except Excception as e:
        print(e)
Ejemplo n.º 33
0
class PPMDecoder(object):
    """Decodes the audio data into PPM pulse data, and then into uinput
    joystick events.
    """
    def __init__(self, rate):
        """
        Parameters
        ----------
        rate : int
            sample rate
        """
        self._rate = float(rate)
        self._lf = None
        self._threshold = 15000
        self._last_edge = None
        self._ch = None

        # Size in sampling intervals, of the frame space marker
        self._marker = int(2.0 * 0.0025 * self._rate)

        # Mapping of channels to events
        self._mapping = {
            0: ecodes.ABS_X,
            1: ecodes.ABS_Y,
            2: ecodes.ABS_Z,
            3: ecodes.ABS_THROTTLE
        }

        events = [(v, (0, 255, 5, 0)) for v in self._mapping.values()]

        self._ev = UInput(name='ppmadapter',
                          events={
                              ecodes.EV_ABS: events,
                              ecodes.EV_KEY: {
                                  288: 'BTN_JOYSTICK'
                              }
                          })

    def __enter__(self):
        return self

    def __exit__(self, type, value, tb):
        self._ev.close()

    def feed(self, data):
        """Feeds the decoder with a block of sample data.

        The data should be integer values, and should only be a single channel.

        Parameters
        ----------
        data : list
            sample data
        """
        sync_req = False
        for i in range(len(data)):
            this_edge = data[i] > self._threshold
            if self._last_edge is None:
                self._last_edge = this_edge
                continue

            if this_edge and not self._last_edge:
                # rising
                if self._lf is not None:
                    sync_req |= self.signal(i - self._lf)
            elif not this_edge and self._last_edge:
                # falling
                self._lf = i

            self._last_edge = this_edge

        if sync_req:
            self._ev.syn()

        if self._lf is not None:
            self._lf = self._lf - len(data)
            if self._lf < (-self._rate):
                print("Lost sync")
                self._ch = None
                self._lf = None

    def signal(self, w):
        """Process the detected signal.

        The signal is the number of sampling intervals between the falling
        edge and the rising edge.

        Parameters
        ----------
        w : int
            signal width

        Returns
        -------
        bool
            does uinput require sync
        """
        if w > self._marker:
            if self._ch is None:
                print("Got sync")
            self._ch = 0
            return False

        if self._ch is None or self._ch not in self._mapping:
            return False

        duration = float(w) / self._rate
        value = int((duration - 0.0007) * 1000 * 255)
        self._ev.write(ecodes.EV_ABS, self._mapping[self._ch], value)

        self._ch += 1

        return True
Ejemplo n.º 34
0
                # Need to emit event BTN_TOOL_PEN = 1 when pen is hovering,
                # this way the system can recognize the device as a tablet.
                # https://www.kernel.org/doc/Documentation/input/event-codes.txt
                vpen.write(ecodes.EV_KEY, ecodes.BTN_TOOL_PEN, 1)
                pen_hovering = True

            pen_x = (data[5] * 255 + data[4])
            pen_y = config['pen']['max_y'] - (data[3] * 255 + data[2])
            pen_pressure = data[7] * 255 + data[6]
            vpen.write(ecodes.EV_ABS, ecodes.ABS_X, pen_x)
            vpen.write(ecodes.EV_ABS, ecodes.ABS_Y, pen_y)
            vpen.write(ecodes.EV_ABS, ecodes.ABS_PRESSURE, pen_pressure)
            if data[1] == 193:  # Pen touch
                vpen.write(ecodes.EV_KEY, ecodes.BTN_TOUCH, 1)
            else:
                vpen.write(ecodes.EV_KEY, ecodes.BTN_TOUCH, 0)
            # Flush
            vpen.syn()

    except usb.core.USBError as e:
        if pen_hovering:
            # Need to emit event BTN_TOOL_PEN = 0 when pen is not hovering,
            # just for compliance with the specs.
            # https://www.kernel.org/doc/Documentation/input/event-codes.txt
            vpen.write(ecodes.EV_KEY, ecodes.BTN_TOOL_PEN, 0)
            pen_hovering = False
            vpen.syn()
        if e.args[0] == 19:
            vpen.close()
            raise Exception('Device has been disconnected')
Ejemplo n.º 35
0
class emulatedDevice(object):
    cap = {
            e.EV_KEY: [e.BTN_MOUSE, e.BTN_WHEEL, e.BTN_MIDDLE, e.BTN_RIGHT, e.BTN_SIDE,
                e.KEY_ZOOM, e.KEY_ZOOMIN, e.KEY_ZOOMOUT, e.KEY_ZOOMRESET,
                e.KEY_LEFTCTRL, e.KEY_SLASH, e.KEY_RIGHTBRACE,
                e.KEY_LEFT, e.KEY_UP, e.KEY_RIGHT, e.KEY_DOWN],
            e.EV_ABS: [
                (e.ABS_X, AbsInfo(value=0, min=0, max=1023, fuzz=0, flat=0, resolution=0)),
                (e.ABS_Y, AbsInfo(value=0, min=0, max=599, fuzz=0, flat=0, resolution=0))
            ],
            e.EV_REL: [
                e.REL_WHEEL, e.REL_HWHEEL
            ],
            e.EV_MSC: [e.MSC_SCAN]
    }
    def __init__(self, id):
        print('Creating emulated touch device #%d' % id)
        self.id = id
        self.dev = UInput(self.cap, name='pytouchd-emutouchdev-%d' % id, version=0x0001)
        self.state = (0, 0, 0)  # (x, y, which key pressed)
        self.keydownstamp = None
        self.movebuffer = []

    def close(self):
        global debug
        if debug:
            print('Closing emulated touch device #%d' % self.id)
        self.dev.close()
        del(self)

    def release(self, key=None, quiet=False):
        global debug
        if not self.state[2] and key is None:
            return
        if debug and not quiet:
            print('REL #%d' % self.id)
        if key is None:
            key = self.state[2]
            noupdate = True
        else:
            noupdate = False
        self.dev.write(e.EV_KEY, key, 0)
        self.dev.syn()
        if not noupdate:
            self.state = (self.state[0], self.state[1], 0)

    def press(self, key=e.BTN_MOUSE, quiet=False, *, value=1):
        global debug
        if not key in self.cap[e.EV_KEY]:
            raise ValueError('Keycode %d is not valid!' % key)
        if debug and not quiet:
            print('PRS #%d, %d' % (self.id, key))
        self.dev.write(e.EV_KEY, key, value)
        self.dev.syn()
        self.state = (self.state[0], self.state[1], key)

    def move(self, x, y, quiet=False):
        global debug
        if debug and not quiet:
            print('MOV #%d, (%d, %d)' % (self.id, x, y))
        self.dev.write(e.EV_ABS, e.ABS_X, x)
        self.dev.write(e.EV_ABS, e.ABS_Y, y)
        self.dev.syn()
        self.state = (x, y, self.state[2])

    def scroll(self, amount, horizontal=False):
        if horizontal:
            wheel = e.REL_HWHEEL
        else:
            wheel = e.REL_WHEEL
        self.dev.write(e.EV_REL, wheel, amount)
        self.dev.syn()

    def runBuffer(self):
        global debug
        if debug:
            print('BUF #%d' % self.id)
        for event in self.movebuffer:
            # TODO new-old handle function
            self.handle(event, True)
        self.movebuffer = []
Ejemplo n.º 36
0
def monitor_events(logf):
    active_keys = []
    key_input = UInput()
    device_path = ""
    devices = [InputDevice(path) for path in list_devices()]
    for device in devices:
        if device.info.vendor == 6127 and device.info.product == 24646 and "input0" in device.phys:
            device_path = device.path

    def inject_input(*args):
        if len(args) > 0:
            for key in args:
                key_input.write(ecodes.EV_KEY, key, 1)
            for key in args:
                key_input.write(ecodes.EV_KEY, key, 0)
            key_input.syn()

    if device_path != "":
        device = InputDevice(device_path)
        device.grab()
        for event in device.read_loop():
            if event.type == ecodes.EV_KEY:
                if event.value == 1:
                    active_keys.append(event.code)
                elif event.value == 0:
                    if len(active_keys) == 1:
                        # Pinch in/out
                        if active_keys[0] == 29:
                            inject_input(ecodes.KEY_LEFTCTRL)
                        # 4 Finger swipe up
                        elif active_keys[0] == 125:
                            inject_input(ecodes.KEY_LEFTMETA,
                                         ecodes.KEY_PAGEDOWN)
                        # 3 Finger swipe down
                        elif active_keys[0] == 109:
                            inject_input(ecodes.KEY_LEFTMETA)
                        # 3 Finger swipe up
                        elif active_keys[0] == 104:
                            inject_input(ecodes.KEY_LEFTMETA, ecodes.KEY_UP)
                    elif len(active_keys) == 2:
                        # Top to Bottom edge Swipe
                        if [56, 62] == active_keys:
                            inject_input(ecodes.KEY_LEFTALT, ecodes.KEY_F4)
                        # Rotate Clockwise
                        elif [29, 52] == active_keys:
                            inject_input(ecodes.KEY_LEFTCTRL, ecodes.KEY_R)
                        # Rotate Counterclockwise
                        elif [29, 51] == active_keys:
                            inject_input(ecodes.KEY_LEFTSHIFT,
                                         ecodes.KEY_LEFTCTRL, ecodes.KEY_R)
                        # 3 Finger swipe left
                        elif [56, 105] == active_keys:
                            inject_input(ecodes.KEY_LEFTMETA, ecodes.KEY_LEFT)
                        # 3 Finger swipe right
                        elif [56, 106] == active_keys:
                            inject_input(ecodes.KEY_LEFTMETA, ecodes.KEY_RIGHT)
                        # 4 Finger swipe down
                        elif [125, 32] == active_keys:
                            inject_input(ecodes.KEY_LEFTMETA,
                                         ecodes.KEY_PAGEUP)
                        # 4 Finger swipe right
                        elif [125, 38] == active_keys:
                            inject_input(ecodes.KEY_LEFTMETA, ecodes.KEY_L)
                    elif len(active_keys) == 3:
                        # Left edge swipe
                        if [29, 125, 14] == active_keys:
                            inject_input(ecodes.KEY_LEFTMETA, ecodes.KEY_A)
                        # Right edge swipe
                        elif [56, 125, 193] == active_keys:
                            inject_input(ecodes.KEY_LEFTMETA, ecodes.KEY_TAB)
                        # Top edge swipe
                        elif [29, 125, 193] == active_keys:
                            inject_input(ecodes.KEY_LEFTMETA, ecodes.KEY_DOWN)
                    active_keys.clear()
    else:
        key_input.close()
Ejemplo n.º 37
0
class K:
  __space_mode_map = {
    ecodes.KEY_1: [ecodes.KEY_1, True],
    ecodes.KEY_2: [ecodes.KEY_2, True],
    ecodes.KEY_3: [ecodes.KEY_3, True],
    ecodes.KEY_4: [ecodes.KEY_4, True],
    ecodes.KEY_5: [ecodes.KEY_5, True],
    ecodes.KEY_6: [ecodes.KEY_6, True],
    ecodes.KEY_7: [ecodes.KEY_7, True],
    ecodes.KEY_8: [ecodes.KEY_8, True],
    ecodes.KEY_9: [ecodes.KEY_9, True],
    ecodes.KEY_0: [ecodes.KEY_0, True],

    ecodes.KEY_Q: [ecodes.KEY_1, True],
    ecodes.KEY_W: [ecodes.KEY_2, True],
    ecodes.KEY_E: [ecodes.KEY_3, True],
    ecodes.KEY_R: [ecodes.KEY_4, True],
    ecodes.KEY_T: [ecodes.KEY_5, True],
    ecodes.KEY_Y: [ecodes.KEY_6, True],
    ecodes.KEY_U: [ecodes.KEY_7, True],
    ecodes.KEY_I: [ecodes.KEY_8, True],
    ecodes.KEY_O: [ecodes.KEY_9, True],
    ecodes.KEY_P: [ecodes.KEY_0, True],

    ecodes.KEY_A: [ecodes.KEY_MINUS, True],
    ecodes.KEY_S: [ecodes.KEY_MINUS, False],
    ecodes.KEY_D: [ecodes.KEY_LEFTBRACE, False],
    ecodes.KEY_F: [ecodes.KEY_RIGHTBRACE, False],
    ecodes.KEY_G: [ecodes.KEY_APOSTROPHE, False],
    ecodes.KEY_H: [ecodes.KEY_APOSTROPHE, True],
    ecodes.KEY_J: [ecodes.KEY_LEFTBRACE, True],
    ecodes.KEY_K: [ecodes.KEY_RIGHTBRACE, True],
    ecodes.KEY_L: [ecodes.KEY_GRAVE, True],
    ecodes.KEY_SEMICOLON: [ecodes.KEY_SEMICOLON, True],

    #ecodes.KEY_Z: used for control mode!
    ecodes.KEY_X: [ecodes.KEY_GRAVE, False],
    ecodes.KEY_C: [ecodes.KEY_BACKSLASH, False],
    ecodes.KEY_V: [ecodes.KEY_EQUAL, False],
    ecodes.KEY_B: [ecodes.KEY_BACKSLASH, True],

    ecodes.KEY_N: [ecodes.KEY_EQUAL, True],
    ecodes.KEY_M: [ecodes.KEY_SPACE, False],
    ecodes.KEY_COMMA: [ecodes.KEY_COMMA, True],
    ecodes.KEY_DOT: [ecodes.KEY_DOT, True],
    ecodes.KEY_SLASH: [ecodes.KEY_SLASH, True],
  }

  __tenkey_mode_map = {
    ecodes.KEY_Q: [ecodes.KEY_1, False],
    ecodes.KEY_W: [ecodes.KEY_2, False],
    ecodes.KEY_E: [ecodes.KEY_3, False],
    ecodes.KEY_R: [ecodes.KEY_4, False],
    ecodes.KEY_T: [ecodes.KEY_5, False],
    ecodes.KEY_Y: [ecodes.KEY_6, False],
    ecodes.KEY_U: [ecodes.KEY_7, False],
    ecodes.KEY_I: [ecodes.KEY_8, False],
    ecodes.KEY_O: [ecodes.KEY_9, False],
    ecodes.KEY_P: [ecodes.KEY_0, False],

    ecodes.KEY_A: [ecodes.KEY_TAB, False],
    ecodes.KEY_S: [ecodes.KEY_DELETE, False],
    ecodes.KEY_D: [ecodes.KEY_BACKSPACE, False],
    ecodes.KEY_F: [ecodes.KEY_ESC, False],
    ecodes.KEY_G: [ecodes.KEY_F1, False],
    ecodes.KEY_H: [ecodes.KEY_LEFT, False],
    ecodes.KEY_J: [ecodes.KEY_DOWN, False],
    ecodes.KEY_K: [ecodes.KEY_UP, False],
    ecodes.KEY_L: [ecodes.KEY_RIGHT, False],
    ecodes.KEY_SEMICOLON: [ecodes.KEY_ENTER, False],
  }

  def __init__(self):
    self.sink = UInput()
    self.reset_state()
    self.buffered_event = None

  def set_state(self, state):
    self.__state = state

  def pop_state(self):
    self.__state.state_exit()
    self.__state.popState()

  def emit_with_space_mode(self, event):
    if event.event.scancode in self.__space_mode_map:
      translated_event = self.__space_mode_map[event.event.scancode]
      if translated_event[1]:
        self.sink.write(ecodes.EV_KEY, ecodes.KEY_LEFTSHIFT, 1)
        self.sink.write(ecodes.EV_KEY, ecodes.KEY_LEFTSHIFT, 2)
        self.sink.write(ecodes.EV_KEY, translated_event[0], 1)
        self.sink.write(ecodes.EV_KEY, translated_event[0], 0)
        self.sink.write(ecodes.EV_KEY, ecodes.KEY_LEFTSHIFT, 0)
      else:
        self.sink.write(ecodes.EV_KEY, translated_event[0], 1)
        self.sink.write(ecodes.EV_KEY, translated_event[0], 0)
    else:
      self.sink.write(ecodes.EV_KEY, event.event.scancode, 1)
      self.sink.write(ecodes.EV_KEY, event.event.scancode, 0)

  def emit_with_tenkey_mode(self, event):
    if event.event.scancode in self.__tenkey_mode_map:
      translated_event = self.__tenkey_mode_map[event.event.scancode]
      if translated_event[1]:
        self.sink.write(ecodes.EV_KEY, ecodes.KEY_LEFTSHIFT, 1)
        self.sink.write(ecodes.EV_KEY, ecodes.KEY_LEFTSHIFT, 2)
        self.sink.write(ecodes.EV_KEY, translated_event[0], 1)
        self.sink.write(ecodes.EV_KEY, translated_event[0], 0)
        self.sink.write(ecodes.EV_KEY, ecodes.KEY_LEFTSHIFT, 0)
      else:
        self.sink.write(ecodes.EV_KEY, translated_event[0], 1)
        self.sink.write(ecodes.EV_KEY, translated_event[0], 0)
    else:
      self.sink.write(ecodes.EV_KEY, event.event.scancode, 1)
      self.sink.write(ecodes.EV_KEY, event.event.scancode, 0)

  def emit_with_control_mode(self, event):
    self.sink.write(ecodes.EV_KEY, ecodes.KEY_LEFTCTRL, 1)
    self.sink.write(ecodes.EV_KEY, ecodes.KEY_LEFTCTRL, 2)
    if self.__space_mode:
      self.emit_with_space_mode(event)
    elif self.__tenkey_mode:
      #print("control tenkey")
      self.emit_with_tenkey_mode(event)
    else:
      self.sink.write(ecodes.EV_KEY, event.event.scancode, 1)
      self.sink.write(ecodes.EV_KEY, event.event.scancode, 0)
    self.sink.write(ecodes.EV_KEY, ecodes.KEY_LEFTCTRL, 0)

  def emit_with_shift_mode(self, event):
    self.sink.write(ecodes.EV_KEY, ecodes.KEY_LEFTSHIFT, 1)
    self.sink.write(ecodes.EV_KEY, ecodes.KEY_LEFTSHIFT, 2)
    self.sink.write(ecodes.EV_KEY, event.event.scancode, 1)
    self.sink.write(ecodes.EV_KEY, event.event.scancode, 0)
    self.sink.write(ecodes.EV_KEY, ecodes.KEY_LEFTSHIFT, 0)

  def emit_with_normal_mode(self, event):
    self.sink.write(ecodes.EV_KEY, event.event.scancode, event.event.keystate)

  def emit(self, event):
    #if event.event.scancode == ecodes.KEY_CAPSLOCK:# or event.event.scancode == ecodes.KEY_SYSRQ:
    #  self.sink.write(ecodes.EV_KEY, ecodes.KEY_F1, event.event.keystate)
    #elif event.event.scancode == ecodes.KEY_LEFTMETA and event.event.keystate == events.KeyEvent.key_hold:
    #  pass
    #  #self.sink.write(ecodes.EV_KEY, ecodes.KEY_F1, event.event.keystate)
    if self.__control_mode and event.event.keystate != events.KeyEvent.key_up:
      self.emit_with_control_mode(event)
    elif self.__space_mode and event.event.keystate != events.KeyEvent.key_up:
      self.emit_with_space_mode(event)
    elif self.__shift_mode and event.event.keystate != events.KeyEvent.key_up:
      self.emit_with_shift_mode(event)
    elif self.__tenkey_mode and event.event.keystate != events.KeyEvent.key_up:
      self.emit_with_tenkey_mode(event)
    else:
      self.emit_with_normal_mode(event)

    self.sink.syn()

  def emit_space(self):
    self.sink.write(ecodes.EV_KEY, ecodes.KEY_SPACE, 1)
    self.sink.write(ecodes.EV_KEY, ecodes.KEY_SPACE, 0)
    self.sink.syn()

  def emit_z(self):
    self.sink.write(ecodes.EV_KEY, ecodes.KEY_Z, 1)
    self.sink.write(ecodes.EV_KEY, ecodes.KEY_Z, 0)
    self.sink.syn()

  def emit_slash(self):
    if self.__space_mode:
      self.sink.write(ecodes.EV_KEY, ecodes.KEY_LEFTSHIFT, 1)
      self.sink.write(ecodes.EV_KEY, ecodes.KEY_LEFTSHIFT, 2)
      self.sink.write(ecodes.EV_KEY, ecodes.KEY_SLASH, 1)
      self.sink.write(ecodes.EV_KEY, ecodes.KEY_SLASH, 0)
      self.sink.write(ecodes.EV_KEY, ecodes.KEY_LEFTSHIFT, 0)
    else:
      self.sink.write(ecodes.EV_KEY, ecodes.KEY_SLASH, 1)
      self.sink.write(ecodes.EV_KEY, ecodes.KEY_SLASH, 0)

    self.sink.syn()

  def emit_as_buffered(self, event):
    self.buffered_event = event

  def emit_buffered(self):
    self.emit(self.buffered_event)
    self.buffered_event = None

  def buffer(self, event):
    self.emit_as_buffered(event)

  def flush(self):
    self.emit_buffered()

  def reset_state(self):
    self.__buffer = None
    self.__space_mode = False
    self.__control_mode = False
    self.__meta_mode = False
    self.__tenkey_mode = False
    self.__shift_mode = False

  def space_mode(self, flag):
    self.__space_mode = flag

  def control_mode(self, flag):
    self.__control_mode = flag

  def meta_mode(self, flag):
    self.__meta_mode = flag

  def shift_mode(self, flag):
    self.__shift_mode = flag

  def tenkey_mode(self, flag):
    self.__tenkey_mode = flag

  def close(self):
    self.sink.close()
Ejemplo n.º 38
0
#!/usr/bin/python3
#
# evdev_keyboard.py
# Injecting input events. Display "hello" on the console
#
# http://python-evdev.readthedocs.org/en/latest/tutorial.html

import time
from evdev import UInput, ecodes as e

ui = UInput()
# accepts only KEY_* events by default
ui.write(e.EV_KEY, e.KEY_H, 1)  # KEY_H down
ui.write(e.EV_KEY, e.KEY_H, 0)  # KEY_H up
time.sleep(0.1)
ui.write(e.EV_KEY, e.KEY_E, 1)
ui.write(e.EV_KEY, e.KEY_E, 0)
time.sleep(0.1)
ui.write(e.EV_KEY, e.KEY_L, 1)
ui.write(e.EV_KEY, e.KEY_L, 0)
time.sleep(0.1)
ui.write(e.EV_KEY, e.KEY_L, 1)
ui.write(e.EV_KEY, e.KEY_L, 0)
time.sleep(0.1)
ui.write(e.EV_KEY, e.KEY_O, 1)
ui.write(e.EV_KEY, e.KEY_O, 0)
time.sleep(0.1)
ui.syn()
ui.close()
Ejemplo n.º 39
0
class HIDMapperController (object):

    def __init__ (self):
        self._profile = None
        self._running = False
        self._input_devices = None
        self._file_descriptors = None
        self._allowed_event_types = None
        self._event_status = None
        self._gesture_codes = deque()
        self._last_queued = None
        self._virtual_input = None
        self._matcher = None

    @property
    def profile (self, profile_obj):
        self._profile=profile_obj

    @profile.setter
    def profile (self, profile_obj):
        self._profile=profile_obj

    def _prepare_device (self):
        #print("device: %s" % self._profile.device.name)
        self._event_status = {key:0 for key in self._profile.device.get_events_supported()}
        #print("Events supported",self._event_status)
        self._allowed_event_types = set([getattr(ecodes,i[-1].split(':')[0]) for i in self._event_status])
        self._input_devices = map(InputDevice, self._profile.device.devices)
        self._file_descriptors = { dev.fd: i for i, dev in enumerate(self._input_devices) }
        
        print("Mappings for '" + self._profile.name+"' " + '-'*30)
        for k,v in sorted(self._profile.mapping.items()):
            print(str(k.replace("EV_KEY:KEY_","").replace("ENTER","<-'").replace("APOSTROPHE","'").replace(",","")).lower().rjust(20)+" as "+(', '.join(v)).replace("r_hand_tap_", "").replace("_vs_thumb", ""))
            
        # Prepare virtual device for event injection
        capabilities = {}
        for ev_chain in self._profile.mapping:
            for k in re.split('[+,]', ev_chain):
                et, ec = k.split(':', 1)
                etype = ecodes.ecodes[et]
                if etype in capabilities:
                    capabilities[etype].append(ecodes.ecodes[ec])
                else:
                    capabilities[etype] = [ ecodes.ecodes[ec] ]
        #print("Capabilities", capabilities)
        self._virtual_input = UInput(events = capabilities)

        # Prepare matcher
        self._matcher = Matcher(self._profile)


    def start (self):
        """
            Start capturing from the device(s) of the current profile
        """
        self._prepare_device()
        try:
            for dev in self._input_devices: dev.grab()
        except Exception as e:
            print("Unable to grab device", e)
        self._running = True
        
        spawn(self._capture_loop)
        spawn(self._process_loop)
        sleep(0)

        
    def stop (self):
        """
            Stop capturing and release the device(s)
        """
        self._running = False 
        try:
            for dev in self._input_devices: dev.ungrab()
        except:
            pass
    
        if self._virtual_input:
            self._virtual_input.close()


    def _capture_loop (self):
        try:
            devices = {dev.fd : dev for dev in self._input_devices}
            while self._running:
                r,_,_ = select(devices, [], [], timeout=self._profile.double_click_timeout/1000.0)
                for fd in r:
                    for event in devices[fd].read():
                        #print("Lo que", event)
                        if self.is_allowed_event(event, fd):
                            event_code = self.get_event_code(event, fd)
                            if event.value == 1:
                                #print("Pressed!", event_code)
                                self.set_event_status(event_code, 1)
                                #print("Statuses", self._event_status)
                                self._store_gestures()
                                                                
                            elif event.value == 0:
                                #print("Released!", event_code)
                                self.set_event_status(event_code, 0)
                                #print("Statuses", self._event_status)
                                #self._store_gestures()
                            else:
                                print("What is this?",event)
        except:
            self._running = False
            traceback.print_exc()


    def _store_gestures (self):
        """
            Fetch current gestures, select those allowed in the profile and store them in the queue of gesture codes
        """

        filtered_gestures = set([
            gesture for gesture in self.get_current_gestures() if gesture in self._profile.gestures
        ])
        if not filtered_gestures:
            return

        if filtered_gestures != self._last_queued:
            distance = 1.0
            if self._last_queued:
                distance = self._profile.get_gestures_distance(filtered_gestures, self._last_queued)
                #print("Distance is", distance)
            self._last_queued = filtered_gestures

            if distance <= 0.5:
                try:
                    timestamp, last_queued = self._gesture_codes.pop()
                    #print("Time interval", time.time() - timestamp)
                    if time.time() - timestamp > self._profile.double_click_timeout/6000.0:
                        self._gesture_codes.append((timestamp, last_queued))
                except IndexError:
                    pass #print("Empty queue!")

        self._gesture_codes.append((time.time(), filtered_gestures))


    def _process_loop (self):
        """
            TODO: Process the queue of gestures and inject remapped events
        """
        while self._running:
            try:
                timestamp, prefixes = self._gesture_codes.pop()
                reduced = self._profile.reduce_gestures(prefixes)
                self._matcher.add_prefix(timestamp, reduced)

                # With every possible option if any...
                for candidate, output_event in self._matcher.get_matching_codes():
                    #print("Candidate(s)",candidate, "would generate events(s)", output_event)
                    self._inject_event(output_event)
            except IndexError:
                pass
            except:
                print("Processing error")
                traceback.print_exc()

            sleep(self._profile.double_click_timeout/5000.0)


    def _inject_event (self, event_codes):
        """
            Insert one or several events in the virtual input
            event_code is a string, normally, that contains an event, like 'EV_KEY:KEY_A'
            event_code can have a sequence of events, like 'EV_KEY:KEY_A,EV_KEY:KEY_B,EV_KEY:KEY_C'
            event_code can contain chained events, to make combination of keys, like: 'EV_KEY:KEY_LEFTCTRL+EV_KEY:KEY_C'
        """
        if isinstance(event_codes, str):
            event_codes = event_codes.split(",")
        for event_code_combo in event_codes:
            for operation in [1, 0]:
                for event_code in event_code_combo.split("+"):
                    if isinstance(event_code, str):
                        event_code = event_code.split(':')
                    if len(event_code) == 1 and ':' in event_code[0]:
                        event_code = event_code[0].split(':')
                    etype = ecodes.ecodes[event_code[0]]
                    ecode = ecodes.ecodes[event_code[1]]
                    
                    #names = ecodes.bytype[etype][ecode]
                    #if not isinstance(names, list):
                    #    names = [names]
                    #print("Inject event {} {}".format(names[0], "pressed" if operation==1 else "released"))
                    
                    self._virtual_input.write(etype, ecode, operation)  # pressed
        self._virtual_input.syn()

    def find_event_keys (self, event_code, where):
        """
            param event_code: Event code to search (as a tuple)
            param where: A dictionary whose keys are event codes
            Search and returns a list of matching keys for an event code, in the dictionary or list 'where'
        """
        matches = []
        event_keys = [event_code]
        if len(event_code) < 2:
            for dev_num, _ in enumerate(self._file_descriptors):
                event_keys.append(('DEV_%d' % dev_num, event_code[0]))
        else:
            event_keys.append((event_code[1],))
        for ev in event_keys:
            if ev in where:
                matches.append(ev)
        return matches


    def is_allowed_event (self, event, fd = None):
        """
            Decide if the controller must capture this event or not 
        """
        if event.type in self._allowed_event_types:
            event_code = self.get_event_code(event)
            if fd is not None:
                key1 = ('DEV_%d' % self._file_descriptors[fd], event_code[0])
                key2 = event_code
                return key1 in self._event_status or key2 in self._event_status
            else:
                if not event_code in self._event_status:
                    for dev_num, _ in enumerate(self._file_descriptors):
                        key = ('DEV_%d' % dev_num, event_code[0])
                        if key in self._event_status:
                            return True
                else:
                    return True
        
        return False


    def get_event_code (self, event, fd = None):
        """
            Returns the event code (type+code), prefixed by the device if 'fd' is present
        """
        name = ecodes.bytype[event.type][event.code]
        #print("Event code from", event, "is", name)
        if isinstance(name, list):
            name = name[0]
        event_code = "%s:%s" % (ecodes.EV[event.type], name)
        if fd is not None:
            return ('DEV_%d' % self._file_descriptors[fd], event_code)
        return (event_code, )

    
    def get_current_gestures (self, where_to_find = None, current_gestures = None):
        """
            return: A set of gestures activated at this moment
        """
        if where_to_find is None:
            where_to_find = self._profile.device.gestures_lut

        if current_gestures is None:
            current_gestures = set([])
        for ev in self._event_status:
            if self._event_status[ev]:  # Is pressed?
                for found in self.find_event_keys(ev, where_to_find):
                    result = where_to_find[found]
                    if isinstance(result, dict):
                        self.get_current_gestures(result, current_gestures)
                    else:
                        current_gestures.add(result)
            
        return current_gestures
                            

    def set_event_status (self, event_code, status):
        """
            Sets the status for every event that matches the event_code
        """
        for ev_key in self.find_event_keys(event_code, self._event_status):
            self._event_status[ev_key] = status    


    def __del__ (self):
        print("Stopping capturer")
        if self._running:
            self.stop()
Ejemplo n.º 40
0
    e.KEY_T, e.KEY_S, e.KEY_A, e.KEY_B, e.KEY_C, e.KEY_D, e.KEY_E, e.KEY_F,
    e.KEY_G, e.KEY_H, e.KEY_ENTER
]


async def VKeybord(ui, name, longPause, shortPause, keys):
    while True:
        await asyncio.sleep(longPause)

        for key in keys:
            print(name, e.KEY[key])
            # accepts only KEY_* events by default
            ui.write(e.EV_KEY, key, 1)  # KEY_A down
            ui.write(e.EV_KEY, key, 0)  # KEY_A up
            ui.syn()
            await asyncio.sleep(shortPause)


loop = asyncio.get_event_loop()
try:
    asyncio.ensure_future(VKeybord(ui, "first", 1, 0.08, A))
    asyncio.ensure_future(VKeybord(ui2, "second", 2.3, 0.0715, B))
    loop.run_forever()
except KeyboardInterrupt:
    pass
finally:
    print("Closing Loop")
    loop.close()
    ui.close()
    ui2.close()
Ejemplo n.º 41
0

i = 5
moves = 100000

print("Go to 2048 window. ["+str(i)+"] secs.")
while i != 0:
	print(" " + str(i))
	time.sleep(1)
	i -= 1

print("Commencing...\n")

keys = ["e.KEY_UP", "e.KEY_DOWN", "e.KEY_LEFT", "e.KEY_RIGHT"]
keys = [105, 106, 103, 108]

# random.choice(foo)
ui = UInput()
current_title = GetActiveWindowTitle()
if 'Firefox' in current_title:
    while moves != 0:
        temp_key = random.choice(keys)
        send_keys(ui, temp_key)
        time.sleep(0.1)
        moves -= 1
    print("Done")
else:
	print("You're not on the firefox window.")

ui.close()
Ejemplo n.º 42
0
        y -= SCROLL_SENSITIVITY

    # mouse button 4 and 5
    if mouse_event.type == EV_KEY and mouse_event.code == BTN_SIDE and mouse_event.value == 1:
        keyboard.write(EV_KEY, KEY_M, 1)
        keyboard.write(EV_KEY, KEY_M, 0)
        keyboard.syn()
        sleep(0.05)
        mouse.write(EV_KEY, BTN_LEFT, 1)
        mouse.write(EV_SYN, SYN_REPORT, 0)
        sleep(0.05)
        mouse.write(EV_KEY, BTN_LEFT, 0)
        mouse.write(EV_SYN, SYN_REPORT, 0)
        ignore_count = 2
    elif mouse_event.type == EV_KEY and mouse_event.code == BTN_EXTRA and mouse_event.value == 1:
        keyboard.write(EV_KEY, KEY_H, 1)
        keyboard.write(EV_KEY, KEY_H, 0)
        keyboard.write(EV_KEY, KEY_A, 1)
        keyboard.write(EV_KEY, KEY_A, 0)
        keyboard.syn()
        sleep(0.05)
        mouse.write(EV_KEY, BTN_LEFT, 1)
        mouse.write(EV_SYN, SYN_REPORT, 0)
        sleep(0.05)
        mouse.write(EV_KEY, BTN_LEFT, 0)
        mouse.write(EV_SYN, SYN_REPORT, 0)
        ignore_count = 2

keyboard.close()
mouse.close()
Ejemplo n.º 43
0
class EvKeyboard(object):
    def __init__(self):

        self.translate = XTranslate()
        self.translate.install_layout_hook()
        self.keyboards = self.detect_keyboards()
        # ~ self.device = UInput.from_device(*self.keyboards, name='macpy keyboard')
        self.device = UInput(name='macpy keyboard')
        self.queue = Queue()
        self.mainloop = Thread(target=self._mainloop,
                               name='EvKeyboard mainloop')
        self.mainloop.start()
        self.selector = DefaultSelector()
        self.events = Thread(target=self._events, name='EvKeyboard event loop')
        self.stop = False
        self.hook = False
        self.hook_callback = None
        self.hotkeys = False
        self.hk_callbacks = {}
        self.input = deque(maxlen=128)
        self.hotstrings = {}

    def detect_keyboards(self):

        keyboards = []
        for device in list_devices():
            input_device = InputDevice(device)
            if ecodes.EV_KEY in input_device.capabilities():
                keyboards.append(input_device)
        return tuple(keyboards)

    def _mainloop(self):

        while True:
            method, args = self.queue.get()
            if method is None:
                break
            try:
                method(*args)
            except Exception as e:
                print(
                    'Error in EvKeyboard mainloop: \n', ''.join(
                        traceback.format_exception(type(e), e,
                                                   e.__traceback__)))
            self.queue.task_done()

    def enqueue(self, method, *args):

        self.queue.put_nowait((method, args))

    def close(self):

        self.device.close()
        self.enqueue(None)
        self.translate.close()
        self.stop = True

    def get_key_state(self, key):

        keycodes = [
            keycode for keyboard in self.keyboards
            for keycode in keyboard.active_keys()
        ]
        if key.ec.value in keycodes:
            return KeyState(True)
        else:
            return KeyState(False)

    def _events(self):

        for keyboard in self.keyboards:
            self.selector.register(keyboard, EVENT_READ)
        while not self.stop:
            for key, mask in self.selector.select(timeout=0.3):
                device = key.fileobj
                for event in device.read():
                    event = categorize(event)
                    if isinstance(event, KeyEvent):
                        if event.keystate < 2:
                            key = Key.from_ec(event.event.code)
                            keystate = (KeyState.PRESSED if event.keystate == 1
                                        else KeyState.RELEASED)
                            mask = 0
                            leds = [
                                led for keyboard in self.keyboards
                                for led in keyboard.leds()
                            ]
                            if ecodes.LED_NUML in leds:
                                mask |= self.translate.lockmask['NUMLOCK']
                            if ecodes.LED_CAPSL in leds:
                                mask |= self.translate.lockmask['CAPSLOCK']
                            if ecodes.LED_SCROLLL in leds:
                                mask |= self.translate.lockmask['SCROLLLOCK']
                            keycodes = [
                                keycode for keyboard in self.keyboards
                                for keycode in keyboard.active_keys()
                            ]
                            for keycode in keycodes:
                                for mod, codes in self.translate.modmap.items(
                                ):
                                    if ((keycode + self.translate.min_keycode)
                                            in codes):
                                        mask |= self.translate.modmask[mod]
                            if self.translate.modmap['ALTGR'][0] in keycodes:
                                mask |= self.translate.modmask['ALTGR']
                            keysym, mods, locks = self.translate. \
                             keycode_to_keysym(
                              key.ec + self.translate.min_keycode, mask)
                            char = None
                            if keysym in PRINT:
                                char = PRINT[keysym]
                            if self.hook:
                                self.enqueue(
                                    self.hook_callback,
                                    KeyboardEvent(key, keystate, char, mods,
                                                  locks))
                            if self.hotkeys and event.keystate == 1:
                                modifiers = set()
                                for mod, state in mods.items():
                                    if state:
                                        modifiers.add(
                                            getattr(Modifiers, mod)[0])
                                hotkey = HotKey(key, modifiers)
                                if hotkey in self.hk_callbacks:
                                    self.enqueue(self.hk_callbacks[hotkey],
                                                 hotkey)
                            if self.hotstrings and event.keystate == 0 and char:
                                self.input.append(char)
                                string = ''.join(self.input)
                                for hotstring in self.hotstrings:
                                    if (string.endswith(hotstring.string)
                                            and not hotstring.triggers):
                                        retstring = HotString(
                                            hotstring.string,
                                            hotstring.triggers)
                                        self.enqueue(
                                            self.hotstrings[hotstring],
                                            retstring)
                                        self.input.clear()
                                    elif (string[:-1].endswith(
                                            hotstring.string) and string[-1]
                                          in hotstring.triggers):
                                        retstring = HotString(
                                            hotstring.string,
                                            hotstring.triggers, string[-1])
                                        self.enqueue(
                                            self.hotstrings[hotstring],
                                            retstring)
                                        self.input.clear()

    def install_keyboard_hook(self, callback, grab=False):

        if not self.events.is_alive():
            self.events.start()
        self.hook = True
        self.hook_callback = callback

    def uninstall_keyboard_hook(self):

        self.hook = False

    def init_hotkeys(self):

        if not self.events.is_alive():
            self.events.start()
        self.hotkeys = True

    def uninit_hotkeys(self):

        self.hotkeys = False
        self.hk_callbacks = {}

    def register_hotkey(self, key, modifiers, callback):

        mods = set()
        for mod in modifiers:
            for Mod in Modifiers:
                if mod in Mod:
                    mods.add(Mod[0])
        hotkey = HotKey(key, mods)
        self.hk_callbacks[hotkey] = callback
        return hotkey

    def unregister_hotkey(self, hotkey):

        if hotkey in self.hk_callbacks:
            del self.hk_callbacks[hotkey]

    def register_hotstring(self, string, triggers, callback):

        if self.hook:
            hotstring = HotString(string, triggers)
            self.hotstrings[hotstring] = callback
            return hotstring
        else:
            raise RuntimeError('Keyboard hook not installed')

    def unregister_hotstring(self, hotstring):

        if hotstring in self.hotstrings:
            del self.hotstrings[hotstring]

    def _press_key(self, key):

        self.device.write(ecodes.EV_KEY, key.ec, 1)

    def _release_key(self, key):

        self.device.write(ecodes.EV_KEY, key.ec, 0)

    def keypress(self, key, state=None):

        if state is None:
            self.enqueue(self._press_key, key)
            self.enqueue(self._release_key, key)
        elif state == KeyState.PRESSED:
            self.enqueue(self._press_key, key)
        elif state == KeyState.RELEASED:
            self.enqueue(self._release_key, key)
        else:
            raise TypeError('Invalid state')
        self.enqueue(self.device.syn)

    def _type(self, string):

        for char in string:
            keysym = self.translate.lookup_keysym(char)
            keycode, mods, locks = self.translate.keysym_to_keycode(keysym)
            key = Key.from_ec(keycode - self.translate.min_keycode)
            if any(mods):
                for mod, state in mods.items():
                    if state:
                        modifier = getattr(Modifiers, mod, None)
                        if modifier:
                            self._press_key(modifier[0])
            self._press_key(key)
            self._release_key(key)
            if any(mods):
                for mod, state in mods.items():
                    if state:
                        modifier = getattr(Modifiers, mod, None)
                        if modifier:
                            self._release_key(modifier[0])
            self.device.syn()

    def type(self, string):

        self.enqueue(self._type, string)
Ejemplo n.º 44
-3
def executaAcao(tecla):
        ui = UInput()
        print tecla
        ui.write(e.EV_KEY, e.ecodes[tecla], 1) #key down
        ui.write(e.EV_KEY, e.ecodes[tecla], 0) #key up
        ui.syn()
        ui.close()