Skip to content

Commit 9821834

Browse files
authored
set the stylus device type for tablet stylus events (#425)
* set the stylus device type for tablet stylus events
1 parent 18ef368 commit 9821834

File tree

1 file changed

+104
-23
lines changed

1 file changed

+104
-23
lines changed

src/user_input.c

Lines changed: 104 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
#define THIS_LIBINPUT_VER LIBINPUT_VER(LIBINPUT_VERSION_MAJOR, LIBINPUT_VERSION_MINOR, LIBINPUT_VERSION_PATCH)
2626

2727
struct input_device_data {
28-
int64_t flutter_device_id_offset;
2928
struct keyboard_state *keyboard_state;
3029
int64_t buttons;
3130
uint64_t timestamp;
@@ -49,6 +48,9 @@ struct input_device_data {
4948
*
5049
*/
5150
struct vec2f *positions;
51+
52+
int64_t touch_device_id_offset;
53+
int64_t stylus_device_id;
5254
};
5355

5456
struct user_input {
@@ -200,6 +202,57 @@ static inline FlutterPointerEvent make_mouse_hover_event(size_t timestamp, struc
200202
return make_mouse_event(kHover, timestamp, pos, device_id, kFlutterPointerSignalKindNone, VEC2F(0, 0), buttons);
201203
}
202204

205+
static inline FlutterPointerEvent make_stylus_event(FlutterPointerPhase phase, size_t timestamp, struct vec2f pos, int32_t device_id) {
206+
FlutterPointerEvent event;
207+
memset(&event, 0, sizeof(event));
208+
209+
event.struct_size = sizeof(event);
210+
event.phase = phase;
211+
event.timestamp = timestamp;
212+
event.x = pos.x;
213+
event.y = pos.y;
214+
event.device = device_id;
215+
event.signal_kind = kFlutterPointerSignalKindNone;
216+
event.scroll_delta_x = 0.0;
217+
event.scroll_delta_y = 0.0;
218+
event.device_kind = kFlutterPointerDeviceKindStylus;
219+
event.buttons = 0;
220+
event.pan_x = 0.0;
221+
event.pan_y = 0.0;
222+
event.scale = 0.0;
223+
event.rotation = 0.0;
224+
225+
return event;
226+
}
227+
228+
UNUSED static inline FlutterPointerEvent make_stylus_cancel_event(size_t timestamp, struct vec2f pos, int32_t device_id) {
229+
return make_stylus_event(kCancel, timestamp, pos, device_id);
230+
}
231+
232+
static inline FlutterPointerEvent make_stylus_up_event(size_t timestamp, struct vec2f pos, int32_t device_id) {
233+
return make_stylus_event(kUp, timestamp, pos, device_id);
234+
}
235+
236+
static inline FlutterPointerEvent make_stylus_down_event(size_t timestamp, struct vec2f pos, int32_t device_id) {
237+
return make_stylus_event(kDown, timestamp, pos, device_id);
238+
}
239+
240+
static inline FlutterPointerEvent make_stylus_move_event(size_t timestamp, struct vec2f pos, int32_t device_id) {
241+
return make_stylus_event(kMove, timestamp, pos, device_id);
242+
}
243+
244+
static inline FlutterPointerEvent make_stylus_hover_event(size_t timestamp, struct vec2f pos, int32_t device_id) {
245+
return make_stylus_event(kHover, timestamp, pos, device_id);
246+
}
247+
248+
static inline FlutterPointerEvent make_stylus_add_event(size_t timestamp, struct vec2f pos, int32_t device_id) {
249+
return make_stylus_event(kAdd, timestamp, pos, device_id);
250+
}
251+
252+
static inline FlutterPointerEvent make_stylus_remove_event(size_t timestamp, struct vec2f pos, int32_t device_id) {
253+
return make_stylus_event(kRemove, timestamp, pos, device_id);
254+
}
255+
203256
// libinput interface
204257
static int on_open(const char *path, int flags, void *userdata) {
205258
struct user_input *input;
@@ -492,7 +545,8 @@ static int on_device_added(struct user_input *input, struct libinput_event *even
492545
return ENOMEM;
493546
}
494547

495-
data->flutter_device_id_offset = input->next_unused_flutter_device_id;
548+
data->touch_device_id_offset = -1;
549+
data->stylus_device_id = -1;
496550
data->keyboard_state = NULL;
497551
data->buttons = 0;
498552
data->timestamp = timestamp;
@@ -523,6 +577,8 @@ static int on_device_added(struct user_input *input, struct libinput_event *even
523577
goto fail_free_data;
524578
}
525579

580+
data->touch_device_id_offset = input->next_unused_flutter_device_id;
581+
526582
for (int i = 0; i < n_slots; i++) {
527583
device_id = input->next_unused_flutter_device_id++;
528584

@@ -550,8 +606,9 @@ static int on_device_added(struct user_input *input, struct libinput_event *even
550606
if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TABLET_TOOL)) {
551607
device_id = input->next_unused_flutter_device_id++;
552608

553-
/// TODO: Use kFlutterPointerDeviceKindStylus here
554-
emit_pointer_event(input, make_touch_add_event(timestamp, VEC2F(0, 0), device_id));
609+
data->stylus_device_id = device_id;
610+
611+
emit_pointer_event(input, make_stylus_add_event(timestamp, VEC2F(0, 0), device_id));
555612
}
556613

557614
return 0;
@@ -594,21 +651,27 @@ static int on_device_removed(struct user_input *input, struct libinput_event *ev
594651
}
595652
}
596653
}
654+
597655
if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TOUCH)) {
598656
// add all touch slots as individual touch devices to flutter
599657
if (emit_flutter_events) {
600658
for (int i = 0; i < libinput_device_touch_get_touch_count(device); i++) {
601-
emit_pointer_event(input, make_touch_remove_event(timestamp, VEC2F(0, 0), data->flutter_device_id_offset + i));
659+
emit_pointer_event(input, make_touch_remove_event(timestamp, VEC2F(0, 0), data->touch_device_id_offset + i));
602660
}
603661
}
604662
}
663+
605664
if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_KEYBOARD)) {
606665
// create a new keyboard state for this keyboard
607666
if (data->keyboard_state != NULL) {
608667
keyboard_state_destroy(data->keyboard_state);
609668
}
610669
}
611670

