I enabled wsmoused for console mouse support, but the cursor was
unusably fast. This is a high resolution, high update rate USB gaming
mouse, but it was off by well over an order of magnitude.

I searched for a global mouse speed setting, but the only thing I
found was a "mouse.scale=0,0,0,0,0,0,0" in wsconsctl, and I couldn't
figure out how to use it even after reading all the source.

There is an ioctl for mouse resolution, but it only applies to PS/2
mice:

/* Set resolution. Not applicable to all mouse types. */
#define WSMOUSEIO_SRES _IOW('W', 33, u_int)

The wsmousecfg values for WSMOUSECFG_DX_SCALE and WSMOUSECFG_DY_SCALE
are only used for touchpads, and are zero for mice.

The USB mouse driver can apply scaling to mouse delta movements if it
is taken out of raw mode and the wsmouse_calibcoords are set to
reasonable values, but the comments don't seem to be correct:

/* Set/get sample coordinates for calibration */
#define WSMOUSE_CALIBCOORDS_MAX 16
#define WSMOUSE_CALIBCOORDS_RESET -1
struct wsmouse_calibcoords {
int minx, miny; /* minimum value of X/Y */
int maxx, maxy; /* maximum value of X/Y */
int swapxy; /* swap X/Y axis */
int resx, resy; /* X/Y resolution */
int samplelen; /* number of samples available or
WSMOUSE_CALIBCOORDS_RESET for raw mode */
struct wsmouse_calibcoord {
int rawx, rawy; /* raw coordinate */
int x, y; /* translated coordinate */
} samples[WSMOUSE_CALIBCOORDS_MAX]; /* sample coordinates */
};

No kernel code uses the samples[] array, and the samplelen field is
interpreted as raw mode when non-0, and scaled by the other values
when it is 0.

This explains wsconsctl's mouse.rawmode and mouse.scale[7] values,
but I still couldn't set them, getting
WSMOUSEIO_SCALIBCOORDS: Invalid argument for everything I tried.

If I called the ioctl with my own code, I could clear raw mode and
scale the mouse speed down by 10x.

That slows the mouse down, but the behavior is terrible.

The scaling applied in hidms_input() would be reasonable for an
absolute referenced touch screen, but it isn't for integer valued
relative motion, because information is permanently lost in the
scaling -- you can slowly move the mouse an arbitrary distance
without the pointer moving at all, as the deltas are rounded to
zero, and it is done per-axis, so slight angles turn into strictly
axial motion.

Mouse scaling needs to maintain a fractional residual for each axis.

The user visible behavior I want to see is:

wsconsctl mouse.speed=0.6

This could overload the existing DX_SCALE value, but that may still
need to be used independently for touchpad configuration, so I
think it would be better to define a new WSMOUSECFG_SPEED
parameter with the same *.12 fixed point format as
WSMOUSECFG_DX_SCALE.

If this sounds reasonable, I will go ahead and make a diff for the
kernel and wsconsctl to implement it that with proper residuals.

For additional cleanup to make it net-negative-LoC, could everything
relating to struct wsmouse_calibcoords go away completely? It looks
like all the fields are now replicated as wsmousecfg parms and
handled at the wsmouse level for the touchpad case, so doing it at
the usb device or other level is redundant, as well as being broken
for relative moves.

It would be nice to use parms for everything, also getting rid of
WSMOUSEIO_GTYPE and WSMOUSEIO_SRES.


Reply via email to