tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Adding mouse sensitivity adjustment to wsmouse
Hi,
I would like to adjust the sensitivity of my external mouse but leave the
sensitivity of my laptop touchpad as is. As far as I can tell, NetBSD has no
facility to do this. I found a couple of mouse ioctl definitions (but no
implementations) that seem relevant and also kern/12132 that partially
implements what I need. I propose changing wsmouse.c as indicated in the
attached diff. It adds scaling factors for x, y, z, and w into the
wsmouse_softc structure and uses a higher resolution internally in order to
handle fractions without adding floats.
WSCONS_MOUSE_RES is (the inverse of) the internal resolution and
sc_mx, sc_my, etc are the scaling factors (multiplied with WSCONS_MOUSE_RES).
It appears to work for my case with a regular bluetooth mouse but it has not
been tested for a device producing absolute positions.
If this looks OK, we need to decide how to set the scaling factors. There are
two ioctls that appear relevant (from wsconsio.h):
/* Set resolution. Not applicable to all mouse types. */
#define WSMOUSEIO_SRES _IOW('W', 33, u_int)
#define WSMOUSE_RES_MIN 0
#define WSMOUSE_RES_DEFAULT 75
#define WSMOUSE_RES_MAX 100
/* Set scale factor (num / den). Not applicable to all mouse types. */
#define WSMOUSEIO_SSCALE _IOW('W', 34, u_int[2])
WSMOUSEIO_SRES has been implemented for one driver
(sys/arch/hpcmips/vr/vrpiu.c) but I'm not sure what is does. WSMOUSEIO_SSCALE
has not been implemented for any driver (but see kern/12132). My current test
implementaion ignores WSMOUSEIO_SRES and changes WSMOUSEIO_SSCALE to take a
single integer which is used to set the x and y scaling factors. Because
WSMOUSE_RES_MAX is 100, the WSMOUSEIO_SSCALE value can be described as a
percent scaling. This is sufficient for my needs but we might want to scale x
and y differently and also set scaling factors for z and w.
If there is interest and we can reach a consensus on the ioctl question I can
clean this up and submit it. Please let me know.
Regards,
Sverre
Index: sys/dev/wscons/wsmouse.c
===================================================================
RCS file: /cvsroot/src/sys/dev/wscons/wsmouse.c,v
retrieving revision 1.62
diff -u -p -r1.62 wsmouse.c
--- sys/dev/wscons/wsmouse.c 15 Jan 2009 04:22:11 -0000 1.62
+++ sys/dev/wscons/wsmouse.c 18 May 2010 20:39:35 -0000
@@ -144,6 +144,8 @@ extern int wsmuxdebug;
#define INVALID_Y INT_MAX
#define INVALID_Z INT_MAX
+#define WSCONS_MOUSE_RES 100
+
struct wsmouse_softc {
struct wsevsrc sc_base;
@@ -161,6 +163,11 @@ struct wsmouse_softc {
int sc_z; /* absolute-z */
int sc_w; /* absolute-w */
+ u_int sc_mx;
+ u_int sc_my;
+ u_int sc_mz;
+ u_int sc_mw;
+
int sc_refcnt;
u_char sc_dying; /* device is being detached */
@@ -251,6 +258,12 @@ wsmouse_attach(device_t parent, device_t
callout_init(&sc->sc_repeat_callout, 0);
callout_setfunc(&sc->sc_repeat_callout, wsmouse_repeat, sc);
+ /* One-to-one scale multipliers. */
+ sc->sc_mx = WSCONS_MOUSE_RES;
+ sc->sc_my = WSCONS_MOUSE_RES;
+ sc->sc_mz = WSCONS_MOUSE_RES;
+ sc->sc_mw = WSCONS_MOUSE_RES;
+
#if NWSMUX > 0
sc->sc_base.me_ops = &wsmouse_srcops;
mux = device_cfdata(self)->wsmousedevcf_mux;
@@ -368,6 +381,11 @@ wsmouse_input(device_t wsmousedev, u_int
sc->sc_base.me_parent, evar));
#endif
+ x *= sc->sc_mx;
+ y *= sc->sc_my;
+ z *= sc->sc_mz;
+ w *= sc->sc_mw;
+
sc->sc_mb = btns;
if (!(flags & WSMOUSE_INPUT_ABSOLUTE_X))
sc->sc_dx += x;
@@ -389,54 +407,54 @@ wsmouse_input(device_t wsmousedev, u_int
nevents = 0;
if (flags & WSMOUSE_INPUT_ABSOLUTE_X) {
- if (sc->sc_x != x) {
+ if ((sc->sc_x - x) / WSCONS_MOUSE_RES) {
events[nevents].type = WSCONS_EVENT_MOUSE_ABSOLUTE_X;
- events[nevents].value = x;
+ events[nevents].value = x / WSCONS_MOUSE_RES;
nevents++;
}
} else {
- if (sc->sc_dx) {
+ if (sc->sc_dx / WSCONS_MOUSE_RES) {
events[nevents].type = WSCONS_EVENT_MOUSE_DELTA_X;
- events[nevents].value = sc->sc_dx;
+ events[nevents].value = sc->sc_dx / WSCONS_MOUSE_RES;
nevents++;
}
}
if (flags & WSMOUSE_INPUT_ABSOLUTE_Y) {
- if (sc->sc_y != y) {
+ if ((sc->sc_y - y) / WSCONS_MOUSE_RES) {
events[nevents].type = WSCONS_EVENT_MOUSE_ABSOLUTE_Y;
- events[nevents].value = y;
+ events[nevents].value = y / WSCONS_MOUSE_RES;
nevents++;
}
} else {
- if (sc->sc_dy) {
+ if (sc->sc_dy / WSCONS_MOUSE_RES) {
events[nevents].type = WSCONS_EVENT_MOUSE_DELTA_Y;
- events[nevents].value = sc->sc_dy;
+ events[nevents].value = sc->sc_dy / WSCONS_MOUSE_RES;
nevents++;
}
}
if (flags & WSMOUSE_INPUT_ABSOLUTE_Z) {
- if (sc->sc_z != z) {
+ if ((sc->sc_z - z) / WSCONS_MOUSE_RES) {
events[nevents].type = WSCONS_EVENT_MOUSE_ABSOLUTE_Z;
- events[nevents].value = z;
+ events[nevents].value = z / WSCONS_MOUSE_RES;
nevents++;
}
} else {
- if (sc->sc_dz) {
+ if (sc->sc_dz / WSCONS_MOUSE_RES) {
events[nevents].type = WSCONS_EVENT_MOUSE_DELTA_Z;
- events[nevents].value = sc->sc_dz;
+ events[nevents].value = sc->sc_dz / WSCONS_MOUSE_RES;
nevents++;
}
}
if (flags & WSMOUSE_INPUT_ABSOLUTE_W) {
- if (sc->sc_w != w) {
+ if ((sc->sc_w - w) / WSCONS_MOUSE_RES) {
events[nevents].type = WSCONS_EVENT_MOUSE_ABSOLUTE_W;
- events[nevents].value = w;
+ events[nevents].value = w / WSCONS_MOUSE_RES;
nevents++;
}
} else {
- if (sc->sc_dw) {
+ if (sc->sc_dw / WSCONS_MOUSE_RES) {
events[nevents].type = WSCONS_EVENT_MOUSE_DELTA_W;
- events[nevents].value = sc->sc_dw;
+ events[nevents].value = sc->sc_dw / WSCONS_MOUSE_RES;
nevents++;
}
}
@@ -494,10 +512,10 @@ wsmouse_input(device_t wsmousedev, u_int
/* All events were correctly injected into the queue.
* Synchronize the mouse's status with what the user
* has received. */
- sc->sc_x = x; sc->sc_dx = 0;
- sc->sc_y = y; sc->sc_dy = 0;
- sc->sc_z = z; sc->sc_dz = 0;
- sc->sc_w = w; sc->sc_dw = 0;
+ sc->sc_x = x; sc->sc_dx %= WSCONS_MOUSE_RES;
+ sc->sc_y = y; sc->sc_dy %= WSCONS_MOUSE_RES;
+ sc->sc_z = z; sc->sc_dz %= WSCONS_MOUSE_RES;
+ sc->sc_w = w; sc->sc_dw %= WSCONS_MOUSE_RES;
sc->sc_ub = ub;
#if NWSMUX > 0
DPRINTFN(5,("wsmouse_input: %s wakeup evar=%p\n",
Home |
Main Index |
Thread Index |
Old Index