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;