commit 680957d
Michael Forney
·
2014-02-17 00:06:06 +0000 UTC
parent 77ec52d
pointer: Add more flexible handler system
3 files changed,
+115,
-28
+108,
-26
1@@ -33,6 +33,12 @@
2 #include <assert.h>
3 #include <wld/wld.h>
4
5+struct button_press
6+{
7+ uint32_t value;
8+ struct swc_pointer_handler * handler;
9+};
10+
11 static void enter(struct swc_input_focus_handler * handler,
12 struct wl_resource * resource, struct swc_surface * surface)
13 {
14@@ -189,6 +195,54 @@ void swc_pointer_set_cursor(struct swc_pointer * pointer, uint32_t id)
15 swc_view_attach(&pointer->cursor.view, pointer->cursor.internal_buffer);
16 }
17
18+static bool client_handle_button(struct swc_pointer_handler * handler,
19+ uint32_t time, uint32_t button, uint32_t state)
20+{
21+ struct swc_pointer * pointer
22+ = CONTAINER_OF(handler, typeof(*pointer), client_handler);
23+ uint32_t serial;
24+
25+ if (!pointer->focus.resource)
26+ return false;
27+
28+ serial = wl_display_get_serial(swc.display);
29+ wl_pointer_send_button(pointer->focus.resource, serial, time,
30+ button, state);
31+
32+ return true;
33+}
34+
35+static bool client_handle_axis(struct swc_pointer_handler * handler,
36+ uint32_t time, uint32_t axis, wl_fixed_t amount)
37+{
38+ struct swc_pointer * pointer
39+ = CONTAINER_OF(handler, typeof(*pointer), client_handler);
40+
41+ if (!pointer->focus.resource)
42+ return false;
43+
44+ wl_pointer_send_axis(pointer->focus.resource, time, axis, amount);
45+
46+ return true;
47+}
48+
49+static bool client_handle_motion(struct swc_pointer_handler * handler,
50+ uint32_t time, wl_fixed_t x, wl_fixed_t y)
51+{
52+ struct swc_pointer * pointer
53+ = CONTAINER_OF(handler, typeof(*pointer), client_handler);
54+
55+ if (!pointer->focus.resource)
56+ return false;
57+
58+ wl_pointer_send_motion
59+ (pointer->focus.resource, time,
60+ x - wl_fixed_from_int(pointer->focus.surface->view->geometry.x),
61+ y - wl_fixed_from_int(pointer->focus.surface->view->geometry.y));
62+
63+ return true;
64+}
65+
66 bool swc_pointer_initialize(struct swc_pointer * pointer)
67 {
68 struct screen * screen;
69@@ -202,6 +256,12 @@ bool swc_pointer_initialize(struct swc_pointer * pointer)
70
71 pointer->focus_handler.enter = &enter;
72 pointer->focus_handler.leave = &leave;
73+ pointer->client_handler.button = &client_handle_button;
74+ pointer->client_handler.axis = &client_handle_axis;
75+ pointer->client_handler.motion = &client_handle_motion;
76+ wl_list_init(&pointer->handlers);
77+ wl_list_insert(&pointer->handlers, &pointer->client_handler.link);
78+ wl_array_init(&pointer->buttons);
79
80 swc_view_initialize(&pointer->cursor.view, &view_impl);
81 pointer->cursor.view_listener.notify = &handle_view_event;
82@@ -322,51 +382,73 @@ struct wl_resource * swc_pointer_bind(struct swc_pointer * pointer,
83 }
84
85 void swc_pointer_handle_button(struct swc_pointer * pointer, uint32_t time,
86- uint32_t button, uint32_t state)
87+ uint32_t value, uint32_t state)
88 {
89- if ((!pointer->handler || !pointer->handler->button
90- || !pointer->handler->button(pointer->handler, time, button, state))
91- && pointer->focus.resource)
92+ struct swc_pointer_handler * handler;
93+ struct button_press * button;
94+ uint32_t serial;
95+
96+ serial = wl_display_next_serial(swc.display);
97+
98+ if (state == WL_POINTER_BUTTON_STATE_RELEASED)
99 {
100- struct wl_client * client
101- = wl_resource_get_client(pointer->focus.resource);
102- struct wl_display * display = wl_client_get_display(client);
103- uint32_t serial = wl_display_next_serial(display);
104+ wl_array_for_each(button, &pointer->buttons)
105+ {
106+ if (button->value == value)
107+ {
108+ swc_array_remove(&pointer->buttons, button, sizeof *button);
109
110- wl_pointer_send_button(pointer->focus.resource, serial, time,
111- button, state);
112+ if (button->handler->button)
113+ {
114+ button->handler->button(button->handler, time,
115+ value, state);
116+ }
117+
118+ break;
119+ }
120+ }
121+ }
122+ else
123+ {
124+ wl_list_for_each(handler, &pointer->handlers, link)
125+ {
126+ if (handler->button && handler->button(handler, time, value, state))
127+ {
128+ button = wl_array_add(&pointer->buttons, sizeof *button);
129+ button->value = value;
130+ button->handler = handler;
131+ break;
132+ }
133+ }
134 }
135 }
136
137 void swc_pointer_handle_axis(struct swc_pointer * pointer, uint32_t time,
138 uint32_t axis, wl_fixed_t amount)
139 {
140- if ((!pointer->handler || !pointer->handler->axis
141- || !pointer->handler->axis(pointer->handler, time, axis, amount))
142- && pointer->focus.resource)
143+ struct swc_pointer_handler * handler;
144+
145+ wl_list_for_each(handler, &pointer->handlers, link)
146 {
147- wl_pointer_send_axis(pointer->focus.resource, time, axis, amount);
148+ if (handler->axis && handler->axis(handler, time, axis, amount))
149+ break;
150 }
151 }
152
153 void swc_pointer_handle_relative_motion
154 (struct swc_pointer * pointer, uint32_t time, wl_fixed_t dx, wl_fixed_t dy)
155 {
156+ struct swc_pointer_handler * handler;
157+
158 clip_position(pointer, pointer->x + dx, pointer->y + dy);
159
160- if ((!pointer->handler || !pointer->handler->motion
161- || !pointer->handler->motion(pointer->handler, time,
162- pointer->x, pointer->y))
163- && pointer->focus.resource)
164+ wl_list_for_each(handler, &pointer->handlers, link)
165 {
166- wl_fixed_t surface_x, surface_y;
167- surface_x = pointer->x
168- - wl_fixed_from_int(pointer->focus.surface->view->geometry.x);
169- surface_y = pointer->y
170- - wl_fixed_from_int(pointer->focus.surface->view->geometry.y);
171-
172- wl_pointer_send_motion(pointer->focus.resource, time,
173- surface_x, surface_y);
174+ if (handler->motion && handler->motion(handler, time,
175+ pointer->x, pointer->y))
176+ {
177+ break;
178+ }
179 }
180
181 update_cursor(pointer);
+5,
-1
1@@ -41,6 +41,8 @@ struct swc_pointer_handler
2 uint32_t button, uint32_t state);
3 bool (* axis)(struct swc_pointer_handler * handler, uint32_t time,
4 enum wl_pointer_axis axis, wl_fixed_t amount);
5+
6+ struct wl_list link;
7 };
8
9 struct swc_pointer
10@@ -65,7 +67,9 @@ struct swc_pointer
11 } hotspot;
12 } cursor;
13
14- struct swc_pointer_handler * handler;
15+ struct wl_array buttons;
16+ struct wl_list handlers;
17+ struct swc_pointer_handler client_handler;
18
19 wl_fixed_t x, y;
20 pixman_region32_t region;
+2,
-1
1@@ -65,7 +65,8 @@ static void setup_compositor()
2
3 wl_list_insert(&swc.seat->keyboard->handlers,
4 &swc.bindings->keyboard_handler->link);
5- swc.seat->pointer->handler = swc.compositor->pointer_handler;
6+ wl_list_insert(&swc.seat->pointer->handlers,
7+ &swc.compositor->pointer_handler->link);
8 wl_signal_add(&swc.seat->pointer->focus.event_signal,
9 &window_enter_listener);
10