Skip to content

Add support for multiple relative wheels #349

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions include/wacom-properties.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,13 @@
/* CARD32, 1 value */
#define WACOM_PROP_SERIAL_BIND "Wacom Serial ID binding"

/* 8 bit, 4 values, left up, left down, right up, right down
OR
Atom, 4 values , left up, left down, right up, right down
/* 8 bit OR Atom, 4 values:
left up, left down, right up, right down
*/
#define WACOM_PROP_STRIPBUTTONS "Wacom Strip Buttons"

/* 8 bit, 6 values, rel wheel up, rel wheel down, abs wheel up, abs wheel down, abs wheel 2 up, abs wheel 2 down
OR
Atom, 6 values , rel wheel up, rel wheel down, abs wheel up, abs wheel down, abs wheel 2 up, abs wheel 2 down
/* 8 bit OR Atom, 8 values:
rel wheel up, rel wheel down, abs wheel up, abs wheel down, abs wheel 2 up, abs wheel 2 down, rel wheel 2 up, rel wheel 2 down
*/
#define WACOM_PROP_WHEELBUTTONS "Wacom Wheel Buttons"

Expand Down
12 changes: 12 additions & 0 deletions man/xsetwacom.man
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,21 @@ applied.
.TQ
\fBAbsWheel2Down\fR [mapping]
.TQ
\fBDialCW\fR [mapping]
.TQ
\fBDialCCW\fR [mapping]
.TQ
\fBDial2CW\fR [mapping]
.TQ
\fBDial2CCW\fR [mapping]
.TQ
\fBRelWheelUp\fR [mapping]
.TQ
\fBRelWheelDown\fR [mapping]
.TQ
\fBRelWheel2Up\fR [mapping]
.TQ
\fBRelWheel2Down\fR [mapping]
Set a mapping for the specified control. Mappings take the form of
either a single numeric button or an 'action' to be performed. If no mapping
is provided, the default mapping is restored. If a control is mapped
Expand Down
41 changes: 29 additions & 12 deletions src/wcmCommon.c
Original file line number Diff line number Diff line change
Expand Up @@ -513,17 +513,17 @@ static int getScrollDelta(int current, int old, int wrap, int flags)
* the scrolling axis and the possible events that can be
* sent.
*
* @param delta Amount of change in the scrolling axis
* @param action_up Array index of action to send on scroll up
* @param action_dn Array index of action to send on scroll down
* @return Array index of action that should be performed, or -1 if none.
* @param delta Amount of change in the scrolling axis
* @param action_positive Array index of action to send on a positive delta
* @param action_negative Array index of action to send on negative delta
* @return Array index of action that should be performed, or -1 if none.
*/
static int getWheelButton(int delta, int action_up, int action_dn)
static int getWheelButton(int delta, int action_positive, int action_negative)
{
if (delta > 0)
return action_up;
return action_positive;
else if (delta < 0)
return action_dn;
return action_negative;
else
return -1;
}
Expand Down Expand Up @@ -571,7 +571,8 @@ static void sendWheelStripEvents(WacomDevicePtr priv, const WacomDeviceState* ds
sendWheelStripEvent(priv, &priv->strip_actions[idx], ds, axes);
}

/* emulate events for relative wheel */
/* emulate events for relative wheel:
* positive delta = scroll up */
delta = getScrollDelta(ds->relwheel, 0, 0, 0);
idx = getWheelButton(delta, WHEEL_REL_UP, WHEEL_REL_DN);
if (idx >= 0 && (IsCursor(priv) || IsPad(priv)) && priv->oldState.proximity == ds->proximity)
Expand All @@ -580,6 +581,15 @@ static void sendWheelStripEvents(WacomDevicePtr priv, const WacomDeviceState* ds
sendWheelStripEvent(priv, &priv->wheel_actions[idx], ds, axes);
}

/* emulate events for 2nd relative wheel */
delta = getScrollDelta(ds->relwheel2, 0, 0, 0);
idx = getWheelButton(delta, WHEEL2_REL_UP, WHEEL2_REL_DN);
if (idx >= 0 && (IsCursor(priv) || IsPad(priv)) && priv->oldState.proximity == ds->proximity)
{
DBG(10, priv, "Relative wheel 2 scroll delta = %d\n", delta);
sendWheelStripEvent(priv, &priv->wheel_actions[idx], ds, axes);
}

