Skip to content

Commit 1bcec4b

Browse files
kakraJacob Essexatar-axis
committed
[WIP] xpadneo, mouse: Implement mouse support
Co-authored-by: Jacob Essex <git@jacobessex.com> Co-authored-by: Florian Dollinger <dollinger.florian@gmx.de> Closes: #160 Closes: #105 Closes: #99 Signed-off-by: Kai Krakow <kai@kaishome.de>
1 parent 5be5996 commit 1bcec4b

File tree

2 files changed

+82
-3
lines changed

2 files changed

+82
-3
lines changed

hid-xpadneo/src/hid-xpadneo.c

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,10 @@ static u8 *xpadneo_report_fixup(struct hid_device *hdev, u8 *rdesc, unsigned int
749749

750750
static void xpadneo_toggle_mouse(struct xpadneo_devdata *xdata)
751751
{
752-
if (xdata->mouse_mode) {
752+
if (!xdata->mouse) {
753+
xdata->mouse_mode = false;
754+
hid_info(xdata->hdev, "mouse not available\n");
755+
} else if (xdata->mouse_mode) {
753756
xdata->mouse_mode = false;
754757
hid_info(xdata->hdev, "mouse mode disabled\n");
755758
} else {
@@ -889,6 +892,7 @@ static int xpadneo_input_configured(struct hid_device *hdev, struct hid_input *h
889892
return 0;
890893
default:
891894
hid_warn(hdev, "unhandled input application 0x%x\n", hi->application);
895+
return 0;
892896
}
893897

894898
/*
@@ -970,14 +974,37 @@ static int xpadneo_input_configured(struct hid_device *hdev, struct hid_input *h
970974
return 0;
971975
}
972976

977+
static void xpadneo_mouse_event(struct timer_list *t)
978+
{
979+
struct xpadneo_devdata *xdata = from_timer(xdata, t, mouse_timer);
980+
struct input_dev *mouse = xdata->mouse;
981+
982+
if (xdata->mouse_mode) {
983+
input_report_rel(mouse, REL_X, xdata->mouse_state.rel_x / 2000);
984+
input_report_rel(mouse, REL_Y, xdata->mouse_state.rel_y / 2000);
985+
input_sync(xdata->mouse);
986+
}
987+
988+
mod_timer(&xdata->mouse_timer, jiffies + msecs_to_jiffies(10));
989+
}
990+
973991
static int xpadneo_event(struct hid_device *hdev, struct hid_field *field,
974992
struct hid_usage *usage, __s32 value)
975993
{
976994
struct xpadneo_devdata *xdata = hid_get_drvdata(hdev);
977995
struct input_dev *gamepad = xdata->gamepad;
978996
struct input_dev *consumer = xdata->consumer;
979997

980-
if (usage->type == EV_ABS) {
998+
if (xdata->mouse_mode && usage->type == EV_ABS) {
999+
switch (usage->code) {
1000+
case ABS_X:
1001+
xdata->mouse_state.rel_x = value - 32768;
1002+
break;
1003+
case ABS_Y:
1004+
xdata->mouse_state.rel_y = value - 32768;
1005+
break;
1006+
}
1007+
} else if (usage->type == EV_ABS) {
9811008
switch (usage->code) {
9821009
case ABS_X:
9831010
case ABS_Y:
@@ -1191,6 +1218,43 @@ static int xpadneo_init_synthetic(struct xpadneo_devdata *xdata, char *suffix,
11911218
return 0;
11921219
}
11931220

1221+
static int xpadneo_init_mouse(struct xpadneo_devdata *xdata)
1222+
{
1223+
struct hid_device *hdev = xdata->hdev;
1224+
int ret;
1225+
1226+
ret = xpadneo_init_synthetic(xdata, "Mouse", &xdata->mouse);
1227+
if (ret || !xdata->mouse)
1228+
return ret;
1229+
1230+
/* enable relative events for mouse emulation */
1231+
__set_bit(EV_REL, xdata->mouse->evbit);
1232+
__set_bit(REL_X, xdata->mouse->relbit);
1233+
__set_bit(REL_Y, xdata->mouse->relbit);
1234+
__set_bit(REL_HWHEEL, xdata->mouse->relbit);
1235+
__set_bit(REL_WHEEL, xdata->mouse->relbit);
1236+
1237+
/* enable button events for mouse emulation */
1238+
__set_bit(EV_KEY, xdata->mouse->evbit);
1239+
__set_bit(BTN_LEFT, xdata->mouse->keybit);
1240+
__set_bit(BTN_RIGHT, xdata->mouse->keybit);
1241+
__set_bit(BTN_MIDDLE, xdata->mouse->keybit);
1242+
__set_bit(BTN_SIDE, xdata->mouse->keybit);
1243+
__set_bit(BTN_EXTRA, xdata->mouse->keybit);
1244+
__set_bit(BTN_FORWARD, xdata->mouse->keybit);
1245+
__set_bit(BTN_BACK, xdata->mouse->keybit);
1246+
__set_bit(BTN_TASK, xdata->mouse->keybit);
1247+
1248+
ret = input_register_device(xdata->mouse);
1249+
if (ret) {
1250+
hid_err(hdev, "failed to register mouse\n");
1251+
return ret;
1252+
}
1253+
1254+
hid_info(hdev, "mouse added\n");
1255+
return 0;
1256+
}
1257+
11941258
static int xpadneo_probe(struct hid_device *hdev, const struct hid_device_id *id)
11951259
{
11961260
int ret;
@@ -1219,6 +1283,12 @@ static int xpadneo_probe(struct hid_device *hdev, const struct hid_device_id *id
12191283
return ret;
12201284
}
12211285

1286+
if (!xdata->mouse) {
1287+
ret = xpadneo_init_mouse(xdata);
1288+
if (ret)
1289+
return ret;
1290+
}
1291+
12221292
ret = xpadneo_init_hw(hdev);
12231293
if (ret) {
12241294
hid_err(hdev, "hw init failed: %d\n", ret);
@@ -1230,6 +1300,9 @@ static int xpadneo_probe(struct hid_device *hdev, const struct hid_device_id *id
12301300
if (ret)
12311301
hid_err(hdev, "could not initialize ff, continuing anyway\n");
12321302

1303+
timer_setup(&xdata->mouse_timer, xpadneo_mouse_event, 0);
1304+
mod_timer(&xdata->mouse_timer, jiffies);
1305+
12331306
hid_info(hdev, "%s connected\n", xdata->battery.name);
12341307

12351308
return 0;
@@ -1249,6 +1322,7 @@ static void xpadneo_remove(struct hid_device *hdev)
12491322

12501323
hid_hw_close(hdev);
12511324

1325+
del_timer_sync(&xdata->mouse_timer);
12521326
cancel_delayed_work_sync(&xdata->ff_worker);
12531327

12541328
kfree(xdata->battery.name);

hid-xpadneo/src/xpadneo.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#define XPADNEO_H_FILE
1313

1414
#include <linux/hid.h>
15+
#include <linux/timer.h>
1516
#include <linux/version.h>
1617

1718
#include "hid-ids.h"
@@ -125,7 +126,7 @@ struct xpadneo_devdata {
125126

126127
/* logical device interfaces */
127128
struct hid_device *hdev;
128-
struct input_dev *consumer, *gamepad, *keyboard;
129+
struct input_dev *consumer, *gamepad, *keyboard, *mouse;
129130
short int missing_reported;
130131

131132
/* quirk flags */
@@ -138,6 +139,10 @@ struct xpadneo_devdata {
138139

139140
/* mouse mode */
140141
bool mouse_mode;
142+
struct timer_list mouse_timer;
143+
struct {
144+
s32 rel_x, rel_y, wheel_x, wheel_y;
145+
} mouse_state;
141146

142147
/* trigger scale */
143148
struct {

0 commit comments

Comments
 (0)