evdev-0.4.1/0000775000175000017500000000000012173701335011703 5ustar gvgv00000000000000evdev-0.4.1/README.rst0000664000175000017500000001063212173700424013372 0ustar gvgv00000000000000*evdev* ---------------------------------------- *evdev* 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/``. *evdev* also comes with bindings to *uinput*, the userspace input subsystem. *Uinput* allows userspace programs to create and handle input devices from which input events can be directly injected into the input subsystem. Documentation: http://packages.python.org/evdev Development: https://github.com/gvalkov/python-evdev PyPi: http://pypi.python.org/pypi/evdev Changelog ========= 0.4.1 (Jul 24, 2013) ^^^^^^^^^^^ Fixes: - Fix reference counting in ``device_read``, ``device_read_many`` and ``ioctl_capabilities``. 0.4.0 (Jul 01, 2013) ^^^^^^^^^^^^^^^^^^^^ Enhancements: - Add ``FF_*`` and ``FF_STATUS`` codes to ``ecodes`` (thanks @bgilbert). - Reverse event code mappings (``ecodes.{KEY,FF,REL,ABS}`` and etc.) will now map to a list of codes, whenever a value corresponds to multiple codes:: >>> ecodes.KEY[152] ... ['KEY_COFFEE', 'KEY_SCREENLOCK'] >>> ecodes.KEY[30] ... 'KEY_A' - Set the state of a LED through ``device.set_led()`` (thanks @accek). ``device.fd`` is opened in ``O_RDWR`` mode from now on. Fixes: - Fix segfault in ``device_read_many()`` (thanks @bgilbert). 0.3.3 (May 29, 2013) ^^^^^^^^^^^^^^^^^^^^ Fixes: - Raise ``IOError`` from ``device_read()`` and ``device_read_many()`` when ``read()`` fails. - Several stability and style changes (thank you debian code reviewers). 0.3.2 (Apr 05, 2013) ^^^^^^^^^^^^^^^^^^^^ Fixes: - Fix vendor id and product id order in ``DeviceInfo`` (thanks @kived). 0.3.1 (Nov 23, 2012) ^^^^^^^^^^^^^^^^^^^^ Fixes: - ``device.read()`` will return an empty tuple if the device has nothing to offer (instead of segfaulting). - Exclude unnecessary package data in sdist and bdist. 0.3.0 (Nov 06, 2012) ^^^^^^^^^^^^^^^^^^^^ Enhancements: - Add ability to set/get auto-repeat settings with ``EVIOC{SG}REP``. - Add ``device.version`` - the value of ``EVIOCGVERSION``. - Add ``device.read_loop()``. - Add ``device.grab()`` and ``device.ungrab()`` - exposes ``EVIOCGRAB``. - Add ``device.leds`` - exposes ``EVIOCGLED``. - Replace ``DeviceInfo`` class with a namedtuple. Fixes: - ``device.read_one()`` was dropping events. - Rename ``AbsData`` to ``AbsInfo`` (as in ``struct input_absinfo``). 0.2.0 (Aug 22, 2012) ^^^^^^^^^^^^^^^^^^^^ Enhancements: - Add the ability to set arbitrary device capabilities on uinput devices (defaults to all ``EV_KEY`` ecodes). - Add ``UInput.device`` which is an open ``InputDevice`` to the input device that uinput 'spawns'. - Add ``UInput.capabilities()`` which is just a shortcut to ``UInput.device.capabilities()``. - Rename ``UInput.write()`` to ``UInput.write_event()``. - Add a simpler ``UInput.write(type, code, value)`` method. - Make all ``UInput`` constructor arguments optional (default device name is now ``py-evdev-uinput``). - Add the ability to set ``absmin``, ``absmax``, ``absfuzz`` and ``absflat`` when specifying the uinput device's capabilities. - Remove the ``nophys`` argument - if a device fails the ``EVIOCGPHYS`` ioctl, phys will equal the empty string. - Make ``InputDevice.capabilities()`` perform a ``EVIOCGABS`` ioctl for devices that support ``EV_ABS`` and return that info wrapped in an ``AbsData`` namedtuple. - Split ``ioctl_devinfo`` into ``ioctl_devinfo`` and ``ioctl_capabilities``. - Split ``uinput_open()`` to ``uinput_open()`` and ``uinput_create()`` - Add more uinput usage examples and documentation. - Rewrite uinput tests. - Remove ``mouserel`` and ``mouseabs`` from ``UInput``. - Tie the sphinx version and release to the distutils version. - Set 'methods-before-attributes' sorting in the docs. Fixes: - Remove ``KEY_CNT`` and ``KEY_MAX`` from ``ecodes.keys``. 0.1.1 (May 18, 2012) ^^^^^^^^^^^^^^^^^^^^ Enhancements: - Add ``events.keys``, which is a combination of all ``BTN_`` and ``KEY_`` event codes. Fixes: - ``ecodes.c`` was not generated when installing through ``pip``. 0.1.0 (May 17, 2012) ^^^^^^^^^^^^^^^^^^^^ *Initial Release* evdev-0.4.1/evdev.egg-info/0000775000175000017500000000000012173701335014506 5ustar gvgv00000000000000evdev-0.4.1/evdev.egg-info/SOURCES.txt0000664000175000017500000000051712173701335016375 0ustar gvgv00000000000000LICENSE MANIFEST.in README.rst setup.py evdev/__init__.py evdev/device.py evdev/ecodes.c evdev/ecodes.py evdev/ecodes.sh evdev/events.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.1/evdev.egg-info/PKG-INFO0000664000175000017500000001500112173701335015600 0ustar gvgv00000000000000Metadata-Version: 1.1 Name: evdev Version: 0.4.1 Summary: bindings for the linux input handling subsystem Home-page: https://github.com/gvalkov/python-evdev Author: Georgi Valkov Author-email: georgi.t.valkov@gmail.com License: New BSD License Description: *evdev* ---------------------------------------- *evdev* 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/``. *evdev* also comes with bindings to *uinput*, the userspace input subsystem. *Uinput* allows userspace programs to create and handle input devices from which input events can be directly injected into the input subsystem. Documentation: http://packages.python.org/evdev Development: https://github.com/gvalkov/python-evdev PyPi: http://pypi.python.org/pypi/evdev Changelog ========= 0.4.1 (Jul 24, 2013) ^^^^^^^^^^^ Fixes: - Fix reference counting in ``device_read``, ``device_read_many`` and ``ioctl_capabilities``. 0.4.0 (Jul 01, 2013) ^^^^^^^^^^^^^^^^^^^^ Enhancements: - Add ``FF_*`` and ``FF_STATUS`` codes to ``ecodes`` (thanks @bgilbert). - Reverse event code mappings (``ecodes.{KEY,FF,REL,ABS}`` and etc.) will now map to a list of codes, whenever a value corresponds to multiple codes:: >>> ecodes.KEY[152] ... ['KEY_COFFEE', 'KEY_SCREENLOCK'] >>> ecodes.KEY[30] ... 'KEY_A' - Set the state of a LED through ``device.set_led()`` (thanks @accek). ``device.fd`` is opened in ``O_RDWR`` mode from now on. Fixes: - Fix segfault in ``device_read_many()`` (thanks @bgilbert). 0.3.3 (May 29, 2013) ^^^^^^^^^^^^^^^^^^^^ Fixes: - Raise ``IOError`` from ``device_read()`` and ``device_read_many()`` when ``read()`` fails. - Several stability and style changes (thank you debian code reviewers). 0.3.2 (Apr 05, 2013) ^^^^^^^^^^^^^^^^^^^^ Fixes: - Fix vendor id and product id order in ``DeviceInfo`` (thanks @kived). 0.3.1 (Nov 23, 2012) ^^^^^^^^^^^^^^^^^^^^ Fixes: - ``device.read()`` will return an empty tuple if the device has nothing to offer (instead of segfaulting). - Exclude unnecessary package data in sdist and bdist. 0.3.0 (Nov 06, 2012) ^^^^^^^^^^^^^^^^^^^^ Enhancements: - Add ability to set/get auto-repeat settings with ``EVIOC{SG}REP``. - Add ``device.version`` - the value of ``EVIOCGVERSION``. - Add ``device.read_loop()``. - Add ``device.grab()`` and ``device.ungrab()`` - exposes ``EVIOCGRAB``. - Add ``device.leds`` - exposes ``EVIOCGLED``. - Replace ``DeviceInfo`` class with a namedtuple. Fixes: - ``device.read_one()`` was dropping events. - Rename ``AbsData`` to ``AbsInfo`` (as in ``struct input_absinfo``). 0.2.0 (Aug 22, 2012) ^^^^^^^^^^^^^^^^^^^^ Enhancements: - Add the ability to set arbitrary device capabilities on uinput devices (defaults to all ``EV_KEY`` ecodes). - Add ``UInput.device`` which is an open ``InputDevice`` to the input device that uinput 'spawns'. - Add ``UInput.capabilities()`` which is just a shortcut to ``UInput.device.capabilities()``. - Rename ``UInput.write()`` to ``UInput.write_event()``. - Add a simpler ``UInput.write(type, code, value)`` method. - Make all ``UInput`` constructor arguments optional (default device name is now ``py-evdev-uinput``). - Add the ability to set ``absmin``, ``absmax``, ``absfuzz`` and ``absflat`` when specifying the uinput device's capabilities. - Remove the ``nophys`` argument - if a device fails the ``EVIOCGPHYS`` ioctl, phys will equal the empty string. - Make ``InputDevice.capabilities()`` perform a ``EVIOCGABS`` ioctl for devices that support ``EV_ABS`` and return that info wrapped in an ``AbsData`` namedtuple. - Split ``ioctl_devinfo`` into ``ioctl_devinfo`` and ``ioctl_capabilities``. - Split ``uinput_open()`` to ``uinput_open()`` and ``uinput_create()`` - Add more uinput usage examples and documentation. - Rewrite uinput tests. - Remove ``mouserel`` and ``mouseabs`` from ``UInput``. - Tie the sphinx version and release to the distutils version. - Set 'methods-before-attributes' sorting in the docs. Fixes: - Remove ``KEY_CNT`` and ``KEY_MAX`` from ``ecodes.keys``. 0.1.1 (May 18, 2012) ^^^^^^^^^^^^^^^^^^^^ Enhancements: - Add ``events.keys``, which is a combination of all ``BTN_`` and ``KEY_`` event codes. Fixes: - ``ecodes.c`` was not generated when installing through ``pip``. 0.1.0 (May 17, 2012) ^^^^^^^^^^^^^^^^^^^^ *Initial Release* Keywords: evdev input uinput Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.2 Classifier: Programming Language :: Python :: 3.3 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.1/evdev.egg-info/zip-safe0000664000175000017500000000000112151433041016126 0ustar gvgv00000000000000 evdev-0.4.1/evdev.egg-info/top_level.txt0000664000175000017500000000000612173701335017234 0ustar gvgv00000000000000evdev evdev-0.4.1/evdev.egg-info/dependency_links.txt0000664000175000017500000000000112173701335020554 0ustar gvgv00000000000000 evdev-0.4.1/PKG-INFO0000664000175000017500000001500112173701335012775 0ustar gvgv00000000000000Metadata-Version: 1.1 Name: evdev Version: 0.4.1 Summary: bindings for the linux input handling subsystem Home-page: https://github.com/gvalkov/python-evdev Author: Georgi Valkov Author-email: georgi.t.valkov@gmail.com License: New BSD License Description: *evdev* ---------------------------------------- *evdev* 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/``. *evdev* also comes with bindings to *uinput*, the userspace input subsystem. *Uinput* allows userspace programs to create and handle input devices from which input events can be directly injected into the input subsystem. Documentation: http://packages.python.org/evdev Development: https://github.com/gvalkov/python-evdev PyPi: http://pypi.python.org/pypi/evdev Changelog ========= 0.4.1 (Jul 24, 2013) ^^^^^^^^^^^ Fixes: - Fix reference counting in ``device_read``, ``device_read_many`` and ``ioctl_capabilities``. 0.4.0 (Jul 01, 2013) ^^^^^^^^^^^^^^^^^^^^ Enhancements: - Add ``FF_*`` and ``FF_STATUS`` codes to ``ecodes`` (thanks @bgilbert). - Reverse event code mappings (``ecodes.{KEY,FF,REL,ABS}`` and etc.) will now map to a list of codes, whenever a value corresponds to multiple codes:: >>> ecodes.KEY[152] ... ['KEY_COFFEE', 'KEY_SCREENLOCK'] >>> ecodes.KEY[30] ... 'KEY_A' - Set the state of a LED through ``device.set_led()`` (thanks @accek). ``device.fd`` is opened in ``O_RDWR`` mode from now on. Fixes: - Fix segfault in ``device_read_many()`` (thanks @bgilbert). 0.3.3 (May 29, 2013) ^^^^^^^^^^^^^^^^^^^^ Fixes: - Raise ``IOError`` from ``device_read()`` and ``device_read_many()`` when ``read()`` fails. - Several stability and style changes (thank you debian code reviewers). 0.3.2 (Apr 05, 2013) ^^^^^^^^^^^^^^^^^^^^ Fixes: - Fix vendor id and product id order in ``DeviceInfo`` (thanks @kived). 0.3.1 (Nov 23, 2012) ^^^^^^^^^^^^^^^^^^^^ Fixes: - ``device.read()`` will return an empty tuple if the device has nothing to offer (instead of segfaulting). - Exclude unnecessary package data in sdist and bdist. 0.3.0 (Nov 06, 2012) ^^^^^^^^^^^^^^^^^^^^ Enhancements: - Add ability to set/get auto-repeat settings with ``EVIOC{SG}REP``. - Add ``device.version`` - the value of ``EVIOCGVERSION``. - Add ``device.read_loop()``. - Add ``device.grab()`` and ``device.ungrab()`` - exposes ``EVIOCGRAB``. - Add ``device.leds`` - exposes ``EVIOCGLED``. - Replace ``DeviceInfo`` class with a namedtuple. Fixes: - ``device.read_one()`` was dropping events. - Rename ``AbsData`` to ``AbsInfo`` (as in ``struct input_absinfo``). 0.2.0 (Aug 22, 2012) ^^^^^^^^^^^^^^^^^^^^ Enhancements: - Add the ability to set arbitrary device capabilities on uinput devices (defaults to all ``EV_KEY`` ecodes). - Add ``UInput.device`` which is an open ``InputDevice`` to the input device that uinput 'spawns'. - Add ``UInput.capabilities()`` which is just a shortcut to ``UInput.device.capabilities()``. - Rename ``UInput.write()`` to ``UInput.write_event()``. - Add a simpler ``UInput.write(type, code, value)`` method. - Make all ``UInput`` constructor arguments optional (default device name is now ``py-evdev-uinput``). - Add the ability to set ``absmin``, ``absmax``, ``absfuzz`` and ``absflat`` when specifying the uinput device's capabilities. - Remove the ``nophys`` argument - if a device fails the ``EVIOCGPHYS`` ioctl, phys will equal the empty string. - Make ``InputDevice.capabilities()`` perform a ``EVIOCGABS`` ioctl for devices that support ``EV_ABS`` and return that info wrapped in an ``AbsData`` namedtuple. - Split ``ioctl_devinfo`` into ``ioctl_devinfo`` and ``ioctl_capabilities``. - Split ``uinput_open()`` to ``uinput_open()`` and ``uinput_create()`` - Add more uinput usage examples and documentation. - Rewrite uinput tests. - Remove ``mouserel`` and ``mouseabs`` from ``UInput``. - Tie the sphinx version and release to the distutils version. - Set 'methods-before-attributes' sorting in the docs. Fixes: - Remove ``KEY_CNT`` and ``KEY_MAX`` from ``ecodes.keys``. 0.1.1 (May 18, 2012) ^^^^^^^^^^^^^^^^^^^^ Enhancements: - Add ``events.keys``, which is a combination of all ``BTN_`` and ``KEY_`` event codes. Fixes: - ``ecodes.c`` was not generated when installing through ``pip``. 0.1.0 (May 17, 2012) ^^^^^^^^^^^^^^^^^^^^ *Initial Release* Keywords: evdev input uinput Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.2 Classifier: Programming Language :: Python :: 3.3 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.1/evdev/0000775000175000017500000000000012173701335013014 5ustar gvgv00000000000000evdev-0.4.1/evdev/input.c0000664000175000017500000002607412172266533014335 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 #include #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)); } // Useful for comparing input events as seen in the extension module // and as seen in python // static void // print_event(struct input_event *ev) { // fprintf(stderr, "[so] event: time %ld.%06ld, code %02d, type %02d, val %02d\n", // ev->time.tv_sec, ev->time.tv_usec, // ev->code, ev->type, ev->value // ); // } // 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) { 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], code_bits[KEY_MAX/8]; 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, EV_MAX), 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; } // 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 ; 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; 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.1/evdev/events.py0000664000175000017500000001221412151432722014667 0ustar gvgv00000000000000# encoding: utf-8 ''' This module provides the :class:`InputEvent` class, which closely resembles the ``input_event`` C struct in ``linux/input.h``: .. code-block:: c struct input_event { struct timeval time; __u16 type; __u16 code; __s32 value; }; This module also defines several abstractions on top of :class:`InputEvent` that know more about the different event types (key, abs, rel etc). The :data:`event_factory` dictionary maps event types to these classes. Assuming you use the provided :func:`evdev.util.categorize()` function to categorize events according to type, adding or replacing a class for a specific event type becomes a matter of modifying :data:`event_factory`. All of the provided classes 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. This closely resembles the ``input_event`` C struct. ''' __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 python 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): ''' Used to describe state changes of keyboards, buttons, 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 #: :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): ''' Used to describe relative axis value changes, e.g. moving the mouse 5 units to the left. ''' __slots__ = 'event' def __init__(self, event): #: :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): ''' Used to describe absolute axis value changes, e.g. describing the coordinates of a touch on a touchscreen. ''' __slots__ = 'event' def __init__(self, event): #: :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): ''' 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): #: :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) #: 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.1/evdev/__init__.py0000664000175000017500000000053712151432722015127 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 evdev-0.4.1/evdev/ecodes.sh0000775000175000017500000000254412155553471014630 0ustar gvgv00000000000000#!/bin/bash # Generate a Python extension module that exports macros from # /usr/include/linux/input.h header=${1:-/usr/include/linux/input.h} [[ ! -e $header ]] && echo "no such file: $header" && exit 1 function codes () { awk ' /#define +(KEY|ABS|REL|SW|MSC|LED|BTN|REP|SND|ID|EV|BUS|SYN|FF)_/ { print " PyModule_AddIntMacro(m, "$2");" }' ${header} } cat << EOF #include #include /* Automatically generated by evdev/ecodes.sh */ #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; $(codes) return m; } #if PY_MAJOR_VERSION >= 3 PyMODINIT_FUNC PyInit__ecodes(void) { return moduleinit(); } #else PyMODINIT_FUNC init_ecodes(void) { moduleinit(); } #endif EOF evdev-0.4.1/evdev/ecodes.py0000664000175000017500000000474512155573646014656 0ustar gvgv00000000000000# encoding: utf-8 ''' This modules exposes most 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.EV_KEY] 'EV_KEY' >>> evdev.ecodes.bytype[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.1/evdev/uinput.c0000664000175000017500000001320512164000265014477 0ustar gvgv00000000000000#include #include #include #include #include #include #include #include #include #include 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; __u16 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.1/evdev/uinput.py0000664000175000017500000001473612151432722014722 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 (an `uinput`) device and that can inject input events directly 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 by default 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() #: open write-only, nonblocking file descriptor to the uinput devnode 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 # to the fake input device self.device = self._find_device() def __enter__(self): return self def __exit__(self, type, value, tb): 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 InputDevice object self.device.close() # destroy the uinput device if self.fd and self.fd > 0: _uinput.close(self.fd) 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 applicable, 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 `.''' return self.device.capabilities(verbose, absinfo) def _verify(self): ''' Verify that an uinput device exists and is readable and writable by our 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): #:todo: use udev #:bug: the device node might not be immediately avaiable 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.1/evdev/device.py0000664000175000017500000002057412172233656014642 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`` c 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. ''' pass 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}, product {:04x}, vendor {: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') 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) 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): ''' Returns 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', 0), ('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 (``absmin``, ``absmax``, ``absfuzz``, ``absflat``) in the following form:: { 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): ''' Returns currently set LED keys. Example:: [0, 1, 8, 9] If ``verbose`` is ``True``, event codes will be resolved to their names. Unknown codes will be resolved to ``'?'``. 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): ''' Sets the state of the selected LED. Example:: device.set_led(ecodes.LED_NUML, 1) ''' _uinput.write(self.fd, ecodes.EV_LED, led_num, value) def __eq__(self, o): '''Two devices are considered equal if their :data:`info` attributes are equal.''' return self.info == o.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): os.close(self.fd) self.fd = -1 def fileno(self): ''' Returns the file descriptor to the event device. This makes passing ``InputDevice`` instances directly to :func:`select.select()` and :class:`asyncore.file_dispatcher` possible. ''' return self.fd def read_one(self): ''' Read and return a single input event as a :class:`InputEvent ` instance. 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 a polling 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. This function returns 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 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('Device or resource busy') exception.''' _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') exception.''' _input.ioctl_EVIOCGRAB(self.fd, 0) @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) evdev-0.4.1/evdev/ecodes.c0000664000175000017500000007044612172266544014444 0ustar gvgv00000000000000#include #include /* Automatically generated by evdev/ecodes.sh */ #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, 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_ZERO); PyModule_AddIntMacro(m, KEY_DISPLAY_OFF); 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_A); PyModule_AddIntMacro(m, BTN_B); PyModule_AddIntMacro(m, BTN_C); PyModule_AddIntMacro(m, BTN_X); 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_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, 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_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.1/evdev/util.py0000664000175000017500000000503712151432722014345 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.''' fns = glob.glob('{}/event*'.format(input_device_dir)) fns = list(filter(is_device, fns)) return fns def is_device(fn): '''Determine if a file exists, is readable and is a 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): return False return True def categorize(event): ''' Categorize an event according to its type. The :data:`event_factory ` dictionary maps event types to their classes. If there is no corresponding key, the event is returned as it was. ''' 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 the typecodemap contains absolute axis info (wrapped in instances of `AbsInfo `) the result would look like:: resove_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.1/MANIFEST.in0000664000175000017500000000013112151432722013431 0ustar gvgv00000000000000# make github and sdist happy include README.rst include evdev/ecodes.sh include LICENSE evdev-0.4.1/setup.py0000775000175000017500000000723312173700454013426 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.build import build from setuptools.command.develop import develop from setuptools.command.bdist_egg import bdist_egg from setuptools import setup, Extension, Command here = abspath(dirname(__file__)) requires = () test_requires = ('pytest',) classifiers = ( 'Development Status :: 4 - Beta', # 'Development Status :: 5 - Production/Stable', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.2', 'Programming Language :: Python :: 3.3', 'Operating System :: POSIX :: Linux', 'Intended Audience :: Developers', 'Topic :: Software Development :: Libraries', 'License :: OSI Approved :: BSD License', 'Programming Language :: Python :: Implementation :: CPython', ) input_c = Extension('evdev._input', sources=['evdev/input.c'], ) # extra_compile_args=['-O0']) uinput_c = Extension('evdev._uinput', sources=['evdev/uinput.c'], ) # extra_compile_args=['-O0']) ecodes_c = Extension('evdev._ecodes', sources=['evdev/ecodes.c'], ) # extra_compile_args=['-O0']) kw = { 'name' : 'evdev', 'version' : '0.4.1', 'description' : 'bindings for the linux input handling subsystem', 'long_description' : open(pjoin(here, 'README.rst')).read(), 'author' : 'Georgi Valkov', 'author_email' : 'georgi.t.valkov@gmail.com', 'license' : 'New BSD License', 'keywords' : 'evdev input uinput', 'classifiers' : classifiers, 'url' : 'https://github.com/gvalkov/python-evdev', 'packages' : ['evdev'], 'ext_modules' : [input_c, uinput_c, ecodes_c], 'install_requires' : requires, 'tests_require' : test_requires, 'include_package_data' : False, 'zip_safe' : True, 'cmdclass' : {}, } def create_ecodes(): # :todo: expose as a command option 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 intall 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 {})'.format(header)) check_call('bash ./ecodes.sh {} > ecodes.c'.format(header), cwd='{}/evdev'.format(here), shell=True) # :todo: figure out a smarter way to do this # :note: subclassing build_ext doesn't really cut it class BuildCommand(build): def run(self): create_ecodes() build.run(self) class DevelopCommand(develop): def run(self): create_ecodes() develop.run(self) class BdistEggCommand(bdist_egg): def run(self): create_ecodes() bdist_egg.run(self) class PyTest(Command): ''' setup.py test -> py.test tests ''' user_options = [] def initialize_options(self): pass def finalize_options(self): pass def run(self): from subprocess import call errno = call(('py.test', 'tests')) raise SystemExit(errno) kw['cmdclass']['test'] = PyTest kw['cmdclass']['build'] = BuildCommand kw['cmdclass']['develop'] = DevelopCommand kw['cmdclass']['bdist_egg'] = BdistEggCommand if __name__ == '__main__': setup(**kw) evdev-0.4.1/setup.cfg0000664000175000017500000000007312173701335013524 0ustar gvgv00000000000000[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 evdev-0.4.1/LICENSE0000664000175000017500000000271612151432722012713 0ustar gvgv00000000000000Copyright (c) 2012 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 GEORGI VALKOV 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.