Giter VIP home page Giter VIP logo

python-evdev's Introduction

evdev

pypi version License Packaging status

This package provides bindings to the generic input event interface in Linux. The evdev interface serves the purpose of passing events generated in the kernel directly to userspace through character devices that are typically located in /dev/input/.

This package also comes with bindings to uinput, the userspace input subsystem. Uinput allows userspace programs to create and handle input devices that can inject events directly into the input subsystem.

Documentation:
https://python-evdev.readthedocs.io/en/latest/

Development:
https://github.com/gvalkov/python-evdev

Package:
https://pypi.python.org/pypi/evdev

Changelog:
https://python-evdev.readthedocs.io/en/latest/changelog.html

python-evdev's People

Contributors

5ucur avatar abhenson avatar accek avatar bgilbert avatar castis avatar gvalkov avatar ismailof avatar jbleon95 avatar karsmulder avatar kived avatar linuscde avatar luizoti avatar meeuw avatar mic92 avatar mk-fg avatar ndreys avatar odormond avatar paulo-raca avatar pmundt avatar quaxalber avatar quoing avatar sarahcosmosys avatar sezanzeb avatar skitt avatar spasche avatar tacaswell avatar tlalexander avatar tomoinn avatar whot avatar wk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

python-evdev's Issues

Exception OSError in __del__ ignored

Hi gvalkov,

I am using python-evdev on a project (spacemouse-py) to get rid of calls to a c library and so far I am really pleased with python-evdev.

With that out of the way; I am using python-evdev 0.4.2 on python 3.3.3 and 2.7.6 and am getting this error writing to ipython/the terminal:
On python2:

Exception OSError: (19, 'No such device') in <bound method InputDevice.__del__ of InputDevice(u'/dev/input/event3')> ignored

And on python3:

Exception OSError: OSError(9, 'Bad file descriptor') in <bound method InputDevice.__del__ of InputDevice('/dev/input/event3')> ignored

anytime an InputDevice is deleted or completely unreferenced.

The problem according to the python documentation:

Warning : Due to the precarious circumstances under which del() methods are invoked, exceptions that occur during their execution are ignored, and a warning is printed to sys.stderr instead. Also, when del() is invoked in response to a module being deleted (e.g., when execution of the program is done), other globals referenced by the del() method may already have been deleted or in the process of being torn down (e.g. the import machinery shutting down). For this reason, del() methods should do the absolute minimum needed to maintain external invariants. Starting with version 1.5, Python guarantees that globals whose name begins with a single underscore are deleted from their module before other globals are deleted; if no other references to such globals exist, this may help in assuring that imported modules are still available at the time when the del() method is called.

Which means any exceptions raised in a del method will not be propagated but instead will be printed as a message to stderr.

My use case is that a device is disconnected while I still have an open connection to it. The device node will be removed and calling close on the still open file descriptor will generate this error.

The solution would be to just ignore this specific error by using an try: except: block in the del method.

Any thoughts on the matter would be appreciated.

Exceptions lost from async_read_one

Hi,

I have a USB device which sometimes disappears unexpectedly for a few ms and I'm trying to handle this cleanly in application-level code -- similar to issue #64, I get an OSError back from a read call, and need to respond by closing and waiting to reopen the device.

I'm using async_read_one(). Unfortunately when the underlying (synchronous) read_one() call raises an exception, the exception leaks out of the future into the event loop. The fix that worked for me is to catch it and attach it to the future:

    def async_read_one(self):
        future = asyncio.Future()
        def read_next():
            try:
                future.set_result(self.read_one())
            except Exception as ex:
                future.set_exception(ex)
        self._do_when_readable(read_next)
        return future

InputDevice does not close file handle

im using InputDevice in a loop to poll for a device to get online.
im not keeping the reference to the InputDevice, so it should be subject to the garbage collection. But still, the open file descriptors are increasing until i hit the max open file limit.

i have to call the .close() function of the InputDevice manually for proper closing.

this can be observed in the first example:

>>> from evdev import InputDevice, list_devices
>>> devices = map(InputDevice, list_devices())
>>> for dev in devices:
        print( '%-20s %-32s %s' % (dev.fn, dev.name, dev.phys) )

if you then ls -la /proc/PID/fd you can see all the handles still open, even if the for dev in devices loop were in a already finished function and no references are left.

if this is not a bug and cannot be done better, the .close() should be at least added the the samples.

After update 0.6.3 error installing on Raspbian Jessie

Using updated Raspbian Jessie with all the dependencies installed, now when I try to install with pip (or pip3)
sudo pip install evdev
Then when building 'evdev._ecodes' extension I get the following error:
In file included from /usr/include/python2.7/Python.h:126:0, from evdev/ecodes.c:2: evdev/ecodes.c: In function ‘moduleinit’: evdev/ecodes.c:69:29: error: ‘BUS_RMI’ undeclared (first use in this function) PyModule_AddIntMacro(m, BUS_RMI);

Thanks in advance!

InputDevice.read() - Recource temporarily unaivalable

