Joe
Joe

Reputation: 51

How to capture raw mouse input in X11?

For the Windows version of my application, I'm using WM_INPUT and registering the mouse device directly to get the most precise movements. How would I go about doing this in X11?

Upvotes: 5

Views: 5852

Answers (2)

Jose_X
Jose_X

Reputation: 1094

Here are eleven links that provide reference, advice, and two different approaches to get raw mouse movements on Linux. Link #2 (Python) shows the traditional way to read the mouse device and #1 (C), #3 (Python), and #4 (C) show the events way. The ps/2 protocol is covered in link #5. Link #6 is a command line example.

Each of the two approaches bypasses X (Xlib) by getting from a device driver file the stream of deltas in the x and y directions. Rather than deltas, Xlib traditionally provides just the window (or screen) position so you must keep moving the pointer from the edge of the window if you want to keep getting readings in a particular direction. [See link #8 for a quick discussion on the "warping to center" hack used by many programs with X.] The new XInput 2.0 extension (link #10), however, offers an X API for getting the deltas (you may have to link at least -lX11 and -lXi).

The essence of either of the two device approaches is this:

1: Open for reading something like the "/dev/input/mouse0" device or something similar (it depends on your distro naming and also on which method you want to use, /dev/input/event4 for the other approach).

2: Read from it. Every so many bytes represents a mouse movement. For example, for the ps/2 raw protocol method, eg, by opening mouse[n] as above, you basically want just the 2nd and 3rd bytes of every 3 byte sequence if you just care about x, y movement. The second byte represents X. The third represents Y. Each of the two bytes is a single int8_t (signed 8 bit) quantity. Positive X seems to be to the right, no problem; however, positive Y seems to be upward (as in most math text books) while on a screen positive Y is usually considered going downward from the upper left corner of the screen (vs. going up from the lower left as the origin in a typical Cartesian coordinate system).

Other notes: You may want to use open/read rather than fopen/getc if you are running X (see link #7 and code in other links). If you want mouse button state for the first 3 buttons or want to confirm the signedness of x or y, then look at the first byte as well. [I doubt overflow is an issue in ordinary "stream" use, but those bits are there as well.] You may notice if you experiment on the Linux command line, eg, a quick "cat" to "less", that most movements are just of 1 unit (lots of ^A ^@ and <FF>). This may depend on how the mouse is configured and on how capable is the mouse. Link #5 covers the simple protocol and even covers the Microsoft intellimouse standard extension for buttons 4 and 5 and the mouse wheel. Link #11 covers the controller chips/logic configuration for ps/2 mouse or keyboard. It explains how the mouse is configured by this interface. There is a tool (link #9, xdotool) that simulates mouse clicks to help automate windowing tasks. Finally, you may need to be root to read directly from these devices (depends on your distro).

Upvotes: 3

j4x
j4x

Reputation: 3716

There are several ways to do this, depending on the framework you are using.

If you intend to do this with "Xlib", the most basic way to program for X11, you should take a look at Xlib manual, with special attention to XInput. More elaborated information can be retrieved by using XI2 (XInput version 2)

Other higher level frameworks can make things easier. Take a look at Qt. It's one of the best GUI API's I've ever seen.

Tell us if you need more.

Upvotes: 2

Related Questions