Search this site





newpsm framework - A new mouse driver framework for FreeBSD 7.x


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:

Test it!

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 'device psm'
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

Configuration File

You can now configure mice via a config file. Format is the same as a termcap file. Read this page 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
  • 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
  • Profit
  • Kill existing moused and psm
  • Kill ums in favor of uhid-userland driver
  • Naptime

Uncompleted Tasks (Todo)

  • 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

Completed Tasks (To... done?!)

  • 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.

Known Issues

  • 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 far.
  • 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.

new psm design

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.

new moused design

moused: slimmed down

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.

plugin structure

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.