Hi,
I'm trying to read out the axis of a "Logitech Cordless RumblePad 2", not without trouble however...
I am able to read out the events coming from the device with .read_loop() (events_get in the sample code) and from read_one. But I am unable to to read from the read() buffer (get_axis_pos in example).

I'm using Ubuntu 14.04.2 LTS

Dumbed down the code I am using looks like this:

import evdev
import logging

controller_name = "Logitech Logitech Cordless RumblePad 2"

logging.basicConfig(level=logging.DEBUG, format="[%(asctime)s] %(threadName)s %(message)s", datefmt="%H:%M:%S")
logging.info("Controller output script started")

def main():
    controller = ControllerInput(controller_name)
    while True:
        controller.get_axis_pos()


class ControllerInput():
    def __init__(self, controller_name):

        devices = [evdev.InputDevice(fn) for fn in evdev.list_devices()]
        logging.debug("Found devices: " + str(len(devices)))

        dev_location = None
        for dev in devices:
            if dev.name == controller_name:
                dev_location = dev.fn
                logging.debug("Found desired device: " + dev.name + " at: " + dev.fn)
                break
        if dev_location is None:
            raise "Device not found!"

        self.dev_obj = evdev.InputDevice(dev_location)
        self.axispos = [128, 128, 128, 128]     #left x,y |right x,y

    def events_get(self):
        for event in self.dev_obj.read_loop():
            if event.type != 0:
                print(event)

    def get_axis_pos(self):
        event_gen = self.dev_obj.read()
        if event_gen is not None:
            for event in event_gen:
                if event.type == 3:
                    if event.code == 0:      #0: left x axis |1: left y axis
                        self.axispos[0] = event.value
                    elif event.code == 1:
                        self.axispos[1] = event.value
                    elif event.code == 2:   #2: right x axis |5: right y axis
                        self.axispos[2] = event.value
                    elif event.code == 5:
                        self.axispos[3] = event.value

        logging.debug("Controller axis: " + str(self.axispos[0]))

if __name__ == "__main__":
    main()

The error I get when running this code is:

[16:34:26] MainThread Controller output script started
[16:34:26] MainThread Found devices: 1
[16:34:26] MainThread Found desired device: Logitech Logitech Cordless RumblePad 2 at: /dev/input/event13
Traceback (most recent call last):
  File "/media/philip/2.3.1-18-amd64/Projects/pycharm/quadcopter/controller.py", line 139, in <module>
    main()
  File "/media/philip/2.3.1-18-amd64/Projects/pycharm/quadcopter/controller.py", line 48, in main
    controller.get_axis_pos()
  File "/media/philip/2.3.1-18-amd64/Projects/pycharm/quadcopter/controller.py", line 125, in get_axis_pos
    for event in event_gen:
  File "/usr/lib/python3/dist-packages/evdev/device.py", line 246, in read
    events = _input.device_read_many(self.fd)
BlockingIOError: [Errno 11] Resource temporarily unavailable

Regards Avraamu

c extensions functions memory leak

When deallocating InputDevice objects the memory is not restored.

This problem was spotted because a problematic USB bus resets randomly. The code needed to workaround this fact, creates a new InputDevice on demand. The memory is allways increasing. Try this to watch:

for i in xrange(10000):
  a = InputDevice(path)
  a.close() 

I looked at the C code and it seems that the ref count calls see this article are missing and thus the memory is not released. This is just a guess - no experience with python C extensions...

Problem with the tutorial code for "Specifying uinput device options"

First of all, thanks for your great work! :-)

Using the code provided in "Specifying uinput device options" raises an error (using Python2.7, python-evdev 0.4.5, Ubuntu 14.04) :

cap = { ecodes.EV_KEY : [ecodes.KEY_A, ecodes.KEY_B], ecodes.EV_ABS : [ (ecodes.ABS_X, AbsInfo(min=0, max=255, fuzz=0, flat=0)), (ecodes.ABS_Y, AbsInfo(0, 255, 0, 0)), (ecodes.ABS_MT_POSITION_X, (0, 255, 128, 0)) ] }
TypeError: __new__() takes exactly 7 arguments (5 given)

Probably because the constructor of AbsInfo changed somehow? I can see how a new parameter called "resolution" has been added, but I don't understand what is the 7th argument. Correcting the AbsInfo instances with:

AbsInfo(min=0, max=255, fuzz=0, flat=0, resolution=0)

raises the same error

TypeError: __new__() takes exactly 7 arguments (6 given)

Changing the line to:

AbsInfo(0, 255, 0, 0, 0, 0)

executes without errors, but (and this might be a separate issue) the virtual mouse does not move, albeit the EV_KEY events work.

debian 8.0 install through pip

import evdev
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "evdev/__init__.py", line 7, in <module>
    from evdev.device import DeviceInfo, InputDevice, AbsInfo
  File "evdev/device.py", line 8, in <module>
    from evdev import _input, _uinput, ecodes, util
  File "evdev/ecodes.py", line 42, in <module>
    from evdev import _ecodes
