commit 614a694
Michael Forney
·
2023-07-01 20:56:06 +0000 UTC
parent 70922f9
pointer: Implement protocol version 8
3 files changed,
+106,
-27
+65,
-6
1@@ -32,6 +32,7 @@
2 #include "util.h"
3 #include "cursor/cursor_data.h"
4
5+#include <assert.h>
6 #include <stdio.h>
7 #include <wld/wld.h>
8
9@@ -204,19 +205,53 @@ client_handle_button(struct pointer_handler *handler, uint32_t time, struct butt
10 }
11
12 static bool
13-client_handle_axis(struct pointer_handler *handler, uint32_t time, uint32_t axis, wl_fixed_t amount)
14+client_handle_axis(struct pointer_handler *handler, uint32_t time, enum wl_pointer_axis axis, enum wl_pointer_axis_source source, wl_fixed_t value, int value120)
15 {
16 struct pointer *pointer = wl_container_of(handler, pointer, client_handler);
17 struct wl_resource *resource;
18+ int ver;
19
20 if (wl_list_empty(&pointer->focus.active))
21 return false;
22
23- wl_resource_for_each (resource, &pointer->focus.active)
24- wl_pointer_send_axis(resource, time, axis, amount);
25+ if (pointer->client_axis_source != -1) {
26+ assert(pointer->client_axis_source == source);
27+ source = -1;
28+ } else {
29+ pointer->client_axis_source = source;
30+ }
31+
32+ wl_resource_for_each (resource, &pointer->focus.active) {
33+ ver = wl_resource_get_version(resource);
34+ if (source != -1 && ver >= WL_POINTER_AXIS_SOURCE_SINCE_VERSION)
35+ wl_pointer_send_axis_source(resource, source);
36+ if (value120) {
37+ if (ver >= WL_POINTER_AXIS_VALUE120_SINCE_VERSION)
38+ wl_pointer_send_axis_value120(resource, axis, value120);
39+ else if (ver >= WL_POINTER_AXIS_DISCRETE_SINCE_VERSION)
40+ wl_pointer_send_axis_discrete(resource, axis, value120 / 120);
41+ }
42+ if (value)
43+ wl_pointer_send_axis(resource, time, axis, value);
44+ else if (ver >= WL_POINTER_AXIS_STOP_SINCE_VERSION)
45+ wl_pointer_send_axis_stop(resource, time, axis);
46+ }
47 return true;
48 }
49
50+static void
51+client_handle_frame(struct pointer_handler *handler)
52+{
53+ struct pointer *pointer = wl_container_of(handler, pointer, client_handler);
54+ struct wl_resource *resource;
55+
56+ wl_resource_for_each (resource, &pointer->focus.active) {
57+ if (wl_resource_get_version(resource) >= WL_POINTER_FRAME_SINCE_VERSION)
58+ wl_pointer_send_frame(resource);
59+ }
60+ pointer->client_axis_source = -1;
61+}
62+
63 bool
64 pointer_initialize(struct pointer *pointer)
65 {
66@@ -232,6 +267,9 @@ pointer_initialize(struct pointer *pointer)
67 pointer->client_handler.motion = client_handle_motion;
68 pointer->client_handler.button = client_handle_button;
69 pointer->client_handler.axis = client_handle_axis;
70+ pointer->client_handler.frame = client_handle_frame;
71+ pointer->client_handler.pending = false;
72+ pointer->client_axis_source = -1;
73 wl_list_init(&pointer->handlers);
74 wl_list_insert(&pointer->handlers, &pointer->client_handler.link);
75 wl_array_init(&pointer->buttons);
76@@ -385,6 +423,7 @@ pointer_handle_button(struct pointer *pointer, uint32_t time, uint32_t value, ui
77 if (button->handler) {
78 button->press.serial = serial;
79 button->handler->button(button->handler, time, button, state);
80+ button->handler->pending = true;
81 }
82
83 array_remove(&pointer->buttons, button, sizeof(*button));
84@@ -404,6 +443,7 @@ pointer_handle_button(struct pointer *pointer, uint32_t time, uint32_t value, ui
85 wl_list_for_each (handler, &pointer->handlers, link) {
86 if (handler->button && handler->button(handler, time, button, state)) {
87 button->handler = handler;
88+ handler->pending = true;
89 break;
90 }
91 }
92@@ -411,13 +451,15 @@ pointer_handle_button(struct pointer *pointer, uint32_t time, uint32_t value, ui
93 }
94
95 void
96-pointer_handle_axis(struct pointer *pointer, uint32_t time, uint32_t axis, wl_fixed_t amount)
97+pointer_handle_axis(struct pointer *pointer, uint32_t time, enum wl_pointer_axis axis, enum wl_pointer_axis_source source, wl_fixed_t value, int value120)
98 {
99 struct pointer_handler *handler;
100
101 wl_list_for_each (handler, &pointer->handlers, link) {
102- if (handler->axis && handler->axis(handler, time, axis, amount))
103+ if (handler->axis && handler->axis(handler, time, axis, source, value, value120)) {
104+ handler->pending = true;
105 break;
106+ }
107 }
108 }
109
110@@ -435,8 +477,25 @@ pointer_handle_absolute_motion(struct pointer *pointer, uint32_t time, wl_fixed_
111 clip_position(pointer, x, y);
112
113 wl_list_for_each (handler, &pointer->handlers, link) {
114- if (handler->motion && handler->motion(handler, time, pointer->x, pointer->y))
115+ if (handler->motion && handler->motion(handler, time, pointer->x, pointer->y)) {
116+ handler->pending = true;
117 break;
118+ }
119+ }
120+
121+ update_cursor(pointer);
122+}
123+
124+void
125+pointer_handle_frame(struct pointer *pointer)
126+{
127+ struct pointer_handler *handler;
128+
129+ wl_list_for_each (handler, &pointer->handlers, link) {
130+ if (handler->pending && handler->frame) {
131+ handler->frame(handler);
132+ handler->pending = false;
133+ }
134 }
135
136 update_cursor(pointer);
+6,
-2
1@@ -38,8 +38,10 @@ struct button {
2 struct pointer_handler {
3 bool (*motion)(struct pointer_handler *handler, uint32_t time, wl_fixed_t x, wl_fixed_t y);
4 bool (*button)(struct pointer_handler *handler, uint32_t time, struct button *button, uint32_t state);
5- bool (*axis)(struct pointer_handler *handler, uint32_t time, enum wl_pointer_axis axis, wl_fixed_t amount);
6+ bool (*axis)(struct pointer_handler *handler, uint32_t time, enum wl_pointer_axis axis, enum wl_pointer_axis_source source, wl_fixed_t value, int value120);
7+ void (*frame)(struct pointer_handler *handler);
8
9+ int pending;
10 struct wl_list link;
11 };
12
13@@ -64,6 +66,7 @@ struct pointer {
14 struct wl_array buttons;
15 struct wl_list handlers;
16 struct pointer_handler client_handler;
17+ enum wl_pointer_axis_source client_axis_source;
18
19 wl_fixed_t x, y;
20 pixman_region32_t region;
21@@ -79,8 +82,9 @@ struct button *pointer_get_button(struct pointer *pointer, uint32_t serial);
22
23 struct wl_resource *pointer_bind(struct pointer *pointer, struct wl_client *client, uint32_t version, uint32_t id);
24 void pointer_handle_button(struct pointer *pointer, uint32_t time, uint32_t button, uint32_t state);
25-void pointer_handle_axis(struct pointer *pointer, uint32_t time, uint32_t axis, wl_fixed_t amount);
26+void pointer_handle_axis(struct pointer *pointer, uint32_t time, enum wl_pointer_axis axis, enum wl_pointer_axis_source source, wl_fixed_t value, int value120);
27 void pointer_handle_relative_motion(struct pointer *pointer, uint32_t time, wl_fixed_t dx, wl_fixed_t dy);
28 void pointer_handle_absolute_motion(struct pointer *pointer, uint32_t time, wl_fixed_t x, wl_fixed_t y);
29+void pointer_handle_frame(struct pointer *pointer);
30
31 #endif
+35,
-19
1@@ -220,18 +220,6 @@ device_capabilities(struct libinput_device *device)
2 return capabilities;
3 }
4
5-static void
6-handle_libinput_axis_event(struct seat *seat, struct libinput_event_pointer *event, enum libinput_pointer_axis axis)
7-{
8- wl_fixed_t amount;
9-
10- if (!libinput_event_pointer_has_axis(event, axis))
11- return;
12-
13- amount = wl_fixed_from_double(libinput_event_pointer_get_axis_value(event, axis));
14- pointer_handle_axis(&seat->pointer, libinput_event_pointer_get_time(event), axis, amount);
15-}
16-
17 static int
18 handle_libinput_data(int fd, uint32_t mask, void *data)
19 {
20@@ -244,8 +232,10 @@ handle_libinput_data(int fd, uint32_t mask, void *data)
21 struct libinput_event_keyboard *k;
22 struct libinput_event_pointer *p;
23 } event;
24- wl_fixed_t x, y;
25+ wl_fixed_t x, y, value;
26 uint32_t time, key, state;
27+ enum wl_pointer_axis_source source;
28+ int value120;
29
30 if (libinput_dispatch(seat->libinput) != 0) {
31 WARNING("libinput_dispatch failed: %s\n", strerror(errno));
32@@ -273,6 +263,7 @@ handle_libinput_data(int fd, uint32_t mask, void *data)
33 x = wl_fixed_from_double(libinput_event_pointer_get_dx(event.p));
34 y = wl_fixed_from_double(libinput_event_pointer_get_dy(event.p));
35 pointer_handle_relative_motion(&seat->pointer, time, x, y);
36+ pointer_handle_frame(&seat->pointer);
37 break;
38 case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
39 screen = wl_container_of(swc.screens.next, screen, link);
40@@ -282,6 +273,7 @@ handle_libinput_data(int fd, uint32_t mask, void *data)
41 x = wl_fixed_from_double(libinput_event_pointer_get_absolute_x_transformed(event.p, rect->width));
42 y = wl_fixed_from_double(libinput_event_pointer_get_absolute_y_transformed(event.p, rect->height));
43 pointer_handle_absolute_motion(&seat->pointer, time, x, y);
44+ pointer_handle_frame(&seat->pointer);
45 break;
46 case LIBINPUT_EVENT_POINTER_BUTTON:
47 event.p = libinput_event_get_pointer_event(generic_event);
48@@ -292,20 +284,44 @@ handle_libinput_data(int fd, uint32_t mask, void *data)
49 if (state == LIBINPUT_BUTTON_STATE_PRESSED) {
50 /* qemu generates GEAR_UP/GEAR_DOWN events on scroll, so pass
51 * those through as axis events. */
52+ source = WL_POINTER_AXIS_SOURCE_WHEEL;
53 switch (key) {
54 case BTN_GEAR_DOWN:
55- pointer_handle_axis(&seat->pointer, time, WL_POINTER_AXIS_VERTICAL_SCROLL, wl_fixed_from_int(10));
56+ pointer_handle_axis(&seat->pointer, time, WL_POINTER_AXIS_VERTICAL_SCROLL, source, wl_fixed_from_int(10), 120);
57 break;
58 case BTN_GEAR_UP:
59- pointer_handle_axis(&seat->pointer, time, WL_POINTER_AXIS_VERTICAL_SCROLL, wl_fixed_from_int(-10));
60+ pointer_handle_axis(&seat->pointer, time, WL_POINTER_AXIS_VERTICAL_SCROLL, source, wl_fixed_from_int(-10), -120);
61 break;
62 }
63 }
64+ pointer_handle_frame(&seat->pointer);
65 break;
66- case LIBINPUT_EVENT_POINTER_AXIS:
67+ case LIBINPUT_EVENT_POINTER_SCROLL_WHEEL:
68+ source = WL_POINTER_AXIS_SOURCE_WHEEL;
69+ goto scroll;
70+ case LIBINPUT_EVENT_POINTER_SCROLL_FINGER:
71+ source = WL_POINTER_AXIS_SOURCE_FINGER;
72+ goto scroll;
73+ case LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS:
74+ source = WL_POINTER_AXIS_SOURCE_CONTINUOUS;
75+ goto scroll;
76+ scroll:
77 event.p = libinput_event_get_pointer_event(generic_event);
78- handle_libinput_axis_event(seat, event.p, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
79- handle_libinput_axis_event(seat, event.p, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
80+ time = libinput_event_pointer_get_time(event.p);
81+ value120 = 0;
82+ if (libinput_event_pointer_has_axis(event.p, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) {
83+ value = wl_fixed_from_double(libinput_event_pointer_get_scroll_value(event.p, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL));
84+ if (source == WL_POINTER_AXIS_SOURCE_WHEEL)
85+ value120 = libinput_event_pointer_get_scroll_value_v120(event.p, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
86+ pointer_handle_axis(&seat->pointer, time, WL_POINTER_AXIS_VERTICAL_SCROLL, source, value, value120);
87+ }
88+ if (libinput_event_pointer_has_axis(event.p, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) {
89+ value = wl_fixed_from_double(libinput_event_pointer_get_scroll_value(event.p, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL));
90+ if (source == WL_POINTER_AXIS_SOURCE_WHEEL)
91+ value120 = libinput_event_pointer_get_scroll_value_v120(event.p, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
92+ pointer_handle_axis(&seat->pointer, time, WL_POINTER_AXIS_HORIZONTAL_SCROLL, source, value, value120);
93+ }
94+ pointer_handle_frame(&seat->pointer);
95 break;
96 default:
97 break;
98@@ -382,7 +398,7 @@ seat_create(struct wl_display *display, const char *seat_name)
99 ERROR("Could not allocate seat name string\n");
100 goto error1;
101 }
102- seat->global = wl_global_create(display, &wl_seat_interface, 4, seat, &bind_seat);
103+ seat->global = wl_global_create(display, &wl_seat_interface, 8, seat, &bind_seat);
104 if (!seat->global)
105 goto error2;
106 seat->capabilities = 0;