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)
If you are interested in reading more in-depth about this project, see the following links:
You will need to be building with -CURRENT for this to definitely
work. I have not tested this on 5.x or 6.x.
Download this patch: patch-CURRENT-Apr.13.06.newpsm+newpsm
Apply the patch (You need /usr/src checked out already):
patch -p0 < patch-CURRENT-Apr.13.06.newmoused+newpsm
Rebuild world with '-DNEWMOUSE' and recompile your kernel with 'device
newpsm' and NOT
make buildworld -DNEWMOUSE
make installworld -DNEWMOUSE
Reboot, and you should be good to go. If you have a ps/2 mouse plugged in, you should see:
psm0: <(new) PS/2 Mouse> irq 12 on atkbdc0
The keyword there is (new)
Assuming everything is OK, you can now try the newmoused. The default
device is /dev/psm0. The default driver option is to try all modules
and pick the first one that succeeds.
- For non-synaptics ps/2 mice:
- Run: "moused"
The default mouse device is /dev/psm0
- For synaptics ps/2 mice:
- Run: "moused -m synaptics"
This will force moused to try the synaptics module
- For USB mice:
- Run: "moused -d /dev/ums0"
- For mse(4) mice:
- Run: "moused -d /dev/mse0"
- -f : run in foreground
- -3 : Emulate 3 button
- -E XXX : emulate 3 button timeout
- -V : Virtual scrolling
- -U XXX : virtual scrolling threshold
- -a X[,Y] : acceleration with x and y (optional) multiplier
- -d dev : specify mouse device
- -m module : specify module name
- -v : increase verbosity (default 0, -ddd means 3)
- -h : usage
You can now configure mice via a config file. Format is the same as
a termcap file. Read
for specific information about the configuration
file. The config file location is "/etc/moused.conf"
You can check on what I've done through p4web:
View my p4 depot on perforce.freebsd.org
- newpsm driver stubbed out and written. (may be scrapped)
the old psm driver needs to be split. It has a part called psmcpnp that needs to become it's own separate driver.
Add per-driver configuration
- new moused module-happy framework
- strip psm(4) of protocol knowledge
- 3 basic drivers: synaptics, geneirc ps/2, and sysmouse
- Have progress committed to -CURRENT and co-exist with existing moused and psm
- Kill existing moused and psm
- Kill ums in favor of uhid-userland driver
- Deal with ums(4) - kill it and move it to userland?
- start newpsm(4) - include extremely basic functionality: probing, attaching, detaching, open, read, etc (might be scrapped)
- Provide module(s?) for mice handled by old psm(4)
- Add uhid joystick module?
- Remove Giant from psm(4)
- Conform to style(9)
- Port up lots of serial mice drivers from the old moused(8)
- Nap time
- PS/2 and usb test/probe application
- Bluetooth support
- Driver example code
- Driver-writing documentation
- start moused(8) manpage - basic commandline options (-p, etc) and reading from newpsm.
- moused - configuration via config files
- moused - write a synaptics module
- moused - write a ps/2 generic pass-through plugin
- moused - write some basic filters (emulate 3 button, etc)
- moused - write a ums (sysymouse?) module
- moused - write a plugin interface for loadable userland mouse drivers.
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.
- Microsoft Explorer Mouse 4.0A acts very strangely under ums/moused.
- Synaptics USB (on my thinkpad ultranav travel keyboard) seems
to act funny with moused, though I've only used it for 5 minutes so
- atkdbcreg.h defines PSM_MOUSE_ID, PSM_INTELLI_ID, and others. Shouldn't this be in a more mouse-specific place?
- psm needs GIANT, why? More research is required, or someone should just tell me.
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
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.