ImportError: cannot import name _ecodes

append to man notify about correct global enviroment variable PYTHON_PATH="/usr/local/lib/python2.7/"

Keyboard LED indicators don't work when grab device

Hi,

I have a question about your code sample from this issue:
link

This is source code:

dev = InputDevice(...)
dev.grab()

for ev in dev.read_loop():
    if ev.code not in (KEY_LEFTCTRL, KEY_RIGHTCTRL, KEY_Q):
        ui.write_event(ev)
        continue

    # lots of messy checks for when Q is pressed/depressed while a
    # Ctrl key is pressed (ev.value == 1)

The LED indicators don't work when device is grabbed and events are resended by ui.write_event function. Is it possible to fix the LEDs work?

Strange behavior of grab()

I am using evdev to catch keyboard events like LCtrl + C + C. I want to grab the device as LCtrl is pressed (event.code = 29, event.value = 1) and ungrab it when Ctrl is released (event.code = 29, event.value = 0) to guarantee that the regular shortcut is not triggered.

The problem is, after the keyboard is ungrabbed on LCtrl release, the system behaves as if LCtrl were still held down, so if I hit C (after LCtrl is released and the device is ungrabbed), it is interpreted as LCtrl + C.

Example code:

from evdev import InputDevice, ecodes

dev = InputDevice('/dev/input/event0') # Or whatever the keyboard device is 

for event in dev.read_loop():
    if (event.type == ecodes.EV_KEY):
            if ((event.code, event.value) == (29, 1)):
                dev.grab()
                print ('Grab')
            elif ((event.code, event.value) == (29, 0)):
                dev.ungrab()
                print('Ungrab')

