4 #include <wayland-server.h>
5 #include <tizen-extension-server-protocol.h>
9 #include "libds-tizen/renderer.h"
11 #define TIZEN_RENDERER_VERSION 1
13 struct ds_tizen_renderer
15 struct wl_global *global;
17 struct wl_list clients;
19 struct wl_listener destroy;
22 struct wl_signal destroy;
23 struct wl_signal get_renderer_surface;
27 struct ds_tizen_renderer_client
29 struct ds_tizen_renderer *renderer;
31 struct wl_resource *resource;
32 struct wl_client *wl_client;
37 struct wl_signal destroy;
40 struct wl_list link; // ds_tizen_renderer::clients
43 struct ds_tizen_renderer_info
45 struct ds_tizen_renderer_client *client;
47 struct wl_resource *resource;
49 struct ds_surface *surface;
51 struct wl_list link; // ds_tizen_renderer_client::infos
54 static void renderer_handle_display_destroy(struct wl_listener *listener,
57 static void renderer_bind(struct wl_client *wl_client, void *data,
58 uint32_t version, uint32_t id);
60 static struct ds_tizen_renderer_info *tizen_renderer_client_find_info(
61 struct ds_tizen_renderer_client *client,
62 struct ds_surface *surface);
64 static struct ds_tizen_renderer_info *tizen_renderer_client_get_info(
65 struct ds_tizen_renderer_client *client,
66 struct ds_surface *surface);
68 WL_EXPORT struct ds_tizen_renderer *
69 ds_tizen_renderer_create(struct wl_display *display)
71 struct ds_tizen_renderer *renderer;
73 renderer = calloc(1, sizeof *renderer);
75 ds_err("calloc() failed.");
79 renderer->global = wl_global_create(display, &tizen_renderer_interface,
80 TIZEN_RENDERER_VERSION, renderer, renderer_bind);
81 if (!renderer->global) {
82 ds_err("wl_global_create() failed. tizen_renderer_interface");
87 wl_list_init(&renderer->clients);
89 renderer->destroy.notify = renderer_handle_display_destroy;
90 wl_display_add_destroy_listener(display, &renderer->destroy);
92 wl_signal_init(&renderer->events.destroy);
93 wl_signal_init(&renderer->events.get_renderer_surface);
95 ds_inf("Global created: tizen_renderer(%p)", renderer);
101 ds_tizen_renderer_add_destroy_listener(
102 struct ds_tizen_renderer *renderer,
103 struct wl_listener *listener)
105 wl_signal_add(&renderer->events.destroy, listener);
109 ds_tizen_renderer_add_get_renderer_surface_info_listener(
110 struct ds_tizen_renderer *renderer,
111 struct wl_listener *listener)
113 wl_signal_add(&renderer->events.get_renderer_surface, listener);
117 ds_tizen_renderer_info_add_destroy_listener(
118 struct ds_tizen_renderer_info *info,
119 struct wl_listener *listener)
121 wl_signal_add(&info->client->events.destroy, listener);
124 WL_EXPORT struct ds_surface *
125 ds_tizen_renderer_info_get_surface(
126 struct ds_tizen_renderer_info *info)
128 return info->surface;
132 ds_tizen_renderer_info_send_redraw(
133 struct ds_tizen_renderer_info *info)
135 tizen_renderer_surface_send_redraw_request(info->resource);
138 static struct ds_tizen_renderer_info *
139 tizen_renderer_client_find_info(struct ds_tizen_renderer_client *client,
140 struct ds_surface *surface)
142 struct ds_tizen_renderer_info *info;
144 wl_list_for_each(info, &client->infos, link) {
145 if (surface == info->surface)
152 static struct ds_tizen_renderer_info *
153 tizen_renderer_client_get_info(struct ds_tizen_renderer_client *client,
154 struct ds_surface *surface)
156 struct ds_tizen_renderer_info *info;
158 info = tizen_renderer_client_find_info(client, surface);
162 info = calloc(1, sizeof *info);
164 ds_err("calloc() failed. tizen_renderer");
168 info->client = client;
169 info->surface = surface;
171 wl_list_insert(&client->infos, &info->link);
177 renderer_handle_display_destroy(struct wl_listener *listener, void *data)
179 struct ds_tizen_renderer *renderer;
181 renderer = wl_container_of(listener, renderer, destroy);
183 ds_inf("Global destroy: renderer(%p)", renderer);
185 wl_signal_emit(&renderer->events.destroy, renderer);
186 wl_list_remove(&renderer->destroy.link);
187 wl_global_destroy(renderer->global);
192 renderer_surface_handle_destroy(struct wl_client *wl_client,
193 struct wl_resource *resource)
195 wl_resource_destroy(resource);
198 static const struct tizen_renderer_surface_interface renderer_surface_impl =
200 renderer_surface_handle_destroy,
204 _tizen_renderer_info_handle_destroy(struct wl_resource *resource)
206 struct ds_tizen_renderer_info *info;
208 info = wl_resource_get_user_data(resource);
210 ds_inf("_tizen_renderer_info_handle_destroy (info:%p)", info);
212 wl_signal_emit(&info->client->events.destroy, info);
213 wl_list_remove(&info->link);
218 renderer_handle_get_renderer_surface(struct wl_client *wl_client,
219 struct wl_resource *resource,uint32_t id,
220 struct wl_resource *surface_resource)
222 struct ds_tizen_renderer_client *client;
223 struct ds_tizen_renderer_info *info;
224 struct ds_surface *surface;
226 ds_inf("tizen_renderer: get_renderer_surface");
228 client = wl_resource_get_user_data(resource);
229 surface = ds_surface_from_resource(surface_resource);
231 info = tizen_renderer_client_get_info(client, surface);
233 ds_err("tizen_renderer_client_get_info() failed.");
234 wl_client_post_no_memory(wl_client);
238 info->resource = wl_resource_create(wl_client,
239 &tizen_renderer_surface_interface, wl_resource_get_version(resource),
241 if (info->resource == NULL) {
242 ds_err("tizen_renderer : wl_resource_create() failed.");
243 wl_list_remove(&info->link);
245 wl_client_post_no_memory(wl_client);
249 wl_resource_set_implementation(info->resource, &renderer_surface_impl, info,
250 _tizen_renderer_info_handle_destroy);
252 wl_signal_emit(&client->renderer->events.get_renderer_surface, info);
256 renderer_handle_destroy(struct wl_client *wl_client,
257 struct wl_resource *resource)
259 struct ds_tizen_renderer_client *client;
261 client = wl_resource_get_user_data(resource);
263 if (!wl_list_empty(&client->infos)) {
264 ds_err("tizen_renderer was destroyed before children");
268 wl_resource_destroy(resource);
271 static const struct tizen_renderer_interface renderer_impl =
273 renderer_handle_get_renderer_surface,
274 renderer_handle_destroy,
278 _tizen_renderer_client_handle_destroy(struct wl_resource *resource)
280 struct ds_tizen_renderer_client *client;
281 struct ds_tizen_renderer_info *info, *tmp;
283 client = wl_resource_get_user_data(resource);
285 ds_inf("_tizen_renderer_client_handle_destroy (client:%p)", client);
287 wl_list_for_each_safe(info, tmp, &client->infos, link) {
288 wl_signal_emit(&client->events.destroy, info);
289 wl_list_remove(&info->link);
293 wl_list_remove(&client->link);
298 renderer_bind(struct wl_client *wl_client, void *data, uint32_t version,
301 struct ds_tizen_renderer *renderer = data;
302 struct ds_tizen_renderer_client *client;
304 client = calloc(1, sizeof *client);
305 if (client == NULL) {
306 ds_err("calloc() failed. tizen_renderer");
307 wl_client_post_no_memory(wl_client);
311 ds_inf("tizen_renderer_client binds. (client:%p)", client);
313 client->renderer = renderer;
314 client->wl_client = wl_client;
316 wl_list_init(&client->infos);
318 client->resource = wl_resource_create(wl_client, &tizen_renderer_interface,
319 MIN(version, TIZEN_RENDERER_VERSION), id);
321 if (client->resource == NULL) {
322 ds_err("tizen_renderer : wl_resource_create() failed.");
324 wl_client_post_no_memory(wl_client);
328 wl_resource_set_implementation(client->resource, &renderer_impl, client,
329 _tizen_renderer_client_handle_destroy);
331 wl_signal_init(&client->events.destroy);
333 wl_list_insert(&renderer->clients, &client->link);