How to Read the Mouse Button State from /Dev/Input/Mice

How do you read the mouse button state from /dev/input/mice?

You can open the device and read from it. Events from /dev/input/mice are 3 bytes long and require some parsing. I think the prefered method now is to use /dev/input/event# instead. However, here is a small example using /dev/input/mice.

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

int main(int argc, char** argv)
{
int fd, bytes;
unsigned char data[3];

const char *pDevice = "/dev/input/mice";

// Open Mouse
fd = open(pDevice, O_RDWR);
if(fd == -1)
{
printf("ERROR Opening %s\n", pDevice);
return -1;
}

int left, middle, right;
signed char x, y;
while(1)
{
// Read Mouse
bytes = read(fd, data, sizeof(data));

if(bytes > 0)
{
left = data[0] & 0x1;
right = data[0] & 0x2;
middle = data[0] & 0x4;

x = data[1];
y = data[2];
printf("x=%d, y=%d, left=%d, middle=%d, right=%d\n", x, y, left, middle, right);
}
}
return 0;
}

One mouse click generates this:

x=0, y=0, left=1, middle=0, right=0
x=0, y=0, left=0, middle=0, right=0

And one mouse move (Note the "relative" mouse move coordinates):

x=1, y=1, left=0, middle=0, right=0

Interpret /dev/input/mice in Java

Thanks to @JustinB for his answer in the comments, just thought I should put it here for others to see:

JustinB: "/dev/input/mice outputs 3 bytes, The first byte is the button data, the next two are x and y. Its not java code, but you might find this or this helpful "

Interpretation of input_event members for mouse actions

I shall assume you are using the event input subsystem (instead of /dev/input/mice) because you wish to read directly form a specific mouse, not from any mice connected to the machine.

The canonical documentation is at doc/Documentation/input/event-codes.txt in (the documentation for) the Linux kernel. That links takes you to the up-to-date web page.

  • type=EV_REL, code=REL_WHEEL, value=1 (2,8,1) indicates (vertical) scroll wheel by one tick forward. The value may be larger than 1 if the user rotates the wheel fast, or if it is a programmable mouse with "fast" scroll wheel mode.

  • type=EV_REL, code=REL_WHEEL, value=-1 (2,8,-1) indicates (vertical) scroll wheel by one tick backward. The value may be smaller than -1 if the user rotates the wheel fast, or if it is a progammable mouse with "fast" scroll wheel mode.

  • Many mice have horizontal scroll wheels. These work the same way as the vertical scroll wheel, except the code is REL_HWHEEL.

  • Other interesting type=EV_REL codes are REL_X, REL_Y, REL_Z (relative movement, REL_Z being "height" or distance from table for 3D mice); REL_RX, REL_RY, REL_RZ for rotation around each axis for things like 3D mice with six-axis accelerometers; and REL_DIAL for jog wheels.

  • type=EV_KEY, code=BTN_MOUSE, value=1 (1,272,1) indicates a mouse click (left click on multi-button mice), and value=0 (1,272,0) a release.

    The code can also be any other KEY_ or BTN_ constant. value is zero for release, nonzero for press.

    In particular, BTN_MOUSE=BTN_LEFT, right mouse button is BTN_RIGHT, middle mouse button is BTN_MIDDLE, side button is BTN_SIDE, extra button is BTN_EXTRA, task button is BTN_TASK, and forward and backward buttons (like on some Logitech mice) are BTN_FORWARD and BTN_BACK.

  • type=EV_MSC, code=MSC_SCAN (4,4,value) provide keyboard scan codes for key/button events not standardized by USB/HID. I do believe you can just ignore these (they often are duplicates of actual events for some odd reason, probably backwards Windows compatibility).

  • type=EV_SYN, code=SYN_REPORT (0,0), is a synchronization event; it means that at this point, the input event state has been completely updated.

    You receive zero or more input records, followed by a type=EV_SYN, code=SYN_REPORT (0,0), for events that happened "at the same time".

    Typically, the HID device will report the changes on all axes and all buttons in one chunk, followed by one of these. This makes a lot of sense, because we want our pointers to move according to the real movement, and not just horizontally/vertically... it'd look weird.

Overall, this is the Linux Input Subsystem, and is extremely stable; it won't change. (New keys, buttons etc. may be added, but existing ones should never change.) The Linux Input Subsystem articles I and II at LinuxJournal (from 2003) are still relevant as background information.

Control mouse by writing to /dev/input/mice

this is not trough the file you mentioned, but its way quicker to use this tool instead of decypering the dump of that file. And it does everything you want in bash.

xdotool does the trick in my terminal.

this is the package site for ubuntu.
you probably can install it trough

# apt-get install xdotool

I could just emerge it on gentoo without adding any repositories.

the tool works fairly simple:

#! /bin/bash
# move the mouse x y
xdotool mousemove 1800 500
# left click
xdotool click 1
# right click
xdotool click 3

found it here

Linux Low Level Mouse Reading

In Linux all mouse events go through /dev/input/mouseX. /dev/input/mice is an accumulator in the single mouse devices. Both gpm and X fetch mouse events from /dev/input/mouseX or /dev/input/mice and forward it.

So reading from /dev/input/mouseX or /dev/input/mice is as low level as you can get – unless you're using libusb/libhid to directly access a USB mouse device. However accessing a mouse that way will detach it from the kernel, cause just a lot of trouble.

Event handlers?

You will have to wait until read has read input the size of input_event structure before you process the data in it.

But the current code only checks if any bytes have been read. This check should be changed to check if the number of bytes read equals the input_event structure.

See the documentation of read:.

Return Value.

On success, the number of bytes read is returned (zero indicates end of file), and the file position is advanced by this number. It is not an error if this number is smaller than the number of bytes requested; this may happen for example because fewer bytes are actually available right now (maybe because we were close to end-of-file, or because we are reading from a pipe, or from a terminal), or because read() was interrupted by a signal. On error, -1 is returned, and errno is set appropriately. In this case it is left unspecified whether the file position (if any) changes.



Related Topics



Leave a reply



Submit