Skip to content

Commit 5ab9bcf

Browse files
committed
xpadneo, core: Handle sync events in xpadneo
To properly sync our multiple sub-devices, we need to synchronize the input frame in xpadneo instead of the generic HID handler, otherwise we may see input late or duplicated. See-also: #460 See-also: #282 Signed-off-by: Kai Krakow <kai@kaishome.de>
1 parent d593fa3 commit 5ab9bcf

File tree

3 files changed

+31
-1
lines changed

3 files changed

+31
-1
lines changed

hid-xpadneo/src/hid-xpadneo.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -917,6 +917,7 @@ static int xpadneo_event(struct hid_device *hdev, struct hid_field *field,
917917
input_report_key(gamepad, BTN_PADDLES(1), value & 2 ? 1 : 0);
918918
input_report_key(gamepad, BTN_PADDLES(2), value & 4 ? 1 : 0);
919919
input_report_key(gamepad, BTN_PADDLES(3), value & 8 ? 1 : 0);
920+
xdata->gamepad_sync = true;
920921
}
921922
goto stop_processing;
922923
} else if (usage->type == EV_ABS) {
@@ -928,6 +929,7 @@ static int xpadneo_event(struct hid_device *hdev, struct hid_field *field,
928929
/* Linux Gamepad Specification */
929930
if (param_gamepad_compliance) {
930931
input_report_abs(gamepad, usage->code, value - 32768);
932+
xdata->gamepad_sync = true;
931933
goto stop_processing;
932934
}
933935
break;
@@ -967,6 +969,7 @@ static int xpadneo_event(struct hid_device *hdev, struct hid_field *field,
967969
if (!keyboard)
968970
goto keyboard_missing;
969971
input_report_key(keyboard, BTN_SHARE, value);
972+
xdata->keyboard_sync = true;
970973
goto stop_processing;
971974
} else if (xdata->xbox_button_down && (usage->type == EV_KEY)) {
972975
if (!(xdata->quirks & XPADNEO_QUIRK_USE_HW_PROFILES)) {
@@ -996,13 +999,16 @@ static int xpadneo_event(struct hid_device *hdev, struct hid_field *field,
996999
}
9971000

9981001
/* Let hid-core handle the event */
1002+
xdata->gamepad_sync = true;
9991003
return 0;
10001004

10011005
combine_z_axes:
10021006
if (++xdata->count_abs_z_rz == 2) {
10031007
xdata->count_abs_z_rz = 0;
1004-
if (param_enable_rolling_axis)
1008+
if (param_enable_rolling_axis) {
10051009
input_report_abs(gamepad, ABS_MISC, xdata->last_abs_rz - xdata->last_abs_z);
1010+
xdata->gamepad_sync = true;
1011+
}
10061012
}
10071013
return 0;
10081014

@@ -1114,6 +1120,7 @@ static int xpadneo_probe(struct hid_device *hdev, const struct hid_device_id *id
11141120

11151121
xdata->hdev = hdev;
11161122
hdev->quirks |= HID_QUIRK_INPUT_PER_APP;
1123+
hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC;
11171124
hid_set_drvdata(hdev, xdata);
11181125

11191126
if (hdev->version == 0x00000903)
@@ -1281,6 +1288,7 @@ static struct hid_driver xpadneo_driver = {
12811288
.input_configured = xpadneo_input_configured,
12821289
.probe = xpadneo_probe,
12831290
.remove = xpadneo_remove,
1291+
.report = xpadneo_report,
12841292
.report_fixup = xpadneo_report_fixup,
12851293
.raw_event = xpadneo_raw_event,
12861294
.event = xpadneo_event,

hid-xpadneo/src/xpadneo.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ struct xpadneo_devdata {
139139
/* logical device interfaces */
140140
struct hid_device *hdev;
141141
struct input_dev *consumer, *gamepad, *keyboard;
142+
bool consumer_sync, gamepad_sync, keyboard_sync;
142143
short int missing_reported;
143144

144145
/* revert fixups on removal */
@@ -193,5 +194,6 @@ struct xpadneo_devdata {
193194
extern int xpadneo_init_consumer(struct xpadneo_devdata *);
194195
extern int xpadneo_init_keyboard(struct xpadneo_devdata *);
195196
extern int xpadneo_init_synthetic(struct xpadneo_devdata *, char *, struct input_dev **);
197+
extern void xpadneo_report(struct hid_device *, struct hid_report *);
196198

197199
#endif

hid-xpadneo/src/xpadneo/core.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,23 @@ extern int xpadneo_init_synthetic(struct xpadneo_devdata *xdata, char *suffix,
3535
*devp = input_dev;
3636
return 0;
3737
}
38+
39+
extern void xpadneo_report(struct hid_device *hdev, struct hid_report *report)
40+
{
41+
struct xpadneo_devdata *xdata = hid_get_drvdata(hdev);
42+
43+
if (xdata->consumer && xdata->consumer_sync) {
44+
xdata->consumer_sync = false;
45+
input_sync(xdata->consumer);
46+
}
47+
48+
if (xdata->gamepad && xdata->gamepad_sync) {
49+
xdata->gamepad_sync = false;
50+
input_sync(xdata->gamepad);
51+
}
52+
53+
if (xdata->keyboard && xdata->keyboard_sync) {
54+
xdata->keyboard_sync = false;
55+
input_sync(xdata->keyboard);
56+
}
57+
}

0 commit comments

Comments
 (0)