subcompositor: Split out from compositor
[platform/core/uifw/libds.git] / src / compositor / compositor.c
1 #include "region.h"
2 #include "compositor_private.h"
3
4 #define COMPOSITOR_VERSION 4
5
6 struct ds_compositor
7 {
8     struct wl_global *global;
9
10     struct {
11         struct wl_signal new_surface;
12         struct wl_signal destroy;
13     } events;
14
15     struct wl_listener display_destroy;
16 };
17
18 static void compositor_bind(struct wl_client *client, void *data,
19         uint32_t version, uint32_t id);
20 static void compositor_handle_display_destroy(struct wl_listener *listener, 
21         void *data);
22
23 WL_EXPORT struct ds_compositor *
24 ds_compositor_create(struct wl_display *display)
25 {
26     struct ds_compositor *compositor;
27
28     compositor = calloc(1, sizeof *compositor);
29     if (!compositor) {
30         ds_log_errno(DS_ERR, "Could not allocate memory");
31         return NULL;
32     }
33
34     compositor->global = wl_global_create(display, &wl_compositor_interface,
35             COMPOSITOR_VERSION, compositor, compositor_bind);
36     if (!compositor->global) {
37         ds_log_errno(DS_ERR, "Could not create global");
38         free(compositor);
39         return NULL;
40     }
41
42     wl_signal_init(&compositor->events.new_surface);
43     wl_signal_init(&compositor->events.destroy);
44
45     compositor->display_destroy.notify = compositor_handle_display_destroy;
46     wl_display_add_destroy_listener(display, &compositor->display_destroy);
47
48     ds_inf("Compositor(%p) created", compositor);
49
50     return compositor;
51 }
52
53 WL_EXPORT void
54 ds_compositor_add_new_surface_listener(struct ds_compositor *compositor,
55         struct wl_listener *listener)
56 {
57     wl_signal_add(&compositor->events.new_surface, listener);
58 }
59
60 WL_EXPORT void
61 ds_compositor_add_destroy_listener(struct ds_compositor *compositor,
62         struct wl_listener *listener)
63 {
64     wl_signal_add(&compositor->events.destroy, listener);
65 }
66
67 static void
68 compositor_handle_create_surface(struct wl_client *client,
69         struct wl_resource *resource, uint32_t id)
70 {
71     struct ds_compositor *compositor;
72     struct ds_surface *surface;
73
74     compositor = wl_resource_get_user_data(resource);
75     surface = create_surface(client, wl_resource_get_version(resource), id);
76     if (!surface) {
77         ds_err("Could not create ds_surface");
78         return;
79     }
80
81     wl_signal_emit_mutable(&compositor->events.new_surface, surface);
82 }
83
84 static void
85 compositor_handle_create_region(struct wl_client *client,
86         struct wl_resource *resource, uint32_t id)
87 {
88     ds_region_add(client, wl_resource_get_version(resource), id);
89 }
90
91 static const struct wl_compositor_interface compositor_impl =
92 {
93     .create_surface = compositor_handle_create_surface,
94     .create_region = compositor_handle_create_region,
95 };
96
97 static void compositor_bind(struct wl_client *client, void *data,
98         uint32_t version, uint32_t id)
99 {
100     struct ds_compositor *compositor = data;
101     struct wl_resource *resource;
102
103     resource = wl_resource_create(client, &wl_compositor_interface,
104             DS_MIN((int)version, COMPOSITOR_VERSION), id);
105     if (resource == NULL) {
106         wl_client_post_no_memory(client);
107         return;
108     }
109
110     wl_resource_set_implementation(resource, &compositor_impl,
111             compositor, NULL);
112 }
113
114 static void
115 compositor_handle_display_destroy(struct wl_listener *listener, void *data)
116 {
117     struct ds_compositor *compositor;
118     
119     compositor = wl_container_of(listener, compositor, display_destroy);
120
121     ds_dbg("Destroy compositor(%p)", compositor);
122
123     wl_signal_emit_mutable(&compositor->events.destroy, compositor);
124
125     wl_list_remove(&compositor->display_destroy.link);
126     free(compositor);
127 }