The old ways are dark. They are known to cause birth defects. Or something...
The old design of mouse magic in FreeBSD appears somewhat ad-hoc.
psm(4) stands on it's own, as does ums(4), and mse(4). moused(8) can
be used, optionally. Independently, all three mouse drivers can be
used as input to X. Without moused(8), you don't get a mouse in the
console (if you want one). moused(8) can direct multiple mice through
the sysmouse(4) device, allowing you to present X (or others) with one
single mouse device. This is great, and allows you to hotplug mice and
not need to reconfigure or restart X to use it.
A problem with this setup is the fact that protocol handlers are all
over the place. psm(4) supports a number of mice, ums(4) has hacks to
support different "broken" mice aswell as standard uhid mice. and
mouse(8) itself supports a number of other mice magic as well.
Adding new ps/2 mice drivers to psm(4) requires hacking code in 3 or 4
different places (if not more) of psm.c. This may not seem all that
bad, except it is further hindered by the fact that you have to reboot
every time you want to test your code. Compound that with kernel
segfaults result in panics, and you have a very difficult environment
in which to write new mouse drivers.
The same goes for ums(4), though uhid is a bit easier to deal with.
Furthermore, moused(8) itself is awkward to hack on. Rather, that has
been my experience. Feature magic such as emulate-3-button is
intertwined amongst other unrelated logic, making debugging annoying
and making it annoying to write new features due to the entangled
nature of the code.
I'm not trying to say "this sucks" as an offense to the developers who
worked on these projects. I simply believe there is a better way to do
it.
To summarize, the problems with the old way are:
- Protocol magic is handled in many different places
- Design is not modular and does not lend itself to easy feature additions
- Kernel-land makes for difficult "trial and error" tweaking
The new design is based upon a few ideas:
- All protocol magic should be handled by moused
- Kernel devices should report raw data only
- Drivers are implemented in the form of loadable modules
- Magic features (ie; emulate 3 buttons) should be modular and independent
I'll address these individually.
Instead of having ums(4) or psm(4) have a deep understanding of
their respective protocols, they should report data, unmodified,
from the hardware.
That is, instead of psm(4) providing Synaptics Touchpad support, a
userland driver module should provide this support. psm(4) should
merely act as a hardware-to-userland interface, and a dumb one at
that.
psm: The new psm kernel driver should allow protocol
commands to be transmitted from the userland to the hardware via
ioctl(2). Such commands include setting packet size, data checksum
information, and little else. Movement data is transmitted using
read(2) and will report data of instructed packet size. The packet
size defaults to 3, the "real" PS/2 protocol's packet size.
ums: ums simply fronts for uhid(4). Therefore, I believe
ums(4) should be moved to a userland moused module, which reads
from uhid(4) devices.
No protocol understanding is required for the new psm to function,
becuase all it does is proxy commands and data between hardware and
the userland.
Mouse-specific drivers will be implemented in userland loadable
modules. A module will provide certain functions such as probing
and data handling.
The probe function is responsible for two things:
- Test if the mouse is a specific kind of mouse by..
- Enabling extended features of the specified mouse
If the probe succeeds, then we can go about using this module as
our mouse driver. If it fails, then return failure to indicate that
this module cannot understand this mouse.
The handler function is called whenever new data is available from
the mouse device. New data is detected using the select(2) system
call. The handler function is expected to read data from the given
mouse device and process it as necessary. Updates are conveyed by
calling an update function with a structure containing the activity
data.
Features such as emulate-3-button, chordmiddle, acceleration,
button remapping, jitter correction, and virtual scrolling, are all
what I would consider post-process filters. They are used to modify
the activity structure after the driver module has processed a new
piece of activity data.
For instance, the button mapping filter would map the reported
mouse button to another mapping, such as swapping left and right
mouse button actions. That is, the reports "right mouse button
held" and this filter would change it to "left mouse button held."
This is extremely useful.
Filters in the old moused(8) are not modular. They are grossly
intertwined with other unrelated code. In the new moused(8),
filters are independent functions. As as result, post processing
filters are chained.
This chaining allowed you to have "emulate 3 button" and "virtual
scroll" enabled at the same time. "emulate 3 button" will send
faked middle-mouse button activity if both left and right buttons
are pressed at the same time. "virtual scroll" will change
movements into scrolling activity while the middle mouse button is
held. "emulate 3 button" is called before "virtual scroll" is
called. Therefore, if you have both enabled, you can press
left and right buttons together, and scroll up and down by moving
the mouse up and down. This is not possible with the old moused(8)
implementation.
The new moused(8) also provides a means to configure each specific
mouse. The syntax is that of termcap entries.
For example, on my laptop I have the following configuration:
synaptics:virtscroll:notouchpad:
This enables "virtual scrolling" only for synaptics and disables the
touchpad. I have a T41 and it has a trackpoint and touchpad, both
show up via the same psm(4) device.
Another example (unimplemented) may look like this, if you have a
fancy logitech MX100 mouse:
usb:type=MX1000:maptokey:9=F5
Assuming I do this (might be useful), 'maptokey' would map a button
press to a keyboard key stroke. Here, mouse button 9 would get
mapped to "F5" - Keep in mind that I have not implemented this yet.
More research is required :)
For some flow-chart-ey goodness, see the following:
Old mouse diagram:

New mouse diagram