4 #include <wayland-server.h>
5 #include <tizen-extension-server-protocol.h>
9 #include "libds-tizen/global_resource.h"
11 #define TIZEN_SURFACE_VERSION 1
13 static uint32_t unique_id = 0;
15 struct ds_tizen_global_resource
17 struct wl_global *global;
19 struct wl_list clients;
21 struct wl_listener destroy;
24 struct wl_signal destroy;
25 struct wl_signal get_resource_info;
29 struct ds_tizen_global_resource_client
31 struct ds_tizen_global_resource *global_resource;
33 struct wl_resource *resource;
34 struct wl_client *wl_client;
39 struct wl_signal destroy;
42 struct wl_list link; // ds_tizen_global_resource::clients
45 struct ds_tizen_global_resource_info
47 struct ds_tizen_global_resource_client *client;
49 struct wl_resource *resource;
51 struct ds_surface *surface;
53 uint32_t universal_id;
55 struct wl_list link; // ds_tizen_global_resource_client::infos
58 static void resource_handle_display_destroy(struct wl_listener *listener,
61 static void resource_bind(struct wl_client *wl_client, void *data,
62 uint32_t version, uint32_t id);
64 static struct ds_tizen_global_resource_info *tizen_global_resource_client_find_info(
65 struct ds_tizen_global_resource_client *client,
66 struct ds_surface *surface);
68 static struct ds_tizen_global_resource_info *tizen_global_resource_client_get_info(
69 struct ds_tizen_global_resource_client *client,
70 struct ds_surface *surface);
72 WL_EXPORT struct ds_tizen_global_resource *
73 ds_tizen_global_resource_create(struct wl_display *display)
75 struct ds_tizen_global_resource *global_resource;
77 global_resource = calloc(1, sizeof *global_resource);
78 if (!global_resource) {
79 ds_err("calloc() failed.");
83 global_resource->global = wl_global_create(display, &tizen_surface_interface,
84 TIZEN_SURFACE_VERSION, global_resource, resource_bind);
85 if (!global_resource->global) {
86 ds_err("wl_global_create() failed. tizen_resource_interface");
87 free(global_resource);
91 wl_list_init(&global_resource->clients);
93 global_resource->destroy.notify = resource_handle_display_destroy;
94 wl_display_add_destroy_listener(display, &global_resource->destroy);
96 wl_signal_init(&global_resource->events.destroy);
97 wl_signal_init(&global_resource->events.get_resource_info);
99 ds_inf("Global created: tizen_global_resource(%p)", global_resource);
101 return global_resource;
105 ds_tizen_global_resource_add_destroy_listener(
106 struct ds_tizen_global_resource *global_resource,
107 struct wl_listener *listener)
109 wl_signal_add(&global_resource->events.destroy, listener);
113 ds_tizen_global_resource_add_get_resource_info_listener(
114 struct ds_tizen_global_resource *global_resource,
115 struct wl_listener *listener)
117 wl_signal_add(&global_resource->events.get_resource_info, listener);
121 ds_tizen_global_resource_info_add_destroy_listener(
122 struct ds_tizen_global_resource_info *info,
123 struct wl_listener *listener)
125 wl_signal_add(&info->client->events.destroy, listener);
128 WL_EXPORT struct ds_surface *
129 ds_tizen_global_resource_info_get_surface(
130 struct ds_tizen_global_resource_info *info)
132 return info->surface;
136 ds_tizen_global_resource_get_universal_id(
137 struct ds_tizen_global_resource_info *info)
139 return info->universal_id;
142 static struct ds_tizen_global_resource_info *
143 tizen_global_resource_client_find_info(
144 struct ds_tizen_global_resource_client *client,
145 struct ds_surface *surface)
147 struct ds_tizen_global_resource_info *info;
149 wl_list_for_each(info, &client->infos, link) {
150 if (surface == info->surface)
157 static struct ds_tizen_global_resource_info *
158 tizen_global_resource_client_get_info(
159 struct ds_tizen_global_resource_client *client,
160 struct ds_surface *surface)
162 struct ds_tizen_global_resource_info *info;
164 info = tizen_global_resource_client_find_info(client, surface);
168 info = calloc(1, sizeof *info);
170 ds_err("calloc() failed. tizen_global_resource");
174 info->client = client;
175 info->surface = surface;
177 wl_list_insert(&client->infos, &info->link);
183 resource_handle_display_destroy(struct wl_listener *listener, void *data)
185 struct ds_tizen_global_resource *global_resource;
187 global_resource = wl_container_of(listener, global_resource, destroy);
189 ds_inf("Global destroy: resource(%p)", global_resource);
191 wl_signal_emit(&global_resource->events.destroy, global_resource);
192 wl_list_remove(&global_resource->destroy.link);
193 wl_global_destroy(global_resource->global);
194 free(global_resource);
198 resource_handle_destroy(struct wl_client *wl_client,
199 struct wl_resource *resource)
201 wl_resource_destroy(resource);
204 static const struct tizen_resource_interface resource_impl =
206 resource_handle_destroy,
210 _tizen_surface_handle_destroy(struct wl_resource *resource)
212 struct ds_tizen_global_resource_info *info;
214 info = wl_resource_get_user_data(resource);
216 ds_inf("_tizen_surface_handle_destroy (info:%p)", info);
218 wl_signal_emit(&info->client->events.destroy, info);
219 wl_list_remove(&info->link);
224 surface_handle_get_tizen_global_resource(struct wl_client *wl_client,
225 struct wl_resource *resource,uint32_t id,
226 struct wl_resource *surface_resource)
228 struct ds_tizen_global_resource_client *client;
229 struct ds_tizen_global_resource_info *info;
230 struct ds_surface *surface;
232 ds_inf("tizen_global_resource: surface_handle_get_tizen_global_resource");
234 client = wl_resource_get_user_data(resource);
235 surface = ds_surface_from_resource(surface_resource);
237 info = tizen_global_resource_client_get_info(client, surface);
239 ds_err("tizen_global_resource_client_get_info() failed.");
240 wl_client_post_no_memory(wl_client);
244 info->resource = wl_resource_create(wl_client,
245 &tizen_resource_interface, wl_resource_get_version(resource),
247 if (info->resource == NULL) {
248 ds_err("tizen_global_resource : wl_resource_create() failed.");
249 wl_list_remove(&info->link);
251 wl_client_post_no_memory(wl_client);
255 // generate the univeral_id;
256 info->universal_id = unique_id++;
258 wl_resource_set_implementation(info->resource, &resource_impl, info,
259 _tizen_surface_handle_destroy);
261 wl_signal_emit(&client->global_resource->events.get_resource_info, info);
263 tizen_resource_send_resource_id(info->resource, info->universal_id);
267 surface_handle_destroy(struct wl_client *wl_client,
268 struct wl_resource *resource)
270 struct ds_tizen_global_resource_client *client;
272 client = wl_resource_get_user_data(resource);
274 if (!wl_list_empty(&client->infos)) {
275 ds_err("tizen_global_resource was destroyed before children");
279 wl_resource_destroy(resource);
282 static const struct tizen_surface_interface surface_impl =
284 surface_handle_get_tizen_global_resource,
285 surface_handle_destroy,
289 _tizen_global_resource_client_handle_destroy(struct wl_resource *resource)
291 struct ds_tizen_global_resource_client *client;
292 struct ds_tizen_global_resource_info *info, *tmp;
294 client = wl_resource_get_user_data(resource);
296 ds_inf("_tizen_global_resource_client_handle_destroy (client:%p)", client);
298 wl_list_for_each_safe(info, tmp, &client->infos, link) {
299 wl_signal_emit(&info->client->events.destroy, info);
300 wl_list_remove(&info->link);
304 wl_list_remove(&client->link);
309 resource_bind(struct wl_client *wl_client, void *data, uint32_t version,
312 struct ds_tizen_global_resource *global_resource = data;
313 struct ds_tizen_global_resource_client *client;
315 client = calloc(1, sizeof *client);
316 if (client == NULL) {
317 ds_err("calloc() failed. tizen_global_resource");
318 wl_client_post_no_memory(wl_client);
322 ds_inf("tizen_global_resource_client binds. (client:%p)", client);
324 client->global_resource = global_resource;
325 client->wl_client = wl_client;
327 wl_list_init(&client->infos);
329 client->resource = wl_resource_create(wl_client, &tizen_surface_interface,
330 MIN(version, TIZEN_SURFACE_VERSION), id);
332 if (client->resource == NULL) {
333 ds_err("tizen_global_resource : wl_resource_create() failed.");
335 wl_client_post_no_memory(wl_client);
339 wl_resource_set_implementation(client->resource, &surface_impl, client,
340 _tizen_global_resource_client_handle_destroy);
342 wl_signal_init(&client->events.destroy);
344 wl_list_insert(&global_resource->clients, &client->link);