523 lines
16 KiB
Diff
523 lines
16 KiB
Diff
diff -Naur orig/evdev/device.py v0.4.7/evdev/device.py
|
|
--- orig/evdev/device.py 2015-06-11 14:05:00.452884781 -0500
|
|
+++ v0.4.7/evdev/device.py 2015-06-11 14:05:47.606553546 -0500
|
|
@@ -4,7 +4,7 @@
|
|
from select import select
|
|
from collections import namedtuple
|
|
|
|
-from evdev import _input, _uinput, ecodes, util
|
|
+from evdev import _input, ecodes, util
|
|
from evdev.events import InputEvent
|
|
|
|
|
|
@@ -203,7 +203,7 @@
|
|
|
|
..
|
|
'''
|
|
- _uinput.write(self.fd, ecodes.EV_LED, led_num, value)
|
|
+ pass
|
|
|
|
def __eq__(self, other):
|
|
'''Two devices are equal if their :data:`info` attributes are equal.'''
|
|
diff -Naur orig/evdev/__init__.py v0.4.7/evdev/__init__.py
|
|
--- orig/evdev/__init__.py 2015-06-11 14:05:00.452884781 -0500
|
|
+++ v0.4.7/evdev/__init__.py 2015-06-11 14:05:22.973204070 -0500
|
|
@@ -6,7 +6,6 @@
|
|
|
|
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
|
|
diff -Naur orig/evdev/uinput.c v0.4.7/evdev/uinput.c
|
|
--- orig/evdev/uinput.c 2015-06-11 14:05:00.453884795 -0500
|
|
+++ v0.4.7/evdev/uinput.c 1969-12-31 18:00:00.000000000 -0600
|
|
@@ -1,255 +0,0 @@
|
|
-#include <Python.h>
|
|
-
|
|
-#include <stdio.h>
|
|
-#include <string.h>
|
|
-#include <errno.h>
|
|
-#include <sys/types.h>
|
|
-#include <sys/stat.h>
|
|
-#include <fcntl.h>
|
|
-#include <unistd.h>
|
|
-
|
|
-#ifdef __FreeBSD__
|
|
-#include <dev/evdev/input.h>
|
|
-#include <dev/evdev/uinput.h>
|
|
-#else
|
|
-#include <linux/input.h>
|
|
-#include <linux/uinput.h>
|
|
-#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<len; i++) {
|
|
- // item -> (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<KEY_MAX && fd; i++) { */
|
|
- /* if (ioctl(fd, UI_SET_KEYBIT, i) < 0) */
|
|
- /* goto on_err; */
|
|
- /* } */
|
|
-
|
|
- if (ioctl(fd, UI_DEV_CREATE) < 0)
|
|
- goto on_err;
|
|
-
|
|
- Py_RETURN_NONE;
|
|
-
|
|
- on_err:
|
|
- _uinput_close(fd);
|
|
- PyErr_SetFromErrno(PyExc_IOError);
|
|
- return NULL;
|
|
-}
|
|
-
|
|
-
|
|
-static PyObject *
|
|
-uinput_close(PyObject *self, PyObject *args)
|
|
-{
|
|
- int fd;
|
|
-
|
|
- int ret = PyArg_ParseTuple(args, "i", &fd);
|
|
- if (!ret) return NULL;
|
|
-
|
|
- if (_uinput_close(fd) < 0) {
|
|
- PyErr_SetFromErrno(PyExc_IOError);
|
|
- return NULL;
|
|
- }
|
|
-
|
|
- Py_RETURN_NONE;
|
|
-}
|
|
-
|
|
-
|
|
-static PyObject *
|
|
-uinput_write(PyObject *self, PyObject *args)
|
|
-{
|
|
- int fd, type, code, value;
|
|
-
|
|
- int ret = PyArg_ParseTuple(args, "iiii", &fd, &type, &code, &value);
|
|
- if (!ret) return NULL;
|
|
-
|
|
- struct input_event event;
|
|
- memset(&event, 0, sizeof(event));
|
|
- gettimeofday(&event.time, 0);
|
|
- event.type = type;
|
|
- event.code = code;
|
|
- event.value = value;
|
|
-
|
|
- if (write(fd, &event, sizeof(event)) != sizeof(event)) {
|
|
- // @todo: elaborate
|
|
- // PyErr_SetString(PyExc_IOError, "error writing event to uinput device");
|
|
- PyErr_SetFromErrno(PyExc_IOError);
|
|
- return NULL;
|
|
- }
|
|
-
|
|
- Py_RETURN_NONE;
|
|
-}
|
|
-
|
|
-
|
|
-static PyObject *
|
|
-uinput_enable_event(PyObject *self, PyObject *args)
|
|
-{
|
|
- int fd;
|
|
- uint16_t type, code;
|
|
- unsigned long req;
|
|
-
|
|
- int ret = PyArg_ParseTuple(args, "ihh", &fd, &type, &code);
|
|
- if (!ret) return NULL;
|
|
-
|
|
- switch (type) {
|
|
- case EV_KEY: req = UI_SET_KEYBIT; break;
|
|
- case EV_ABS: req = UI_SET_ABSBIT; break;
|
|
- case EV_REL: req = UI_SET_RELBIT; break;
|
|
- case EV_MSC: req = UI_SET_MSCBIT; break;
|
|
- case EV_SW: req = UI_SET_SWBIT; break;
|
|
- case EV_LED: req = UI_SET_LEDBIT; break;
|
|
- case EV_FF: req = UI_SET_FFBIT; break;
|
|
- case EV_SND: req = UI_SET_SNDBIT; break;
|
|
- default:
|
|
- errno = EINVAL;
|
|
- goto on_err;
|
|
- }
|
|
-
|
|
- if (ioctl(fd, UI_SET_EVBIT, type) < 0)
|
|
- goto on_err;
|
|
-
|
|
- if (ioctl(fd, req, code) < 0)
|
|
- goto on_err;
|
|
-
|
|
- Py_RETURN_NONE;
|
|
-
|
|
- on_err:
|
|
- _uinput_close(fd);
|
|
- PyErr_SetFromErrno(PyExc_IOError);
|
|
- return NULL;
|
|
-}
|
|
-
|
|
-
|
|
-#define MODULE_NAME "_uinput"
|
|
-#define MODULE_HELP "Python bindings for parts of linux/uinput.c"
|
|
-
|
|
-static PyMethodDef MethodTable[] = {
|
|
- { "open", uinput_open, METH_VARARGS,
|
|
- "Open uinput device node."},
|
|
-
|
|
- { "create", uinput_create, METH_VARARGS,
|
|
- "Create an uinput device."},
|
|
-
|
|
- { "close", uinput_close, METH_VARARGS,
|
|
- "Destroy uinput device."},
|
|
-
|
|
- { "write", uinput_write, METH_VARARGS,
|
|
- "Write event to uinput device."},
|
|
-
|
|
- { "enable", uinput_enable_event, METH_VARARGS,
|
|
- "Enable a type of event."},
|
|
-
|
|
- { 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 */
|
|
-};
|
|
-
|
|
-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
|
|
diff -Naur orig/evdev/uinput.py v0.4.7/evdev/uinput.py
|
|
--- orig/evdev/uinput.py 2015-06-11 14:05:00.453884795 -0500
|
|
+++ v0.4.7/evdev/uinput.py 1969-12-31 18:00:00.000000000 -0600
|
|
@@ -1,208 +0,0 @@
|
|
-# 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 <evdev.device.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
|
|
- <evdev.events.KeyEvent>`, :class:`RelEvent
|
|
- <evdev.events.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 <evdev.device.InputDevice.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
|
|
diff -Naur orig/setup.py v0.4.7/setup.py
|
|
--- orig/setup.py 2015-06-11 14:05:00.450884753 -0500
|
|
+++ v0.4.7/setup.py 2015-06-11 14:06:13.050914776 -0500
|
|
@@ -37,7 +37,6 @@
|
|
#-----------------------------------------------------------------------------
|
|
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)
|
|
|
|
#-----------------------------------------------------------------------------
|
|
@@ -56,7 +55,7 @@
|
|
'classifiers': classifiers,
|
|
|
|
'packages': ['evdev'],
|
|
- 'ext_modules': [input_c, uinput_c, ecodes_c],
|
|
+ 'ext_modules': [input_c, ecodes_c],
|
|
'include_package_data': False,
|
|
'zip_safe': True,
|
|
'cmdclass': {},
|