Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 104 additions & 23 deletions src/user_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
#define THIS_LIBINPUT_VER LIBINPUT_VER(LIBINPUT_VERSION_MAJOR, LIBINPUT_VERSION_MINOR, LIBINPUT_VERSION_PATCH)

struct input_device_data {
int64_t flutter_device_id_offset;
struct keyboard_state *keyboard_state;
int64_t buttons;
uint64_t timestamp;
Expand All @@ -49,6 +48,9 @@ struct input_device_data {
*
*/
struct vec2f *positions;

int64_t touch_device_id_offset;
int64_t stylus_device_id;
};

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

static inline FlutterPointerEvent make_stylus_event(FlutterPointerPhase phase, size_t timestamp, struct vec2f pos, int32_t device_id) {
FlutterPointerEvent event;
memset(&event, 0, sizeof(event));

event.struct_size = sizeof(event);
event.phase = phase;
event.timestamp = timestamp;
event.x = pos.x;
event.y = pos.y;
event.device = device_id;
event.signal_kind = kFlutterPointerSignalKindNone;
event.scroll_delta_x = 0.0;
event.scroll_delta_y = 0.0;
event.device_kind = kFlutterPointerDeviceKindStylus;
event.buttons = 0;
event.pan_x = 0.0;
event.pan_y = 0.0;
event.scale = 0.0;
event.rotation = 0.0;

return event;
}

UNUSED static inline FlutterPointerEvent make_stylus_cancel_event(size_t timestamp, struct vec2f pos, int32_t device_id) {
return make_stylus_event(kCancel, timestamp, pos, device_id);
}

static inline FlutterPointerEvent make_stylus_up_event(size_t timestamp, struct vec2f pos, int32_t device_id) {
return make_stylus_event(kUp, timestamp, pos, device_id);
}

static inline FlutterPointerEvent make_stylus_down_event(size_t timestamp, struct vec2f pos, int32_t device_id) {
return make_stylus_event(kDown, timestamp, pos, device_id);
}

static inline FlutterPointerEvent make_stylus_move_event(size_t timestamp, struct vec2f pos, int32_t device_id) {
return make_stylus_event(kMove, timestamp, pos, device_id);
}

static inline FlutterPointerEvent make_stylus_hover_event(size_t timestamp, struct vec2f pos, int32_t device_id) {
return make_stylus_event(kHover, timestamp, pos, device_id);
}

static inline FlutterPointerEvent make_stylus_add_event(size_t timestamp, struct vec2f pos, int32_t device_id) {
return make_stylus_event(kAdd, timestamp, pos, device_id);
}

static inline FlutterPointerEvent make_stylus_remove_event(size_t timestamp, struct vec2f pos, int32_t device_id) {
return make_stylus_event(kRemove, timestamp, pos, device_id);
}

// libinput interface
static int on_open(const char *path, int flags, void *userdata) {
struct user_input *input;
Expand Down Expand Up @@ -492,7 +545,8 @@ static int on_device_added(struct user_input *input, struct libinput_event *even
return ENOMEM;
}

data->flutter_device_id_offset = input->next_unused_flutter_device_id;
data->touch_device_id_offset = -1;
data->stylus_device_id = -1;
data->keyboard_state = NULL;
data->buttons = 0;
data->timestamp = timestamp;
Expand Down Expand Up @@ -523,6 +577,8 @@ static int on_device_added(struct user_input *input, struct libinput_event *even
goto fail_free_data;
}

data->touch_device_id_offset = input->next_unused_flutter_device_id;

for (int i = 0; i < n_slots; i++) {
device_id = input->next_unused_flutter_device_id++;

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

/// TODO: Use kFlutterPointerDeviceKindStylus here
emit_pointer_event(input, make_touch_add_event(timestamp, VEC2F(0, 0), device_id));
data->stylus_device_id = device_id;

emit_pointer_event(input, make_stylus_add_event(timestamp, VEC2F(0, 0), device_id));
}

return 0;
Expand Down Expand Up @@ -594,21 +651,27 @@ static int on_device_removed(struct user_input *input, struct libinput_event *ev
}
}
}

if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TOUCH)) {
// add all touch slots as individual touch devices to flutter
if (emit_flutter_events) {
for (int i = 0; i < libinput_device_touch_get_touch_count(device); i++) {
emit_pointer_event(input, make_touch_remove_event(timestamp, VEC2F(0, 0), data->flutter_device_id_offset + i));
emit_pointer_event(input, make_touch_remove_event(timestamp, VEC2F(0, 0), data->touch_device_id_offset + i));
}
}
}

if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_KEYBOARD)) {
// create a new keyboard state for this keyboard
if (data->keyboard_state != NULL) {
keyboard_state_destroy(data->keyboard_state);
}
}

if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TABLET_TOOL)) {
emit_pointer_event(input, make_stylus_remove_event(timestamp, VEC2F(0, 0), data->stylus_device_id));
}

if (data != NULL) {
if (data->positions != NULL) {
free(data->positions);
Expand Down Expand Up @@ -1020,7 +1083,7 @@ static int on_touch_down(struct user_input *input, struct libinput_event *event)
slot = 0;
}

device_id = data->flutter_device_id_offset + slot;
device_id = data->touch_device_id_offset + slot;

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

device_id = data->flutter_device_id_offset + slot;
device_id = data->touch_device_id_offset + slot;

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

Expand Down Expand Up @@ -1091,7 +1154,7 @@ static int on_touch_motion(struct user_input *input, struct libinput_event *even
slot = 0;
}

device_id = data->flutter_device_id_offset + slot;
device_id = data->touch_device_id_offset + slot;

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

device_id = data->flutter_device_id_offset;
device_id = data->stylus_device_id;

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

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

emit_pointer_event(input, make_touch_move_event(timestamp, pos, device_id));
if (data->tip) {
emit_pointer_event(input, make_stylus_move_event(timestamp, pos, device_id));
} else {
emit_pointer_event(input, make_stylus_hover_event(timestamp, pos, device_id));
}

return 0;
}

static int on_tablet_tool_proximity(struct user_input *input, struct libinput_event *event) {
struct libinput_event_tablet_tool *tablet_event;
struct input_device_data *data;
struct vec2f pos;
uint64_t timestamp;
int64_t device_id;

ASSERT_NOT_NULL(input);
ASSERT_NOT_NULL(event);

(void) input;
(void) event;
data = libinput_device_get_user_data(libinput_event_get_device(event));
ASSERT_NOT_NULL(data);

tablet_event = libinput_event_get_tablet_tool_event(event);
timestamp = libinput_event_tablet_tool_get_time_usec(tablet_event);

device_id = data->stylus_device_id;

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

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

if (!data->tip) {
emit_pointer_event(input, make_stylus_hover_event(timestamp, pos, device_id));
}

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

device_id = data->flutter_device_id_offset;
device_id = data->stylus_device_id;

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

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

/// FIXME: Use kFlutterPointerDeviceKindStylus here
if (libinput_event_tablet_tool_get_tip_state(tablet_event) == LIBINPUT_TABLET_TOOL_TIP_DOWN) {
data->tip = true;
emit_pointer_event(input, make_touch_down_event(timestamp, pos, device_id));
emit_pointer_event(input, make_stylus_down_event(timestamp, pos, device_id));
} else {
data->tip = false;
emit_pointer_event(input, make_touch_up_event(timestamp, pos, device_id));
emit_pointer_event(input, make_stylus_up_event(timestamp, pos, device_id));
}

return 0;
Expand Down