4 #include <wayland-server.h>
5 #include <tizen-surface-server-protocol.h>
6 #include <wtz-blur-server-protocol.h>
8 #include <libds/region.h>
9 #include <libds/util/addon.h>
10 #include <libds/types/ds_surface.h>
14 #include "libds-tizen/blur.h"
16 #define TIZEN_BLUR_VERSION 1
18 struct ds_tizen_blur_manager
20 struct wl_global *global;
22 struct wl_list clients;
24 struct wl_listener destroy;
27 struct wl_signal destroy;
28 struct wl_signal new_blur;
32 struct ds_tizen_blur_client
34 struct wl_list link; //clients
36 struct ds_tizen_blur_manager *blur_manager;
38 struct wl_resource *resource;
39 struct wl_client *wl_client;
42 struct wl_signal destroy;
48 struct wl_resource *resource;
49 struct wl_client *wl_client;
51 struct ds_tizen_blur_state current, pending;
53 struct ds_surface *surface;
54 struct ds_addon surface_addon;
57 struct wl_listener surface_commit;
61 struct wl_signal commit;
62 struct wl_signal destroy;
67 blur_manager_handle_display_destroy(struct wl_listener *listener, void *data);
69 blur_manager_bind(struct wl_client *wl_client, void *data, uint32_t version,
72 WL_EXPORT struct ds_tizen_blur_manager *
73 ds_tizen_blur_manager_create(struct wl_display *display)
75 struct ds_tizen_blur_manager *blur_manager;
77 blur_manager = calloc(1, sizeof *blur_manager);
79 ds_err("calloc() failed.");
83 blur_manager->global = wl_global_create(display, &wtz_blur_manager_interface,
84 TIZEN_BLUR_VERSION, blur_manager, blur_manager_bind);
85 if (!blur_manager->global) {
86 ds_err("wl_global_create() failed. tizen_surface_shm_interface");
91 wl_list_init(&blur_manager->clients);
93 blur_manager->destroy.notify = blur_manager_handle_display_destroy;
94 wl_display_add_destroy_listener(display, &blur_manager->destroy);
96 wl_signal_init(&blur_manager->events.destroy);
97 wl_signal_init(&blur_manager->events.new_blur);
99 ds_inf("Global created: tizen_blur_manager(%p)", blur_manager);
105 ds_tizen_blur_manager_add_destroy_listener(struct ds_tizen_blur_manager *blur,
106 struct wl_listener *listener)
108 wl_signal_add(&blur->events.destroy, listener);
112 ds_tizen_blur_manager_add_new_blur_listener(struct ds_tizen_blur_manager *blur,
113 struct wl_listener *listener)
115 wl_signal_add(&blur->events.new_blur, listener);
119 ds_tizen_blur_add_destroy_listener(struct ds_tizen_blur *blur,
120 struct wl_listener *listener)
122 wl_signal_add(&blur->events.destroy, listener);
126 ds_tizen_blur_add_commit_listener(struct ds_tizen_blur *blur,
127 struct wl_listener *listener)
129 wl_signal_add(&blur->events.commit, listener);
132 WL_EXPORT struct ds_surface *
133 ds_tizen_blur_get_surface(struct ds_tizen_blur *blur)
135 return blur->surface;
138 WL_EXPORT struct ds_tizen_blur_state *
139 ds_tizen_blur_get_state(struct ds_tizen_blur *blur)
141 return &blur->current;
145 blur_manager_handle_display_destroy(struct wl_listener *listener, void *data)
147 struct ds_tizen_blur_manager *blur_manager;
149 blur_manager = wl_container_of(listener, blur_manager, destroy);
151 ds_inf("Global destroy: blur_manager(%p)", blur_manager);
153 wl_signal_emit_mutable(&blur_manager->events.destroy, blur_manager);
154 wl_list_remove(&blur_manager->destroy.link);
155 wl_global_destroy(blur_manager->global);
160 blur_handle_destroy(struct wl_client *client, struct wl_resource *resource)
162 wl_resource_destroy(resource);
166 blur_handle_set_region(struct wl_client *client, struct wl_resource *resource,
167 struct wl_resource *region_resource)
169 struct ds_tizen_blur *blur;
170 pixman_region32_t *region;
172 blur = wl_resource_get_user_data(resource);
173 region = ds_region_from_resource(region_resource);
176 pixman_region32_copy(&blur->pending.region, region);
178 pixman_region32_fini(&blur->pending.region);
179 pixman_region32_init_rect(&blur->pending.region, INT32_MIN, INT32_MIN, UINT32_MAX, UINT32_MAX);
182 blur->pending.committed |= DS_TIZEN_BLUR_STATE_REGION;
186 blur_handle_set_radius(struct wl_client *client, struct wl_resource *resource,
189 struct ds_tizen_blur *blur;
191 blur = wl_resource_get_user_data(resource);
193 blur->pending.radius = radius;
194 blur->pending.committed |= DS_TIZEN_BLUR_STATE_RADIUS;
197 static const struct wtz_blur_interface blur_impl = {
199 blur_handle_set_region,
200 blur_handle_set_radius,
204 blur_destroy(struct ds_tizen_blur *blur)
206 ds_inf("blur_destroy (blur:%p)", blur);
208 wl_signal_emit_mutable(&blur->events.destroy, blur);
210 if (blur->listener.surface_commit.notify)
211 wl_list_remove(&blur->listener.surface_commit.link);
214 ds_addon_finish(&blur->surface_addon);
216 pixman_region32_fini(&blur->pending.region);
217 pixman_region32_fini(&blur->current.region);
222 blur_handle_resource_destroy(struct wl_resource *resource)
224 struct ds_tizen_blur *blur;
226 blur = wl_resource_get_user_data(resource);
228 ds_inf("blur_handle_resource_destroy (blur:%p)", blur);
231 blur->resource = NULL;
239 blur_handle_surface_commit(struct wl_listener *listener, void *data)
241 struct ds_tizen_blur *blur;
243 blur = wl_container_of(listener, blur, listener.surface_commit);
245 if (!blur->resource) {
250 if (blur->pending.committed == DS_TIZEN_BLUR_STATE_NONE)
253 if (blur->pending.committed & DS_TIZEN_BLUR_STATE_REGION)
254 pixman_region32_copy(&blur->current.region, &blur->pending.region);
256 if (blur->pending.committed & DS_TIZEN_BLUR_STATE_RADIUS)
257 blur->current.radius = blur->pending.radius;
259 blur->current.committed = blur->pending.committed;
260 blur->pending.committed = DS_TIZEN_BLUR_STATE_NONE;
262 wl_signal_emit_mutable(&blur->events.commit, blur);
266 blur_handle_surface_destroy(struct ds_addon *addon)
268 struct ds_tizen_blur *blur;
270 blur = wl_container_of(addon, blur, surface_addon);
272 if (blur->listener.surface_commit.notify) {
273 wl_list_remove(&blur->listener.surface_commit.link);
274 blur->listener.surface_commit.notify = NULL;
277 ds_addon_finish(&blur->surface_addon);
278 blur->surface = NULL;
284 static struct ds_addon_interface blur_addon_impl = {
285 .name = "ds_tizen_blur",
286 .destroy = blur_handle_surface_destroy,
289 static struct ds_tizen_blur *
290 blur_client_get_from_surface(struct ds_tizen_blur_client *client, struct ds_surface *surface)
292 struct ds_addon *addon;
293 struct ds_tizen_blur *blur;
295 addon = ds_addon_find(&surface->addons, client, &blur_addon_impl);
296 if (!addon) return NULL;
298 blur = wl_container_of(addon, blur, surface_addon);
304 blur_manager_handle_get_blur(struct wl_client *wl_client,
305 struct wl_resource *resource,
306 uint32_t id, struct wl_resource *surface_resource)
308 struct ds_tizen_blur_client *client;
309 struct ds_surface *surface;
310 struct ds_tizen_blur *blur;
312 ds_inf("tizen_blur: get_blur");
314 client = wl_resource_get_user_data(resource);
316 surface = ds_surface_from_resource(surface_resource);
318 wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
319 "invalid wl_surface resource:%u",
320 (unsigned int)wl_resource_get_id(surface_resource));
324 blur = blur_client_get_from_surface(client, surface);
326 wl_resource_post_error(resource, WTZ_BLUR_MANAGER_ERROR_BLUR_EXISTS,
327 "blend object already exists");
331 blur = calloc(1, sizeof *blur);
333 ds_err("calloc() failed. tizen_blur");
334 wl_client_post_no_memory(wl_client);
338 blur->resource = wl_resource_create(wl_client, &wtz_blur_interface,
339 wl_resource_get_version(resource), id);
340 if (blur->resource == NULL) {
341 ds_err("tizen_blur : wl_resource_create() failed.");
343 wl_client_post_no_memory(wl_client);
347 pixman_region32_init_rect(&blur->pending.region, INT32_MIN, INT32_MIN, UINT32_MAX, UINT32_MAX);
348 pixman_region32_init_rect(&blur->current.region, INT32_MIN, INT32_MIN, UINT32_MAX, UINT32_MAX);
350 wl_resource_set_implementation(blur->resource, &blur_impl, blur,
351 blur_handle_resource_destroy);
353 ds_addon_init(&blur->surface_addon, &surface->addons, client, &blur_addon_impl);
355 blur->listener.surface_commit.notify = blur_handle_surface_commit;
356 ds_surface_add_commit_listener(surface, &blur->listener.surface_commit);
358 blur->surface = surface;
360 wl_signal_init(&blur->events.destroy);
361 wl_signal_init(&blur->events.commit);
363 wl_signal_emit_mutable(&client->blur_manager->events.new_blur, blur);
367 blur_manager_handle_destroy(struct wl_client *wl_client,
368 struct wl_resource *resource)
370 wl_resource_destroy(resource);
373 static const struct wtz_blur_manager_interface blur_manager_impl =
375 blur_manager_handle_destroy,
376 blur_manager_handle_get_blur,
380 blur_manager_client_handle_destroy(struct wl_resource *resource)
382 struct ds_tizen_blur_client *client;
384 client = wl_resource_get_user_data(resource);
386 ds_inf("blur_manager_client_handle_destroy (client:%p)", client);
388 wl_list_remove(&client->link);
393 blur_manager_bind(struct wl_client *wl_client, void *data, uint32_t version,
396 struct ds_tizen_blur_manager *blur_manager = data;
397 struct ds_tizen_blur_client *client;
399 client = calloc(1, sizeof *client);
400 if (client == NULL) {
401 ds_err("calloc() failed. tizen_blur");
402 wl_client_post_no_memory(wl_client);
406 ds_inf("tizen_blur_client binds. (client:%p)", client);
408 client->blur_manager = blur_manager;
409 client->wl_client = wl_client;
411 client->resource = wl_resource_create(wl_client, &wtz_blur_manager_interface,
412 MIN(version, TIZEN_BLUR_VERSION), id);
413 if (client->resource == NULL) {
414 ds_err("tizen_blur : wl_resource_create() failed.");
416 wl_client_post_no_memory(wl_client);
420 wl_resource_set_implementation(client->resource, &blur_manager_impl, client,
421 blur_manager_client_handle_destroy);
423 wl_signal_init(&client->events.destroy);
425 wl_list_insert(&blur_manager->clients, &client->link);