Input events on X have an old world and a new world
The X Window System is now very old, and it never had what you could call 'protocol agility' in the core X protocol. As a result, over the years X has been extended through both conventions (such as modern X fonts) and X server extensions. In theory both forms of extension are optional and servers and clients may not support any specific one; in practice, various common things are now mandatory for any X server or client that wants to work right in the modern world.
(For instance, X servers increasingly don't have many old style X fonts available for you to use and they're often not very good looking.)
As part of X's evolution over time, input event handling has gone
through a practical change, although one that is what you could
call unevenly distributed. The original X protocol has input events,
of course, which are sometimes now called core input events.
You can see what core events are generated from various activities
through the venerable
program, and many straightforward X programs continue to interact
only with core events.
However, core input events have limitations that date from X's origins. Core input events are only really designed to deal with straightforward keyboards and mice with buttons. Even mouse scroll wheels have an awkward representation in core X events; moving the scroll wheel actually generates mouse button events for pressing and releasing button 4 or 5 (for normal, implicitly vertical scroll wheels). I don't think there's anything in the X protocol that reserves these buttons for scroll wheels, it's just a convention that people came up with when they started needing to handle scroll wheels in X.
I suspect that what pushed people over the edge on X input handling was laptop touchpads and trackpads. You can pretend that a touchpad is a mouse and manufacture appropriate X events from finger touches and presses, but this isn't really a good representation of what is actually going on. More sophisticated programs might want to know all sorts of additional information that a touchpad can deliver, and then there's additional input devices like pens.
The solution to this is the X Input (Device) Extension. This
extension understands that you may have multiple input devices
connected, not just one (for example you may have both a touchpad
and an external mouse) and it delivers a much richer event stream
to programs that want to use it. It also generates core input events
from this richer, more sophisticated input event stream. You can
more or less see what XIE events are generated when you do things
although you probably need to know more than you do to interpret
Programs using a modern toolkit like GTK+ will often attempt to use XIE (and may in practice require it). On Linux (and perhaps other Unixes), one sign of such programs is that they use the libXi shared library, which is the X client library for dealing with the X Input Extension. A C program that isn't using this shared library is very unlikely to be using XIE; a C program that has loaded it very likely is using XIE in preference to core input events, especially if it's using a toolkit like GTK+.
One of the important consequences of this split between core input
events and XIE events is that events that look identical at the
core input event level (for example, as shown by
xev) may be
different at the XIE level (as interpreted by libXi and then toolkit
libraries, and perhaps as shown by
xinput). This means that some
programs will treat them exactly the same because they're
indistinguishable and some programs may react to them differently.
This can cause rather odd issues, but that's a story for another