Skip to content
Advertisement

How to send and execute multiple events in one file stream by writting to “/dev/input/EventX”

I am writting to a specific eventX file in /dev/input/, to trigger “hardware” events. The problem is, the events get executed, only after the file has closed and to trigger new events, the file needs to be reopened. It’s as if all the events are put on a queue and then when the file closes, they get executed. For example

Task: Perform mouse press.

# Path is specific to my machine for the mouse
with open("/dev/input/event2") as controller: 
    send_mouse_click_event(controller) # This is put into a queue

print("File has closed") # here the press event triggers

The send_mouse_click_event, which depends on the function send, in defined as follows

# First a `send` function is used to interact with file
# it is basically the inverse of https://stackoverflow.com/a/16682549/13616163
def send(file_stream, type: int, code: int, value: int):
    timeval = str(time.time()).split(".") # Time that the event happend is requried, but seems to be redundant  
    if timeval[0][0] == '0': # the second part of `time.time()` must not start with a `0`
        utime = utime[1:len(utime)] 
    timeval = [int(item) for item in utime]
    # Convert to the following formats (long int, long int, ushort, ushort, uint)
    event: bytes = struct.pack('llHHI', *utime, type, code, value)
    file_stream.write(event)

# Now the specific events to trigger a mouse click
def send_mouse_click_event(filestream, value: int):
    # 0x90001 is always send before a click
    send(filestream, 4, 4, 0x90001)
    # 0x110 is indicating the LEFT CLICK
    # value is either 0 for mouse RELEASE and 1 for PRESS
    send(filestream, 1, 0x110, value)
    # (0, 0, 0) is indiciating the end of an event
    send(filestream, 0, 0, 0)

My question is, Is there any event I can send() to indicate that I want to execute all the items that are placed in the queue.

Closing and opening a file, is an expensive operation, and having to do that multiple times is a performance killer. There must be a better way that keeps the file stream open.

Advertisement

Answer

Unless buffering has been disabled in the open call by setting the buffering parameter to 0, the file stream will be either fully buffered or line buffered. This depends on the type of file being opened and on the open mode, but binary file streams are never set to line buffered mode.

In buffered mode, the write method will write to the buffer, but the buffer contents will not be written to the underlying file until either the buffer is full, or a newline is written in line buffered mode.

The flush and close methods will write the buffer contents to the underlying file. The close method also closes the file afterwards.

In OP’s code, adding file_stream.flush() to the end of the send function will write the buffer contents through to the underlying file every time the send function is called. An alternative is to add filestream.flush() to the end the send_mouse_click_event function so that the data written by the three calls to send is flushed to the underlying file in one go.

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement