2525#define THIS_LIBINPUT_VER LIBINPUT_VER(LIBINPUT_VERSION_MAJOR, LIBINPUT_VERSION_MINOR, LIBINPUT_VERSION_PATCH)
2626
2727struct 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
5456struct 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
204257static 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
11701232static 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