FreeBSD's psm(4) driver is well over 3000 lines long. It supports 12
kinds of mice. moused(8) supports another 15 kinds mice. Between ums(4),
psm(4), and moused(8), there is a great deal of redundancy and mess in
the source code. Furthermore, moused(8) is a userland utility while
psm(4) is a kernel driver. I believe that all mouse support should come
primarily from a userland utility, such as moused(8). This will allow the
psm(4) driver to provide the bare minimum and allow specific mice support
to be written as plugins for moused(8).
Write psm(4) somewhat from scratch to provide moused(8) with a
means of accessing in a fairly raw manner.
Write a basic moused(8) that provides a useful API for
describing mouse actions and supports plugins loadable at run-time
(aswell as probing for mice features)
Installing libps2 and the moused modules will not overwrite anything
already existing in the system. It is safe to install them. Now, try
running moused:
if you have synaptics: ./moused -m synaptics
if you have another ps/2 mouse: ./moused -m generic
if you use ums: ./moused -m sysmouse -d /dev/ums0
Build Problems?
Compilation errors with psm(4) regarding 'MOUSE_COMMAND' not being defined:
You didn't properly patch sys/sys/mouse.h. cp newmoused/newpsm/oldpsm/sys/mouse.h /usr/src/sys/sys/mouse.h
Compilation errors with libps2
Make sure you copied my mouse.h to /usr/include/sys/mouse.h
Patches to bugs:
Synaptics taphold (leftbutton down) always triggers after a tap and a finger-down
cd newmoused/moused/modules/synaptics/
patch < synaptics-tapholdclick.patch
Current issues:
Synaptics support has a few issues probably due to incomplete
porting from the psm(4) implementation and the new module. It still
works, however, for me.
The X "sysmouse" driver will no longer work on /dev/psm0. This is becuase X expects the 'sysmouse' mouse protocol and it gets whatever the mouse spits out. You MUST use moused from now on.
If you get compilation errors, email me and I'll help you get them fixed.
newpsm(4) will only provide a more-or-less raw interface with a
connected ps/2 mouse. I don't know right now whether or not the X ps/2
mouse driver will still work, but we'll see. If it doesn't, I'll look
into having newpsm provide a generic ps/2 interface X will understand
with an ioctl that lets you switch between generic ps/2 and raw.
I'm still trying to get my feet wet with both FreeBSD's kernel and
talking to hardware, so a lot of my ideas are probably misguided.
I recently bought a new keyboard (IBM USB Travel Keyboard with
UltraNav) which has a synaptics touchpad and trackpoint for mice. The
trackpoint and touchpad come up as two separate uhid devices . The
windows driver probably supports lots of things like pressure
sensitivity, touchpad-scrolling, etc. The protocol may or may not be
uhid, I don't know.
The new psm kernel driver only provides the bare minimum features. All
of the ioctls have been stripped and replaced with, essentially,
MOUSE_COMMAND and MOUSE_SET_SYNCBITS. Every other activity has been
moved to the userland in the form of moused's libps2, a ps/2
protocol library. Such actions as the old MOUSE_SET_RESOLUTION are
replaced by libps2/s ps2_set_resolution() which in-turn calls
MOUSE_COMMAND using an ioctl on /dev/psm0.
This moves all of the real work handling the mouse to the userland and
provides a much more flexible model for implementing mice drivers.
The new moused(8) will provide a minimum api for the plugin drivers to
access. The api should provide means to pass state deltas (x, y, and
other changes) with little else. What kinds of data will a mouse
driver need to convey? However, deltas may not be the easiest way of
transmitting button changes from the driver to moused. I'm not sure
yet. At any rate, the delta will be in the form of passing a structure
back to moused(8) containing x, y, z1, z2, and button deltas. I'm
not sure if this should be of the callback form where moused calls
the plugin for data, or if the plugin loops itself. However, seeing
as how plugins (drivers) should do the least amount of OS-level
work, but instead act as liasons between hardware and the OS, I
think the read loop should go in moused itself. This should be the
easy part.
The plugin structure will work similiarly to how the freebsd kernel
object system works. Plugins will provide functions to probe for
mice, read from mice, and reset mice. Probing will be used to
detection of mice given the mouse type of "auto" to moused. It will
also be used to make sure the right plugin is used if a user
specifies what plugin to use. Plugins will be shared objects loaded
during runtime with dlopen(3).
Modules will be provided with protocol libraries to aid in the
creation of new modules. The ps/2 protocol library has already been
created and will help developers write new drivers for ps/2 mice.
Filters may be a good idea, but their lifespan/usefulness may be
short, I haven't decided yet. However, the goal behind them is
something I consider to be a good idea, so moused(8) may provide
these natively instead of using output filters. The premise behind
filters would be to manipulate the output of moused before it hits
the device (and thus, the OS). Such filters could be to add
features interpreted from the deltas. For example, a recent patch I
made to moused(8) added "virtual scrolling" - this could be
implemented in a filter so that this feature would be accessible
regardless of the plugin driver. Another such example is the
"emulate 3 button mouse" feature provided again by the current
moused(8) using the -3 option. However, I don't know if
there are enough delta-reactive features (like virtual scrolling)
to be written that would merit a filter framework. This requires further
discussion and brainstorming. A short list of some useful features I can
come up with are:
Emulate 3 button mouse
Virtual Scrolling (Vertical/Horizontal)
X/Y acceleration
Physical to Logical button mapping
Z-Axis activity (moused -z option)
Jitter correction/smoothing
Many of these have already been written. Check moused/filters.c for what I have done.