tech-x11 archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Precise scrolling for wsmouse
Greetz tech-x11,
OpenBSD has WSCONS_EVENT_HSCROLL and WSCONS_EVENT_VSCROLL.
These are useful for scrolling with precise coordinates.
The following diff adds support for HSCROLL and VSCROLL
to our wsmouse(4) and synaptics(4), where it's used to provide
much smoother two-finger and trackpoint scrolling.
The synaptics driver also gets some simplification.
I think this is much better than its previous state.
Also attached is a diff with the necessary changes to
xf86-input-ws.
Later I should make it so scrolling speed and
direction configurable in wsconsctl -m. But right now,
I should sleep.
Testing would be nice.
I have in my xorg.conf:
Section "ServerLayout"
Identifier "layout"
InputDevice "Mouse0" "CorePointer"
EndSection
Section "InputDevice"
Identifier "Mouse0"
Driver "ws"
Option "Device" "/dev/wsmouse0"
EndSection
Index: dev/wscons/wsmouse.c
===================================================================
RCS file: /cvsroot/src/sys/dev/wscons/wsmouse.c,v
retrieving revision 1.69
diff -u -r1.69 wsmouse.c
--- dev/wscons/wsmouse.c 27 Dec 2020 16:09:33 -0000 1.69
+++ dev/wscons/wsmouse.c 21 Sep 2021 22:22:32 -0000
@@ -516,6 +516,37 @@
}
}
+void
+wsmouse_precision_scroll(device_t wsmousedev, int x, int y)
+{
+ struct wsmouse_softc *sc = device_private(wsmousedev);
+ struct wseventvar *evar;
+ struct wscons_event events[2];
+ int nevents = 0;
+
+ evar = sc->sc_base.me_evp;
+ if (evar == NULL)
+ return;
+
+ /* XXX: scroll distance should be configurable */
+ x = (x * 4096) / 12;
+ y = (y * 4096) / 12;
+
+ if (x != 0) {
+ events[nevents].type = WSCONS_EVENT_HSCROLL;
+ events[nevents].value = x;
+ nevents++;
+ }
+
+ if (y != 0) {
+ events[nevents].type = WSCONS_EVENT_VSCROLL;
+ events[nevents].value = y;
+ nevents++;
+ }
+
+ (void)wsevent_inject(evar, events, nevents);
+}
+
static void
wsmouse_repeat(void *v)
{
Index: dev/wscons/wsmousevar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/wscons/wsmousevar.h,v
retrieving revision 1.11
diff -u -r1.11 wsmousevar.h
--- dev/wscons/wsmousevar.h 12 May 2009 14:47:55 -0000 1.11
+++ dev/wscons/wsmousevar.h 21 Sep 2021 22:22:32 -0000
@@ -73,3 +73,4 @@
#define WSMOUSE_INPUT_ABSOLUTE_Z (1<<2)
#define WSMOUSE_INPUT_ABSOLUTE_W (1<<3)
void wsmouse_input(device_t, u_int, int, int, int, int, u_int);
+void wsmouse_precision_scroll(device_t, int, int);
Index: dev/pckbport/synaptics.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pckbport/synaptics.c,v
retrieving revision 1.71
diff -u -r1.71 synaptics.c
--- dev/pckbport/synaptics.c 30 May 2021 13:20:01 -0000 1.71
+++ dev/pckbport/synaptics.c 21 Sep 2021 22:22:32 -0000
@@ -120,9 +120,6 @@
static int synaptics_max_speed_y = 32;
static int synaptics_max_speed_z = 2;
static int synaptics_movement_threshold = 4;
-static int synaptics_fscroll_min = 13;
-static int synaptics_fscroll_max = 14;
-static int synaptics_dz_hold = 30;
static int synaptics_movement_enable = 1;
static bool synaptics_aux_mid_button_scroll = TRUE;
static int synaptics_debug = 0;
@@ -159,9 +156,6 @@
static int synaptics_max_speed_y_nodenum;
static int synaptics_max_speed_z_nodenum;
static int synaptics_movement_threshold_nodenum;
-static int synaptics_finger_scroll_min_nodenum;
-static int synaptics_finger_scroll_max_nodenum;
-static int synaptics_dz_hold_nodenum;
static int synaptics_movement_enable_nodenum;
static int synaptics_aux_mid_button_scroll_nodenum;
@@ -503,7 +497,6 @@
sc->gesture_tap_packet = 0;
sc->gesture_type = 0;
sc->gesture_buttons = 0;
- sc->dz_hold = 0;
for (i = 0; i < SYN_MAX_FINGERS; i++) {
sc->rem_x[i] = sc->rem_y[i] = sc->rem_z[i] = 0;
sc->movement_history[i] = 0;
@@ -809,42 +802,6 @@
if ((rc = sysctl_createv(clog, 0, NULL, &node,
CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
- CTLTYPE_INT, "finger_scroll-min",
- SYSCTL_DESCR("Minimum width at which y cursor movements will be converted to scroll wheel events"),
- pms_sysctl_synaptics_verify, 0,
- &synaptics_fscroll_min,
- 0, CTL_HW, root_num, CTL_CREATE,
- CTL_EOL)) != 0)
- goto err;
-
- synaptics_finger_scroll_min_nodenum = node->sysctl_num;
-
- if ((rc = sysctl_createv(clog, 0, NULL, &node,
- CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
- CTLTYPE_INT, "finger_scroll-max",
- SYSCTL_DESCR("Maximum width at which y cursor movements will be converted to scroll wheel events"),
- pms_sysctl_synaptics_verify, 0,
- &synaptics_fscroll_max,
- 0, CTL_HW, root_num, CTL_CREATE,
- CTL_EOL)) != 0)
- goto err;
-
- synaptics_finger_scroll_max_nodenum = node->sysctl_num;
-
- if ((rc = sysctl_createv(clog, 0, NULL, &node,
- CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
- CTLTYPE_INT, "finger_scroll-hysteresis",
- SYSCTL_DESCR("Number of packets to keep reporting y cursor movements as scroll wheel events"),
- pms_sysctl_synaptics_verify, 0,
- &synaptics_dz_hold,
- 0, CTL_HW, root_num, CTL_CREATE,
- CTL_EOL)) != 0)
- goto err;
-
- synaptics_dz_hold_nodenum = node->sysctl_num;
-
- if ((rc = sysctl_createv(clog, 0, NULL, &node,
- CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
CTLTYPE_BOOL, "aux_mid_button_scroll",
SYSCTL_DESCR("Interpet Y-Axis movement with the middle button held as scrolling on the passthrough device (e.g. TrackPoint)"),
pms_sysctl_synaptics_verify, 0,
@@ -943,17 +900,6 @@
if (t < SYNAPTICS_EDGE_LEFT || t > SYNAPTICS_EDGE_RIGHT)
return (EINVAL);
} else
- if (node.sysctl_num == synaptics_finger_scroll_min_nodenum ||
- node.sysctl_num == synaptics_finger_scroll_max_nodenum) {
- /* make sure we avoid the "magic" widths, 4 and below
- are for fingers, 15 is palm detect. */
- if ((t < 5) || (t > 14))
- return (EINVAL);
- } else
- if (node.sysctl_num == synaptics_dz_hold_nodenum) {
- if (t < 0)
- return (EINVAL);
- } else
if (node.sysctl_num == synaptics_movement_enable_nodenum) {
if (t < 0 || t > 1)
return (EINVAL);
@@ -1213,20 +1159,20 @@
psc->buttons ^= changed;
if (dx || dy || dz || changed) {
+ s = spltty();
/*
- * If the middle button is held, interpret Y-axis
- * movement as scrolling.
+ * If the middle button is held, interpret movement as
+ * scrolling.
*/
if (synaptics_aux_mid_button_scroll &&
dy && (psc->buttons & 0x2)) {
- dz = -dy;
- dx = dy = 0;
+ wsmouse_precision_scroll(psc->sc_wsmousedev, dx, dy);
+ } else {
+ buttons = (psc->buttons & 0x1f) | ((psc->buttons >> 5) & 0x7);
+ wsmouse_input(psc->sc_wsmousedev,
+ buttons, dx, dy, dz, 0,
+ WSMOUSE_INPUT_DELTA);
}
- buttons = (psc->buttons & 0x1f) | ((psc->buttons >> 5) & 0x7);
- s = spltty();
- wsmouse_input(psc->sc_wsmousedev,
- buttons, dx, dy, dz, 0,
- WSMOUSE_INPUT_DELTA);
splx(s);
}
}
@@ -1650,27 +1596,19 @@
static inline void
synaptics_movement(struct synaptics_softc *sc, struct synaptics_packet *sp,
- int finger, int scroll_emul, int *dxp, int *dyp, int *dzp)
+ int finger, int *dxp, int *dyp, int *dzp)
{
int dx, dy, dz, edge;
dx = dy = dz = 0;
/*
- * Compute the next values of dx and dy and dz. If scroll_emul
- * is non-zero, take the dy and used it as use it as dz so we
- * can emulate a scroll wheel.
+ * Compute the next values of dx and dy and dz.
*/
- if (scroll_emul == 0) {
- dx = synaptics_filter_policy(sc, finger, sc->history_x[finger],
- sp->sp_x);
- dy = synaptics_filter_policy(sc, finger, sc->history_y[finger],
- sp->sp_y);
- } else {
- dz = synaptics_filter_policy(sc, finger, sc->history_z[finger],
- sp->sp_y);
- dx = dy = 0;
- }
+ dx = synaptics_filter_policy(sc, finger, sc->history_x[finger],
+ sp->sp_x);
+ dy = synaptics_filter_policy(sc, finger, sc->history_y[finger],
+ sp->sp_y);
/*
* If we're dealing with a drag gesture, and the finger moves to
@@ -1720,7 +1658,7 @@
struct synaptics_softc *sc = &psc->u.synaptics;
int dx, dy, dz;
int fingers, palm, buttons, changed;
- int s, z_emul;
+ int s;
/*
* Do Z-axis emulation using up/down buttons if required.
@@ -1781,20 +1719,21 @@
*/
if (palm == 0 && synaptics_movement_enable) {
if (fingers == 1) {
- z_emul = 0;
-
- if ((sp->sp_w >= synaptics_fscroll_min) &&
- (sp->sp_w <= synaptics_fscroll_max)) {
- z_emul = 1;
- sc->dz_hold = synaptics_dz_hold;
- }
-
- if (sc->dz_hold > 0) {
- z_emul = 1;
- }
-
+ /*
+ * Single finger - normal movement.
+ */
+ synaptics_movement(sc, sp, sp->sp_finger,
+ &dx, &dy, &dz);
+ } else if (fingers == 2 && sc->gesture_type == 0) {
+ /*
+ * Multiple finger movement. Interpret it as scrolling.
+ */
synaptics_movement(sc, sp, sp->sp_finger,
- z_emul, &dx, &dy, &dz);
+ &dx, &dy, &dz);
+ s = spltty();
+ wsmouse_precision_scroll(psc->sc_wsmousedev, dx, dy);
+ splx(s);
+ return;
} else {
/*
* No valid finger. Therefore no movement.
@@ -1812,9 +1751,6 @@
dx = dy = dz = 0;
}
- if (sc->dz_hold > 0)
- sc->dz_hold--;
-
/*
* Pass the final results up to wsmouse_input() if necessary.
*/
Index: external/mit/xf86-input-ws/dist/src/ws.c
===================================================================
RCS file: /cvsroot/xsrc/external/mit/xf86-input-ws/dist/src/ws.c,v
retrieving revision 1.11
diff -u -r1.11 ws.c
--- external/mit/xf86-input-ws/dist/src/ws.c 14 Apr 2017 19:19:43 -0000 1.11
+++ external/mit/xf86-input-ws/dist/src/ws.c 21 Sep 2021 22:23:35 -0000
@@ -450,6 +450,10 @@
axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
}
+ axes_labels[HSCROLL_AXIS] =
+ XIGetKnownProperty(AXIS_LABEL_PROP_REL_HSCROLL);
+ axes_labels[VSCROLL_AXIS] =
+ XIGetKnownProperty(AXIS_LABEL_PROP_REL_VSCROLL);
if (!InitValuatorClassDeviceStruct(pWS,
NAXES,
axes_labels,
@@ -478,6 +482,25 @@
);
xf86InitValuatorDefaults(pWS, 1);
+
+ xf86InitValuatorAxisStruct(pWS, HSCROLL_AXIS,
+ axes_labels[HSCROLL_AXIS], 0, -1, 0, 0, 0, Relative);
+ xf86InitValuatorAxisStruct(pWS, VSCROLL_AXIS,
+ axes_labels[VSCROLL_AXIS], 0, -1, 0, 0, 0, Relative);
+ priv->scroll_mask = valuator_mask_new(MAX_VALUATORS);
+ if (!priv->scroll_mask) {
+ return !Success;
+ }
+
+ /*
+ * The value of an HSCROLL or VSCROLL event is the fraction
+ * motion_delta / scroll_distance
+ * in [*.12] fixed-point format. The 'increment' attribute of the
+ * scroll axes is constant:
+ */
+ SetScrollValuator(pWS, HSCROLL_AXIS, SCROLL_TYPE_HORIZONTAL, 4096, 0);
+ SetScrollValuator(pWS, VSCROLL_AXIS, SCROLL_TYPE_VERTICAL, 4096, 0);
+
#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12
xf86MotionHistoryAllocate(pInfo);
AssignTypeAndName(pWS, pInfo->atom, pInfo->name);
@@ -601,6 +624,7 @@
int buttons = priv->lastButtons;
int dx = 0, dy = 0, dz = 0, dw = 0;
int zbutton = 0, wbutton = 0;
+ int hscroll = 0, vscroll = 0;
ax = 0; ay = 0;
switch (event->type) {
@@ -650,6 +674,14 @@
DBG(4, ErrorF("Relative W %d\n", event->value));
dw = event->value;
break;
+ case WSCONS_EVENT_HSCROLL:
+ hscroll = event->value;
+ DBG(4, ErrorF("Horiz. Scrolling %d\n", event->value));
+ break;
+ case WSCONS_EVENT_VSCROLL:
+ vscroll = event->value;
+ DBG(4, ErrorF("Vert. Scrolling %d\n", event->value));
+ break;
default:
xf86Msg(X_WARNING, "%s: bad wsmouse event type=%d\n",
pInfo->name, event->type);
@@ -694,6 +726,16 @@
buttons |= wbutton;
dw = 0;
}
+ if (hscroll || vscroll) {
+ xf86Msg(X_WARNING, "%s: hscroll=%d, vscroll=%d\n",
+ pInfo->name, hscroll, vscroll);
+ valuator_mask_zero(priv->scroll_mask);
+ valuator_mask_set_double(priv->scroll_mask,
+ HSCROLL_AXIS, (double) hscroll);
+ valuator_mask_set_double(priv->scroll_mask,
+ VSCROLL_AXIS, (double) vscroll);
+ xf86PostMotionEventM(pInfo->dev, FALSE, priv->scroll_mask);
+ }
if (priv->lastButtons != buttons) {
/* button event */
wsSendButtons(pInfo, buttons);
Home |
Main Index |
Thread Index |
Old Index