commit c5c473b
Michael Forney
·
2013-09-13 03:00:27 +0000 UTC
parent e672b60
Implement cursor surfaces
8 files changed,
+195,
-3
+1,
-0
1@@ -12,6 +12,7 @@ libswc_la_SOURCES = \
2 plane.c plane.h \
3 surface.c surface.h \
4 compositor_surface.c compositor_surface.h \
5+ cursor_surface.c cursor_surface.h \
6 region.c region.h \
7 renderer.c renderer.h \
8 input_focus.c input_focus.h \
+27,
-0
1@@ -5,6 +5,7 @@
2
3 #include "compositor.h"
4 #include "compositor_surface.h"
5+#include "cursor_surface.h"
6 #include "tty.h"
7 #include "output.h"
8 #include "surface.h"
9@@ -300,6 +301,27 @@ static void handle_drm_event(struct wl_listener * listener, void * data)
10 }
11 }
12
13+static void handle_pointer_event(struct wl_listener * listener, void * data)
14+{
15+ struct swc_event * event = data;
16+ struct swc_pointer_event_data * event_data = event->data;
17+ struct swc_compositor * compositor;
18+
19+ compositor = swc_container_of(listener, typeof(*compositor),
20+ pointer_listener);
21+
22+ switch (event->type)
23+ {
24+ case SWC_POINTER_CURSOR_CHANGED:
25+ if (event_data->old)
26+ swc_surface_set_class(event_data->old, NULL);
27+
28+ if (event_data->new)
29+ swc_surface_set_class(event_data->new, &compositor->cursor_class);
30+ break;
31+ }
32+}
33+
34 static void handle_terminate(uint32_t time, uint32_t value, void * data)
35 {
36 struct wl_display * display = data;
37@@ -381,10 +403,13 @@ bool swc_compositor_initialize(struct swc_compositor * compositor,
38 compositor->display = display;
39 compositor->tty_listener.notify = &handle_tty_event;
40 compositor->drm_listener.notify = &handle_drm_event;
41+ compositor->pointer_listener.notify = &handle_pointer_event;
42 compositor->scheduled_updates = 0;
43 compositor->pending_flips = 0;
44 compositor->compositor_class.interface
45 = &swc_compositor_class_implementation;
46+ compositor->cursor_class.interface = &swc_cursor_class_implementation;
47+
48
49 compositor->udev = udev_new();
50
51@@ -415,6 +440,8 @@ bool swc_compositor_initialize(struct swc_compositor * compositor,
52 swc_seat_add_event_sources(&compositor->seat, event_loop);
53 compositor->seat.keyboard.handler = &keyboard_handler;
54 compositor->seat.pointer.handler = &pointer_handler;
55+ wl_signal_add(&compositor->seat.pointer.event_signal,
56+ &compositor->pointer_listener);
57
58 /* TODO: configurable seat */
59 if (!swc_drm_initialize(&compositor->drm, compositor->udev, default_seat))
+2,
-0
1@@ -40,9 +40,11 @@ struct swc_compositor
2 };
3
4 struct swc_surface_class compositor_class;
5+ struct swc_surface_class cursor_class;
6
7 struct wl_listener tty_listener;
8 struct wl_listener drm_listener;
9+ struct wl_listener pointer_listener;
10
11 struct wl_signal destroy_signal;
12 };
+112,
-0
1@@ -0,0 +1,112 @@
2+/* swc: cursor_surface.c
3+ *
4+ * Copyright (c) 2013 Michael Forney
5+ *
6+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7+ * of this software and associated documentation files (the "Software"), to deal
8+ * in the Software without restriction, including without limitation the rights
9+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+ * copies of the Software, and to permit persons to whom the Software is
11+ * furnished to do so, subject to the following conditions:
12+ *
13+ * The above copyright notice and this permission notice shall be included in
14+ * all copies or substantial portions of the Software.
15+ *
16+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+ * SOFTWARE.
23+ */
24+
25+#include "cursor_surface.h"
26+#include "compositor.h"
27+
28+#include <string.h>
29+#include <wld/wld.h>
30+
31+/* Cursor class */
32+static const uint32_t cursor_buffer_size = 64 * 64 * 4;
33+
34+static void update_plane(struct swc_plane * plane, void * data)
35+{
36+ struct wld_drawable * drawable = swc_plane_get_buffer(plane);
37+
38+ wld_write(drawable, data, cursor_buffer_size);
39+ swc_plane_flip(plane);
40+}
41+
42+static void attach(struct swc_surface * surface,
43+ struct wl_resource * resource)
44+{
45+ struct swc_compositor * compositor = swc_container_of
46+ (surface->class, typeof(*compositor), cursor_class);
47+
48+ if (pixman_region32_not_empty(&surface->state.damage))
49+ {
50+ struct wl_shm_buffer * buffer = wl_shm_buffer_get(resource);
51+ uint32_t width, height;
52+
53+ if (!buffer)
54+ return;
55+
56+ width = wl_shm_buffer_get_width(buffer);
57+ height = wl_shm_buffer_get_height(buffer);
58+
59+ if (width <= 64 && height <= 64)
60+ {
61+ struct swc_output * output;
62+ char data[cursor_buffer_size];
63+
64+ memset(data, 0, sizeof data);
65+ pixman_blt(wl_shm_buffer_get_data(buffer), (uint32_t *) data,
66+ wl_shm_buffer_get_stride(buffer) >> 2, 64, 32, 32,
67+ 0, 0, 0, 0, width, height);
68+ wl_buffer_send_release(resource);
69+ pixman_region32_clear(&surface->state.damage);
70+
71+ wl_list_for_each(output, &compositor->outputs, link)
72+ {
73+ if (swc_rectangle_overlap(&output->geometry,
74+ &surface->geometry))
75+ {
76+ update_plane(&output->cursor_plane, data);
77+ }
78+ }
79+ }
80+ }
81+}
82+
83+static void update(struct swc_surface * surface)
84+{
85+ swc_surface_send_frame_callbacks(surface, swc_time());
86+}
87+
88+static void move(struct swc_surface * surface, int32_t x, int32_t y)
89+{
90+ struct swc_compositor * compositor = swc_container_of
91+ (surface->class, typeof(*compositor), cursor_class);
92+ struct swc_output * output;
93+
94+ surface->geometry.x = x;
95+ surface->geometry.y = y;
96+
97+ wl_list_for_each(output, &compositor->outputs, link)
98+ {
99+ if (swc_rectangle_overlap(&output->geometry, &surface->geometry))
100+ {
101+ swc_plane_move(&output->cursor_plane,
102+ surface->geometry.x - output->geometry.x,
103+ surface->geometry.y - output->geometry.y);
104+ }
105+ }
106+}
107+
108+const struct swc_surface_class_interface swc_cursor_class_implementation = {
109+ .attach = &attach,
110+ .update = &update,
111+ .move = &move
112+};
113+
+33,
-0
1@@ -0,0 +1,33 @@
2+/* swc: cursor_surface.h
3+ *
4+ * Copyright (c) 2013 Michael Forney
5+ *
6+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7+ * of this software and associated documentation files (the "Software"), to deal
8+ * in the Software without restriction, including without limitation the rights
9+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+ * copies of the Software, and to permit persons to whom the Software is
11+ * furnished to do so, subject to the following conditions:
12+ *
13+ * The above copyright notice and this permission notice shall be included in
14+ * all copies or substantial portions of the Software.
15+ *
16+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+ * SOFTWARE.
23+ */
24+
25+#ifndef SWC_CURSOR_SURFACE_H
26+#define SWC_CURSOR_SURFACE_H 1
27+
28+#include "surface.h"
29+
30+extern const struct swc_surface_class_interface
31+ swc_cursor_class_implementation;
32+
33+#endif
34+
+5,
-2
1@@ -88,8 +88,9 @@ static void set_cursor(struct wl_client * client,
2 {
3 struct swc_pointer * pointer = wl_resource_get_user_data(resource);
4 struct swc_surface * surface;
5+ struct swc_pointer_event_data data;
6
7- printf("set_cursor\n");
8+ data.old = pointer->cursor.surface;
9
10 if (pointer->cursor.surface)
11 wl_list_remove(&pointer->cursor.destroy_listener.link);
12@@ -109,7 +110,9 @@ static void set_cursor(struct wl_client * client,
13 pointer->cursor.hotspot_x = hotspot_x;
14 pointer->cursor.hotspot_y = hotspot_y;
15
16- swc_send_event(&pointer->event_signal, SWC_POINTER_CURSOR_CHANGED, pointer);
17+ data.new = pointer->cursor.surface;
18+
19+ swc_send_event(&pointer->event_signal, SWC_POINTER_CURSOR_CHANGED, &data);
20 }
21
22 struct wl_pointer_interface pointer_implementation = {
+6,
-1
1@@ -16,11 +16,16 @@ struct swc_pointer_handler
2 uint32_t button, uint32_t state);
3 };
4
5-enum swc_pointer_event
6+enum swc_pointer_event_type
7 {
8 SWC_POINTER_CURSOR_CHANGED
9 };
10
11+struct swc_pointer_event_data
12+{
13+ struct swc_surface * old, * new;
14+};
15+
16 struct swc_pointer
17 {
18 struct swc_input_focus focus;
+9,
-0
1@@ -2,6 +2,7 @@
2 #define SWC_UTIL_H 1
3
4 #include <stdbool.h>
5+#include <sys/time.h>
6 #include <sys/param.h>
7 #include <wayland-server.h>
8 #include <pixman.h>
9@@ -17,6 +18,14 @@
10
11 void swc_remove_resource(struct wl_resource * resource);
12
13+static inline uint32_t swc_time()
14+{
15+ struct timeval timeval;
16+
17+ gettimeofday(&timeval, NULL);
18+ return timeval.tv_sec * 1000 + timeval.tv_usec / 1000;
19+}
20+
21 static inline bool swc_rectangle_contains_point
22 (pixman_rectangle32_t * rectangle, int32_t x, int32_t y)
23 {