/* emulate events for left touch ring */
delta = getScrollDelta(ds->abswheel, priv->oldState.abswheel, common->wcmMaxRing, AXIS_INVERT);
idx = getWheelButton(delta, WHEEL_ABS_UP, WHEEL_ABS_DN);
Expand Down Expand Up @@ -621,7 +631,7 @@ static void sendCommonEvents(WacomDevicePtr priv, const WacomDeviceState* ds,
wcmSendButtons(priv, ds, buttons, axes);

/* emulate wheel/strip events when defined */
if ( ds->relwheel || (ds->abswheel != priv->oldState.abswheel) || (ds->abswheel2 != priv->oldState.abswheel2) ||
if ( ds->relwheel || ds->relwheel2 || (ds->abswheel != priv->oldState.abswheel) || (ds->abswheel2 != priv->oldState.abswheel2) ||
( (ds->stripx - priv->oldState.stripx) && ds->stripx && priv->oldState.stripx) ||
((ds->stripy - priv->oldState.stripy) && ds->stripy && priv->oldState.stripy) )
sendWheelStripEvents(priv, ds, axes);
Expand Down Expand Up @@ -710,7 +720,7 @@ wcmSendPadEvents(WacomDevicePtr priv, const WacomDeviceState* ds, const WacomAxi
if (!priv->oldState.proximity && ds->proximity)
wcmEmitProximity(priv, TRUE, axes);

if (axes->mask || ds->buttons || ds->relwheel ||
if (axes->mask || ds->buttons || ds->relwheel || ds->relwheel2 ||
(ds->abswheel != priv->oldState.abswheel) || (ds->abswheel2 != priv->oldState.abswheel2))
{
sendCommonEvents(priv, ds, axes);
Expand Down Expand Up @@ -1000,6 +1010,7 @@ wcmCheckSuppress(WacomCommonPtr common,
if (abs(dsOrig->abswheel - dsNew->abswheel) > suppress) goto out;
if (abs(dsOrig->abswheel2 - dsNew->abswheel2) > suppress) goto out;
if (dsNew->relwheel != 0) goto out;
if (dsNew->relwheel2 != 0) goto out;

returnV = SUPPRESS_ALL;

Expand Down Expand Up @@ -1136,15 +1147,15 @@ void wcmEvent(WacomCommonPtr common, unsigned int channel,

DBG(10, common,
"c=%u i=%d t=%d s=0x%x x=%d y=%d b=%u "
"p=%d rz=%d tx=%d ty=%d aw=%d aw2=%d rw=%d "
"p=%d rz=%d tx=%d ty=%d aw=%d aw2=%d rw=%d rw2=%d "
"t=%d px=%d st=%u cs=%d \n",
channel,
ds.device_id,
ds.device_type,
ds.serial_num,
ds.x, ds.y, ds.buttons,
ds.pressure, ds.rotation, ds.tiltx,
ds.tilty, ds.abswheel, ds.abswheel2, ds.relwheel, ds.throttle,
ds.tilty, ds.abswheel, ds.abswheel2, ds.relwheel, ds.relwheel2, ds.throttle,
ds.proximity, ds.sample,
pChannel->nSamples);

Expand Down Expand Up @@ -1994,6 +2005,12 @@ TEST_CASE(test_suppress)
assert(rc == SUPPRESS_NONE);
new.relwheel = 0;

/* any movement on relwheel2 counts */
new.relwheel2 = 1;
rc = wcmCheckSuppress(&common, &old, &new);
assert(rc == SUPPRESS_NONE);
new.relwheel2 = 0;

/* x axis movement */

/* not enough movement */
Expand Down
8 changes: 5 additions & 3 deletions src/wcmConfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,10 @@ WacomDevicePtr wcmAllocate(void *frontend, const char *name)
priv->button_default[i] = (i < 3) ? i + 1 : i + 5;

priv->nbuttons = WCM_MAX_BUTTONS; /* Default number of buttons */
priv->wheel_default[WHEEL_REL_UP] = 5;
priv->wheel_default[WHEEL_REL_DN] = 4;
priv->wheel_default[WHEEL_REL_UP] = 4; /* scroll up */
priv->wheel_default[WHEEL_REL_DN] = 5; /* scroll down */
priv->wheel_default[WHEEL2_REL_UP] = 7; /* scroll right */
priv->wheel_default[WHEEL2_REL_DN] = 6; /* scroll left */
/* wheel events are set to 0, but the pad overwrites this default
* later in wcmParseOptions, when we have IsPad() available */
priv->wheel_default[WHEEL_ABS_UP] = 0;
Expand Down Expand Up @@ -674,7 +676,7 @@ static void wcmInitActions(WacomDevicePtr priv)

if (IsPad(priv) || IsCursor(priv))
{
for (i = 0; i < 6; i++)
for (i = 0; i < 8; i++)
wcmResetWheelAction(priv, i);
}
}
Expand Down
42 changes: 35 additions & 7 deletions src/wcmUSB.c
Original file line number Diff line number Diff line change
Expand Up @@ -1735,8 +1735,8 @@ static int refreshDeviceType(WacomDevicePtr priv, int fd)
return 0;
}

static int deriveDeviceTypeFromButtonEvent(WacomDevicePtr priv,
const struct input_event *event_ptr)
static Bool eventCouldBeFromPad(WacomDevicePtr priv,
const struct input_event *event_ptr)
{
WacomCommonPtr common = priv->common;
wcmUSBData *usbdata = common->private;
Expand All @@ -1752,18 +1752,35 @@ static int deriveDeviceTypeFromButtonEvent(WacomDevicePtr priv,
case BTN_BACK:
case BTN_EXTRA:
case BTN_FORWARD:
return PAD_ID;
return TRUE;
default:
for (nkeys = 0; nkeys < usbdata->npadkeys; nkeys++)
{
if (event_ptr->code == usbdata->padkey_code[nkeys]) {
return PAD_ID;
return TRUE;
}
}
break;
}
}
return 0;
if (event_ptr->type == EV_REL) {
switch (event_ptr->code) {
case REL_WHEEL:
case REL_HWHEEL:
case REL_WHEEL_HI_RES:
case REL_HWHEEL_HI_RES:
return TRUE;
}
}
if (event_ptr->type == EV_ABS) {
switch (event_ptr->code) {
case ABS_WHEEL:
case ABS_THROTTLE:
return TRUE;
}
}

return FALSE;
}

/***
Expand Down Expand Up @@ -1800,7 +1817,8 @@ static int usbInitToolType(WacomDevicePtr priv, int fd,

if (!device_type) /* expresskey pressed at startup or missing type */
for (i = 0; (i < nevents) && !device_type; ++i)
device_type = deriveDeviceTypeFromButtonEvent(priv, &event_ptr[i]);
if (eventCouldBeFromPad(priv, &event_ptr[i]))
device_type = PAD_ID;

return device_type;
}
Expand Down Expand Up @@ -1879,6 +1897,7 @@ static void usbDispatchEvents(WacomDevicePtr priv)

/* all USB data operates from previous context except relative values*/
ds->relwheel = 0;
ds->relwheel2 = 0;
ds->serial_num = private->wcmLastToolSerial;

/* loop through all events in group */
Expand Down Expand Up @@ -1919,18 +1938,27 @@ static void usbDispatchEvents(WacomDevicePtr priv)
{
switch (event->code) {
case REL_WHEEL:
ds->relwheel = -event->value;
ds->relwheel = event->value;
ds->time = wcmTimeInMillis();
common->wcmChannel[channel].dirty |= TRUE;
break;
case REL_WHEEL_HI_RES:
/* unsupported */
break;
case REL_HWHEEL:
ds->relwheel2 = event->value;
ds->time = wcmTimeInMillis();
common->wcmChannel[channel].dirty |= TRUE;
break;
case REL_HWHEEL_HI_RES:
/* unsupported */
break;
default:
wcmLogSafe(priv, W_ERROR,
"%s: rel event recv'd (%d)!\n",
priv->name,
event->code);
break;
}
}
else if (event->type == EV_KEY)
Expand Down
4 changes: 2 additions & 2 deletions src/x11/xf86WacomProperties.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,10 +269,10 @@ void InitWcmDeviceProperties(WacomDevicePtr priv)

if (IsPad(priv) || IsCursor(priv))
{
for (i = 0; i < 6; i++)
for (i = 0; i < 8; i++)
wcmInitWheelActionProp(priv, i);
prop_wheel_buttons = InitWcmAtom(pInfo->dev, WACOM_PROP_WHEELBUTTONS, XA_ATOM, 32,
6, (int*)priv->wheel_action_props);
8, (int*)priv->wheel_action_props);
}

if (IsStylus(priv) || IsEraser(priv)) {
Expand Down
9 changes: 6 additions & 3 deletions src/xf86WacomDefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ struct _WacomModel
#define WHEEL_ABS_DN 3
#define WHEEL2_ABS_UP 4
#define WHEEL2_ABS_DN 5
#define WHEEL2_REL_UP 6
#define WHEEL2_REL_DN 7
#define STRIP_LEFT_UP 0
#define STRIP_LEFT_DN 1
#define STRIP_RIGHT_UP 2
Expand Down Expand Up @@ -207,6 +209,7 @@ struct _WacomDeviceState
int abswheel;
int abswheel2;
int relwheel;
int relwheel2;
int distance;
int throttle;
int proximity;
Expand Down Expand Up @@ -272,13 +275,13 @@ struct _WacomDeviceRec
*/
int button_default[WCM_MAX_BUTTONS]; /* Default mappings set by ourselves (possibly overridden by xorg.conf) */
int strip_default[4];
int wheel_default[6];
int wheel_default[8];
WacomAction key_actions[WCM_MAX_BUTTONS]; /* Action codes to perform when the associated event occurs */
WacomAction strip_actions[4];
WacomAction wheel_actions[6];
WacomAction wheel_actions[8];
Atom btn_action_props[WCM_MAX_BUTTONS]; /* Action references so we can update the action codes when a client makes a change */
Atom strip_action_props[4];
Atom wheel_action_props[6];
Atom wheel_action_props[8];

int nbuttons; /* number of buttons for this subdevice */
int naxes; /* number of axes */
Expand Down
Loading
Loading