1
+ #ifndef USER_INPUT_H_
2
+ #define USER_INPUT_H_
3
+
4
+ #include <xkbcommon/xkbcommon.h>
5
+ #include <flutter_embedder.h>
6
+
7
+ #define LOG_USER_INPUT_ERROR (...) fprintf(stderr, "[user input] " __VA_ARGS__)
8
+ #define MAX_COLLECTED_FLUTTER_POINTER_EVENTS 64
9
+
10
+ #define FLUTTER_POINTER_EVENT (_phase , _timestamp , _x , _y , _device , _signal_kind , _scroll_delta_x , _scroll_delta_y , _device_kind , _buttons ) \
11
+ (FlutterPointerEvent) { \
12
+ .struct_size = sizeof(FlutterPointerEvent), \
13
+ .phase = (_phase), \
14
+ .timestamp = (_timestamp), \
15
+ .x = (_x), .y = (_y), \
16
+ .device = (_device), \
17
+ .signal_kind = (_signal_kind), \
18
+ .scroll_delta_x = (_scroll_delta_x), \
19
+ .scroll_delta_y = (_scroll_delta_y), \
20
+ .device_kind = (_device_kind), \
21
+ .buttons = (_buttons) \
22
+ }
23
+
24
+ #define FLUTTER_POINTER_TOUCH_ADD_EVENT (_timestamp , _x , _y , _device_id ) \
25
+ FLUTTER_POINTER_EVENT(kAdd, _timestamp, _x, _y, _device_id, kFlutterPointerSignalKindNone, 0.0, 0.0, kFlutterPointerDeviceKindTouch, 0)
26
+
27
+ #define FLUTTER_POINTER_TOUCH_REMOVE_EVENT (_timestamp , _x , _y , _device_id ) \
28
+ FLUTTER_POINTER_EVENT(kRemove, _timestamp, _x, _y, _device_id, kFlutterPointerSignalKindNone, 0.0, 0.0, kFlutterPointerDeviceKindTouch, 0)
29
+
30
+ #define FLUTTER_POINTER_TOUCH_MOVE_EVENT (_timestamp , _x , _y , _device_id ) \
31
+ FLUTTER_POINTER_EVENT(kMove, _timestamp, _x, _y, _device_id, kFlutterPointerSignalKindNone, 0.0, 0.0, kFlutterPointerDeviceKindTouch, 0)
32
+
33
+ #define FLUTTER_POINTER_TOUCH_DOWN_EVENT (_timestamp , _x , _y , _device_id ) \
34
+ FLUTTER_POINTER_EVENT(kDown, _timestamp, _x, _y, _device_id, kFlutterPointerSignalKindNone, 0.0, 0.0, kFlutterPointerDeviceKindTouch, 0)
35
+
36
+ #define FLUTTER_POINTER_TOUCH_UP_EVENT (_timestamp , _x , _y , _device_id ) \
37
+ FLUTTER_POINTER_EVENT(kUp, _timestamp, _x, _y, _device_id, kFlutterPointerSignalKindNone, 0.0, 0.0, kFlutterPointerDeviceKindTouch, 0)
38
+
39
+ #define FLUTTER_POINTER_MOUSE_BUTTON_EVENT (_phase , _timestamp , _x , _y , _device_id , _buttons ) \
40
+ FLUTTER_POINTER_EVENT(_phase, _timestamp, _x, _y, _device_id, kFlutterPointerSignalKindNone, 0.0, 0.0, kFlutterPointerDeviceKindMouse, _buttons)
41
+
42
+ #define FLUTTER_POINTER_MOUSE_ADD_EVENT (_timestamp , _x , _y , _device_id , _buttons ) \
43
+ FLUTTER_POINTER_EVENT(kAdd, _timestamp, _x, _y, _device_id, kFlutterPointerSignalKindNone, 0.0, 0.0, kFlutterPointerDeviceKindMouse, _buttons)
44
+
45
+ #define FLUTTER_POINTER_MOUSE_REMOVE_EVENT (_timestamp , _x , _y , _device_id , _buttons ) \
46
+ FLUTTER_POINTER_EVENT(kRemove, _timestamp, _x, _y, _device_id, kFlutterPointerSignalKindNone, 0.0, 0.0, kFlutterPointerDeviceKindMouse, _buttons)
47
+
48
+ #define FLUTTER_POINTER_REMOVE_EVENT (_timestamp , _x , _y , _device , _buttons ) \
49
+ FLUTTER_POINTER_EVENT(kRemove, _timestamp, _x, _y, _device_id, kFlutterPointerSignalKindNone, 0.0, 0.0, kFlutterPointerDeviceKindMouse, _buttons)
50
+
51
+ #define FLUTTER_POINTER_MOUSE_MOVE_EVENT (_timestamp , _x , _y , _device_id , _buttons ) \
52
+ FLUTTER_POINTER_EVENT( \
53
+ (_buttons) & kFlutterPointerButtonMousePrimary ? kMove : kHover, \
54
+ _timestamp, \
55
+ _x, _y, \
56
+ _device_id, \
57
+ kFlutterPointerSignalKindNone, \
58
+ 0.0, 0.0, \
59
+ kFlutterPointerDeviceKindMouse, \
60
+ _buttons\
61
+ )
62
+
63
+ typedef void (* flutter_pointer_event_callback_t )(void * userdata , const FlutterPointerEvent * events , size_t n_events );
64
+
65
+ typedef void (* utf8_character_callback_t )(void * userdata , uint8_t * character );
66
+
67
+ typedef void (* xkb_keysym_callback_t )(void * userdata , xkb_keysym_t keysym );
68
+
69
+ typedef void (* gtk_keyevent_callback_t )(
70
+ void * userdata ,
71
+ uint32_t unicode_scalar_values ,
72
+ uint32_t key_code ,
73
+ uint32_t scan_code ,
74
+ uint32_t modifiers ,
75
+ bool is_down
76
+ );
77
+
78
+ typedef void (* set_cursor_enabled_callback_t )(void * userdata , bool enabled );
79
+
80
+ typedef void (* move_cursor_callback_t )(void * userdata , unsigned int x , unsigned int y );
81
+
82
+ struct user_input_interface {
83
+ flutter_pointer_event_callback_t on_flutter_pointer_event ;
84
+ utf8_character_callback_t on_utf8_character ;
85
+ xkb_keysym_callback_t on_xkb_keysym ;
86
+ gtk_keyevent_callback_t on_gtk_keyevent ;
87
+ set_cursor_enabled_callback_t on_set_cursor_enabled ;
88
+ move_cursor_callback_t on_move_cursor ;
89
+ };
90
+
91
+ struct user_input ;
92
+
93
+ /**
94
+ * @brief Create a new user input instance. Will try to load the default keyboard config from /etc/default/keyboard
95
+ * and create a udev-backed libinput instance.
96
+ */
97
+ struct user_input * user_input_new (
98
+ const struct user_input_interface * interface ,
99
+ void * userdata ,
100
+ const FlutterTransformation * display_to_view_transform ,
101
+ const FlutterTransformation * view_to_display_transform ,
102
+ unsigned int display_width ,
103
+ unsigned int display_height
104
+ );
105
+
106
+ /**
107
+ * @brief Destroy this user input instance and free all allocated memory. This will not remove any input devices
108
+ * added to flutter and won't invoke any callbacks in the user input interface at all.
109
+ */
110
+ void user_input_destroy (struct user_input * input );
111
+
112
+ /**
113
+ * @brief Set a 3x3 matrix and display width / height so user_input can transform any device coordinates into
114
+ * proper flutter view coordinates. (For example to account for a rotated display)
115
+ * Will also transform absolute & relative mouse movements.
116
+ *
117
+ * @param display_to_view_transform will be copied internally.
118
+ */
119
+ void user_input_set_transform (
120
+ struct user_input * input ,
121
+ const FlutterTransformation * display_to_view_transform ,
122
+ const FlutterTransformation * view_to_display_transform ,
123
+ unsigned int display_width ,
124
+ unsigned int display_height
125
+ );
126
+
127
+ /**
128
+ * @brief Returns a filedescriptor used for input event notification. The returned
129
+ * filedescriptor should be listened to with EPOLLIN | EPOLLRDHUP | EPOLLPRI or equivalent.
130
+ * When the fd becomes ready, @ref user_input_on_fd_ready should be called not long after it
131
+ * became ready. (libinput somehow relies on that)
132
+ */
133
+ int user_input_get_fd (struct user_input * input );
134
+
135
+ /**
136
+ * @brief Should be called when the fd returned by @ref user_input_get_fd becomes ready.
137
+ * The user_input_interface callbacks will be called inside this function.
138
+ */
139
+ int user_input_on_fd_ready (struct user_input * input );
140
+
141
+ #endif
0 commit comments