commit 9b3ddc4
Michael Forney
·
2014-01-18 11:48:33 +0000 UTC
parent 627e642
pointer: Implement cursor handling
2 files changed,
+134,
-27
+124,
-14
1@@ -1,10 +1,13 @@
2 #include "pointer.h"
3 #include "event.h"
4+#include "internal.h"
5+#include "screen.h"
6+#include "shm.h"
7 #include "util.h"
8-#include "view.h"
9
10 #include <stdio.h>
11 #include <assert.h>
12+#include <wld/wld.h>
13
14 static void enter(struct swc_input_focus_handler * handler,
15 struct wl_resource * resource, struct swc_surface * surface)
16@@ -49,12 +52,108 @@ static void handle_cursor_surface_destroy(struct wl_listener * listener,
17 struct swc_pointer * pointer = CONTAINER_OF(listener, typeof(*pointer),
18 cursor.destroy_listener);
19
20- pointer->cursor.surface = NULL;
21+ swc_view_attach(&pointer->cursor.view, NULL);
22+}
23+
24+static bool update(struct swc_view * view)
25+{
26+ return true;
27+}
28+
29+static bool attach(struct swc_view * view, struct swc_buffer * buffer)
30+{
31+ struct swc_pointer * pointer
32+ = CONTAINER_OF(view, typeof(*pointer), cursor.view);
33+ struct swc_surface * surface = pointer->cursor.surface;
34+
35+ if (surface && !pixman_region32_not_empty(&surface->state.damage))
36+ return true;
37+
38+ wld_set_target_buffer(swc.shm->renderer, pointer->cursor.buffer.wld);
39+ wld_fill_rectangle(swc.shm->renderer, 0x00000000, 0, 0, 64, 64);
40+ wld_copy_rectangle(swc.shm->renderer, buffer->wld, 0, 0, 0, 0,
41+ buffer->wld->width, buffer->wld->height);
42+ wld_flush(swc.shm->renderer);
43+
44+ if (surface)
45+ pixman_region32_clear(&surface->state.damage);
46+
47+ /* TODO: Send an early release to the buffer */
48+
49+ return true;
50+}
51+
52+static bool move(struct swc_view * view, int32_t x, int32_t y)
53+{
54+ return true;
55+}
56+
57+static const struct swc_view_impl view_impl = {
58+ .update = &update,
59+ .attach = &attach,
60+ .move = &move,
61+};
62+
63+static void handle_view_event(struct wl_listener * listener, void * data)
64+{
65+ struct swc_pointer * pointer
66+ = CONTAINER_OF(listener, typeof(*pointer), cursor.view_listener);
67+ struct swc_event * event = data;
68+ struct swc_view_event_data * event_data = event->data;
69+ struct swc_view * view = event_data->view;
70+
71+ switch (event->type)
72+ {
73+ case SWC_VIEW_EVENT_MOVED:
74+ {
75+ struct swc_screen_internal * screen;
76+
77+ wl_list_for_each(screen, &swc.screens, link)
78+ {
79+ if (view->screens & swc_screen_mask(screen))
80+ {
81+ struct swc_pointer * pointer
82+ = CONTAINER_OF(view, typeof(*pointer), cursor.view);
83+
84+ swc_view_move(&screen->planes.cursor.view,
85+ view->geometry.x - screen->base.geometry.x,
86+ view->geometry.y - screen->base.geometry.y);
87+
88+ if (!screen->planes.cursor.view.buffer)
89+ {
90+ swc_view_attach(&screen->planes.cursor.view,
91+ &pointer->cursor.buffer);
92+ }
93+ }
94+ else if (screen->planes.cursor.view.buffer)
95+ swc_view_attach(&screen->planes.cursor.view, NULL);
96+ }
97+ break;
98+ }
99+ case SWC_VIEW_EVENT_SCREENS_CHANGED:
100+ {
101+ struct swc_screen_internal * screen;
102+ uint32_t entered = event_data->screens_changed.entered,
103+ left = event_data->screens_changed.left;
104+
105+ wl_list_for_each(screen, &swc.screens, link)
106+ {
107+ if (entered & swc_screen_mask(screen))
108+ {
109+ swc_view_attach(&screen->planes.cursor.view,
110+ &pointer->cursor.buffer);
111+ }
112+ else if (left & swc_screen_mask(screen))
113+ swc_view_attach(&screen->planes.cursor.view, NULL);
114+ }
115+ break;
116+ }
117+ }
118 }
119
120 bool swc_pointer_initialize(struct swc_pointer * pointer)
121 {
122- wl_signal_init(&pointer->event_signal);
123+ struct wld_buffer * buffer;
124
125 pointer->x = wl_fixed_from_int(0);
126 pointer->y = wl_fixed_from_int(0);
127@@ -62,7 +161,18 @@ bool swc_pointer_initialize(struct swc_pointer * pointer)
128 pointer->focus_handler.enter = &enter;
129 pointer->focus_handler.leave = &leave;
130
131+ swc_view_initialize(&pointer->cursor.view, &view_impl);
132+ pointer->cursor.view_listener.notify = &handle_view_event;
133+ wl_signal_add(&pointer->cursor.view.event_signal,
134+ &pointer->cursor.view_listener);
135+ pointer->cursor.surface = NULL;
136 pointer->cursor.destroy_listener.notify = &handle_cursor_surface_destroy;
137+ buffer = wld_create_buffer(swc.drm->context, 64, 64, WLD_FORMAT_ARGB8888);
138+
139+ if (!buffer)
140+ return false;
141+
142+ swc_buffer_initialize(&pointer->cursor.buffer, buffer);
143
144 swc_input_focus_initialize(&pointer->focus, &pointer->focus_handler);
145 pixman_region32_init(&pointer->region);
146@@ -124,29 +234,25 @@ static void set_cursor(struct wl_client * client,
147 {
148 struct swc_pointer * pointer = wl_resource_get_user_data(resource);
149 struct swc_surface * surface;
150- struct swc_pointer_event_data data;
151-
152- data.old = pointer->cursor.surface;
153
154 if (pointer->cursor.surface)
155 wl_list_remove(&pointer->cursor.destroy_listener.link);
156
157 surface = surface_resource ? wl_resource_get_user_data(surface_resource)
158 : NULL;
159+ pointer->cursor.surface = surface;
160+ pointer->cursor.hotspot.x = hotspot_x;
161+ pointer->cursor.hotspot.y = hotspot_y;
162
163 if (surface)
164 {
165+ swc_surface_set_view(surface, &pointer->cursor.view);
166 wl_resource_add_destroy_listener(surface->resource,
167 &pointer->cursor.destroy_listener);
168+ swc_view_move(&pointer->cursor.view,
169+ wl_fixed_to_int(pointer->x) - hotspot_x,
170+ wl_fixed_to_int(pointer->y) - hotspot_y);
171 }
172-
173- pointer->cursor.surface = surface;
174- pointer->cursor.hotspot_x = hotspot_x;
175- pointer->cursor.hotspot_y = hotspot_y;
176-
177- data.new = pointer->cursor.surface;
178-
179- swc_send_event(&pointer->event_signal, SWC_POINTER_CURSOR_CHANGED, &data);
180 }
181
182 static struct wl_pointer_interface pointer_implementation = {
183@@ -224,5 +330,9 @@ void swc_pointer_handle_relative_motion
184 wl_pointer_send_motion(pointer->focus.resource, time,
185 surface_x, surface_y);
186 }
187+
188+ swc_view_move(&pointer->cursor.view,
189+ wl_fixed_to_int(pointer->x) - pointer->cursor.hotspot.x,
190+ wl_fixed_to_int(pointer->y) - pointer->cursor.hotspot.y);
191 }
192
+10,
-13
1@@ -1,8 +1,10 @@
2 #ifndef SWC_POINTER_H
3 #define SWC_POINTER_H
4
5+#include "buffer.h"
6 #include "input_focus.h"
7 #include "surface.h"
8+#include "view.h"
9
10 #include <wayland-server.h>
11 #include <pixman.h>
12@@ -19,28 +21,23 @@ struct swc_pointer_handler
13 enum wl_pointer_axis axis, wl_fixed_t amount);
14 };
15
16-enum swc_pointer_event_type
17-{
18- SWC_POINTER_CURSOR_CHANGED
19-};
20-
21-struct swc_pointer_event_data
22-{
23- struct swc_surface * old, * new;
24-};
25-
26 struct swc_pointer
27 {
28 struct swc_input_focus focus;
29 struct swc_input_focus_handler focus_handler;
30
31- struct wl_signal event_signal;
32-
33 struct
34 {
35+ struct swc_view view;
36+ struct wl_listener view_listener;
37 struct swc_surface * surface;
38- int32_t hotspot_x, hotspot_y;
39 struct wl_listener destroy_listener;
40+ struct swc_buffer buffer;
41+
42+ struct
43+ {
44+ int32_t x, y;
45+ } hotspot;
46 } cursor;
47
48 struct swc_pointer_handler * handler;