commit 5b1678f

Michael Forney  ·  2014-08-16 19:40:25 +0000 UTC
parent 28f049f
view: Use a view_handler structure instead of swc_event
6 files changed,  +140, -165
+23, -29
 1@@ -57,7 +57,7 @@ struct target
 2     struct wld_surface * surface;
 3     struct wld_buffer * next_buffer, * current_buffer;
 4     struct view * view;
 5-    struct wl_listener view_listener;
 6+    struct view_handler view_handler;
 7     uint32_t mask;
 8 
 9     struct wl_listener screen_destroy_listener;
10@@ -112,40 +112,34 @@ static struct target * target_get(struct screen * screen)
11                     : NULL;
12 }
13 
14-static void handle_screen_view_event(struct wl_listener * listener, void * data)
15+static void handle_screen_frame(struct view_handler * handler, uint32_t time)
16 {
17-    struct swc_event * event = data;
18-    struct view_event_data * event_data = event->data;
19-    struct target * target = wl_container_of(listener, target, view_listener);
20-
21-    switch (event->type)
22-    {
23-        case VIEW_EVENT_FRAME:
24-        {
25-            struct compositor_view * view;
26+    struct target * target = wl_container_of(handler, target, view_handler);
27+    struct compositor_view * view;
28 
29-            compositor.pending_flips &= ~target->mask;
30+    compositor.pending_flips &= ~target->mask;
31 
32-            wl_list_for_each(view, &compositor.views, link)
33-            {
34-                if (view->base.screens & target->mask)
35-                    view_frame(&view->base, event_data->frame.time);
36-            }
37+    wl_list_for_each(view, &compositor.views, link)
38+    {
39+        if (view->base.screens & target->mask)
40+            view_frame(&view->base, time);
41+    }
42 
43-            if (target->current_buffer)
44-                wld_surface_release(target->surface, target->current_buffer);
45+    if (target->current_buffer)
46+        wld_surface_release(target->surface, target->current_buffer);
47 
48-            target->current_buffer = target->next_buffer;
49+    target->current_buffer = target->next_buffer;
50 
51-            /* If we had scheduled updates that couldn't run because we were
52-             * waiting on a page flip, run them now. */
53-            if (compositor.scheduled_updates && !compositor.updating)
54-                perform_update(NULL);
55-            break;
56-        }
57-    }
58+    /* If we had scheduled updates that couldn't run because we were
59+     * waiting on a page flip, run them now. */
60+    if (compositor.scheduled_updates && !compositor.updating)
61+        perform_update(NULL);
62 }
63 
64+static const struct view_handler_impl screen_view_handler = {
65+    .frame = &handle_screen_frame,
66+};
67+
68 static int target_swap_buffers(struct target * target)
69 {
70     target->next_buffer = wld_surface_take(target->surface);
71@@ -169,8 +163,8 @@ static struct target * target_new(struct screen * screen)
72         goto error1;
73 
74     target->view = &screen->planes.framebuffer.view;
75-    target->view_listener.notify = &handle_screen_view_event;
76-    wl_signal_add(&target->view->event_signal, &target->view_listener);
77+    target->view_handler.impl = &screen_view_handler;
78+    wl_list_insert(&target->view->handlers, &target->view_handler.link);
79     target->current_buffer = NULL;
80     target->mask = screen_mask(screen);
81     target_swap_buffers(target);
+15, -19
 1@@ -23,7 +23,6 @@
 2 
 3 #include "panel.h"
 4 #include "compositor.h"
 5-#include "event.h"
 6 #include "internal.h"
 7 #include "keyboard.h"
 8 #include "output.h"
 9@@ -44,7 +43,7 @@ struct panel
10     struct swc_surface * surface;
11     struct wl_listener surface_destroy_listener;
12     struct compositor_view * view;
13-    struct wl_listener view_listener;
14+    struct view_handler view_handler;
15     struct screen * screen;
16     struct screen_modifier modifier;
17     uint32_t edge;
18@@ -107,7 +106,7 @@ static void dock(struct wl_client * client, struct wl_resource * resource,
19     }
20 
21     if (panel->docked)
22-        wl_list_remove(&panel->view_listener.link);
23+        wl_list_remove(&panel->view_handler.link);
24 
25     if (panel->screen && screen_changed)
26     {
27@@ -128,7 +127,7 @@ static void dock(struct wl_client * client, struct wl_resource * resource,
28 
29     update_position(panel);
30     compositor_view_show(panel->view);
31-    wl_signal_add(&panel->view->base.event_signal, &panel->view_listener);
32+    wl_list_insert(&panel->view->base.handlers, &panel->view_handler.link);
33     wl_list_insert(&screen->modifiers, &panel->modifier.link);
34 
35     if (focus)
36@@ -165,6 +164,17 @@ static const struct swc_panel_interface panel_implementation = {
37     .set_strut = &set_strut
38 };
39 
40+static void handle_resize(struct view_handler * handler)
41+{
42+    struct panel * panel = wl_container_of(handler, panel, view_handler);
43+
44+    update_position(panel);
45+}
46+
47+static const struct view_handler_impl view_handler_impl = {
48+    .resize = &handle_resize,
49+};
50+
51 static void modify(struct screen_modifier * modifier,
52                    const struct swc_rectangle * geometry,
53                    pixman_region32_t * usable)
54@@ -211,7 +221,6 @@ static void destroy_panel(struct wl_resource * resource)
55 
56     if (panel->docked)
57     {
58-        wl_list_remove(&panel->view_listener.link);
59         wl_list_remove(&panel->modifier.link);
60         screen_update_usable_geometry(panel->screen);
61         compositor_view_destroy(panel->view);
62@@ -220,19 +229,6 @@ static void destroy_panel(struct wl_resource * resource)
63     free(panel);
64 }
65 
66-static void handle_view_event(struct wl_listener * listener, void * data)
67-{
68-    struct panel * panel = wl_container_of(listener, panel, view_listener);
69-    struct swc_event * event = data;
70-
71-    switch (event->type)
72-    {
73-        case VIEW_EVENT_RESIZED:
74-            update_position(panel);
75-            break;
76-    }
77-}
78-
79 static void handle_surface_destroy(struct wl_listener * listener, void * data)
80 {
81     struct panel * panel
82@@ -261,7 +257,7 @@ struct panel * panel_new(struct wl_client * client, uint32_t id,
83 
84     panel->surface = surface;
85     panel->surface_destroy_listener.notify = &handle_surface_destroy;
86-    panel->view_listener.notify = &handle_view_event;
87+    panel->view_handler.impl = &view_handler_impl;
88     panel->modifier.modify = &modify;
89     panel->screen = NULL;
90     panel->offset = 0;
+58, -62
  1@@ -107,6 +107,60 @@ static void state_set_buffer(struct swc_surface_state * state,
  2     state->buffer_resource = resource;
  3 }
  4 
  5+static void handle_frame(struct view_handler * handler, uint32_t time)
  6+{
  7+    struct swc_surface * surface
  8+        = wl_container_of(handler, surface, view_handler);
  9+    struct wl_resource * resource, * tmp;
 10+
 11+    wl_list_for_each_safe(resource, tmp,
 12+                          &surface->state.frame_callbacks, link)
 13+    {
 14+        wl_callback_send_done(resource, time);
 15+        wl_resource_destroy(resource);
 16+    }
 17+
 18+    wl_list_init(&surface->state.frame_callbacks);
 19+}
 20+
 21+static void handle_screens(struct view_handler * handler,
 22+                           uint32_t entered, uint32_t left)
 23+{
 24+    struct swc_surface * surface
 25+        = wl_container_of(handler, surface, view_handler);
 26+    struct screen * screen;
 27+    struct swc_output * output;
 28+    struct wl_client * client;
 29+    struct wl_resource * resource;
 30+
 31+    client = wl_resource_get_client(surface->resource);
 32+
 33+    wl_list_for_each(screen, &swc.screens, link)
 34+    {
 35+        if (!((entered | left) & screen_mask(screen)))
 36+            continue;
 37+
 38+        wl_list_for_each(output, &screen->outputs, link)
 39+        {
 40+            resource = wl_resource_find_for_client
 41+                (&output->resources, client);
 42+
 43+            if (resource)
 44+            {
 45+                if (entered & screen_mask(screen))
 46+                    wl_surface_send_enter(surface->resource, resource);
 47+                else if (left & screen_mask(screen))
 48+                    wl_surface_send_leave(surface->resource, resource);
 49+            }
 50+        }
 51+    }
 52+}
 53+
 54+static const struct view_handler_impl view_handler_impl = {
 55+    .frame = &handle_frame,
 56+    .screens = &handle_screens,
 57+};
 58+
 59 static void destroy(struct wl_client * client, struct wl_resource * resource)
 60 {
 61     wl_resource_destroy(resource);
 62@@ -291,69 +345,11 @@ static void surface_destroy(struct wl_resource * resource)
 63     state_finalize(&surface->pending.state);
 64 
 65     if (surface->view)
 66-        wl_list_remove(&surface->view_listener.link);
 67+        wl_list_remove(&surface->view_handler.link);
 68 
 69     free(surface);
 70 }
 71 
 72-static void handle_view_event(struct wl_listener * listener, void * data)
 73-{
 74-    struct swc_surface * surface
 75-        = wl_container_of(listener, surface, view_listener);
 76-    struct swc_event * event = data;
 77-    struct view_event_data * event_data = event->data;
 78-
 79-    switch (event->type)
 80-    {
 81-        case VIEW_EVENT_FRAME:
 82-        {
 83-            struct wl_resource * resource, * tmp;
 84-
 85-            wl_list_for_each_safe(resource, tmp,
 86-                                  &surface->state.frame_callbacks, link)
 87-            {
 88-                wl_callback_send_done(resource, event_data->frame.time);
 89-                wl_resource_destroy(resource);
 90-            }
 91-
 92-            wl_list_init(&surface->state.frame_callbacks);
 93-            break;
 94-        }
 95-        case VIEW_EVENT_SCREENS_CHANGED:
 96-        {
 97-            struct screen * screen;
 98-            struct swc_output * output;
 99-            struct wl_client * client;
100-            struct wl_resource * resource;
101-            uint32_t entered = event_data->screens_changed.entered,
102-                     left = event_data->screens_changed.left;
103-
104-            client = wl_resource_get_client(surface->resource);
105-
106-            wl_list_for_each(screen, &swc.screens, link)
107-            {
108-                if (!((entered | left) & screen_mask(screen)))
109-                    continue;
110-
111-                wl_list_for_each(output, &screen->outputs, link)
112-                {
113-                    resource = wl_resource_find_for_client
114-                        (&output->resources, client);
115-
116-                    if (resource)
117-                    {
118-                        if (entered & screen_mask(screen))
119-                            wl_surface_send_enter(surface->resource, resource);
120-                        else if (left & screen_mask(screen))
121-                            wl_surface_send_leave(surface->resource, resource);
122-                    }
123-                }
124-            }
125-            break;
126-        }
127-    }
128-}
129-
130 /**
131  * Construct a new surface, adding it to the given client as id.
132  *
133@@ -374,7 +370,7 @@ struct swc_surface * swc_surface_new(struct wl_client * client,
134     /* Initialize the surface. */
135     surface->pending.commit = 0;
136     surface->view = NULL;
137-    surface->view_listener.notify = &handle_view_event;
138+    surface->view_handler.impl = &view_handler_impl;
139 
140     state_initialize(&surface->state);
141     state_initialize(&surface->pending.state);
142@@ -394,13 +390,13 @@ void swc_surface_set_view(struct swc_surface * surface, struct view * view)
143         return;
144 
145     if (surface->view)
146-        wl_list_remove(&surface->view_listener.link);
147+        wl_list_remove(&surface->view_handler.link);
148 
149     surface->view = view;
150 
151     if (view)
152     {
153-        wl_signal_add(&view->event_signal, &surface->view_listener);
154+        wl_list_insert(&view->handlers, &surface->view_handler.link);
155         view_attach(view, surface->state.buffer);
156         view_update(view);
157     }
+3, -1
 1@@ -24,6 +24,8 @@
 2 #ifndef SWC_SURFACE_H
 3 #define SWC_SURFACE_H
 4 
 5+#include "view.h"
 6+
 7 #include <stdbool.h>
 8 #include <wayland-server.h>
 9 #include <pixman.h>
10@@ -69,7 +71,7 @@ struct swc_surface
11     } pending;
12 
13     struct view * view;
14-    struct wl_listener view_listener;
15+    struct view_handler view_handler;
16 };
17 
18 struct swc_surface * swc_surface_new(struct wl_client * client,
+21, -15
 1@@ -29,6 +29,16 @@
 2 
 3 #include <wld/wld.h>
 4 
 5+#define HANDLE(view, handler, method, ...)                                  \
 6+    do                                                                      \
 7+    {                                                                       \
 8+        wl_list_for_each(handler, &view->handlers, link)                    \
 9+        {                                                                   \
10+            if (handler->impl->method)                                      \
11+                handler->impl->method(handler, ## __VA_ARGS__);             \
12+        }                                                                   \
13+    } while (0)
14+
15 void view_initialize(struct view * view, const struct view_impl * impl)
16 {
17     view->impl = impl;
18@@ -38,7 +48,7 @@ void view_initialize(struct view * view, const struct view_impl * impl)
19     view->geometry.height = 0;
20     view->buffer = NULL;
21     view->screens = 0;
22-    wl_signal_init(&view->event_signal);
23+    wl_list_init(&view->handlers);
24 }
25 
26 void view_finalize(struct view * view)
27@@ -77,28 +87,28 @@ bool view_move(struct view * view, int32_t x, int32_t y)
28 
29 bool view_set_position(struct view * view, int32_t x, int32_t y)
30 {
31-    struct view_event_data data = { .view = view };
32+    struct view_handler * handler;
33 
34     if (x == view->geometry.x && y == view->geometry.y)
35         return false;
36 
37     view->geometry.x = x;
38     view->geometry.y = y;
39-    swc_send_event(&view->event_signal, VIEW_EVENT_MOVED, &data);
40+    HANDLE(view, handler, move);
41 
42     return true;
43 }
44 
45 bool view_set_size(struct view * view, uint32_t width, uint32_t height)
46 {
47-    struct view_event_data data = { .view = view };
48+    struct view_handler * handler;
49 
50     if (view->geometry.width == width && view->geometry.height == height)
51         return false;
52 
53     view->geometry.width = width;
54     view->geometry.height = height;
55-    swc_send_event(&view->event_signal, VIEW_EVENT_RESIZED, &data);
56+    HANDLE(view, handler, resize);
57 
58     return true;
59 }
60@@ -114,16 +124,12 @@ void view_set_screens(struct view * view, uint32_t screens)
61     if (view->screens == screens)
62         return;
63 
64-    struct view_event_data data = {
65-        .view = view,
66-        .screens_changed = {
67-            .entered = screens & ~view->screens,
68-            .left = view->screens & ~screens
69-        }
70-    };
71+    uint32_t entered = screens & ~view->screens,
72+             left = view->screens & ~screens;
73+    struct view_handler * handler;
74 
75     view->screens = screens;
76-    swc_send_event(&view->event_signal, VIEW_EVENT_SCREENS_CHANGED, &data);
77+    HANDLE(view, handler, screens, entered, left);
78 }
79 
80 void view_update_screens(struct view * view)
81@@ -142,8 +148,8 @@ void view_update_screens(struct view * view)
82 
83 void view_frame(struct view * view, uint32_t time)
84 {
85-    struct view_event_data data = { .view = view, .frame = { time } };
86+    struct view_handler * handler;
87 
88-    swc_send_event(&view->event_signal, VIEW_EVENT_FRAME, &data);
89+    HANDLE(view, handler, frame, time);
90 }
91 
+20, -39
 1@@ -26,44 +26,6 @@
 2 
 3 #include "swc.h"
 4 
 5-enum
 6-{
 7-    /* Sent when the view has displayed the next frame. */
 8-    VIEW_EVENT_FRAME,
 9-
10-    /* Sent when the origin of the view has moved. */
11-    VIEW_EVENT_MOVED,
12-
13-    /* Sent when the view's size changes. */
14-    VIEW_EVENT_RESIZED,
15-
16-    /* Sent when the set of screens the view is visible on changes. */
17-    VIEW_EVENT_SCREENS_CHANGED
18-};
19-
20-/**
21- * This structure contains data sent along with a view's events.
22- *
23- * Extra data correspending to the particular event is stored in the
24- * corresponding struct inside the union.
25- */
26-struct view_event_data
27-{
28-    struct view * view;
29-    union
30-    {
31-        struct
32-        {
33-            uint32_t time;
34-        } frame;
35-
36-        struct
37-        {
38-            uint32_t left, entered;
39-        } screens_changed;
40-    };
41-};
42-
43 /**
44  * A view represents a component that can display buffers to the user.
45  *
46@@ -79,14 +41,20 @@ struct view_event_data
47 struct view
48 {
49     const struct view_impl * impl;
50+    struct wl_list handlers;
51 
52-    struct wl_signal event_signal;
53     struct swc_rectangle geometry;
54     uint32_t screens;
55 
56     struct wld_buffer * buffer;
57 };
58 
59+struct view_handler
60+{
61+    const struct view_handler_impl * impl;
62+    struct wl_list link;
63+};
64+
65 /**
66  * Every view must have an implementation containing these functions.
67  *
68@@ -99,6 +67,19 @@ struct view_impl
69     bool (* move)(struct view * view, int32_t x, int32_t y);
70 };
71 
72+struct view_handler_impl
73+{
74+    /* Called when the view has displayed the next frame. */
75+    void (* frame)(struct view_handler * handler, uint32_t time);
76+    /* Called after the view's position changes. */
77+    void (* move)(struct view_handler * handler);
78+    /* Called after the view's size changes. */
79+    void (* resize)(struct view_handler * handler);
80+    /* Called when the set of screens the view is visible on changes. */
81+    void (* screens)(struct view_handler * handler,
82+                     uint32_t left, uint32_t entered);
83+};
84+
85 /**
86  * Attach a new buffer to the view.
87  *