671+
if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TABLET_TOOL)) {
672+
emit_pointer_event(input, make_stylus_remove_event(timestamp, VEC2F(0, 0), data->stylus_device_id));
673+
}
674+
612675
if (data != NULL) {
613676
if (data->positions != NULL) {
614677
free(data->positions);
@@ -1020,7 +1083,7 @@ static int on_touch_down(struct user_input *input, struct libinput_event *event)
10201083
slot = 0;
10211084
}
10221085

1023-
device_id = data->flutter_device_id_offset + slot;
1086+
device_id = data->touch_device_id_offset + slot;
10241087

10251088
// transform the display coordinates to view (flutter) coordinates
10261089
pos_view = transform_point(
@@ -1062,7 +1125,7 @@ static int on_touch_up(struct user_input *input, struct libinput_event *event) {
10621125
slot = 0;
10631126
}
10641127

1065-
device_id = data->flutter_device_id_offset + slot;
1128+
device_id = data->touch_device_id_offset + slot;
10661129

10671130
emit_pointer_event(input, make_touch_up_event(timestamp, data->positions[slot], device_id));
10681131

@@ -1091,7 +1154,7 @@ static int on_touch_motion(struct user_input *input, struct libinput_event *even
10911154
slot = 0;
10921155
}
10931156

1094-
device_id = data->flutter_device_id_offset + slot;
1157+
device_id = data->touch_device_id_offset + slot;
10951158

10961159
// transform the display coordinates to view (flutter) coordinates
10971160
pos_view = transform_point(
@@ -1150,29 +1213,48 @@ static int on_tablet_tool_axis(struct user_input *input, struct libinput_event *
11501213
tablet_event = libinput_event_get_tablet_tool_event(event);
11511214
timestamp = libinput_event_tablet_tool_get_time_usec(tablet_event);
11521215

1153-
device_id = data->flutter_device_id_offset;
1216+
device_id = data->stylus_device_id;
11541217

1155-
// Only report down events when the tool is in contact with the tablet.
1156-
/// TODO: Maybe report hover events when it's not in contact?
1157-
/// FIXME: Use kFlutterPointerDeviceKindStylus here
1158-
if (data->tip) {
1159-
pos.x = libinput_event_tablet_tool_get_x_transformed(tablet_event, input->display_width - 1);
1160-
pos.y = libinput_event_tablet_tool_get_y_transformed(tablet_event, input->display_height - 1);
1218+
pos.x = libinput_event_tablet_tool_get_x_transformed(tablet_event, input->display_width - 1);
1219+
pos.y = libinput_event_tablet_tool_get_y_transformed(tablet_event, input->display_height - 1);
11611220

1162-
pos = transform_point(input->display_to_view_transform, pos);
1221+
pos = transform_point(input->display_to_view_transform, pos);
11631222

1164-
emit_pointer_event(input, make_touch_move_event(timestamp, pos, device_id));
1223+
if (data->tip) {
1224+
emit_pointer_event(input, make_stylus_move_event(timestamp, pos, device_id));
1225+
} else {
1226+
emit_pointer_event(input, make_stylus_hover_event(timestamp, pos, device_id));
11651227
}
11661228

11671229
return 0;
11681230
}
11691231

11701232
static int on_tablet_tool_proximity(struct user_input *input, struct libinput_event *event) {
1233+
struct libinput_event_tablet_tool *tablet_event;
1234+
struct input_device_data *data;
1235+
struct vec2f pos;
1236+
uint64_t timestamp;
1237+
int64_t device_id;
1238+
11711239
ASSERT_NOT_NULL(input);
11721240
ASSERT_NOT_NULL(event);
11731241

1174-
(void) input;
1175-
(void) event;
1242+
data = libinput_device_get_user_data(libinput_event_get_device(event));
1243+
ASSERT_NOT_NULL(data);
1244+
1245+
tablet_event = libinput_event_get_tablet_tool_event(event);
1246+
timestamp = libinput_event_tablet_tool_get_time_usec(tablet_event);
1247+
1248+
device_id = data->stylus_device_id;
1249+
1250+
pos.x = libinput_event_tablet_tool_get_x_transformed(tablet_event, input->display_width - 1);
1251+
pos.y = libinput_event_tablet_tool_get_y_transformed(tablet_event, input->display_height - 1);
1252+
1253+
pos = transform_point(input->display_to_view_transform, pos);
1254+
1255+
if (!data->tip) {
1256+
emit_pointer_event(input, make_stylus_hover_event(timestamp, pos, device_id));
1257+
}
11761258

11771259
return 0;
11781260
}
@@ -1193,20 +1275,19 @@ static int on_tablet_tool_tip(struct user_input *input, struct libinput_event *e
11931275
tablet_event = libinput_event_get_tablet_tool_event(event);
11941276
timestamp = libinput_event_tablet_tool_get_time_usec(tablet_event);
11951277

1196-
device_id = data->flutter_device_id_offset;
1278+
device_id = data->stylus_device_id;
11971279

11981280
pos.x = libinput_event_tablet_tool_get_x_transformed(tablet_event, input->display_width - 1);
11991281
pos.y = libinput_event_tablet_tool_get_y_transformed(tablet_event, input->display_height - 1);
12001282

12011283
pos = transform_point(input->display_to_view_transform, pos);
12021284

1203-
/// FIXME: Use kFlutterPointerDeviceKindStylus here
12041285
if (libinput_event_tablet_tool_get_tip_state(tablet_event) == LIBINPUT_TABLET_TOOL_TIP_DOWN) {
12051286
data->tip = true;
1206-
emit_pointer_event(input, make_touch_down_event(timestamp, pos, device_id));
1287+
emit_pointer_event(input, make_stylus_down_event(timestamp, pos, device_id));
12071288
} else {
12081289
data->tip = false;
1209-
emit_pointer_event(input, make_touch_up_event(timestamp, pos, device_id));
1290+
emit_pointer_event(input, make_stylus_up_event(timestamp, pos, device_id));
12101291
}
12111292

12121293
return 0;

0 commit comments

Comments
 (0)