• evdev module-----uinput.py


    uinput.py , python code of evdev module

      1 # encoding: utf-8
      2 
      3 import os
      4 import stat
      5 import time
      6 
      7 from evdev import _uinput
      8 from evdev import ecodes, util, device
      9 
     10 
     11 class UInputError(Exception):
     12     pass
     13 
     14 
     15 class UInput(object):
     16     '''
     17     A userland input (an `uinput`) device and that can inject input
     18     events directly into the linux input subsystem.
     19     '''
     20 
     21     __slots__ = (
     22         'name', 'vendor', 'product', 'version', 'bustype',
     23         'events', 'devnode', 'fd', 'device',
     24     )
     25 
     26     def __init__(self,
     27                  events=None,
     28                  name='py-evdev-uinput',
     29                  vendor=0x1, product=0x1, version=0x1, bustype=0x3,
     30                  devnode='/dev/uinput'):
     31         '''
     32 
     33         :param events: the event types and codes that the uinput
     34                        device will be able to inject - defaults to all
     35                        key codes.
     36 
     37         :type events: dictionary of event types mapping to lists of
     38                       event codes
     39 
     40         :param name: the name of the input device
     41         :param vendor:  vendor identifier
     42         :param product: product identifier
     43         :param version: version identifier
     44         :param bustype: bustype identifier
     45 
     46         .. note:: If you do not specify any events, the uinput device
     47                   will by default be able to inject only KEY_* and
     48                   BTN_* event codes.
     49 
     50         '''
     51 
     52         self.name = name         #: uinput device name
     53         self.vendor = vendor     #: device vendor identifier
     54         self.product = product   #: device product identifier
     55         self.version = version   #: device version identifier
     56         self.bustype = bustype   #: device bustype - eg. ``BUS_USB``
     57         self.devnode = devnode   #: uinput device node - eg. ``/dev/uinput/``
     58 
     59         if not events:
     60              events = {ecodes.EV_KEY: ecodes.keys.keys()}
     61 
     62         # the min, max, fuzz and flat values for the absolute axis for
     63         # a given code
     64         absinfo = []
     65 
     66         self._verify()
     67 
     68         #: open write-only, nonblocking file descriptor to the uinput devnode
     69         self.fd = _uinput.open(devnode)
     70 
     71         # set device capabilities
     72         for etype, codes in events.items():
     73             for code in codes:
     74                 # handle max,min,fuzz,flat
     75                 if isinstance(code, (tuple, list, device.AbsInfo)):
     76                     # flatten (ABS_Y, (0,255,0,0)) to (ABS_Y,0,255,0,0)
     77                     f = [code[0]] ; f += code[1]
     78                     absinfo.append(f)
     79                     code = code[0]
     80 
     81                 #:todo: a lot of unnecessary packing/unpacking
     82                 _uinput.enable(self.fd, etype, code)
     83 
     84         # create uinput device
     85         _uinput.create(self.fd, name, vendor, product, version, bustype, absinfo)
     86 
     87         #: an :class:`InputDevice <evdev.device.InputDevice>` instance
     88         # to the fake input device
     89         self.device = self._find_device()
     90 
     91     def __enter__(self):
     92         return self
     93 
     94     def __exit__(self, type, value, tb):
     95         self.close()
     96 
     97     def __repr__(self):
     98         # :todo:
     99         v = (repr(getattr(self, i)) for i in
    100              ('name', 'bustype', 'vendor', 'product', 'version'))
    101         return '{0}({1})'.format(self.__class__.__name__, ', '.join(v))
    102 
    103     def __str__(self):
    104         msg = ('name "{0}", bus "{1}", vendor "{2:04x}", product "{3:04x}", version "{4:04x}"
    '
    105                'event types: {5}')
    106 
    107         evtypes = [i[0] for i in self.capabilities(True).keys()]
    108         msg = msg.format(self.name, ecodes.BUS[self.bustype], self.vendor, self.product,
    109                          self.version, ' '.join(evtypes))
    110 
    111         return msg
    112 
    113     def close(self):
    114         # close InputDevice object
    115         self.device.close()
    116 
    117         # destroy the uinput device
    118         if self.fd and self.fd > 0:
    119             _uinput.close(self.fd)
    120 
    121     def write_event(self, event):
    122         '''
    123         Inject an input event into the input subsystem. Events are
    124         queued until a synchronization event is received.
    125 
    126         :param event: InputEvent instance or an object with an
    127                       ``event`` attribute (:class:`KeyEvent
    128                       <evdev.events.KeyEvent>`, :class:`RelEvent
    129                       <evdev.events.RelEvent>` etc)
    130 
    131         Example::
    132 
    133             ev = InputEvent(1334414993, 274296, ecodes.EV_KEY, ecodes.KEY_A, 1)
    134             ui.write_event(ev)
    135         '''
    136 
    137         if hasattr(event, 'event'):
    138             event = event.event
    139 
    140         self.write(event.type, event.code, event.value)
    141 
    142     def write(self, etype, code, value):
    143         '''
    144 
    145         Inject an input event into the input subsystem. Events are
    146         queued until a synchronization event is received.
    147 
    148         :param etype: event type (eg. ``EV_KEY``)
    149         :param code:  event code (eg. ``KEY_A``)
    150         :param value: event value (eg. 0 1 2 - depends on event type)
    151 
    152         Example::
    153 
    154             ui.write(e.EV_KEY, e.KEY_A, 1) # key A - down
    155             ui.write(e.EV_KEY, e.KEY_A, 0) # key A - up
    156         '''
    157 
    158         _uinput.write(self.fd, etype, code, value)
    159 
    160     def syn(self):
    161         ''' Inject a ``SYN_REPORT`` event into the input subsystem. Events
    162         queued by :func:`write()` will be fired. If applicable, events
    163         will be merged into an 'atomic' event.'''
    164 
    165         _uinput.write(self.fd, ecodes.EV_SYN, ecodes.SYN_REPORT, 0)
    166 
    167     def capabilities(self, verbose=False, absinfo=True):
    168         '''See :func:`capabilities <evdev.device.InputDevice.capabilities>`.'''
    169         return self.device.capabilities(verbose, absinfo)
    170 
    171     def _verify(self):
    172         ''' Verify that an uinput device exists and is readable and writable
    173         by our process.'''
    174 
    175         try:
    176             m = os.stat(self.devnode)[stat.ST_MODE]
    177             if not stat.S_ISCHR(m):
    178                 raise
    179         except:
    180             msg = '"{0}" does not exist or is not a character device file '
    181                   '- verify that the uinput module is loaded'
    182             raise UInputError(msg.format(self.devnode))
    183 
    184         if not os.access(self.devnode, os.W_OK):
    185             msg = '"{0}" cannot be opened for writing'
    186             raise UInputError(msg.format(self.devnode))
    187 
    188         if len(self.name) > _uinput.maxnamelen:
    189             msg = 'uinput device name must not be longer than {0} characters'
    190             raise UInputError(msg.format(_uinput.maxnamelen))
    191 
    192     def _find_device(self):
    193         #:todo: use udev
    194 
    195         #:bug: the device node might not be immediately avaiable
    196         time.sleep(0.1)
    197 
    198         for fn in util.list_devices('/dev/input/'):
    199             d = device.InputDevice(fn)
    200             if d.name == self.name:
    201                  return d
  • 相关阅读:
    学习windows的半天+学习Git分布式系统的半天
    输出从1加到100的结果、打印100以内的质数、计算一个文件中的每个英文单词出现的次数
    Linux操作系统--初级--进程管理的命令
    Linux操作系统--初级--防火墙
    Linux操作系统--初级--dns服务
    Linux操作系统--初级--网络安全基础
    Linux操作系统--初级--进程管理
    Linux操作系统--初级--Linux网络
    Linux操作系统--初级--Linux磁盘管理
    Linux操作系统--初级--Linux的用户与用户组(权限管理)
  • 原文地址:https://www.cnblogs.com/winditsway/p/5665830.html
Copyright © 2020-2023  润新知