evdev-0.4.7/0000770000175000017500000000000012454333505011706 5ustar gvgv00000000000000evdev-0.4.7/evdev/0000770000175000017500000000000012454333505013017 5ustar gvgv00000000000000evdev-0.4.7/evdev/__init__.py0000600000175000017500000000101412402430674015115 0ustar gvgv00000000000000# encoding: utf-8 #-------------------------------------------------------------------------- # Gather everything into a convenient namespace #-------------------------------------------------------------------------- from evdev.device import DeviceInfo, InputDevice, AbsInfo from evdev.events import InputEvent, KeyEvent, RelEvent, SynEvent, AbsEvent, event_factory from evdev.uinput import UInput, UInputError from evdev.util import list_devices, categorize, resolve_ecodes from evdev import ecodes from evdev import ff evdev-0.4.7/evdev/_ecodes.py0000640000175000017500000000034712236546445015004 0ustar gvgv00000000000000KEY = ABS = REL = SW = MSC = LED = REP = SND = SYN = FF = FF_STATUS = BTN_A = KEY_A = 1 EV_KEY = EV_ABS = EV_REL = EV_SW = EV_MSC = EV_LED = EV_REP = 1 EV_SND = EV_SYN = EV_FF = EV_FF_STATUS = FF_STATUS = 1 KEY_MAX, KEY_CNT = 1, 2evdev-0.4.7/evdev/_input.py0000640000175000017500000000000012236546445014663 0ustar gvgv00000000000000evdev-0.4.7/evdev/_uinput.py0000640000175000017500000000000012236546445015050 0ustar gvgv00000000000000evdev-0.4.7/evdev/device.py0000640000175000017500000002361712417321363014636 0ustar gvgv00000000000000# encoding: utf-8 import os from select import select from collections import namedtuple from evdev import _input, _uinput, ecodes, util from evdev.events import InputEvent #-------------------------------------------------------------------------- _AbsInfo = namedtuple('AbsInfo', ['value', 'min', 'max', 'fuzz', 'flat', 'resolution']) _KbdInfo = namedtuple('KbdInfo', ['repeat', 'delay']) _DeviceInfo = namedtuple('DeviceInfo', ['bustype', 'vendor', 'product', 'version']) class AbsInfo(_AbsInfo): ''' A ``namedtuple`` for storing absolut axis information - corresponds to the ``input_absinfo`` struct: **value** Latest reported value for the axis. **min** Specifies minimum value for the axis. **max** Specifies maximum value for the axis. **fuzz** Specifies fuzz value that is used to filter noise from the event stream. **flat** Values that are within this value will be discarded by joydev interface and reported as 0 instead. **resolution** Specifies resolution for the values reported for the axis. Resolution for main axes (``ABS_X, ABS_Y, ABS_Z``) is reported in units per millimeter (units/mm), resolution for rotational axes (``ABS_RX, ABS_RY, ABS_RZ``) is reported in units per radian. .. note: The input core does not clamp reported values to the ``[minimum, maximum]`` limits, such task is left to userspace. ''' def __str__(self): return 'val {}, min {}, max {}, fuzz {}, flat {}, res {}'.format(*self) class KbdInfo(_KbdInfo): ''' Keyboard repeat rate: **repeat** Keyboard repeat rate in characters per second. **delay** Amount of time that a key must be depressed before it will start to repeat (in milliseconds). ''' def __str__(self): return 'repeat {}, delay {}'.format(*self) class DeviceInfo(_DeviceInfo): def __str__(self): msg = 'bus: {:04x}, vendor {:04x}, product {:04x}, version {:04x}' return msg.format(*self) class InputDevice(object): ''' A linux input device from which input events can be read. ''' __slots__ = ('fn', 'fd', 'info', 'name', 'phys', '_rawcapabilities', 'version', 'ff_effects_count') def __init__(self, dev): ''' :param dev: path to input device ''' #: Path to input device. self.fn = dev #: A non-blocking file descriptor to the device file. self.fd = os.open(dev, os.O_RDWR | os.O_NONBLOCK) # Returns (bustype, vendor, product, version, name, phys, capabilities). info_res = _input.ioctl_devinfo(self.fd) #: A :class:`DeviceInfo ` instance. self.info = DeviceInfo(*info_res[:4]) #: The name of the event device. self.name = info_res[4] #: The physical topology of the device. self.phys = info_res[5] #: The evdev protocol version. self.version = _input.ioctl_EVIOCGVERSION(self.fd) #: The raw dictionary of device capabilities - see `:func:capabilities()`. self._rawcapabilities = _input.ioctl_capabilities(self.fd) #: The number of force feedback effects the device can keep in its memory. self.ff_effects_count = _input.ioctl_EVIOCGEFFECTS(self.fd) def __del__(self): if hasattr(self, 'fd') and self.fd is not None: try: self.close() except OSError: pass def _capabilities(self, absinfo=True): res = {} for etype, ecodes in self._rawcapabilities.items(): for code in ecodes: l = res.setdefault(etype, []) if isinstance(code, tuple): if absinfo: a = code[1] # (0, 0, 0, 255, 0, 0) i = AbsInfo(*a) l.append((code[0], i)) else: l.append(code[0]) else: l.append(code) return res def capabilities(self, verbose=False, absinfo=True): ''' Return the event types that this device supports as a mapping of supported event types to lists of handled event codes. Example:: { 1: [272, 273, 274], 2: [0, 1, 6, 8] } If ``verbose`` is ``True``, event codes and types will be resolved to their names. Example:: { ('EV_KEY', 1): [('BTN_MOUSE', 272), ('BTN_RIGHT', 273), ('BTN_MIDDLE', 273)], ('EV_REL', 2): [('REL_X', 0), ('REL_Y', 1), ('REL_HWHEEL', 6), ('REL_WHEEL', 8)] } Unknown codes or types will be resolved to ``'?'``. If ``absinfo`` is ``True``, the list of capabilities will also include absolute axis information in the form of :class:`AbsInfo` instances:: { 3: [ (0, AbsInfo(min=0, max=255, fuzz=0, flat=0)), (1, AbsInfo(min=0, max=255, fuzz=0, flat=0)) ]} Combined with ``verbose`` the above becomes:: { ('EV_ABS', 3): [ (('ABS_X', 0), AbsInfo(min=0, max=255, fuzz=0, flat=0)), (('ABS_Y', 1), AbsInfo(min=0, max=255, fuzz=0, flat=0)) ]} ''' if verbose: return dict(util.resolve_ecodes(self._capabilities(absinfo))) else: return self._capabilities(absinfo) def leds(self, verbose=False): ''' Return currently set LED keys. For example:: [0, 1, 8, 9] If ``verbose`` is ``True``, event codes are resolved to their names. Unknown codes are resolved to ``'?'``. For example:: [('LED_NUML', 0), ('LED_CAPSL', 1), ('LED_MISC', 8), ('LED_MAIL', 9)] ''' leds = _input.get_sw_led_snd(self.fd, ecodes.EV_LED) if verbose: return [(ecodes.LED[l] if l in ecodes.LED else '?', l) for l in leds] return leds def set_led(self, led_num, value): ''' Set the state of the selected LED. For example:: device.set_led(ecodes.LED_NUML, 1) .. ''' _uinput.write(self.fd, ecodes.EV_LED, led_num, value) def __eq__(self, other): '''Two devices are equal if their :data:`info` attributes are equal.''' return self.info == other.info def __str__(self): msg = 'device {}, name "{}", phys "{}"' return msg.format(self.fn, self.name, self.phys) def __repr__(self): msg = (self.__class__.__name__, self.fn) return '{}({!r})'.format(*msg) def close(self): if self.fd > -1: try: os.close(self.fd) finally: self.fd = -1 def fileno(self): ''' Return the file descriptor to the open event device. This makes it possible to pass pass ``InputDevice`` instances directly to :func:`select.select()` and :class:`asyncore.file_dispatcher`.''' return self.fd def read_one(self): ''' Read and return a single input event as an instance of :class:`InputEvent `. Return ``None`` if there are no pending input events. ''' # event -> (sec, usec, type, code, val) event = _input.device_read(self.fd) if event: return InputEvent(*event) def read_loop(self): '''Enter an endless ``select()`` loop that yields input events.''' while True: r, w, x = select([self.fd], [], []) for event in self.read(): yield event def read(self): ''' Read multiple input events from device. Return a generator object that yields :class:`InputEvent ` instances. ''' # events -> [(sec, usec, type, code, val), ...] events = _input.device_read_many(self.fd) for i in events: yield InputEvent(*i) def grab(self): ''' Grab input device using ``EVIOCGRAB`` - other applications will be unable to receive events until the device is released. Only one process can hold a ``EVIOCGRAB`` on a device. .. warning:: Grabbing an already grabbed device will raise an ``IOError``.''' _input.ioctl_EVIOCGRAB(self.fd, 1) def ungrab(self): '''Release device if it has been already grabbed (uses `EVIOCGRAB`). .. warning:: Releasing an already released device will raise an ``IOError('Invalid argument')``.''' _input.ioctl_EVIOCGRAB(self.fd, 0) def upload_effect(self, effect): '''Upload a force feedback effect to a force feedback device.''' data = bytes(buffer(effect)[:]) ff_id = _input.upload_effect(self.fd, data) return ff_id def erase_effect(self, ff_id): '''Erase a force effect from a force feedback device. This also stops the effect.''' _input.erase_effect(self.fd, ff_id) @property def repeat(self): '''Get or set the keyboard repeat rate (in characters per minute) and delay (in milliseconds).''' return KbdInfo(*_input.ioctl_EVIOCGREP(self.fd)) @repeat.setter def repeat(self, value): return _input.ioctl_EVIOCSREP(self.fd, *value) def active_keys(self, verbose=False): ''' Return currently active keys. Example:: [1, 42] If ``verbose`` is ``True``, key codes are resolved to their verbose names. Unknown codes are resolved to ``'?'``. For example:: [('KEY_ESC', 1), ('KEY_LEFTSHIFT', 42)] ''' active_keys = _input.ioctl_EVIOCGKEY(self.fd) if verbose: return [(ecodes.KEY[k] if k in ecodes.KEY else '?', k) for k in active_keys] return active_keys evdev-0.4.7/evdev/ecodes.c0000640000175000017500000007376512454331560014445 0ustar gvgv00000000000000 #include #ifdef __FreeBSD__ #include #else #include #endif /* Automatically generated by evdev.genecodes */ /* Generated on Linux 3.17.7-300.fc21.x86_64 #1 SMP Wed Dec 17 03:08:44 UTC 2014 x86_64 */ #define MODULE_NAME "_ecodes" #define MODULE_HELP "linux/input.h macros" static PyMethodDef MethodTable[] = { { NULL, NULL, 0, NULL} }; #if PY_MAJOR_VERSION >= 3 static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, MODULE_NAME, MODULE_HELP, -1, /* m_size */ MethodTable, /* m_methods */ NULL, /* m_reload */ NULL, /* m_traverse */ NULL, /* m_clear */ NULL, /* m_free */ }; #endif static PyObject * moduleinit(void) { #if PY_MAJOR_VERSION >= 3 PyObject* m = PyModule_Create(&moduledef); #else PyObject* m = Py_InitModule3(MODULE_NAME, MethodTable, MODULE_HELP); #endif if (m == NULL) return NULL; PyModule_AddIntMacro(m, EV_VERSION); PyModule_AddIntMacro(m, EV_SYN); PyModule_AddIntMacro(m, EV_KEY); PyModule_AddIntMacro(m, EV_REL); PyModule_AddIntMacro(m, EV_ABS); PyModule_AddIntMacro(m, EV_MSC); PyModule_AddIntMacro(m, EV_SW); PyModule_AddIntMacro(m, EV_LED); PyModule_AddIntMacro(m, EV_SND); PyModule_AddIntMacro(m, EV_REP); PyModule_AddIntMacro(m, EV_FF); PyModule_AddIntMacro(m, EV_PWR); PyModule_AddIntMacro(m, EV_FF_STATUS); PyModule_AddIntMacro(m, EV_MAX); PyModule_AddIntMacro(m, EV_CNT); PyModule_AddIntMacro(m, SYN_REPORT); PyModule_AddIntMacro(m, SYN_CONFIG); PyModule_AddIntMacro(m, SYN_MT_REPORT); PyModule_AddIntMacro(m, SYN_DROPPED); PyModule_AddIntMacro(m, SYN_MAX); PyModule_AddIntMacro(m, SYN_CNT); PyModule_AddIntMacro(m, KEY_RESERVED); PyModule_AddIntMacro(m, KEY_ESC); PyModule_AddIntMacro(m, KEY_1); PyModule_AddIntMacro(m, KEY_2); PyModule_AddIntMacro(m, KEY_3); PyModule_AddIntMacro(m, KEY_4); PyModule_AddIntMacro(m, KEY_5); PyModule_AddIntMacro(m, KEY_6); PyModule_AddIntMacro(m, KEY_7); PyModule_AddIntMacro(m, KEY_8); PyModule_AddIntMacro(m, KEY_9); PyModule_AddIntMacro(m, KEY_0); PyModule_AddIntMacro(m, KEY_MINUS); PyModule_AddIntMacro(m, KEY_EQUAL); PyModule_AddIntMacro(m, KEY_BACKSPACE); PyModule_AddIntMacro(m, KEY_TAB); PyModule_AddIntMacro(m, KEY_Q); PyModule_AddIntMacro(m, KEY_W); PyModule_AddIntMacro(m, KEY_E); PyModule_AddIntMacro(m, KEY_R); PyModule_AddIntMacro(m, KEY_T); PyModule_AddIntMacro(m, KEY_Y); PyModule_AddIntMacro(m, KEY_U); PyModule_AddIntMacro(m, KEY_I); PyModule_AddIntMacro(m, KEY_O); PyModule_AddIntMacro(m, KEY_P); PyModule_AddIntMacro(m, KEY_LEFTBRACE); PyModule_AddIntMacro(m, KEY_RIGHTBRACE); PyModule_AddIntMacro(m, KEY_ENTER); PyModule_AddIntMacro(m, KEY_LEFTCTRL); PyModule_AddIntMacro(m, KEY_A); PyModule_AddIntMacro(m, KEY_S); PyModule_AddIntMacro(m, KEY_D); PyModule_AddIntMacro(m, KEY_F); PyModule_AddIntMacro(m, KEY_G); PyModule_AddIntMacro(m, KEY_H); PyModule_AddIntMacro(m, KEY_J); PyModule_AddIntMacro(m, KEY_K); PyModule_AddIntMacro(m, KEY_L); PyModule_AddIntMacro(m, KEY_SEMICOLON); PyModule_AddIntMacro(m, KEY_APOSTROPHE); PyModule_AddIntMacro(m, KEY_GRAVE); PyModule_AddIntMacro(m, KEY_LEFTSHIFT); PyModule_AddIntMacro(m, KEY_BACKSLASH); PyModule_AddIntMacro(m, KEY_Z); PyModule_AddIntMacro(m, KEY_X); PyModule_AddIntMacro(m, KEY_C); PyModule_AddIntMacro(m, KEY_V); PyModule_AddIntMacro(m, KEY_B); PyModule_AddIntMacro(m, KEY_N); PyModule_AddIntMacro(m, KEY_M); PyModule_AddIntMacro(m, KEY_COMMA); PyModule_AddIntMacro(m, KEY_DOT); PyModule_AddIntMacro(m, KEY_SLASH); PyModule_AddIntMacro(m, KEY_RIGHTSHIFT); PyModule_AddIntMacro(m, KEY_KPASTERISK); PyModule_AddIntMacro(m, KEY_LEFTALT); PyModule_AddIntMacro(m, KEY_SPACE); PyModule_AddIntMacro(m, KEY_CAPSLOCK); PyModule_AddIntMacro(m, KEY_F1); PyModule_AddIntMacro(m, KEY_F2); PyModule_AddIntMacro(m, KEY_F3); PyModule_AddIntMacro(m, KEY_F4); PyModule_AddIntMacro(m, KEY_F5); PyModule_AddIntMacro(m, KEY_F6); PyModule_AddIntMacro(m, KEY_F7); PyModule_AddIntMacro(m, KEY_F8); PyModule_AddIntMacro(m, KEY_F9); PyModule_AddIntMacro(m, KEY_F10); PyModule_AddIntMacro(m, KEY_NUMLOCK); PyModule_AddIntMacro(m, KEY_SCROLLLOCK); PyModule_AddIntMacro(m, KEY_KP7); PyModule_AddIntMacro(m, KEY_KP8); PyModule_AddIntMacro(m, KEY_KP9); PyModule_AddIntMacro(m, KEY_KPMINUS); PyModule_AddIntMacro(m, KEY_KP4); PyModule_AddIntMacro(m, KEY_KP5); PyModule_AddIntMacro(m, KEY_KP6); PyModule_AddIntMacro(m, KEY_KPPLUS); PyModule_AddIntMacro(m, KEY_KP1); PyModule_AddIntMacro(m, KEY_KP2); PyModule_AddIntMacro(m, KEY_KP3); PyModule_AddIntMacro(m, KEY_KP0); PyModule_AddIntMacro(m, KEY_KPDOT); PyModule_AddIntMacro(m, KEY_ZENKAKUHANKAKU); PyModule_AddIntMacro(m, KEY_102ND); PyModule_AddIntMacro(m, KEY_F11); PyModule_AddIntMacro(m, KEY_F12); PyModule_AddIntMacro(m, KEY_RO); PyModule_AddIntMacro(m, KEY_KATAKANA); PyModule_AddIntMacro(m, KEY_HIRAGANA); PyModule_AddIntMacro(m, KEY_HENKAN); PyModule_AddIntMacro(m, KEY_KATAKANAHIRAGANA); PyModule_AddIntMacro(m, KEY_MUHENKAN); PyModule_AddIntMacro(m, KEY_KPJPCOMMA); PyModule_AddIntMacro(m, KEY_KPENTER); PyModule_AddIntMacro(m, KEY_RIGHTCTRL); PyModule_AddIntMacro(m, KEY_KPSLASH); PyModule_AddIntMacro(m, KEY_SYSRQ); PyModule_AddIntMacro(m, KEY_RIGHTALT); PyModule_AddIntMacro(m, KEY_LINEFEED); PyModule_AddIntMacro(m, KEY_HOME); PyModule_AddIntMacro(m, KEY_UP); PyModule_AddIntMacro(m, KEY_PAGEUP); PyModule_AddIntMacro(m, KEY_LEFT); PyModule_AddIntMacro(m, KEY_RIGHT); PyModule_AddIntMacro(m, KEY_END); PyModule_AddIntMacro(m, KEY_DOWN); PyModule_AddIntMacro(m, KEY_PAGEDOWN); PyModule_AddIntMacro(m, KEY_INSERT); PyModule_AddIntMacro(m, KEY_DELETE); PyModule_AddIntMacro(m, KEY_MACRO); PyModule_AddIntMacro(m, KEY_MUTE); PyModule_AddIntMacro(m, KEY_VOLUMEDOWN); PyModule_AddIntMacro(m, KEY_VOLUMEUP); PyModule_AddIntMacro(m, KEY_POWER); PyModule_AddIntMacro(m, KEY_KPEQUAL); PyModule_AddIntMacro(m, KEY_KPPLUSMINUS); PyModule_AddIntMacro(m, KEY_PAUSE); PyModule_AddIntMacro(m, KEY_SCALE); PyModule_AddIntMacro(m, KEY_KPCOMMA); PyModule_AddIntMacro(m, KEY_HANGEUL); PyModule_AddIntMacro(m, KEY_HANGUEL); PyModule_AddIntMacro(m, KEY_HANJA); PyModule_AddIntMacro(m, KEY_YEN); PyModule_AddIntMacro(m, KEY_LEFTMETA); PyModule_AddIntMacro(m, KEY_RIGHTMETA); PyModule_AddIntMacro(m, KEY_COMPOSE); PyModule_AddIntMacro(m, KEY_STOP); PyModule_AddIntMacro(m, KEY_AGAIN); PyModule_AddIntMacro(m, KEY_PROPS); PyModule_AddIntMacro(m, KEY_UNDO); PyModule_AddIntMacro(m, KEY_FRONT); PyModule_AddIntMacro(m, KEY_COPY); PyModule_AddIntMacro(m, KEY_OPEN); PyModule_AddIntMacro(m, KEY_PASTE); PyModule_AddIntMacro(m, KEY_FIND); PyModule_AddIntMacro(m, KEY_CUT); PyModule_AddIntMacro(m, KEY_HELP); PyModule_AddIntMacro(m, KEY_MENU); PyModule_AddIntMacro(m, KEY_CALC); PyModule_AddIntMacro(m, KEY_SETUP); PyModule_AddIntMacro(m, KEY_SLEEP); PyModule_AddIntMacro(m, KEY_WAKEUP); PyModule_AddIntMacro(m, KEY_FILE); PyModule_AddIntMacro(m, KEY_SENDFILE); PyModule_AddIntMacro(m, KEY_DELETEFILE); PyModule_AddIntMacro(m, KEY_XFER); PyModule_AddIntMacro(m, KEY_PROG1); PyModule_AddIntMacro(m, KEY_PROG2); PyModule_AddIntMacro(m, KEY_WWW); PyModule_AddIntMacro(m, KEY_MSDOS); PyModule_AddIntMacro(m, KEY_COFFEE); PyModule_AddIntMacro(m, KEY_SCREENLOCK); PyModule_AddIntMacro(m, KEY_DIRECTION); PyModule_AddIntMacro(m, KEY_CYCLEWINDOWS); PyModule_AddIntMacro(m, KEY_MAIL); PyModule_AddIntMacro(m, KEY_BOOKMARKS); PyModule_AddIntMacro(m, KEY_COMPUTER); PyModule_AddIntMacro(m, KEY_BACK); PyModule_AddIntMacro(m, KEY_FORWARD); PyModule_AddIntMacro(m, KEY_CLOSECD); PyModule_AddIntMacro(m, KEY_EJECTCD); PyModule_AddIntMacro(m, KEY_EJECTCLOSECD); PyModule_AddIntMacro(m, KEY_NEXTSONG); PyModule_AddIntMacro(m, KEY_PLAYPAUSE); PyModule_AddIntMacro(m, KEY_PREVIOUSSONG); PyModule_AddIntMacro(m, KEY_STOPCD); PyModule_AddIntMacro(m, KEY_RECORD); PyModule_AddIntMacro(m, KEY_REWIND); PyModule_AddIntMacro(m, KEY_PHONE); PyModule_AddIntMacro(m, KEY_ISO); PyModule_AddIntMacro(m, KEY_CONFIG); PyModule_AddIntMacro(m, KEY_HOMEPAGE); PyModule_AddIntMacro(m, KEY_REFRESH); PyModule_AddIntMacro(m, KEY_EXIT); PyModule_AddIntMacro(m, KEY_MOVE); PyModule_AddIntMacro(m, KEY_EDIT); PyModule_AddIntMacro(m, KEY_SCROLLUP); PyModule_AddIntMacro(m, KEY_SCROLLDOWN); PyModule_AddIntMacro(m, KEY_KPLEFTPAREN); PyModule_AddIntMacro(m, KEY_KPRIGHTPAREN); PyModule_AddIntMacro(m, KEY_NEW); PyModule_AddIntMacro(m, KEY_REDO); PyModule_AddIntMacro(m, KEY_F13); PyModule_AddIntMacro(m, KEY_F14); PyModule_AddIntMacro(m, KEY_F15); PyModule_AddIntMacro(m, KEY_F16); PyModule_AddIntMacro(m, KEY_F17); PyModule_AddIntMacro(m, KEY_F18); PyModule_AddIntMacro(m, KEY_F19); PyModule_AddIntMacro(m, KEY_F20); PyModule_AddIntMacro(m, KEY_F21); PyModule_AddIntMacro(m, KEY_F22); PyModule_AddIntMacro(m, KEY_F23); PyModule_AddIntMacro(m, KEY_F24); PyModule_AddIntMacro(m, KEY_PLAYCD); PyModule_AddIntMacro(m, KEY_PAUSECD); PyModule_AddIntMacro(m, KEY_PROG3); PyModule_AddIntMacro(m, KEY_PROG4); PyModule_AddIntMacro(m, KEY_DASHBOARD); PyModule_AddIntMacro(m, KEY_SUSPEND); PyModule_AddIntMacro(m, KEY_CLOSE); PyModule_AddIntMacro(m, KEY_PLAY); PyModule_AddIntMacro(m, KEY_FASTFORWARD); PyModule_AddIntMacro(m, KEY_BASSBOOST); PyModule_AddIntMacro(m, KEY_PRINT); PyModule_AddIntMacro(m, KEY_HP); PyModule_AddIntMacro(m, KEY_CAMERA); PyModule_AddIntMacro(m, KEY_SOUND); PyModule_AddIntMacro(m, KEY_QUESTION); PyModule_AddIntMacro(m, KEY_EMAIL); PyModule_AddIntMacro(m, KEY_CHAT); PyModule_AddIntMacro(m, KEY_SEARCH); PyModule_AddIntMacro(m, KEY_CONNECT); PyModule_AddIntMacro(m, KEY_FINANCE); PyModule_AddIntMacro(m, KEY_SPORT); PyModule_AddIntMacro(m, KEY_SHOP); PyModule_AddIntMacro(m, KEY_ALTERASE); PyModule_AddIntMacro(m, KEY_CANCEL); PyModule_AddIntMacro(m, KEY_BRIGHTNESSDOWN); PyModule_AddIntMacro(m, KEY_BRIGHTNESSUP); PyModule_AddIntMacro(m, KEY_MEDIA); PyModule_AddIntMacro(m, KEY_SWITCHVIDEOMODE); PyModule_AddIntMacro(m, KEY_KBDILLUMTOGGLE); PyModule_AddIntMacro(m, KEY_KBDILLUMDOWN); PyModule_AddIntMacro(m, KEY_KBDILLUMUP); PyModule_AddIntMacro(m, KEY_SEND); PyModule_AddIntMacro(m, KEY_REPLY); PyModule_AddIntMacro(m, KEY_FORWARDMAIL); PyModule_AddIntMacro(m, KEY_SAVE); PyModule_AddIntMacro(m, KEY_DOCUMENTS); PyModule_AddIntMacro(m, KEY_BATTERY); PyModule_AddIntMacro(m, KEY_BLUETOOTH); PyModule_AddIntMacro(m, KEY_WLAN); PyModule_AddIntMacro(m, KEY_UWB); PyModule_AddIntMacro(m, KEY_UNKNOWN); PyModule_AddIntMacro(m, KEY_VIDEO_NEXT); PyModule_AddIntMacro(m, KEY_VIDEO_PREV); PyModule_AddIntMacro(m, KEY_BRIGHTNESS_CYCLE); PyModule_AddIntMacro(m, KEY_BRIGHTNESS_AUTO); PyModule_AddIntMacro(m, KEY_BRIGHTNESS_ZERO); PyModule_AddIntMacro(m, KEY_DISPLAY_OFF); PyModule_AddIntMacro(m, KEY_WWAN); PyModule_AddIntMacro(m, KEY_WIMAX); PyModule_AddIntMacro(m, KEY_RFKILL); PyModule_AddIntMacro(m, KEY_MICMUTE); PyModule_AddIntMacro(m, BTN_MISC); PyModule_AddIntMacro(m, BTN_0); PyModule_AddIntMacro(m, BTN_1); PyModule_AddIntMacro(m, BTN_2); PyModule_AddIntMacro(m, BTN_3); PyModule_AddIntMacro(m, BTN_4); PyModule_AddIntMacro(m, BTN_5); PyModule_AddIntMacro(m, BTN_6); PyModule_AddIntMacro(m, BTN_7); PyModule_AddIntMacro(m, BTN_8); PyModule_AddIntMacro(m, BTN_9); PyModule_AddIntMacro(m, BTN_MOUSE); PyModule_AddIntMacro(m, BTN_LEFT); PyModule_AddIntMacro(m, BTN_RIGHT); PyModule_AddIntMacro(m, BTN_MIDDLE); PyModule_AddIntMacro(m, BTN_SIDE); PyModule_AddIntMacro(m, BTN_EXTRA); PyModule_AddIntMacro(m, BTN_FORWARD); PyModule_AddIntMacro(m, BTN_BACK); PyModule_AddIntMacro(m, BTN_TASK); PyModule_AddIntMacro(m, BTN_JOYSTICK); PyModule_AddIntMacro(m, BTN_TRIGGER); PyModule_AddIntMacro(m, BTN_THUMB); PyModule_AddIntMacro(m, BTN_THUMB2); PyModule_AddIntMacro(m, BTN_TOP); PyModule_AddIntMacro(m, BTN_TOP2); PyModule_AddIntMacro(m, BTN_PINKIE); PyModule_AddIntMacro(m, BTN_BASE); PyModule_AddIntMacro(m, BTN_BASE2); PyModule_AddIntMacro(m, BTN_BASE3); PyModule_AddIntMacro(m, BTN_BASE4); PyModule_AddIntMacro(m, BTN_BASE5); PyModule_AddIntMacro(m, BTN_BASE6); PyModule_AddIntMacro(m, BTN_DEAD); PyModule_AddIntMacro(m, BTN_GAMEPAD); PyModule_AddIntMacro(m, BTN_SOUTH); PyModule_AddIntMacro(m, BTN_A); PyModule_AddIntMacro(m, BTN_EAST); PyModule_AddIntMacro(m, BTN_B); PyModule_AddIntMacro(m, BTN_C); PyModule_AddIntMacro(m, BTN_NORTH); PyModule_AddIntMacro(m, BTN_X); PyModule_AddIntMacro(m, BTN_WEST); PyModule_AddIntMacro(m, BTN_Y); PyModule_AddIntMacro(m, BTN_Z); PyModule_AddIntMacro(m, BTN_TL); PyModule_AddIntMacro(m, BTN_TR); PyModule_AddIntMacro(m, BTN_TL2); PyModule_AddIntMacro(m, BTN_TR2); PyModule_AddIntMacro(m, BTN_SELECT); PyModule_AddIntMacro(m, BTN_START); PyModule_AddIntMacro(m, BTN_MODE); PyModule_AddIntMacro(m, BTN_THUMBL); PyModule_AddIntMacro(m, BTN_THUMBR); PyModule_AddIntMacro(m, BTN_DIGI); PyModule_AddIntMacro(m, BTN_TOOL_PEN); PyModule_AddIntMacro(m, BTN_TOOL_RUBBER); PyModule_AddIntMacro(m, BTN_TOOL_BRUSH); PyModule_AddIntMacro(m, BTN_TOOL_PENCIL); PyModule_AddIntMacro(m, BTN_TOOL_AIRBRUSH); PyModule_AddIntMacro(m, BTN_TOOL_FINGER); PyModule_AddIntMacro(m, BTN_TOOL_MOUSE); PyModule_AddIntMacro(m, BTN_TOOL_LENS); PyModule_AddIntMacro(m, BTN_TOOL_QUINTTAP); PyModule_AddIntMacro(m, BTN_TOUCH); PyModule_AddIntMacro(m, BTN_STYLUS); PyModule_AddIntMacro(m, BTN_STYLUS2); PyModule_AddIntMacro(m, BTN_TOOL_DOUBLETAP); PyModule_AddIntMacro(m, BTN_TOOL_TRIPLETAP); PyModule_AddIntMacro(m, BTN_TOOL_QUADTAP); PyModule_AddIntMacro(m, BTN_WHEEL); PyModule_AddIntMacro(m, BTN_GEAR_DOWN); PyModule_AddIntMacro(m, BTN_GEAR_UP); PyModule_AddIntMacro(m, KEY_OK); PyModule_AddIntMacro(m, KEY_SELECT); PyModule_AddIntMacro(m, KEY_GOTO); PyModule_AddIntMacro(m, KEY_CLEAR); PyModule_AddIntMacro(m, KEY_POWER2); PyModule_AddIntMacro(m, KEY_OPTION); PyModule_AddIntMacro(m, KEY_INFO); PyModule_AddIntMacro(m, KEY_TIME); PyModule_AddIntMacro(m, KEY_VENDOR); PyModule_AddIntMacro(m, KEY_ARCHIVE); PyModule_AddIntMacro(m, KEY_PROGRAM); PyModule_AddIntMacro(m, KEY_CHANNEL); PyModule_AddIntMacro(m, KEY_FAVORITES); PyModule_AddIntMacro(m, KEY_EPG); PyModule_AddIntMacro(m, KEY_PVR); PyModule_AddIntMacro(m, KEY_MHP); PyModule_AddIntMacro(m, KEY_LANGUAGE); PyModule_AddIntMacro(m, KEY_TITLE); PyModule_AddIntMacro(m, KEY_SUBTITLE); PyModule_AddIntMacro(m, KEY_ANGLE); PyModule_AddIntMacro(m, KEY_ZOOM); PyModule_AddIntMacro(m, KEY_MODE); PyModule_AddIntMacro(m, KEY_KEYBOARD); PyModule_AddIntMacro(m, KEY_SCREEN); PyModule_AddIntMacro(m, KEY_PC); PyModule_AddIntMacro(m, KEY_TV); PyModule_AddIntMacro(m, KEY_TV2); PyModule_AddIntMacro(m, KEY_VCR); PyModule_AddIntMacro(m, KEY_VCR2); PyModule_AddIntMacro(m, KEY_SAT); PyModule_AddIntMacro(m, KEY_SAT2); PyModule_AddIntMacro(m, KEY_CD); PyModule_AddIntMacro(m, KEY_TAPE); PyModule_AddIntMacro(m, KEY_RADIO); PyModule_AddIntMacro(m, KEY_TUNER); PyModule_AddIntMacro(m, KEY_PLAYER); PyModule_AddIntMacro(m, KEY_TEXT); PyModule_AddIntMacro(m, KEY_DVD); PyModule_AddIntMacro(m, KEY_AUX); PyModule_AddIntMacro(m, KEY_MP3); PyModule_AddIntMacro(m, KEY_AUDIO); PyModule_AddIntMacro(m, KEY_VIDEO); PyModule_AddIntMacro(m, KEY_DIRECTORY); PyModule_AddIntMacro(m, KEY_LIST); PyModule_AddIntMacro(m, KEY_MEMO); PyModule_AddIntMacro(m, KEY_CALENDAR); PyModule_AddIntMacro(m, KEY_RED); PyModule_AddIntMacro(m, KEY_GREEN); PyModule_AddIntMacro(m, KEY_YELLOW); PyModule_AddIntMacro(m, KEY_BLUE); PyModule_AddIntMacro(m, KEY_CHANNELUP); PyModule_AddIntMacro(m, KEY_CHANNELDOWN); PyModule_AddIntMacro(m, KEY_FIRST); PyModule_AddIntMacro(m, KEY_LAST); PyModule_AddIntMacro(m, KEY_AB); PyModule_AddIntMacro(m, KEY_NEXT); PyModule_AddIntMacro(m, KEY_RESTART); PyModule_AddIntMacro(m, KEY_SLOW); PyModule_AddIntMacro(m, KEY_SHUFFLE); PyModule_AddIntMacro(m, KEY_BREAK); PyModule_AddIntMacro(m, KEY_PREVIOUS); PyModule_AddIntMacro(m, KEY_DIGITS); PyModule_AddIntMacro(m, KEY_TEEN); PyModule_AddIntMacro(m, KEY_TWEN); PyModule_AddIntMacro(m, KEY_VIDEOPHONE); PyModule_AddIntMacro(m, KEY_GAMES); PyModule_AddIntMacro(m, KEY_ZOOMIN); PyModule_AddIntMacro(m, KEY_ZOOMOUT); PyModule_AddIntMacro(m, KEY_ZOOMRESET); PyModule_AddIntMacro(m, KEY_WORDPROCESSOR); PyModule_AddIntMacro(m, KEY_EDITOR); PyModule_AddIntMacro(m, KEY_SPREADSHEET); PyModule_AddIntMacro(m, KEY_GRAPHICSEDITOR); PyModule_AddIntMacro(m, KEY_PRESENTATION); PyModule_AddIntMacro(m, KEY_DATABASE); PyModule_AddIntMacro(m, KEY_NEWS); PyModule_AddIntMacro(m, KEY_VOICEMAIL); PyModule_AddIntMacro(m, KEY_ADDRESSBOOK); PyModule_AddIntMacro(m, KEY_MESSENGER); PyModule_AddIntMacro(m, KEY_DISPLAYTOGGLE); PyModule_AddIntMacro(m, KEY_BRIGHTNESS_TOGGLE); PyModule_AddIntMacro(m, KEY_SPELLCHECK); PyModule_AddIntMacro(m, KEY_LOGOFF); PyModule_AddIntMacro(m, KEY_DOLLAR); PyModule_AddIntMacro(m, KEY_EURO); PyModule_AddIntMacro(m, KEY_FRAMEBACK); PyModule_AddIntMacro(m, KEY_FRAMEFORWARD); PyModule_AddIntMacro(m, KEY_CONTEXT_MENU); PyModule_AddIntMacro(m, KEY_MEDIA_REPEAT); PyModule_AddIntMacro(m, KEY_10CHANNELSUP); PyModule_AddIntMacro(m, KEY_10CHANNELSDOWN); PyModule_AddIntMacro(m, KEY_IMAGES); PyModule_AddIntMacro(m, KEY_DEL_EOL); PyModule_AddIntMacro(m, KEY_DEL_EOS); PyModule_AddIntMacro(m, KEY_INS_LINE); PyModule_AddIntMacro(m, KEY_DEL_LINE); PyModule_AddIntMacro(m, KEY_FN); PyModule_AddIntMacro(m, KEY_FN_ESC); PyModule_AddIntMacro(m, KEY_FN_F1); PyModule_AddIntMacro(m, KEY_FN_F2); PyModule_AddIntMacro(m, KEY_FN_F3); PyModule_AddIntMacro(m, KEY_FN_F4); PyModule_AddIntMacro(m, KEY_FN_F5); PyModule_AddIntMacro(m, KEY_FN_F6); PyModule_AddIntMacro(m, KEY_FN_F7); PyModule_AddIntMacro(m, KEY_FN_F8); PyModule_AddIntMacro(m, KEY_FN_F9); PyModule_AddIntMacro(m, KEY_FN_F10); PyModule_AddIntMacro(m, KEY_FN_F11); PyModule_AddIntMacro(m, KEY_FN_F12); PyModule_AddIntMacro(m, KEY_FN_1); PyModule_AddIntMacro(m, KEY_FN_2); PyModule_AddIntMacro(m, KEY_FN_D); PyModule_AddIntMacro(m, KEY_FN_E); PyModule_AddIntMacro(m, KEY_FN_F); PyModule_AddIntMacro(m, KEY_FN_S); PyModule_AddIntMacro(m, KEY_FN_B); PyModule_AddIntMacro(m, KEY_BRL_DOT1); PyModule_AddIntMacro(m, KEY_BRL_DOT2); PyModule_AddIntMacro(m, KEY_BRL_DOT3); PyModule_AddIntMacro(m, KEY_BRL_DOT4); PyModule_AddIntMacro(m, KEY_BRL_DOT5); PyModule_AddIntMacro(m, KEY_BRL_DOT6); PyModule_AddIntMacro(m, KEY_BRL_DOT7); PyModule_AddIntMacro(m, KEY_BRL_DOT8); PyModule_AddIntMacro(m, KEY_BRL_DOT9); PyModule_AddIntMacro(m, KEY_BRL_DOT10); PyModule_AddIntMacro(m, KEY_NUMERIC_0); PyModule_AddIntMacro(m, KEY_NUMERIC_1); PyModule_AddIntMacro(m, KEY_NUMERIC_2); PyModule_AddIntMacro(m, KEY_NUMERIC_3); PyModule_AddIntMacro(m, KEY_NUMERIC_4); PyModule_AddIntMacro(m, KEY_NUMERIC_5); PyModule_AddIntMacro(m, KEY_NUMERIC_6); PyModule_AddIntMacro(m, KEY_NUMERIC_7); PyModule_AddIntMacro(m, KEY_NUMERIC_8); PyModule_AddIntMacro(m, KEY_NUMERIC_9); PyModule_AddIntMacro(m, KEY_NUMERIC_STAR); PyModule_AddIntMacro(m, KEY_NUMERIC_POUND); PyModule_AddIntMacro(m, KEY_CAMERA_FOCUS); PyModule_AddIntMacro(m, KEY_WPS_BUTTON); PyModule_AddIntMacro(m, KEY_TOUCHPAD_TOGGLE); PyModule_AddIntMacro(m, KEY_TOUCHPAD_ON); PyModule_AddIntMacro(m, KEY_TOUCHPAD_OFF); PyModule_AddIntMacro(m, KEY_CAMERA_ZOOMIN); PyModule_AddIntMacro(m, KEY_CAMERA_ZOOMOUT); PyModule_AddIntMacro(m, KEY_CAMERA_UP); PyModule_AddIntMacro(m, KEY_CAMERA_DOWN); PyModule_AddIntMacro(m, KEY_CAMERA_LEFT); PyModule_AddIntMacro(m, KEY_CAMERA_RIGHT); PyModule_AddIntMacro(m, KEY_ATTENDANT_ON); PyModule_AddIntMacro(m, KEY_ATTENDANT_OFF); PyModule_AddIntMacro(m, KEY_ATTENDANT_TOGGLE); PyModule_AddIntMacro(m, KEY_LIGHTS_TOGGLE); PyModule_AddIntMacro(m, BTN_DPAD_UP); PyModule_AddIntMacro(m, BTN_DPAD_DOWN); PyModule_AddIntMacro(m, BTN_DPAD_LEFT); PyModule_AddIntMacro(m, BTN_DPAD_RIGHT); PyModule_AddIntMacro(m, KEY_ALS_TOGGLE); PyModule_AddIntMacro(m, KEY_BUTTONCONFIG); PyModule_AddIntMacro(m, KEY_TASKMANAGER); PyModule_AddIntMacro(m, KEY_JOURNAL); PyModule_AddIntMacro(m, KEY_CONTROLPANEL); PyModule_AddIntMacro(m, KEY_APPSELECT); PyModule_AddIntMacro(m, KEY_SCREENSAVER); PyModule_AddIntMacro(m, KEY_VOICECOMMAND); PyModule_AddIntMacro(m, KEY_BRIGHTNESS_MIN); PyModule_AddIntMacro(m, KEY_BRIGHTNESS_MAX); PyModule_AddIntMacro(m, KEY_KBDINPUTASSIST_PREV); PyModule_AddIntMacro(m, KEY_KBDINPUTASSIST_NEXT); PyModule_AddIntMacro(m, KEY_KBDINPUTASSIST_PREVGROUP); PyModule_AddIntMacro(m, KEY_KBDINPUTASSIST_NEXTGROUP); PyModule_AddIntMacro(m, KEY_KBDINPUTASSIST_ACCEPT); PyModule_AddIntMacro(m, KEY_KBDINPUTASSIST_CANCEL); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY1); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY2); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY3); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY4); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY5); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY6); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY7); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY8); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY9); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY10); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY11); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY12); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY13); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY14); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY15); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY16); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY17); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY18); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY19); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY20); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY21); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY22); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY23); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY24); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY25); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY26); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY27); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY28); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY29); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY30); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY31); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY32); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY33); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY34); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY35); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY36); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY37); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY38); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY39); PyModule_AddIntMacro(m, BTN_TRIGGER_HAPPY40); PyModule_AddIntMacro(m, KEY_MIN_INTERESTING); PyModule_AddIntMacro(m, KEY_MAX); PyModule_AddIntMacro(m, KEY_CNT); PyModule_AddIntMacro(m, REL_X); PyModule_AddIntMacro(m, REL_Y); PyModule_AddIntMacro(m, REL_Z); PyModule_AddIntMacro(m, REL_RX); PyModule_AddIntMacro(m, REL_RY); PyModule_AddIntMacro(m, REL_RZ); PyModule_AddIntMacro(m, REL_HWHEEL); PyModule_AddIntMacro(m, REL_DIAL); PyModule_AddIntMacro(m, REL_WHEEL); PyModule_AddIntMacro(m, REL_MISC); PyModule_AddIntMacro(m, REL_MAX); PyModule_AddIntMacro(m, REL_CNT); PyModule_AddIntMacro(m, ABS_X); PyModule_AddIntMacro(m, ABS_Y); PyModule_AddIntMacro(m, ABS_Z); PyModule_AddIntMacro(m, ABS_RX); PyModule_AddIntMacro(m, ABS_RY); PyModule_AddIntMacro(m, ABS_RZ); PyModule_AddIntMacro(m, ABS_THROTTLE); PyModule_AddIntMacro(m, ABS_RUDDER); PyModule_AddIntMacro(m, ABS_WHEEL); PyModule_AddIntMacro(m, ABS_GAS); PyModule_AddIntMacro(m, ABS_BRAKE); PyModule_AddIntMacro(m, ABS_HAT0X); PyModule_AddIntMacro(m, ABS_HAT0Y); PyModule_AddIntMacro(m, ABS_HAT1X); PyModule_AddIntMacro(m, ABS_HAT1Y); PyModule_AddIntMacro(m, ABS_HAT2X); PyModule_AddIntMacro(m, ABS_HAT2Y); PyModule_AddIntMacro(m, ABS_HAT3X); PyModule_AddIntMacro(m, ABS_HAT3Y); PyModule_AddIntMacro(m, ABS_PRESSURE); PyModule_AddIntMacro(m, ABS_DISTANCE); PyModule_AddIntMacro(m, ABS_TILT_X); PyModule_AddIntMacro(m, ABS_TILT_Y); PyModule_AddIntMacro(m, ABS_TOOL_WIDTH); PyModule_AddIntMacro(m, ABS_VOLUME); PyModule_AddIntMacro(m, ABS_MISC); PyModule_AddIntMacro(m, ABS_MT_SLOT); PyModule_AddIntMacro(m, ABS_MT_TOUCH_MAJOR); PyModule_AddIntMacro(m, ABS_MT_TOUCH_MINOR); PyModule_AddIntMacro(m, ABS_MT_WIDTH_MAJOR); PyModule_AddIntMacro(m, ABS_MT_WIDTH_MINOR); PyModule_AddIntMacro(m, ABS_MT_ORIENTATION); PyModule_AddIntMacro(m, ABS_MT_POSITION_X); PyModule_AddIntMacro(m, ABS_MT_POSITION_Y); PyModule_AddIntMacro(m, ABS_MT_TOOL_TYPE); PyModule_AddIntMacro(m, ABS_MT_BLOB_ID); PyModule_AddIntMacro(m, ABS_MT_TRACKING_ID); PyModule_AddIntMacro(m, ABS_MT_PRESSURE); PyModule_AddIntMacro(m, ABS_MT_DISTANCE); PyModule_AddIntMacro(m, ABS_MT_TOOL_X); PyModule_AddIntMacro(m, ABS_MT_TOOL_Y); PyModule_AddIntMacro(m, ABS_MAX); PyModule_AddIntMacro(m, ABS_CNT); PyModule_AddIntMacro(m, SW_LID); PyModule_AddIntMacro(m, SW_TABLET_MODE); PyModule_AddIntMacro(m, SW_HEADPHONE_INSERT); PyModule_AddIntMacro(m, SW_RFKILL_ALL); PyModule_AddIntMacro(m, SW_RADIO); PyModule_AddIntMacro(m, SW_MICROPHONE_INSERT); PyModule_AddIntMacro(m, SW_DOCK); PyModule_AddIntMacro(m, SW_LINEOUT_INSERT); PyModule_AddIntMacro(m, SW_JACK_PHYSICAL_INSERT); PyModule_AddIntMacro(m, SW_VIDEOOUT_INSERT); PyModule_AddIntMacro(m, SW_CAMERA_LENS_COVER); PyModule_AddIntMacro(m, SW_KEYPAD_SLIDE); PyModule_AddIntMacro(m, SW_FRONT_PROXIMITY); PyModule_AddIntMacro(m, SW_ROTATE_LOCK); PyModule_AddIntMacro(m, SW_LINEIN_INSERT); PyModule_AddIntMacro(m, SW_MUTE_DEVICE); PyModule_AddIntMacro(m, SW_MAX); PyModule_AddIntMacro(m, SW_CNT); PyModule_AddIntMacro(m, MSC_SERIAL); PyModule_AddIntMacro(m, MSC_PULSELED); PyModule_AddIntMacro(m, MSC_GESTURE); PyModule_AddIntMacro(m, MSC_RAW); PyModule_AddIntMacro(m, MSC_SCAN); PyModule_AddIntMacro(m, MSC_TIMESTAMP); PyModule_AddIntMacro(m, MSC_MAX); PyModule_AddIntMacro(m, MSC_CNT); PyModule_AddIntMacro(m, LED_NUML); PyModule_AddIntMacro(m, LED_CAPSL); PyModule_AddIntMacro(m, LED_SCROLLL); PyModule_AddIntMacro(m, LED_COMPOSE); PyModule_AddIntMacro(m, LED_KANA); PyModule_AddIntMacro(m, LED_SLEEP); PyModule_AddIntMacro(m, LED_SUSPEND); PyModule_AddIntMacro(m, LED_MUTE); PyModule_AddIntMacro(m, LED_MISC); PyModule_AddIntMacro(m, LED_MAIL); PyModule_AddIntMacro(m, LED_CHARGING); PyModule_AddIntMacro(m, LED_MAX); PyModule_AddIntMacro(m, LED_CNT); PyModule_AddIntMacro(m, REP_DELAY); PyModule_AddIntMacro(m, REP_PERIOD); PyModule_AddIntMacro(m, REP_MAX); PyModule_AddIntMacro(m, REP_CNT); PyModule_AddIntMacro(m, SND_CLICK); PyModule_AddIntMacro(m, SND_BELL); PyModule_AddIntMacro(m, SND_TONE); PyModule_AddIntMacro(m, SND_MAX); PyModule_AddIntMacro(m, SND_CNT); PyModule_AddIntMacro(m, ID_BUS); PyModule_AddIntMacro(m, ID_VENDOR); PyModule_AddIntMacro(m, ID_PRODUCT); PyModule_AddIntMacro(m, ID_VERSION); PyModule_AddIntMacro(m, BUS_PCI); PyModule_AddIntMacro(m, BUS_ISAPNP); PyModule_AddIntMacro(m, BUS_USB); PyModule_AddIntMacro(m, BUS_HIL); PyModule_AddIntMacro(m, BUS_BLUETOOTH); PyModule_AddIntMacro(m, BUS_VIRTUAL); PyModule_AddIntMacro(m, BUS_ISA); PyModule_AddIntMacro(m, BUS_I8042); PyModule_AddIntMacro(m, BUS_XTKBD); PyModule_AddIntMacro(m, BUS_RS232); PyModule_AddIntMacro(m, BUS_GAMEPORT); PyModule_AddIntMacro(m, BUS_PARPORT); PyModule_AddIntMacro(m, BUS_AMIGA); PyModule_AddIntMacro(m, BUS_ADB); PyModule_AddIntMacro(m, BUS_I2C); PyModule_AddIntMacro(m, BUS_HOST); PyModule_AddIntMacro(m, BUS_GSC); PyModule_AddIntMacro(m, BUS_ATARI); PyModule_AddIntMacro(m, BUS_SPI); PyModule_AddIntMacro(m, FF_STATUS_STOPPED); PyModule_AddIntMacro(m, FF_STATUS_PLAYING); PyModule_AddIntMacro(m, FF_STATUS_MAX); PyModule_AddIntMacro(m, FF_RUMBLE); PyModule_AddIntMacro(m, FF_PERIODIC); PyModule_AddIntMacro(m, FF_CONSTANT); PyModule_AddIntMacro(m, FF_SPRING); PyModule_AddIntMacro(m, FF_FRICTION); PyModule_AddIntMacro(m, FF_DAMPER); PyModule_AddIntMacro(m, FF_INERTIA); PyModule_AddIntMacro(m, FF_RAMP); PyModule_AddIntMacro(m, FF_EFFECT_MIN); PyModule_AddIntMacro(m, FF_EFFECT_MAX); PyModule_AddIntMacro(m, FF_SQUARE); PyModule_AddIntMacro(m, FF_TRIANGLE); PyModule_AddIntMacro(m, FF_SINE); PyModule_AddIntMacro(m, FF_SAW_UP); PyModule_AddIntMacro(m, FF_SAW_DOWN); PyModule_AddIntMacro(m, FF_CUSTOM); PyModule_AddIntMacro(m, FF_WAVEFORM_MIN); PyModule_AddIntMacro(m, FF_WAVEFORM_MAX); PyModule_AddIntMacro(m, FF_GAIN); PyModule_AddIntMacro(m, FF_AUTOCENTER); PyModule_AddIntMacro(m, FF_MAX); PyModule_AddIntMacro(m, FF_CNT); return m; } #if PY_MAJOR_VERSION >= 3 PyMODINIT_FUNC PyInit__ecodes(void) { return moduleinit(); } #else PyMODINIT_FUNC init_ecodes(void) { moduleinit(); } #endif evdev-0.4.7/evdev/ecodes.py0000640000175000017500000000477312366711015014643 0ustar gvgv00000000000000# encoding: utf-8 ''' This modules exposes the integer constants defined in ``linux/input.h``. Exposed constants:: KEY, ABS, REL, SW, MSC, LED, BTN, REP, SND, ID, EV, BUS, SYN, FF, FF_STATUS This module also provides numerous reverse and forward mappings that are best illustrated by a few examples:: >>> evdev.ecodes.KEY_A 30 >>> evdev.ecodes.ecodes['KEY_A'] 30 >>> evdev.ecodes.KEY[30] 'KEY_A' >>> evdev.ecodes.REL[0] 'REL_X' >>> evdev.ecodes.EV[evdev.ecodes.EV_KEY] 'EV_KEY' >>> evdev.ecodes.bytype[evdev.ecodes.EV_REL][0] 'REL_X' Values in reverse mappings may point to one or more ecodes. For example:: >>> evdev.ecodes.FF[80] ['FF_EFFECT_MIN', 'FF_RUMBLE'] >>> evdev.ecodes.FF[81] 'FF_PERIODIC' ''' from inspect import getmembers from evdev import _ecodes #: Mapping of names to values. ecodes = {} prefixes = 'KEY ABS REL SW MSC LED BTN REP SND ID EV BUS SYN FF_STATUS FF' prev_prefix = '' g = globals() # eg. code: 'REL_Z', val: 2 for code, val in getmembers(_ecodes): for prefix in prefixes.split(): # eg. 'REL' if code.startswith(prefix): ecodes[code] = val # FF_STATUS codes should not appear in the FF reverse mapping if not code.startswith(prev_prefix): d = g.setdefault(prefix, {}) # codes that share the same value will be added to a list. eg: # >>> ecodes.FF_STATUS # {0: 'FF_STATUS_STOPPED', 1: ['FF_STATUS_MAX', 'FF_STATUS_PLAYING']} if val in d: if isinstance(d[val], list): d[val].append(code) else: d[val] = [d[val], code] else: d[val] = code prev_prefix = prefix #: Keys are a combination of all BTN and KEY codes. keys = {} keys.update(BTN) keys.update(KEY) # make keys safe to use for the default list of uinput device # capabilities del keys[_ecodes.KEY_MAX] del keys[_ecodes.KEY_CNT] #: Mapping of event types to other value/name mappings. bytype = { _ecodes.EV_KEY: keys, _ecodes.EV_ABS: ABS, _ecodes.EV_REL: REL, _ecodes.EV_SW: SW, _ecodes.EV_MSC: MSC, _ecodes.EV_LED: LED, _ecodes.EV_REP: REP, _ecodes.EV_SND: SND, _ecodes.EV_SYN: SYN, _ecodes.EV_FF: FF, _ecodes.EV_FF_STATUS: FF_STATUS, } from evdev._ecodes import * # cheaper than whitelisting in an __all__ del code, val, prefix, getmembers, g, d, prefixes, prev_prefix evdev-0.4.7/evdev/events.py0000600000175000017500000001231512403035151014660 0ustar gvgv00000000000000# encoding: utf-8 ''' This module provides the :class:`InputEvent` class, which closely resembles the ``input_event`` struct defined in ``linux/input.h``: .. code-block:: c struct input_event { struct timeval time; __u16 type; __u16 code; __s32 value; }; This module also defines several :class:`InputEvent` sub-classes that know more about the different types of events (key, abs, rel etc). The :data:`event_factory` dictionary maps event types to these classes. Assuming you use the :func:`evdev.util.categorize()` function to categorize events according to their type, adding or replacing a class for a specific event type becomes a matter of modifying :data:`event_factory`. All classes in this module have reasonable ``str()`` and ``repr()`` methods:: >>> print(event) event at 1337197425.477827, code 04, type 04, val 458792 >>> print(repr(event)) InputEvent(1337197425L, 477827L, 4, 4, 458792L) >>> print(key_event) key event at 1337197425.477835, 28 (KEY_ENTER), up >>> print(repr(key_event)) KeyEvent(InputEvent(1337197425L, 477835L, 1, 28, 0L)) ''' # event type descriptions have been taken mot-a-mot from: # http://www.kernel.org/doc/Documentation/input/event-codes.txt from evdev.ecodes import keys, KEY, SYN, REL, ABS, EV_KEY, EV_REL, EV_ABS, EV_SYN class InputEvent(object): '''A generic input event.''' __slots__ = 'sec', 'usec', 'type', 'code', 'value' def __init__(self, sec, usec, type, code, value): #: Time in seconds since epoch at which event occurred. self.sec = sec #: Microsecond portion of the timestamp. self.usec = usec #: Event type - one of ``ecodes.EV_*``. self.type = type #: Event code related to the event type. self.code = code #: Event value related to the event type. self.value = value def timestamp(self): '''Return event timestamp as a float.''' return self.sec + (self.usec / 1000000.0) def __str__(s): msg = 'event at {:f}, code {:02d}, type {:02d}, val {:02d}' return msg.format(s.timestamp(), s.code, s.type, s.value) def __repr__(s): msg = '{}({!r}, {!r}, {!r}, {!r}, {!r})' return msg.format(s.__class__.__name__, s.sec, s.usec, s.type, s.code, s.value) class KeyEvent(object): '''An event generated by a keyboard, button or other key-like devices.''' key_up = 0x0 key_down = 0x1 key_hold = 0x2 __slots__ = 'scancode', 'keycode', 'keystate', 'event' def __init__(self, event): if event.value == 0: self.keystate = KeyEvent.key_up elif event.value == 2: self.keystate = KeyEvent.key_hold elif event.value == 1: self.keystate = KeyEvent.key_down self.keycode = keys[event.code] # :todo: self.scancode = event.code #: Reference to an :class:`InputEvent` instance. self.event = event def __str__(self): try: ks = ('up', 'down', 'hold')[self.keystate] except IndexError: ks = 'unknown' msg = 'key event at {:f}, {} ({}), {}' return msg.format(self.event.timestamp(), self.scancode, self.keycode, ks) def __repr__(s): return '{}({!r})'.format(s.__class__.__name__, s.event) class RelEvent(object): '''A relative axis event (e.g moving the mouse 5 units to the left).''' __slots__ = 'event' def __init__(self, event): #: Reference to an :class:`InputEvent` instance. self.event = event def __str__(self): msg = 'relative axis event at {:f}, {} ' return msg.format(self.event.timestamp(), REL[self.event.code]) def __repr__(s): return '{}({!r})'.format(s.__class__.__name__, s.event) class AbsEvent(object): '''An absolute axis event (e.g the coordinates of a tap on a touchscreen).''' __slots__ = 'event' def __init__(self, event): #: Reference to an :class:`InputEvent` instance. self.event = event def __str__(self): msg = 'absolute axis event at {:f}, {} ' return msg.format(self.event.timestamp(), ABS[self.event.code]) def __repr__(s): return '{}({!r})'.format(s.__class__.__name__, s.event) class SynEvent(object): ''' A synchronization event. Synchronization events are used as markers to separate event. Used as markers to separate events. Events may be separated in time or in space, such as with the multitouch protocol. ''' __slots__ = 'event' def __init__(self, event): #: Reference to an :class:`InputEvent` instance. self.event = event def __str__(self): msg = 'synchronization event at {:f}, {} ' return msg.format(self.event.timestamp(), SYN[self.event.code]) def __repr__(s): return '{}({!r})'.format(s.__class__.__name__, s.event) #: A mapping of event types to :class:`InputEvent` sub-classes. Used #: by :func:`evdev.util.categorize()` event_factory = { EV_KEY: KeyEvent, EV_REL: RelEvent, EV_ABS: AbsEvent, EV_SYN: SynEvent, } __all__ = ('InputEvent', 'KeyEvent', 'RelEvent', 'SynEvent', 'AbsEvent', 'event_factory') evdev-0.4.7/evdev/ff.py0000640000175000017500000001104312366711015013760 0ustar gvgv00000000000000# encoding: utf-8 import ctypes from evdev import ecodes _u8 = ctypes.c_uint8 _u16 = ctypes.c_uint16 _u32 = ctypes.c_uint32 _s16 = ctypes.c_int16 class Replay(ctypes.Structure): ''' Defines scheduling of the force-feedback effect @length: duration of the effect @delay: delay before effect should start playing ''' _fields_ = [ ('length', _u16), ('delay', _u16), ] class Trigger(ctypes.Structure): ''' Defines what triggers the force-feedback effect @button: number of the button triggering the effect @interval: controls how soon the effect can be re-triggered ''' _fields_ = [ ('button', _u16), ('interval', _u16), ] class Envelope(ctypes.Structure): ''' Generic force-feedback effect envelope @attack_length: duration of the attack (ms) @attack_level: level at the beginning of the attack @fade_length: duration of fade (ms) @fade_level: level at the end of fade The @attack_level and @fade_level are absolute values; when applying envelope force-feedback core will convert to positive/negative value based on polarity of the default level of the effect. Valid range for the attack and fade levels is 0x0000 - 0x7fff ''' _fields_ = [ ('attach_length', _u16), ('attack_level', _u16), ('fade_length', _u16), ('fade_level', _u16), ] class Constant(ctypes.Structure): ''' Defines parameters of a constant force-feedback effect @level: strength of the effect; may be negative @envelope: envelope data ''' _fields_ = [ ('level', _s16), ('ff_envelope', Envelope), ] class Ramp(ctypes.Structure): ''' Defines parameters of a ramp force-feedback effect @start_level: beginning strength of the effect; may be negative @end_level: final strength of the effect; may be negative @envelope: envelope data ''' _fields_ = [ ('start_level', _s16), ('end_level', _s16), ('ff_envelope', Envelope), ] class Condition(ctypes.Structure): ''' Defines a spring or friction force-feedback effect @right_saturation: maximum level when joystick moved all way to the right @left_saturation: same for the left side @right_coeff: controls how fast the force grows when the joystick moves to the right @left_coeff: same for the left side @deadband: size of the dead zone, where no force is produced @center: position of the dead zone ''' _fields_ = [ ('right_saturation', _u16), ('left_saturation', _u16), ('right_coeff', _s16), ('left_foeff', _s16), ('deadband', _u16), ('center', _s16), ] class Periodic(ctypes.Structure): ''' Defines parameters of a periodic force-feedback effect @waveform: kind of the effect (wave) @period: period of the wave (ms) @magnitude: peak value @offset: mean value of the wave (roughly) @phase: 'horizontal' shift @envelope: envelope data @custom_len: number of samples (FF_CUSTOM only) @custom_data: buffer of samples (FF_CUSTOM only) ''' _fields_ = [ ('waveform', _u16), ('period', _u16), ('magnitude', _s16), ('offset', _s16), ('phase', _u16), ('envelope', Envelope), ('custom_len', _u32), ('custom_data', ctypes.POINTER(_s16)), ] class Rumble(ctypes.Structure): ''' Defines parameters of a periodic force-feedback effect @strong_magnitude: magnitude of the heavy motor @weak_magnitude: magnitude of the light one Some rumble pads have two motors of different weight. Strong_magnitude represents the magnitude of the vibration generated by the heavy one. ''' _fields_ = [ ('strong_magnitude', _u16), ('weak_magnitude', _u16), ] class EffectType(ctypes.Union): _fields_ = [ ('ff_constant_effect', Constant), ('ff_ramp_effect', Ramp), ('ff_periodic_effect', Periodic), ('ff_condition_effect', Condition * 2), # one for each axis ('ff_rumble_effect', Rumble), ] class Effect(ctypes.Structure): _fields_ = [ ('type', _u16), ('id', _s16), ('direction', _u16), ('ff_trigger', Trigger), ('ff_replay', Replay), ('u', EffectType) ] # ff_types = { # ecodes.FF_CONSTANT, # ecodes.FF_PERIODIC, # ecodes.FF_RAMP, # ecodes.FF_SPRING, # ecodes.FF_FRICTION, # ecodes.FF_DAMPER, # ecodes.FF_RUMBLE, # ecodes.FF_INERTIA, # ecodes.FF_CUSTOM, # } evdev-0.4.7/evdev/genecodes.py0000770000175000017500000000344212415045070015325 0ustar gvgv00000000000000#!/usr/bin/env python # -*- coding: utf-8; -*- ''' Generate a Python extension module that exports macros from /usr/include/linux/input.h ''' import os, sys, re template = r''' #include #ifdef __FreeBSD__ #include #else #include #endif /* Automatically generated by evdev.genecodes */ /* Generated on %s */ #define MODULE_NAME "_ecodes" #define MODULE_HELP "linux/input.h macros" static PyMethodDef MethodTable[] = { { NULL, NULL, 0, NULL} }; #if PY_MAJOR_VERSION >= 3 static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, MODULE_NAME, MODULE_HELP, -1, /* m_size */ MethodTable, /* m_methods */ NULL, /* m_reload */ NULL, /* m_traverse */ NULL, /* m_clear */ NULL, /* m_free */ }; #endif static PyObject * moduleinit(void) { #if PY_MAJOR_VERSION >= 3 PyObject* m = PyModule_Create(&moduledef); #else PyObject* m = Py_InitModule3(MODULE_NAME, MethodTable, MODULE_HELP); #endif if (m == NULL) return NULL; %s return m; } #if PY_MAJOR_VERSION >= 3 PyMODINIT_FUNC PyInit__ecodes(void) { return moduleinit(); } #else PyMODINIT_FUNC init_ecodes(void) { moduleinit(); } #endif ''' header = '/usr/include/linux/input.h' if len(sys.argv) == 1 else sys.argv[1] regex = r'#define +((?:KEY|ABS|REL|SW|MSC|LED|BTN|REP|SND|ID|EV|BUS|SYN|FF)_\w+)' regex = re.compile(regex) if not os.path.exists(header): print('no such file: %s' % header) sys.exit(1) def getmacros(): for line in open(header): macro = regex.search(line) if macro: yield ' PyModule_AddIntMacro(m, %s);' % macro.group(1) uname = list(os.uname()); del uname[1] uname = ' '.join(uname) macros = os.linesep.join(getmacros()) print(template % (uname, macros)) evdev-0.4.7/evdev/input.c0000660000175000017500000003360612415045073014330 0ustar gvgv00000000000000 /* * Python bindings to certain linux input subsystem functions. * * While everything here can be implemented in pure Python with struct and * fcntl.ioctl, imho, it is much more straightforward to do so in C. * */ #include #include #include #include #include #include #include #include #include #ifdef __FreeBSD__ #include #else #include #endif #define MAX_NAME_SIZE 256 extern char* EV_NAME[EV_CNT]; extern int EV_TYPE_MAX[EV_CNT]; extern char** EV_TYPE_NAME[EV_CNT]; extern char* BUS_NAME[]; int test_bit(const char* bitmask, int bit) { return bitmask[bit/8] & (1 << (bit % 8)); } // Read input event from a device and return a tuple that mimics input_event static PyObject * device_read(PyObject *self, PyObject *args) { int fd; struct input_event event; // get device file descriptor (O_RDONLY|O_NONBLOCK) if (PyArg_ParseTuple(args, "i", &fd) < 0) return NULL; int n = read(fd, &event, sizeof(event)); if (n < 0) { if (errno == EAGAIN) { Py_INCREF(Py_None); return Py_None; } PyErr_SetFromErrno(PyExc_IOError); return NULL; } PyObject* sec = PyLong_FromLong(event.time.tv_sec); PyObject* usec = PyLong_FromLong(event.time.tv_usec); PyObject* val = PyLong_FromLong(event.value); PyObject* py_input_event = NULL; py_input_event = Py_BuildValue("OOhhO", sec, usec, event.type, event.code, val); Py_DECREF(sec); Py_DECREF(usec); Py_DECREF(val); return py_input_event; } // Read multiple input events from a device and return a list of tuples static PyObject * device_read_many(PyObject *self, PyObject *args) { int fd, i; // get device file descriptor (O_RDONLY|O_NONBLOCK) int ret = PyArg_ParseTuple(args, "i", &fd); if (!ret) return NULL; PyObject* event_list = PyList_New(0); PyObject* py_input_event = NULL; PyObject* sec = NULL; PyObject* usec = NULL; PyObject* val = NULL; struct input_event event[64]; size_t event_size = sizeof(struct input_event); ssize_t nread = read(fd, event, event_size*64); if (nread < 0) { PyErr_SetFromErrno(PyExc_IOError); return NULL; } // Construct a list of event tuples, which we'll make sense of in Python for (i = 0 ; i < nread/event_size ; i++) { sec = PyLong_FromLong(event[i].time.tv_sec); usec = PyLong_FromLong(event[i].time.tv_usec); val = PyLong_FromLong(event[i].value); py_input_event = Py_BuildValue("OOhhO", sec, usec, event[i].type, event[i].code, val); PyList_Append(event_list, py_input_event); Py_DECREF(py_input_event); Py_DECREF(sec); Py_DECREF(usec); Py_DECREF(val); } return event_list; } // Unpack a single event (this is essentially a struct.unpack(), without having // to worry about word size. static PyObject * event_unpack(PyObject *self, PyObject *args) { struct input_event event; const char *data; int len; int ret = PyArg_ParseTuple(args, "s#", &data, &len); if (!ret) return NULL; memcpy(&event, data, sizeof(event)); Py_RETURN_NONE; } // Get the event types and event codes that the input device supports static PyObject * ioctl_capabilities(PyObject *self, PyObject *args) { int fd, ev_type, ev_code; char ev_bits[EV_MAX/8 + 1], code_bits[KEY_MAX/8 + 1]; struct input_absinfo absinfo; int ret = PyArg_ParseTuple(args, "i", &fd); if (!ret) return NULL; // @todo: figure out why fd gets zeroed on an ioctl after the // refactoring and get rid of this workaround const int _fd = fd; // Capabilities is a mapping of supported event types to lists of handled // events e.g: {1: [272, 273, 274, 275], 2: [0, 1, 6, 8]} PyObject* capabilities = PyDict_New(); PyObject* eventcodes = NULL; PyObject* evlong = NULL; PyObject* capability = NULL; PyObject* py_absinfo = NULL; PyObject* absitem = NULL; memset(&ev_bits, 0, sizeof(ev_bits)); if (ioctl(_fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) < 0) goto on_err; // Build a dictionary of the device's capabilities for (ev_type=0 ; ev_type tuple(ABS_X, (0, 255, 0, 0)) PyList_Append(eventcodes, absitem); Py_DECREF(absitem); Py_DECREF(py_absinfo); } else { evlong = PyLong_FromLong(ev_code); PyList_Append(eventcodes, evlong); } Py_DECREF(evlong); } } // capabilities[EV_KEY] = [KEY_A, KEY_B, KEY_C, ...] // capabilities[EV_ABS] = [(ABS_X, (0, 255, 0, 0)), ...] PyDict_SetItem(capabilities, capability, eventcodes); Py_DECREF(capability); Py_DECREF(eventcodes); } } return capabilities; on_err: PyErr_SetFromErrno(PyExc_IOError); return NULL; } // An all-in-one function for describing an input device static PyObject * ioctl_devinfo(PyObject *self, PyObject *args) { int fd; struct input_id iid; char name[MAX_NAME_SIZE]; char phys[MAX_NAME_SIZE] = {0}; int ret = PyArg_ParseTuple(args, "i", &fd); if (!ret) return NULL; memset(&iid, 0, sizeof(iid)); if (ioctl(fd, EVIOCGID, &iid) < 0) goto on_err; if (ioctl(fd, EVIOCGNAME(sizeof(name)), name) < 0) goto on_err; // Some devices do not have a physical topology associated with them ioctl(fd, EVIOCGPHYS(sizeof(phys)), phys); return Py_BuildValue("hhhhss", iid.bustype, iid.vendor, iid.product, iid.version, name, phys); on_err: PyErr_SetFromErrno(PyExc_IOError); return NULL; } static PyObject * ioctl_EVIOCGREP(PyObject *self, PyObject *args) { int fd, ret; unsigned int rep[2] = {0}; ret = PyArg_ParseTuple(args, "i", &fd); if (!ret) return NULL; ioctl(fd, EVIOCGREP, &rep); return Py_BuildValue("(ii)", rep[0], rep[1]); } static PyObject * ioctl_EVIOCSREP(PyObject *self, PyObject *args) { int fd, ret; unsigned int rep[2] = {0}; ret = PyArg_ParseTuple(args, "iii", &fd, &rep[0], &rep[1]); if (!ret) return NULL; ret = ioctl(fd, EVIOCSREP, &rep); return Py_BuildValue("i", ret); } static PyObject * ioctl_EVIOCGVERSION(PyObject *self, PyObject *args) { int fd, ret, res; ret = PyArg_ParseTuple(args, "i", &fd); if (!ret) return NULL; ret = ioctl(fd, EVIOCGVERSION, &res); return Py_BuildValue("i", res); } static PyObject * ioctl_EVIOCGRAB(PyObject *self, PyObject *args) { int fd, ret, flag; ret = PyArg_ParseTuple(args, "ii", &fd, &flag); if (!ret) return NULL; ret = ioctl(fd, EVIOCGRAB, (intptr_t)flag); if (ret != 0) { PyErr_SetFromErrno(PyExc_IOError); return NULL; } Py_INCREF(Py_None); return Py_None; } static PyObject * ioctl_EVIOCGKEY(PyObject *self, PyObject *args) { int fd, ret, key; char keys_bitmask[KEY_MAX/8 + 1]; PyObject* res = PyList_New(0); ret = PyArg_ParseTuple(args, "i", &fd); if (!ret) return NULL; memset(&keys_bitmask, 0, sizeof(keys_bitmask)); ret = ioctl(fd, EVIOCGKEY(sizeof(keys_bitmask)), keys_bitmask); if (ret < 0) { PyErr_SetFromErrno(PyExc_IOError); return NULL; } for (key = 0; key < KEY_MAX; key++) { if (test_bit(keys_bitmask, key)) { PyList_Append(res, Py_BuildValue("i", key)); } } return res; } // todo: this function needs a better name static PyObject * get_sw_led_snd(PyObject *self, PyObject *args) { int i, max, fd, evtype, ret; PyObject* res = PyList_New(0); ret = PyArg_ParseTuple(args, "ii", &fd, &evtype); if (!ret) return NULL; if (evtype == EV_LED) max = LED_MAX; else if (evtype == EV_SW) max = SW_MAX; else if (evtype == EV_SND) max = SND_MAX; else return NULL; char bytes[(max+7)/8]; memset(bytes, 0, sizeof bytes); if (evtype == EV_LED) ret = ioctl(fd, EVIOCGLED(sizeof(bytes)), &bytes); else if (evtype == EV_SW) ret = ioctl(fd, EVIOCGSW(sizeof(bytes)), &bytes); else if (evtype == EV_SND) ret = ioctl(fd, EVIOCGSND(sizeof(bytes)), &bytes); for (i=0 ; itype, effect->id, effect->direction, effect->trigger.button, effect->trigger.interval, effect->replay.length, effect->replay.delay ); switch (effect->type) { case FF_CONSTANT: fprintf(stderr, " constant: (%d, (%d, %d, %d, %d))\n", effect->u.constant.level, effect->u.constant.envelope.attack_length, effect->u.constant.envelope.attack_level, effect->u.constant.envelope.fade_length, effect->u.constant.envelope.fade_level); break; } } static PyObject * upload_effect(PyObject *self, PyObject *args) { int fd, ret; PyObject* effect_data; ret = PyArg_ParseTuple(args, "iO", &fd, &effect_data); if (!ret) return NULL; void* data = PyBytes_AsString(effect_data); struct ff_effect effect = {}; memmove(&effect, data, sizeof(struct ff_effect)); // print_ff_effect(&effect); ret = ioctl(fd, EVIOCSFF, &effect); if (ret != 0) { PyErr_SetFromErrno(PyExc_IOError); return NULL; } return Py_BuildValue("i", effect.id); } static PyObject * erase_effect(PyObject *self, PyObject *args) { int fd, ret; PyObject* ff_id_obj; ret = PyArg_ParseTuple(args, "iO", &fd, &ff_id_obj); if (!ret) return NULL; long ff_id = PyLong_AsLong(ff_id_obj); ret = ioctl(fd, EVIOCRMFF, ff_id); if (ret != 0) { PyErr_SetFromErrno(PyExc_IOError); return NULL; } Py_INCREF(Py_None); return Py_None; } static PyMethodDef MethodTable[] = { { "unpack", event_unpack, METH_VARARGS, "unpack a single input event" }, { "ioctl_devinfo", ioctl_devinfo, METH_VARARGS, "fetch input device info" }, { "ioctl_capabilities", ioctl_capabilities, METH_VARARGS, "fetch input device capabilities" }, { "ioctl_EVIOCGREP", ioctl_EVIOCGREP, METH_VARARGS}, { "ioctl_EVIOCSREP", ioctl_EVIOCSREP, METH_VARARGS}, { "ioctl_EVIOCGVERSION", ioctl_EVIOCGVERSION, METH_VARARGS}, { "ioctl_EVIOCGRAB", ioctl_EVIOCGRAB, METH_VARARGS}, { "ioctl_EVIOCGKEY", ioctl_EVIOCGKEY, METH_VARARGS, "get global key state" }, { "ioctl_EVIOCGEFFECTS", ioctl_EVIOCGEFFECTS, METH_VARARGS, "fetch the number of effects the device can keep in its memory." }, { "get_sw_led_snd", get_sw_led_snd, METH_VARARGS}, { "device_read", device_read, METH_VARARGS, "read an input event from a device" }, { "device_read_many", device_read_many, METH_VARARGS, "read all available input events from a device" }, { "upload_effect", upload_effect, METH_VARARGS, "" }, { "erase_effect", erase_effect, METH_VARARGS, "" }, { NULL, NULL, 0, NULL} }; #define MODULE_NAME "_input" #define MODULE_HELP "Python bindings to certain linux input subsystem functions" #if PY_MAJOR_VERSION >= 3 static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, MODULE_NAME, MODULE_HELP, -1, /* m_size */ MethodTable, /* m_methods */ NULL, /* m_reload */ NULL, /* m_traverse */ NULL, /* m_clear */ NULL, /* m_free */ }; static PyObject * moduleinit(void) { PyObject* m = PyModule_Create(&moduledef); if (m == NULL) return NULL; return m; } PyMODINIT_FUNC PyInit__input(void) { return moduleinit(); } #else static PyObject * moduleinit(void) { PyObject* m = Py_InitModule3(MODULE_NAME, MethodTable, MODULE_HELP); if (m == NULL) return NULL; return m; } PyMODINIT_FUNC init_input(void) { moduleinit(); } #endif evdev-0.4.7/evdev/uinput.c0000660000175000017500000001334512415045102014504 0ustar gvgv00000000000000#include #include #include #include #include #include #include #include #ifdef __FreeBSD__ #include #include #else #include #include #endif int _uinput_close(int fd) { if (ioctl(fd, UI_DEV_DESTROY) < 0) { int oerrno = errno; close(fd); errno = oerrno; return -1; } return close(fd); } static PyObject * uinput_open(PyObject *self, PyObject *args) { const char* devnode; int ret = PyArg_ParseTuple(args, "s", &devnode); if (!ret) return NULL; int fd = open(devnode, O_WRONLY | O_NONBLOCK); if (fd < 0) { PyErr_SetString(PyExc_IOError, "could not open uinput device in write mode"); return NULL; } return Py_BuildValue("i", fd); } static PyObject * uinput_create(PyObject *self, PyObject *args) { int fd, len, i, abscode; uint16_t vendor, product, version, bustype; PyObject *absinfo = NULL, *item = NULL; struct uinput_user_dev uidev; const char* name; int ret = PyArg_ParseTuple(args, "ishhhhO", &fd, &name, &vendor, &product, &version, &bustype, &absinfo); if (!ret) return NULL; memset(&uidev, 0, sizeof(uidev)); strncpy(uidev.name, name, UINPUT_MAX_NAME_SIZE); uidev.id.vendor = vendor; uidev.id.product = product; uidev.id.version = version; uidev.id.bustype = bustype; len = PyList_Size(absinfo); for (i=0; i (ABS_X, 0, 255, 0, 0) item = PyList_GetItem(absinfo, i); abscode = (int)PyLong_AsLong(PyList_GetItem(item, 0)); uidev.absmin[abscode] = PyLong_AsLong(PyList_GetItem(item, 1)); uidev.absmax[abscode] = PyLong_AsLong(PyList_GetItem(item, 2)); uidev.absfuzz[abscode] = PyLong_AsLong(PyList_GetItem(item, 3)); uidev.absflat[abscode] = PyLong_AsLong(PyList_GetItem(item, 4)); } if (write(fd, &uidev, sizeof(uidev)) != sizeof(uidev)) goto on_err; /* if (ioctl(fd, UI_SET_EVBIT, EV_KEY) < 0) */ /* goto on_err; */ /* int i; */ /* for (i=0; i= 3 static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, MODULE_NAME, MODULE_HELP, -1, /* m_size */ MethodTable, /* m_methods */ NULL, /* m_reload */ NULL, /* m_traverse */ NULL, /* m_clear */ NULL, /* m_free */ }; static PyObject * moduleinit(void) { PyObject* m = PyModule_Create(&moduledef); if (m == NULL) return NULL; PyModule_AddIntConstant(m, "maxnamelen", UINPUT_MAX_NAME_SIZE); return m; } PyMODINIT_FUNC PyInit__uinput(void) { return moduleinit(); } #else static PyObject * moduleinit(void) { PyObject* m = Py_InitModule3(MODULE_NAME, MethodTable, MODULE_HELP); if (m == NULL) return NULL; PyModule_AddIntConstant(m, "maxnamelen", UINPUT_MAX_NAME_SIZE); return m; } PyMODINIT_FUNC init_uinput(void) { moduleinit(); } #endif evdev-0.4.7/evdev/uinput.py0000640000175000017500000001550612403115625014716 0ustar gvgv00000000000000# encoding: utf-8 import os import stat import time from evdev import _uinput from evdev import ecodes, util, device class UInputError(Exception): pass class UInput(object): ''' A userland input device and that can inject input events into the linux input subsystem. ''' __slots__ = ( 'name', 'vendor', 'product', 'version', 'bustype', 'events', 'devnode', 'fd', 'device', ) def __init__(self, events=None, name='py-evdev-uinput', vendor=0x1, product=0x1, version=0x1, bustype=0x3, devnode='/dev/uinput'): ''' :param events: the event types and codes that the uinput device will be able to inject - defaults to all key codes. :type events: dictionary of event types mapping to lists of event codes. :param name: the name of the input device. :param vendor: vendor identifier. :param product: product identifier. :param version: version identifier. :param bustype: bustype identifier. .. note:: If you do not specify any events, the uinput device will be able to inject only ``KEY_*`` and ``BTN_*`` event codes. ''' self.name = name #: Uinput device name. self.vendor = vendor #: Device vendor identifier. self.product = product #: Device product identifier. self.version = version #: Device version identifier. self.bustype = bustype #: Device bustype - eg. ``BUS_USB``. self.devnode = devnode #: Uinput device node - eg. ``/dev/uinput/``. if not events: events = {ecodes.EV_KEY: ecodes.keys.keys()} # the min, max, fuzz and flat values for the absolute axis for # a given code absinfo = [] self._verify() #: Write-only, non-blocking file descriptor to the uinput device node. self.fd = _uinput.open(devnode) # set device capabilities for etype, codes in events.items(): for code in codes: # handle max, min, fuzz, flat if isinstance(code, (tuple, list, device.AbsInfo)): # flatten (ABS_Y, (0, 255, 0, 0)) to (ABS_Y, 0, 255, 0, 0) f = [code[0]]; f += code[1] absinfo.append(f) code = code[0] #:todo: a lot of unnecessary packing/unpacking _uinput.enable(self.fd, etype, code) # create uinput device _uinput.create(self.fd, name, vendor, product, version, bustype, absinfo) #: An :class:`InputDevice ` instance #: for the fake input device. ``None`` if the device cannot be #: opened for reading and writing. self.device = self._find_device() def __enter__(self): return self def __exit__(self, type, value, tb): if hasattr(self, 'fd'): self.close() def __repr__(self): # :todo: v = (repr(getattr(self, i)) for i in ('name', 'bustype', 'vendor', 'product', 'version')) return '{}({})'.format(self.__class__.__name__, ', '.join(v)) def __str__(self): msg = ('name "{}", bus "{}", vendor "{:04x}", product "{:04x}", version "{:04x}"\n' 'event types: {}') evtypes = [i[0] for i in self.capabilities(True).keys()] msg = msg.format(self.name, ecodes.BUS[self.bustype], self.vendor, self.product, self.version, ' '.join(evtypes)) return msg def close(self): # close the associated InputDevice, if it was previously opened if self.device is not None: self.device.close() # destroy the uinput device if self.fd > -1: _uinput.close(self.fd) self.fd = -1 def write_event(self, event): ''' Inject an input event into the input subsystem. Events are queued until a synchronization event is received. :param event: InputEvent instance or an object with an ``event`` attribute (:class:`KeyEvent `, :class:`RelEvent ` etc). Example:: ev = InputEvent(1334414993, 274296, ecodes.EV_KEY, ecodes.KEY_A, 1) ui.write_event(ev) ''' if hasattr(event, 'event'): event = event.event self.write(event.type, event.code, event.value) def write(self, etype, code, value): ''' Inject an input event into the input subsystem. Events are queued until a synchronization event is received. :param etype: event type (eg. ``EV_KEY``). :param code: event code (eg. ``KEY_A``). :param value: event value (eg. 0 1 2 - depends on event type). Example:: ui.write(e.EV_KEY, e.KEY_A, 1) # key A - down ui.write(e.EV_KEY, e.KEY_A, 0) # key A - up ''' _uinput.write(self.fd, etype, code, value) def syn(self): ''' Inject a ``SYN_REPORT`` event into the input subsystem. Events queued by :func:`write()` will be fired. If possible, events will be merged into an 'atomic' event. ''' _uinput.write(self.fd, ecodes.EV_SYN, ecodes.SYN_REPORT, 0) def capabilities(self, verbose=False, absinfo=True): '''See :func:`capabilities `.''' if self.device is None: raise UInputError('input device not opened - cannot read capabilites') return self.device.capabilities(verbose, absinfo) def _verify(self): ''' Verify that an uinput device exists and is readable and writable by the current process. ''' try: m = os.stat(self.devnode)[stat.ST_MODE] if not stat.S_ISCHR(m): raise except (IndexError, OSError): msg = '"{}" does not exist or is not a character device file '\ '- verify that the uinput module is loaded' raise UInputError(msg.format(self.devnode)) if not os.access(self.devnode, os.W_OK): msg = '"{}" cannot be opened for writing' raise UInputError(msg.format(self.devnode)) if len(self.name) > _uinput.maxnamelen: msg = 'uinput device name must not be longer than {} characters' raise UInputError(msg.format(_uinput.maxnamelen)) def _find_device(self): #:bug: the device node might not be immediately available time.sleep(0.1) for fn in util.list_devices('/dev/input/'): d = device.InputDevice(fn) if d.name == self.name: return d evdev-0.4.7/evdev/util.py0000640000175000017500000000523012403116000014324 0ustar gvgv00000000000000# encoding: utf-8 import os import stat import glob from evdev import ecodes from evdev.events import event_factory def list_devices(input_device_dir='/dev/input'): '''List readable character devices in ``input_device_dir``.''' fns = glob.glob('{}/event*'.format(input_device_dir)) fns = list(filter(is_device, fns)) return fns def is_device(fn): '''Check if ``fn`` is a readable and writable character device.''' if not os.path.exists(fn): return False m = os.stat(fn)[stat.ST_MODE] if not stat.S_ISCHR(m): return False if not os.access(fn, os.R_OK | os.W_OK): return False return True def categorize(event): ''' Categorize an event according to its type. The :data:`event_factory ` dictionary maps event types to sub-classes of :class:`InputEvent `. If the event cannot be categorized, it is returned unmodified.''' if event.type in event_factory: return event_factory[event.type](event) else: return event def resolve_ecodes(typecodemap, unknown='?'): ''' Resolve event codes and types to their verbose names. :param typecodemap: mapping of event types to lists of event codes. :param unknown: symbol to which unknown types or codes will be resolved. Example:: resolve_ecodes({ 1: [272, 273, 274] }) { ('EV_KEY', 1): [('BTN_MOUSE', 272), ('BTN_RIGHT', 273), ('BTN_MIDDLE', 274)] } If ``typecodemap`` contains absolute axis info (instances of :class:`AbsInfo ` ) the result would look like:: resolve_ecodes({ 3: [(0, AbsInfo(...))] }) { ('EV_ABS', 3L): [(('ABS_X', 0L), AbsInfo(...))] } ''' for etype, codes in typecodemap.items(): type_name = ecodes.EV[etype] # ecodes.keys are a combination of KEY_ and BTN_ codes if etype == ecodes.EV_KEY: code_names = ecodes.keys else: code_names = getattr(ecodes, type_name.split('_')[-1]) res = [] for i in codes: # elements with AbsInfo(), eg { 3 : [(0, AbsInfo(...)), (1, AbsInfo(...))] } if isinstance(i, tuple): l = ((code_names[i[0]], i[0]), i[1]) if i[0] in code_names \ else ((unknown, i[0]), i[1]) # just ecodes { 0 : [0, 1, 3], 1 : [30, 48] } else: l = (code_names[i], i) if i in code_names else (unknown, i) res.append(l) yield (type_name, etype), res __all__ = ('list_devices', 'is_device', 'categorize', 'resolve_ecodes') evdev-0.4.7/evdev.egg-info/0000770000175000017500000000000012454333505014511 5ustar gvgv00000000000000evdev-0.4.7/evdev.egg-info/PKG-INFO0000660000175000017500000000333512454333505015613 0ustar gvgv00000000000000Metadata-Version: 1.1 Name: evdev Version: 0.4.7 Summary: Bindings to the Linux input handling subsystem Home-page: https://github.com/gvalkov/python-evdev Author: Georgi Valkov Author-email: georgi.t.valkov@gmail.com License: Revised BSD License Description: *evdev* ------- This package provides bindings to the generic input event interface in Linux. The *evdev* interface serves the purpose of passing events generated in the kernel directly to userspace through character devices that are typically located in ``/dev/input/``. This package also comes with bindings to *uinput*, the userspace input subsystem. *Uinput* allows userspace programs to create and handle input devices that can inject events directly into the input subsystem. Documentation: http://python-evdev.readthedocs.org/en/latest/ Development: https://github.com/gvalkov/python-evdev Package: http://pypi.python.org/pypi/evdev Changelog: http://python-evdev.readthedocs.org/en/latest/changelog.html Keywords: evdev input uinput Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: 3.4 Classifier: Operating System :: POSIX :: Linux Classifier: Intended Audience :: Developers Classifier: Topic :: Software Development :: Libraries Classifier: License :: OSI Approved :: BSD License Classifier: Programming Language :: Python :: Implementation :: CPython evdev-0.4.7/evdev.egg-info/SOURCES.txt0000660000175000017500000000062012454333505016374 0ustar gvgv00000000000000LICENSE MANIFEST.in README.rst setup.py evdev/__init__.py evdev/_ecodes.py evdev/_input.py evdev/_uinput.py evdev/device.py evdev/ecodes.c evdev/ecodes.py evdev/events.py evdev/ff.py evdev/genecodes.py evdev/input.c evdev/uinput.c evdev/uinput.py evdev/util.py evdev.egg-info/PKG-INFO evdev.egg-info/SOURCES.txt evdev.egg-info/dependency_links.txt evdev.egg-info/top_level.txt evdev.egg-info/zip-safeevdev-0.4.7/evdev.egg-info/dependency_links.txt0000660000175000017500000000000112454333505020560 0ustar gvgv00000000000000 evdev-0.4.7/evdev.egg-info/top_level.txt0000660000175000017500000000000612454333505017240 0ustar gvgv00000000000000evdev evdev-0.4.7/evdev.egg-info/zip-safe0000660000175000017500000000000112454331163016140 0ustar gvgv00000000000000 evdev-0.4.7/LICENSE0000660000175000017500000000274312454277245012732 0ustar gvgv00000000000000Copyright (c) 2012-2015 Georgi Valkov. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. evdev-0.4.7/MANIFEST.in0000640000175000017500000000013412266517410013441 0ustar gvgv00000000000000# make github and sdist happy include README.rst include evdev/genecodes.py include LICENSE evdev-0.4.7/README.rst0000600000175000017500000000133612236533701013371 0ustar gvgv00000000000000*evdev* ------- This package provides bindings to the generic input event interface in Linux. The *evdev* interface serves the purpose of passing events generated in the kernel directly to userspace through character devices that are typically located in ``/dev/input/``. This package also comes with bindings to *uinput*, the userspace input subsystem. *Uinput* allows userspace programs to create and handle input devices that can inject events directly into the input subsystem. Documentation: http://python-evdev.readthedocs.org/en/latest/ Development: https://github.com/gvalkov/python-evdev Package: http://pypi.python.org/pypi/evdev Changelog: http://python-evdev.readthedocs.org/en/latest/changelog.html evdev-0.4.7/setup.py0000770000175000017500000000723112454333326013427 0ustar gvgv00000000000000#!/usr/bin/env python # encoding: utf-8 import os import sys import textwrap from os.path import abspath, dirname, join as pjoin from distutils.command import build #----------------------------------------------------------------------------- try: from setuptools import setup, Extension from setuptools.command import bdist_egg, develop except ImportError: from distutils.core import setup, Extension from distutils.command import build develop, bdist_egg = None, None #----------------------------------------------------------------------------- here = abspath(dirname(__file__)) #----------------------------------------------------------------------------- classifiers = [ 'Development Status :: 5 - Production/Stable', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', 'Operating System :: POSIX :: Linux', 'Intended Audience :: Developers', 'Topic :: Software Development :: Libraries', 'License :: OSI Approved :: BSD License', 'Programming Language :: Python :: Implementation :: CPython', ] #----------------------------------------------------------------------------- cflags = ['-std=c99', '-Wno-error=declaration-after-statement'] input_c = Extension('evdev._input', sources=['evdev/input.c'], extra_compile_args=cflags) uinput_c = Extension('evdev._uinput', sources=['evdev/uinput.c'], extra_compile_args=cflags) ecodes_c = Extension('evdev._ecodes', sources=['evdev/ecodes.c'], extra_compile_args=cflags) #----------------------------------------------------------------------------- kw = { 'name': 'evdev', 'version': '0.4.7', 'description': 'Bindings to the Linux input handling subsystem', 'long_description': open(pjoin(here, 'README.rst')).read(), 'author': 'Georgi Valkov', 'author_email': 'georgi.t.valkov@gmail.com', 'license': 'Revised BSD License', 'keywords': 'evdev input uinput', 'url': 'https://github.com/gvalkov/python-evdev', 'classifiers': classifiers, 'packages': ['evdev'], 'ext_modules': [input_c, uinput_c, ecodes_c], 'include_package_data': False, 'zip_safe': True, 'cmdclass': {}, } #----------------------------------------------------------------------------- def create_ecodes(): header = '/usr/include/linux/input.h' if not os.path.isfile(header): msg = '''\ The linux/input.h header file is missing. You will have to install the headers for your kernel in order to continue: yum install kernel-headers-$(uname -r) apt-get install linux-headers-$(uname -r) pacman -S kernel-headers\n\n''' sys.stderr.write(textwrap.dedent(msg)) sys.exit(1) from subprocess import check_call print('writing ecodes.c (using %s)' % header) cmd = '%s genecodes.py %s > ecodes.c' % (sys.executable, header) check_call(cmd, cwd="%s/evdev" % here, shell=True) def cmdfactory(cmd): class cls(cmd): def run(self): create_ecodes() cmd.run(self) return cls #----------------------------------------------------------------------------- kw['cmdclass']['build'] = cmdfactory(build.build) if develop and bdist_egg: kw['cmdclass']['develop'] = cmdfactory(develop.develop) kw['cmdclass']['bdist_egg'] = cmdfactory(bdist_egg.bdist_egg) #----------------------------------------------------------------------------- if __name__ == '__main__': setup(**kw) evdev-0.4.7/PKG-INFO0000660000175000017500000000333512454333505013010 0ustar gvgv00000000000000Metadata-Version: 1.1 Name: evdev Version: 0.4.7 Summary: Bindings to the Linux input handling subsystem Home-page: https://github.com/gvalkov/python-evdev Author: Georgi Valkov Author-email: georgi.t.valkov@gmail.com License: Revised BSD License Description: *evdev* ------- This package provides bindings to the generic input event interface in Linux. The *evdev* interface serves the purpose of passing events generated in the kernel directly to userspace through character devices that are typically located in ``/dev/input/``. This package also comes with bindings to *uinput*, the userspace input subsystem. *Uinput* allows userspace programs to create and handle input devices that can inject events directly into the input subsystem. Documentation: http://python-evdev.readthedocs.org/en/latest/ Development: https://github.com/gvalkov/python-evdev Package: http://pypi.python.org/pypi/evdev Changelog: http://python-evdev.readthedocs.org/en/latest/changelog.html Keywords: evdev input uinput Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: 3.4 Classifier: Operating System :: POSIX :: Linux Classifier: Intended Audience :: Developers Classifier: Topic :: Software Development :: Libraries Classifier: License :: OSI Approved :: BSD License Classifier: Programming Language :: Python :: Implementation :: CPython evdev-0.4.7/setup.cfg0000660000175000017500000000007312454333505013530 0ustar gvgv00000000000000[egg_info] tag_svn_revision = 0 tag_build = tag_date = 0