Hello!

Here is early and *experimental* patch for wsmoused(8) that will
smoothly track PS/2 mouse movements (accumulating full delta events from
mouse) on text wsconsole. It is intentionally this simple PoC, because
I like to know few things first.

Here is patch for OpenBSD 7.3. release:

--- /usr/src/usr.sbin/wsmoused/wsmoused.c.orig  Fri Jun  2 16:07:14 2023
+++ /usr/src/usr.sbin/wsmoused/wsmoused.c       Fri Jun  2 17:34:56 2023
@@ -316,6 +316,46 @@
        }
 }

+// normalize mouse event but keep preserve full deltas
+static void
+normalize_event_fullres(struct wscons_event *event)
+{
+
+#define SCALE_FACTOR 8
+       // track mouse position with highest precision
+       // EXPERIMENTAL CODE - NOT thread/mp safe !!!
+       // Support only 1 mouse properly
+       static int px=0, py=0;
+       int npx,npy; // temporary store of new position
+
+       int dx, dy;
+
+       switch (event->type) {
+       case WSCONS_EVENT_MOUSE_DELTA_X:
+               dx = event->value;
+               // track mouse movements deltas with full precision
+               npx = px + dx;
+               // downscale result for wscons, ...
+               dx = npx / SCALE_FACTOR;
+               // subtract "overflowed" value from full position
+               npx -= dx * SCALE_FACTOR;
+               // preserve full delta precision internally
+               px = npx;
+               event->value = dx;
+               break;
+       case WSCONS_EVENT_MOUSE_DELTA_Y:
+               // same for dy
+               dy = event->value;
+               npy = py + dy;
+               dy = npy / SCALE_FACTOR;
+               npy -= dy * SCALE_FACTOR;
+               py = npy;
+               event->value = dy;
+               break;
+       }
+}
+
+
 /* send a wscons_event to the kernel */
 static void
 treat_event(struct wscons_event *event)
@@ -410,6 +450,7 @@
                if (mouse.proto == P_WSCONS) {
                        /* wsmouse supported mouse */
                        read(mouse.mfd, &event, sizeof(event));
+                       normalize_event_fullres(&event);
                        treat_event(&event);
                } else {
                        /* serial mouse (not supported by wsmouse) */


How to use:
1. apply this patch on 7.3-RELEASE source
2. for the 1st time ensure that obj is created:

cd /usr/src/usr.sbin/wsmoused
make obj

3. then build with just "make" command
4. kill existing wsmoused (as root) with: pkill wsmoused
5. run as root: /usr/src/usr.sbin/wsmoused/obj/wsmoused
6. try to move your PS/2 mouse in various directions and compare
   difference when running with stock /usr/sbin/wsmoused

Explanation: Why is "normalize_event()" function wrong:
- existing function "normalize_event()" in wsmoused.c source
  attempts to scale move deltas for Serial mouse
- but that function is incorrect because it simply drops too
  small deltas
- so if user moves mouse too slowly (when deltas do not exceed
  threshold) the mouse will *never* move on console (which is bug)
- the only way to move mouse on console is to move quickly enough
  to exceed cut threshold - which make mouse movements again jumpy ...
- please be aware that PS/2 mouse (driver in
  /usr/src/sys/dev/pckbc/pms.c) does *not* track absolute position,
  but it reports only deltas on every movement. So we must accumulate
  all deltas until they exceed our threshold to properly handle slow
  mouse movements even on coarse text console.


Now I have following questions:

1. Is there any interest at all on such improvement? Are there
   still enough users of PS/2 mouse on local wscons console
   with wsmoused(8) daemon?

2. If yes, what parameters should be configurable by wsmoused(8)?
   (probably enable/disable and scaling factor?)

3. Where is best place to store per-mouse data (that should be used
   instead of "static int px=0, py=0;" in my patch)?

Best regards
  --Henryk Paluch

Reply via email to