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