John Forkosh John Forkosh - 3 months ago 16x
Linux Question

Interpretation of input_event members for mouse actions

I'm writing an essentially character-based program, but running in an xterm, and want to use mouse scroll-wheel-up/down and left-clicks as synonyms for keyboard arrow-up/down and return, just for a little extra user convenience.

I've got a

with all the input fdset's working fine, and am asynchronously capturing the raw input fine (seems so, anyway). But I'm having a little trouble unambiguously interpreting the type,code,value members from the input_event struct.
seems to have some EV's, and I'm seeing

  • EV_REL=0x02
    (relative position when mouse is moved)

  • EV_MSC=0x04
    (miscellaneous) for all other mouse actions.

Question 1:Is that universally true??? I'm not successfully googling anything much about that specifically.

But beyond EV's, I'm seeing nothing in
for codes,values. My experimenting shows the following, and I'm further asking if everything below is (universally) true. Or even better, where's (definitive) documentation about this stuff? I'd have thought it would be easy to google, but couldn't find answers.

Any one action seems to generate either two or three separate input_event's, with the last (the second or third) a "trailer" with type=code=value=0. I'm writing input_event's below as triples (type,code,value)...

For left-click-press you get three events: (4,4,589825),(1,272,1),(0,0,0). And for left-click-release you get: (4,4,589825),(1,272,0),(0,0,0). Is that all correct? And what the heck's 589825???

For scroll-wheel-up you get two events: (2,8,1),(0,0,0). And for scroll-wheel-down you get: (2,8,-1),(0,0,0). (Universally) correct, again?

I don't particularly care about right-clicks or mouse movements, which I'll just be ignoring. So can I hard-code (with some #define'ed symbols) the preceding stuff, or is it more like termcap, where it's device-capability-dependent in some way? And, again, where's this stuff documented for real? Thanks.


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.