Just run it in terminal (I assume you're on Linux), press and release LCtrl, then press C, and see that the script is interrupted, as if you pressed Ctrl+C.

Ignore events

Is it possible to ignore/disregard events?

I'm trying to re-map certain keypresses. For example, ctrl-q would become crtl-c.

Your documentation shows how I can easily watch for the keypress and then fire a new keypress event (this is very clear, thanks). However, I don't know how to ignore the first keypress event.

Thanks very much for this library.

Pointer does not move with ecodes.EV_REL

I am trying to move the mouse visually on screen for an automation tool that I am working on, it seems the mouse pointer does not move with ecodes.EV_REL. I am working on Ubuntu and I tried on both X11 and Mir display server. python-uinput seems to be working fine though, but our project heavily uses python-evdev so we need to keep using it. Below is the code that reproduces the issue.

from time import sleep

from evdev import UInput, ecodes

ui = UInput()
for i in range(20):
    ui.write(ecodes.EV_REL, ecodes.REL_X, 5)
    ui.write(ecodes.EV_REL, ecodes.REL_Y, 5)
    ui.syn()
    sleep(0.01)

That codes does run without errors but it does not do anything, OTH, mouse click events do work.

Generating a 'shifted' key (i.e. #)

Hi,

How would I determine what key codes to fire off to generate a specific character?
(For instance to generate a '~' there is ecodes.KEY_GRAVE, but I don't see something like ecodes.COLON (for ':').)

So on my desktop I use a combination of KEY_LEFTSHIFT + KEY_SEMICOLON to generate a colon (:).
How would I determine the correct sequence of events on a particular platform/keyboard layout?

Oh also this is using UInput.

Read-only opening of devices

Currently InputDevice wants to open the device os.RDWR (code) but there's good reason to be able to open a device os.RDONLY, either if there's no intention to modify anything or there's not sufficient permissions.

Making a custom derived class with changed __init__ seems to work but I think it could very well be included in the library:

from evdev import InputDevice, _input, DeviceInfo
import os

class ReadInputDevice(InputDevice):
    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_RDONLY | os.O_NONBLOCK)

        # Returns (bustype, vendor, product, version, name, phys, capabilities).
        info_res = _input.ioctl_devinfo(self.fd)

        #: A :class:`DeviceInfo <evdev.device.DeviceInfo>` instance.
        self.info = DeviceInfo(*info_res[:4])

        #: The name of the event device.
        self.name = info_res[4]

        #: The physical topology of the device.
        self.phys = info_res[5]

        #: The evdev protocol version.
        self.version = _input.ioctl_EVIOCGVERSION(self.fd)

        #: The raw dictionary of device capabilities - see `:func:capabilities()`.
        self._rawcapabilities = _input.ioctl_capabilities(self.fd)

        #: The number of force feedback effects the device can keep in its memory.
        self.ff_effects_count = _input.ioctl_EVIOCGEFFECTS(self.fd)

KeyError in evtest.py with a PS4 controller

I get a KeyError when using evtest.py and a PS4 controller. The same error occurs in both Python2 and 3.

  File "/usr/local/lib/python3.5/dist-packages/evdev/evtest.py", line 183, in <module>
    ret = main()
  File "/usr/local/lib/python3.5/dist-packages/evdev/evtest.py", line 79, in main
    print_event(event)
  File "/usr/local/lib/python3.5/dist-packages/evdev/evtest.py", line 164, in print_event
    codename = ecodes.bytype[e.type][e.code]
KeyError: 45

The way I had to worked around it is by checking that e.code is in ecodes.bytype[e.type]

Bob

Suport for read() on UInput

I'm using UInput to connect a device with leds and a buzzer (EV_LED and EV_SND)

Python-evdev should support a read() operation that lets me set those.

Send vibration to gamepad

Hi!
I'm try send vibration to Xbox 360 controller with python. Do you have example of sending vibroeffect with evdev?

Add a description of what is/not working

Some uses of uinput are not currently supported (for example, rumblers: #23, ff branch). Which, doesn't seem to be documented.

Adding to the documentation, a brief description of what is and isn't working, might help potential users anticipate whether python-evdev is appropriate for their intended use.

Here is a strawman draft:

Scope and status

All keyboard and mice events should work. Rumblers #23 currently do not work. Joysticks, touchpads, tablets, cameras, force feedback, and less common devices probably work / probably don't work / sometimes work / partially work / haven't been tested / are not supported.

Some characters, such as : (colon), cannot easily be generated from scratch #7. Translating them into UInput events would require knowing the kernel keyboard translation table, and there is no python equivalent of dumpkeys. Consider using PyUserInput instead.

Related projects include: python-uinput; uinput-mapper; PyUserInput; pygame.

Dependencies

If the documentation etc doesn't say which version of what it depends on eg python etc it would be nice if it did. BTW I haven't looked through everything yet to check. I'd also say I tried the pip install from the web site documentation and discovered that you have to be root to make it work, maybe obvious but why not indicate it; hardly difficult to put a '#' in front of each command.

Device has wrong __ne__ operator.

>>> import evdev
>>> e = evdev.InputDevice(evdev.list_devices()[0])
>>> e2 = evdev.InputDevice(evdev.list_devices()[0])
>>> e == e2
True
>>> e != e2
True

Problem with d-pad detection

Hello!
I just bought a "retro" gamepad, with 8 buttons and a directional pad (d-pad).
Buttons are detected and can be separated (though ecodes are a bit strange — but this isn't an issue).

D-pad on the contrary seems to be a bit harder to understand…
Here's a print of caught events:

# UP
event at 1380042926.679244, code 01, type 03, val 00
event at 1380042926.679262, code 00, type 00, val 00
event at 1380042926.767252, code 01, type 03, val 127
event at 1380042926.767270, code 00, type 00, val 00
# RIGHT
event at 1380042927.919373, code 00, type 03, val 255
event at 1380042927.919392, code 00, type 00, val 00
event at 1380042927.983368, code 00, type 03, val 127
event at 1380042927.983387, code 00, type 00, val 00
# BOTTOM
event at 1380042929.063476, code 01, type 03, val 255
event at 1380042929.063495, code 00, type 00, val 00
event at 1380042929.111483, code 01, type 03, val 127
event at 1380042929.111500, code 00, type 00, val 00
# LEFT
event at 1380042930.175583, code 00, type 03, val 00
event at 1380042930.175603, code 00, type 00, val 00
event at 1380042930.263594, code 00, type 03, val 127
event at 1380042930.263612, code 00, type 00, val 00

Any advice on how to use those values ? Each press-release seems to do four events, as you can see -.-'.

Thank you for your time!

Cheers,

C.

UInput.close() error

When i trying inject event as described in tutorial, i receiving following error:

from evdev import UInput, ecodes as e
ui = UInput()
ui.write(e.EV_KEY, e.KEY_A, 1)
ui.write(e.EV_KEY, e.KEY_A, 0)
ui.syn()

# for this point everything works ok, i can see "a" symbol input in console
ui.close()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "evdev/uinput.py", line 115, in close
    self.device.close()
AttributeError: 'NoneType' object has no attribute 'close'

Request: Add typehints

It would be nice to have PEP-484 typehints for all functions and methods to make it easier to write correct code using python-evdev.

Installing on Linkit smart 7688 fail

Hello @gvalkov, recently there was a new board called Linkit smart 7688, which is a cheap IoT board. I was trying to use this board to build an bluetooth keyboard adapter, and just like Arduino Yun, it uses openwrt as the OS.
As I was trying to use this awesome plugin, the installation was failed due to missing linux kernel header files. Then I found there is another evdev for Arduino Yun, I downloaded and run opkg install to install that package, it popped error messages, saying that "incompatible with the architectures configured".
Can you give some me advise? Thank you!

spec of Linkit smart 7688:
MIPS CPU

msg in DeviceInfo Class needs vendor and product swapping

Possibly linked to the change for issue #5 the msg string defined in the str method of DeviceInfo (currently line 71 of device.py) needs to swap the vendor and product names.

from lsusb -v:
Bus 001 Device 004: ID 08ff:0009 AuthenTec, Inc.
idVendor 0x08ff AuthenTec, Inc.
idProduct 0x0009

from print str(dev.info):
bus: 0003, product 08ff, vendor 0009, version 0110

Import error with Linux kernel 4.4.0

Using Gentoo's gentoo-sources-4.4.0, python-evdev generates from a input.h which causes it to fail on input:

python

Python 2.7.11 (default, Jan 21 2016, 21:00:40)
[GCC 5.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.

from evdev import UInput, UInputError, ecodes
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib64/python2.7/site-packages/evdev/init.py", line 5, in
from evdev.device import DeviceInfo, InputDevice, AbsInfo
File "/usr/lib64/python2.7/site-packages/evdev/device.py", line 7, in
from evdev import _input, _uinput, ecodes, util
File "/usr/lib64/python2.7/site-packages/evdev/ecodes.py", line 75, in
keys.update(BTN)
NameError: name 'BTN' is not defined

This affects at least python-evdev 0.4.5 and 0.5.0 and can be fixed by downgrading both the kernel and sys-kernel/linux-headers to version 4.3, then rebuilding python-evdev.

Hardcoded headers randomly breaks embedded builds

If the build host kernel/linux-headers package provides the same headers as the embedded toolchain/sysroot, then all is fine. As soon as they diverge, it blows up. Since both setup.py and genecodes.py have the full path hardcoded, I made this patch for openembedded/yocto:

https://github.com/sarnold/meta-openembedded/blob/python-evdev-fix/meta-python/recipes-devtools/python/python-evdev/use-sysroot-headers.patch

In the above patch, STAGING_INCDIR is specific to the bitbake build environment, and I didn't want to try mind-reading (since that never works anyway) so what ideas might you have for a generic fix? Something like adding a (normally empty) SYSROOT var in front of the header path (sort of like DESTDIR) might be enough.

Basically a way to configure the header path with a local prefix.

Not working inside loop in Raspberry Pi

I am trying to do a mouse button click when I receive some input from serial in Raspberry Pi. When done in a shell with just evdev, it works, but when done inside a loop that monitors the serial, it does not work. It gives no error or any message in the shell. The same code works in a laptop though.

Is is an issue with the Raspberry Pi (ArchLinuxARM) or some issue inside python-evdev?

Something wrong with AbsInfo

I'm trying to mirror a gamepad with code below.

from evdev import InputDevice, UInput, AbsInfo, ecodes as e

cap = {
    e.EV_MSC : [e.MSC_SCAN],
    e.EV_KEY : [e.BTN_A, e.BTN_B, e.BTN_C, e.BTN_X, e.BTN_Y, e.BTN_Z, e.BTN_TL, e.BTN_TR, e.BTN_TL2],
    e.EV_ABS : [(e.ABS_X, AbsInfo(value=128, min=0, max=255, fuzz=0, flat=15, resolution=0)), (e.ABS_Y, AbsInfo(value=128, min=0, max=255, fuzz=0, flat=15, resolution=0))]
}

dev_real = InputDevice('/dev/input/event20')
dev_virt = UInput(cap, name='Cypress Virtual')

for event in dev_real.read_loop():
    dev_virt.write_event(event)

Above code keeps getting the error below.

Traceback (most recent call last):
  File "pytest.py", line 10, in <module>
    dev_virt = UInput(cap, name='Cypress Virtual')
  File "/usr/lib/python3.5/site-packages/evdev/uinput.py", line 83, in __init__
    _uinput.create(self.fd, name, vendor, product, version, bustype, absinfo)
OSError: [Errno 22] Invalid argument

But when I change the value=128 to value=0 for both AbsInfo()'s. it runs without an error.
Printing the uinput device capabilities with evtest.py reveals this:

  Type EV_ABS 3:
    Code ABS_X 0:
      val 139, min 0, max 0, fuzz 255, flat 0, res 0
    Code ABS_Y 1:
      val 101, min 0, max 0, fuzz 255, flat 0, res 0

Any help would be appreciated.

Thanks

Hardcoded values in setup.py

Hello,

In setup.py and gencodes.py, locations of input.h and input-event-codes.h are hardcoded. It seems problematic for cross-compiling.

Example: I use buildroot and try to integrate python-evdev in my local buildroot repo. During the cross-compilation of python-evdev, gencodes.py parses theses two headers files in order to generate a encode.c. Then the compiler try to compile with the target header files which are located in the buildroot path.

I temporarily changed theses hardocded values to point on my buildroot local repository, but it's ugly and couldn't be automatized.

OSError: [Errno 22] Invalid argument while copy capabilities from InputDevice to UInput

Howdy,
I currently write a screenreader deamon for linux.
for this i need to "consume" the shortcuts for the screenreader because there should no other programm react to it. so i need to grab the InputDevices -> Check ist the keypress for me? No -> write it back to the "normal" input line for other programms.
so i try to generate a UInput class per InputDevice and i like to have the same capabilities (because later i just forewart the input)
If i define the UInput variable with (see example):

uDevices[fd] = UInput( dev.capabilities())

i get the following error:
Traceback (most recent call last): File "<stdin>", line 7, in <module> File "/usr/lib/python3.5/site-packages/evdev/uinput.py", line 104, in __init__ _uinput.enable(self.fd, etype, code) OSError: [Errno 22] Invalid argument

if i try something more simple it works:
from evdev import UInput, AbsInfo, ecodes as e t = UInput({ e.EV_KEY : [e.KEY_A, e.KEY_B]})

so somehow it seems that it is not able to parse.

Did i something wrong? can I got this working somehow? is this maybe a bug?

the following example code gives me the error:

import evdev
from evdev import InputDevice, UInput
from select import select
import time

iDevices = map(evdev.InputDevice, (evdev.list_devices()))
iDevices = {dev.fd: dev for dev in iDevices if dev.fn in ['/dev/input/event14']} # event14 is in my example a keyboard
uDevices = {}
for fd in iDevices:
    dev = iDevices[fd]
    print(dev.capabilities(verbose=True))
    print('-----------')
    print(dev.capabilities(verbose=False))    
    print('-----------')    
    uDevices[fd] = UInput( dev.capabilities())

the prints give me the following:

{('EV_MSC', 4): [('MSC_SCAN', 4)], ('EV_SYN', 0): [('SYN_REPORT', 0), ('SYN_CONFIG', 1), ('?', 4), ('?', 17), ('?', 20)], ('EV_KEY', 1): [('KEY_ESC', 1), ('KEY_1', 2), ('KEY_2', 3), ('KEY_3', 4), ('KEY_4', 5), ('KEY_5', 6), ('KEY_6', 7), ('KEY_7', 8), ('KEY_8', 9), ('KEY_9', 10), ('KEY_0', 11), ('KEY_MINUS', 12), ('KEY_EQUAL', 13), ('KEY_BACKSPACE', 14), ('KEY_TAB', 15), ('KEY_Q', 16), ('KEY_W', 17), ('KEY_E', 18), ('KEY_R', 19), ('KEY_T', 20), ('KEY_Y', 21), ('KEY_U', 22), ('KEY_I', 23), ('KEY_O', 24), ('KEY_P', 25), ('KEY_LEFTBRACE', 26), ('KEY_RIGHTBRACE', 27), ('KEY_ENTER', 28), ('KEY_LEFTCTRL', 29), ('KEY_A', 30), ('KEY_S', 31), ('KEY_D', 32), ('KEY_F', 33), ('KEY_G', 34), ('KEY_H', 35), ('KEY_J', 36), ('KEY_K', 37), ('KEY_L', 38), ('KEY_SEMICOLON', 39), ('KEY_APOSTROPHE', 40), ('KEY_GRAVE', 41), ('KEY_LEFTSHIFT', 42), ('KEY_BACKSLASH', 43), ('KEY_Z', 44), ('KEY_X', 45), ('KEY_C', 46), ('KEY_V', 47), ('KEY_B', 48), ('KEY_N', 49), ('KEY_M', 50), ('KEY_COMMA', 51), ('KEY_DOT', 52), ('KEY_SLASH', 53), ('KEY_RIGHTSHIFT', 54), ('KEY_KPASTERISK', 55), ('KEY_LEFTALT', 56), ('KEY_SPACE', 57), ('KEY_CAPSLOCK', 58), ('KEY_F1', 59), ('KEY_F2', 60), ('KEY_F3', 61), ('KEY_F4', 62), ('KEY_F5', 63), ('KEY_F6', 64), ('KEY_F7', 65), ('KEY_F8', 66), ('KEY_F9', 67), ('KEY_F10', 68), ('KEY_NUMLOCK', 69), ('KEY_SCROLLLOCK', 70), ('KEY_KP7', 71), ('KEY_KP8', 72), ('KEY_KP9', 73), ('KEY_KPMINUS', 74), ('KEY_KP4', 75), ('KEY_KP5', 76), ('KEY_KP6', 77), ('KEY_KPPLUS', 78), ('KEY_KP1', 79), ('KEY_KP2', 80), ('KEY_KP3', 81), ('KEY_KP0', 82), ('KEY_KPDOT', 83), ('KEY_ZENKAKUHANKAKU', 85), ('KEY_102ND', 86), ('KEY_F11', 87), ('KEY_F12', 88), ('KEY_RO', 89), ('KEY_KATAKANA', 90), ('KEY_HIRAGANA', 91), ('KEY_HENKAN', 92), ('KEY_KATAKANAHIRAGANA', 93), ('KEY_MUHENKAN', 94), ('KEY_KPJPCOMMA', 95), ('KEY_KPENTER', 96), ('KEY_RIGHTCTRL', 97), ('KEY_KPSLASH', 98), ('KEY_SYSRQ', 99), ('KEY_RIGHTALT', 100), ('KEY_HOME', 102), ('KEY_UP', 103), ('KEY_PAGEUP', 104), ('KEY_LEFT', 105), ('KEY_RIGHT', 106), ('KEY_END', 107), ('KEY_DOWN', 108), ('KEY_PAGEDOWN', 109), ('KEY_INSERT', 110), ('KEY_DELETE', 111), (['KEY_MIN_INTERESTING', 'KEY_MUTE'], 113), ('KEY_VOLUMEDOWN', 114), ('KEY_VOLUMEUP', 115), ('KEY_POWER', 116), ('KEY_KPEQUAL', 117), ('KEY_PAUSE', 119), ('KEY_KPCOMMA', 121), (['KEY_HANGEUL', 'KEY_HANGUEL'], 122), ('KEY_HANJA', 123), ('KEY_YEN', 124), ('KEY_LEFTMETA', 125), ('KEY_RIGHTMETA', 126), ('KEY_COMPOSE', 127), ('KEY_STOP', 128), ('KEY_AGAIN', 129), ('KEY_PROPS', 130), ('KEY_UNDO', 131), ('KEY_FRONT', 132), ('KEY_COPY', 133), ('KEY_OPEN', 134), ('KEY_PASTE', 135), ('KEY_FIND', 136), ('KEY_CUT', 137), ('KEY_HELP', 138), ('KEY_F13', 183), ('KEY_F14', 184), ('KEY_F15', 185), ('KEY_F16', 186), ('KEY_F17', 187), ('KEY_F18', 188), ('KEY_F19', 189), ('KEY_F20', 190), ('KEY_F21', 191), ('KEY_F22', 192), ('KEY_F23', 193), ('KEY_F24', 194), ('KEY_UNKNOWN', 240)], ('EV_LED', 17): [('LED_NUML', 0), ('LED_CAPSL', 1), ('LED_SCROLLL', 2), ('LED_COMPOSE', 3), ('LED_KANA', 4)]}
-----------
{0: [0, 1, 4, 17, 20], 1: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 113, 114, 115, 116, 117, 119, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 240], 4: [4], 17: [0, 1, 2, 3, 4]}
-----------

Strange behavior on n-key rollover keyboard

I will look more into it but here is what I have figured out so far:

  • It registers up to 6 keys pressed simultaneously.
  • When grab is on, any more keys pressed after 6 keys appear on the terminal.
  • Any more keys pressed after 6 are not registered.
  • The keyboard is supposed to be n-key rollover and if I open the keyboard layout on gnome I can see X can register up to 17 keys. (I think that's how many the keyboard can really handle.)
  • testing with evtest I can see it suffers from the same problem.

I am not sure if this a problem with this package or with evdev, but X uses the same API right? Anyway I will try to figure it out but please let me know If you have any ideas about what is happening.

some error when run setup.py install at python26 platform

File "setup.py", line 85, in create_ecodes
print('writing ecodes.c (using {})'.format(header))

cwd='{}/evdev'.format(here),

ValueError: zero length field name in format

for corrent this issue:

diff --git a/setup.py b/setup.py
index d5dc724..58db7e7 100755
--- a/setup.py
+++ b/setup.py
@@ -82,9 +82,9 @@ def create_ecodes():

 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),
    
  • print('writing ecodes.c (using {0})'.format(header))
  • check_call('bash ./ecodes.sh {0} > ecodes.c'.format(header),
  •           cwd='{0}/evdev'.format(here),
            shell=True)
    

Error in device.py

Line 217 should be (under python 2.6):
return '{0!r}'.format(msg)
Not:
return '{}({!r})'.format(msg)
Is this valid syntax anyway, use of (), since {0}({!r}) doesn't work!

Having made my changes tutorial 1 now works under python 2.6

UInput.from_device does not merge every event code

When using UInput.from_device() to merge the capabilities of several devices, the resulting capabilities of the uinput device are not the full list of those in the source devices.

Since for each ev_type in dev.capabilities() we have a list of ev_codes, if two devices have same ev_type but differente ev_codes, the update method on uinput.py replaces the previous list with the last ones:

     all_capabilities = {}
     for dev in device_instances:
         all_capabilities.update(dev.capabilities())

To correctly merge capabilities of several devices we should do something like this to extend the lists instead of replacing them:

    all_capabilities = defaultdict(list)
    for dev in device_instances:
        dev_caps = dev.capabilities()        
        for ev_type, ev_codes in dev_caps.iteritems():
            all_capabilities[ev_type].extend(ev_codes)
            all_capabilities[ev_type] = list(set(all_capabilities[ev_type]))  # removes duplicate ev_codes

The last line could be avoided if instead of lists we had sets for device capabilities, which would automatically avoid duplicate ev_codes, but that might be a bigger API change, I think.

I could do a pull request if you find it appropriate

Behavior of read() and read_one() when input device disappears

Hi there. I'm trying to implement a little script which watches for a certain bluetooth button device to appear, then read events from it, and handle gracefully if it disappears.

I actually found your post on https://stackoverflow.com/questions/15944987/python-evdev-detect-device-unplugged/16500472#16500472 and I'm using that as an example.

However, the interesting thing is that when my bluetooth device goes to sleep, it appears that select() returns with descriptor in the read array. When I go and call read() or read_one() on the corresponding InputDevice I get:

Traceback (most recent call last):
  File "key_controller.py", line 67, in <module>
    event = dev.read_one()
  File "/usr/local/lib/python2.7/dist-packages/evdev/eventio.py", line 54, in read_one
    event = _input.device_read(self.fd)
IOError: [Errno 19] No such device

So interestingly, it seems that it takes a while for udev to actually tell me that the device is gone (so that I can tear down the fd in the selected set. I dealt with this by just doing an os.path.exists() on the devices' .fn field, which seems to work.

Not sure if this should be considered a bug or expected behavior, but given these devices can appear and disappear, it might be nice for the python evdev api to be able to handle that more gracefully somehow. I expected read_one() to return None in this case, and for there to maybe be some kind of other flag I could check to see if this InputDevice instance was still "valid".

Error in util.py

line 14 on util.py reads:

fns = glob.glob('{}/event*'.format(input_device_dir))

to work (on python 2.6) it has to read:

fns = glob.glob('{0}/event*'.format(input_device_dir))

If you run the first tutorial example with the current util.py line 14 you get:

>>> devices = map(InputDevice, list_devices())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.6/dist-packages/evdev/util.py", line 14, in list_devices
    fns = glob.glob('{}/event*'.format(input_device_dir))
ValueError: zero length field name in format

If you run the modified line 14 you get:

>>> fns = glob.glob('{0}/event*'.format('/dev/input'))
>>> print fns
['/dev/input/event6', '/dev/input/event5', '/dev/input/event4', '/dev/input/event3', '/dev/input/event2', '/dev/input/event1', '/dev/input/event0']

Hope that helps

Installing python-evdev on arduino yun - fhonour-copts error

Hi:
I am trying to install python-evdev on my arduino yun using "./setup.py install". I get the following error: Any suggestion will be appreciated (bear in mind that I am a newbie).

./setup.py install

running install

running bdist_egg

writing ecodes.c (using /usr/include/linux/input.h)

running egg_info

writing evdev.egg-info/PKG-INFO

writing top-level names to evdev.egg-info/top_level.txt

writing dependency_links to evdev.egg-info/dependency_links.txt

reading manifest file 'evdev.egg-info/SOURCES.txt'

reading manifest template 'MANIFEST.in'

writing manifest file 'evdev.egg-info/SOURCES.txt'

installing library code to build/bdist.linux-mips/egg

running install_lib

running build_py

running build_ext

building 'evdev._input' extension

mips-openwrt-linux-uclibc-gcc -fno-strict-aliasing -Os -pipe -mips32r2 
-mtune=mips32r2 -fno-caller-saves -fhonour-copts -Wno-error=unused-but-set-variable -msoft-float -DNDEBUG -Os -pipe -mips32r2 -mtune=mips32r2 -fno-caller-saves -fhonour-copts -Wno-error=unused-but-set-variable -msoft-float -fPIC -I/usr/include/python2.7 -c evdev/input.c -o build/temp.linux-mips-2.7/evdev/input.o -std=c99 -Wno-error=declaration-after-statement

cc1: error: unrecognized command line option '-fhonour-copts'

cc1: error: unrecognized command line option '-fhonour-copts'

error: command 'mips-openwrt-linux-uclibc-gcc' failed with exit status 1

root@Arduino:/mnt/sda1/python-evdev-0.4.7# cc1: error: unrecognized command 
line option '-fhonour-copts'
-ash: cc1:: not found
root@Arduino:/mnt/sda1/python-evdev-0.4.7# cc1: error: unrecognized command line option '-fhonour-copts'
-ash: cc1:: not found

cannot convert keycodes to character sequences

Hello,

I've started working on a project that reads from a remote control and sends the input to another child process. I could try to find out the key mapping by trial and error, but I hoped I could find something ready to do this.

Unfortunately evdev doesn't seem to help much with it, only shows keycodes e.g. KEY_UP = 103, that can only be redirected system wide (using UInput.write()), but does not map to convert the keycode to the corresponding ascii character sequence ("\027[A") or allow to redirect the input to a user process

Do you know a way to see this mapping?

Regards, Mauro

Loop stuck, runs only once on each keypress

I'm working on a project that needs to do certain things on specific keypresses.

To do this I'm using a loop to check the value of the pressed key and do something accordingly. The problem I'm having is that the while loop is interrupted whenever I'm using the getKey() function, so the rest of the loop only runs once after each keypress.

I'm probably doing something very basic horribly wrong as I've just started out with python recently. A push in the right direction would be of great help!

from evdev import InputDevice, list_devices, categorize, ecodes

dev = InputDevice('/dev/input/event0')
def getKey():
    for event in dev.read_loop():
        if event.type == ecodes.EV_KEY:
            keybrd = categorize(event)
            if keybrd.keystate == keybrd.key_down:
                c = keybrd.keycode
                return c
                c = ''

while 42:
    c = getKey()
    print 'expected to be looping'

    if c == 'KEY_Z':
        print 'dosomething'
    if c == 'KEY_Q':
        print 'dosomethingelse'
    runSomeOtherFunctionThatNeedsToBeLooped()

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.