launch: merge header files in one (launch.h)
[platform/core/uifw/libds-tizen.git] / src / launch / effect.c
1 #include <stdlib.h>
2 #include <wayland-server.h>
3 #include <tizen-launch-server-protocol.h>
4 #include <libds/log.h>
5
6 #include "util.h"
7 #include <libds-tizen/launch.h>
8
9 #define TIZEN_EFFECT_VERSION 1
10 #define SPLASH_CLIENT_PID 321 // no meaning
11 #define CUSTOM_EFFECT_CALLEE "_CUSTOM_EFFECT_CALLEE_"
12
13 struct ds_tizen_launch_effect
14 {
15     struct wl_global *global;
16
17     struct wl_list clients;
18     struct wl_list infos;
19
20     struct wl_listener destroy;
21
22     struct {
23         struct wl_signal destroy;
24         struct wl_signal type_set;
25         struct wl_signal type_unset;
26         struct wl_signal new_splash;
27     } events;
28 };
29
30 struct ds_tizen_launch_effect_client
31 {
32     struct ds_tizen_launch_effect *effect;
33
34     struct wl_resource *resource;
35     struct wl_client *wl_client;
36
37     struct wl_list splashs;
38
39     struct wl_list link; // ds_tizen_launch_effect::clients
40 };
41
42 struct ds_tizen_launch_effect_info
43 {
44     uint32_t pid;
45     int effect_type;
46
47     struct wl_list link; // ds_tizen_launch_effect::infos
48 };
49
50 struct ds_tizen_launch_splash
51 {
52     struct ds_tizen_launch_effect *effect;
53
54     struct ds_tizen_launch_effect_client *client;
55     struct wl_resource *resource;
56
57     uint32_t pid;
58     char *appid;
59     bool custom_effect_callee;
60
61     struct {
62         struct wl_signal destroy;
63         struct wl_signal owner;
64     } events;
65
66     struct wl_list link; // ds_tizen_launch_effect_client::splashs
67 };
68
69 static void effect_handle_display_destroy(struct wl_listener *listener,
70         void *data);
71
72 static void effect_bind(struct wl_client *wl_client, void *data,
73         uint32_t version, uint32_t id);
74
75 WL_EXPORT struct ds_tizen_launch_effect *
76 ds_tizen_launch_effect_create(struct wl_display *display)
77 {
78     struct ds_tizen_launch_effect *effect;
79
80     effect = calloc(1, sizeof *effect);
81     if (!effect) {
82         ds_err("calloc() failed.");
83         return NULL;
84     }
85
86     effect->global = wl_global_create(display, &tizen_launch_effect_interface,
87             TIZEN_EFFECT_VERSION, effect, effect_bind);
88     if (!effect->global) {
89         ds_err("wl_global_create() failed. tizen_launch_effect_interface");
90         free(effect);
91         return NULL;
92     }
93
94     wl_list_init(&effect->clients);
95     wl_list_init(&effect->infos);
96
97     effect->destroy.notify = effect_handle_display_destroy;
98     wl_display_add_destroy_listener(display, &effect->destroy);
99
100     wl_signal_init(&effect->events.destroy);
101     wl_signal_init(&effect->events.type_set);
102     wl_signal_init(&effect->events.type_unset);
103     wl_signal_init(&effect->events.new_splash);
104
105     ds_inf("Global create: tizen_launch_effect. effect(%p)", effect);
106
107     return effect;
108 }
109
110 //launch_effect
111 WL_EXPORT void
112 ds_tizen_launch_effect_add_destroy_listener(
113     struct ds_tizen_launch_effect *effect, struct wl_listener *listener)
114 {
115     wl_signal_add(&effect->events.destroy, listener);
116 }
117
118 WL_EXPORT void
119 ds_tizen_launch_effect_add_type_set_listener(
120     struct ds_tizen_launch_effect *effect, struct wl_listener *listener)
121 {
122     wl_signal_add(&effect->events.type_set, listener);
123 }
124
125 WL_EXPORT void
126 ds_tizen_launch_effect_add_type_unset_listener(
127     struct ds_tizen_launch_effect *effect, struct wl_listener *listener)
128 {
129     wl_signal_add(&effect->events.type_unset, listener);
130 }
131
132 WL_EXPORT void
133 ds_tizen_launch_effect_add_new_splash_listener(
134     struct ds_tizen_launch_effect *effect, struct wl_listener *listener)
135 {
136     wl_signal_add(&effect->events.new_splash, listener);
137 }
138
139 WL_EXPORT void
140 ds_tizen_launch_effect_set_effect_type(struct ds_tizen_launch_effect *effect,
141     uint32_t pid, int effect_type)
142 {
143     struct ds_tizen_launch_effect_info *info;
144
145     ds_inf("ds_tizen_launch_effect_set_effect_type() pid(%u), effect_type(%d)", pid, effect_type);
146
147     info = calloc(1, sizeof *info);
148     if (info == NULL) {
149         ds_err("calloc() failed. tizen_effect_info");
150         return;
151     }
152     info->pid = pid;
153     info->effect_type = effect_type;
154
155     wl_list_insert(&effect->infos, &info->link);
156 }
157
158 WL_EXPORT void
159 ds_tizen_launch_effect_unset_effect_type(struct ds_tizen_launch_effect *effect,
160     uint32_t pid)
161 {
162     struct ds_tizen_launch_effect_info *info, *tmp;
163
164     ds_inf("ds_tizen_launch_effect_unset_effect_type() pid(%u)", pid);
165
166     wl_list_for_each_safe(info, tmp, &effect->infos, link) {
167         if (info->pid == pid) {
168             ds_inf("ds_tizen_launch_effect_unset_effect_type() pid found.", pid);
169             wl_list_remove(&info->link);
170             free(info);
171         }
172     }
173 }
174
175 WL_EXPORT int
176 ds_tizen_launch_effect_get_effect_type(struct ds_tizen_launch_effect *effect,
177     uint32_t pid)
178 {
179     struct ds_tizen_launch_effect_info *info;
180
181     ds_inf("ds_tizen_launch_effect_get_effect_type() pid(%u)", pid);
182
183     wl_list_for_each(info, &effect->infos, link) {
184         if (info->pid == pid) {
185             return info->effect_type;
186         }
187     }
188     return -1;
189 }
190
191 //launch_splash
192 WL_EXPORT void
193 ds_tizen_launch_splash_add_destroy_listener(
194     struct ds_tizen_launch_splash *splash, struct wl_listener *listener)
195 {
196     wl_signal_add(&splash->events.destroy, listener);
197 }
198
199 WL_EXPORT void
200 ds_tizen_launch_splash_add_owner_listener(
201     struct ds_tizen_launch_splash *splash, struct wl_listener *listener)
202 {
203     wl_signal_add(&splash->events.owner, listener);
204 }
205
206 WL_EXPORT uint32_t
207 ds_tizen_launch_splash_get_pid(struct ds_tizen_launch_splash *splash)
208 {
209     return splash->pid;
210 }
211
212 WL_EXPORT void
213 ds_tizen_launch_splash_set_pid(struct ds_tizen_launch_splash *splash, uint32_t pid)
214 {
215     splash->pid = pid;
216 }
217
218 static void
219 effect_client_destroy(struct ds_tizen_launch_effect_client *client)
220 {
221     struct ds_tizen_launch_splash *splash, *tmp;
222
223     wl_list_for_each_safe(splash, tmp, &client->splashs, link) {
224         wl_signal_emit(&splash->events.destroy, splash);
225         wl_list_remove(&splash->link);
226         free(splash);
227     }
228
229     wl_list_remove(&client->link);
230     free(client);
231 }
232
233 static void effect_handle_display_destroy(struct wl_listener *listener,
234     void *data)
235 {
236     struct ds_tizen_launch_effect *effect;
237     struct ds_tizen_launch_effect_client *client, *tmp_client;
238     struct ds_tizen_launch_effect_info *info, *tmp_info;
239
240     effect = wl_container_of(listener, effect, destroy);
241
242     ds_inf("Global destroy: effect(%p)", effect);
243
244     wl_signal_emit(&effect->events.destroy, effect);
245     wl_list_remove(&effect->destroy.link);
246
247     wl_list_for_each_safe(client, tmp_client, &effect->clients, link) {
248         effect_client_destroy(client);
249     }
250
251     wl_list_for_each_safe(info, tmp_info, &effect->infos, link) {
252         wl_list_remove(&info->link);
253         free(info);
254     }
255
256     wl_global_destroy(effect->global);
257     free(effect);
258 }
259
260 static int
261 effect_get_effect_type(const char *effect_type)
262 {
263     enum ds_tizen_launch_effect_type type = 0;
264
265     if (!effect_type) return 0;
266
267     if (!strncmp(effect_type, "launch", sizeof("launch"))) type =  DS_TIZEN_LAUNCH_EFFECT_TYPE_LAUNCH;
268     else if (!strncmp(effect_type, "depth-in", sizeof("depth-in"))) type = DS_TIZEN_LAUNCH_EFFECT_TYPE_DEPTH_IN;
269
270     return type;
271 }
272
273 static void
274 splash_handle_destroy(struct wl_client *wl_client, struct wl_resource *resource)
275 {
276     wl_resource_destroy(resource);
277 }
278
279 static void
280 splash_handle_launch(struct wl_client *wl_client,
281     struct wl_resource *resource, const char *pfname, uint32_t ftype,
282     uint32_t depth, uint32_t angle, uint32_t indicator,
283     const char *effect_type, const char *theme_type,
284     struct wl_array *options)
285 {
286     struct ds_tizen_launch_effect_event_type_set ds_event;
287     struct ds_tizen_launch_splash *splash;
288     struct ds_tizen_launch_effect *effect;
289
290     ds_inf("splash launch");
291     ds_inf("path %s(%s), indicator(%d), angle(%d), effect_type(%s)",
292         pfname, (ftype == DS_TIZEN_LAUNCH_SPLASH_FILE_TYPE_IMG) ? "IMG" : "EDC", indicator, angle, effect_type);
293     ds_inf("theme_type(%s), options(%p)",theme_type, options);
294
295     splash = wl_resource_get_user_data(resource);
296     splash->pid = SPLASH_CLIENT_PID;
297     effect = splash->effect;
298     if (effect) {
299         ds_event.pid = SPLASH_CLIENT_PID;
300         ds_event.effect_type = effect_get_effect_type(effect_type);
301
302         ds_inf("Effect type_set. pid:%u type:%s", ds_event.pid, effect_type);
303
304         wl_signal_emit(&effect->events.type_set, &ds_event);
305     }
306 }
307
308 static void
309 splash_handle_owner(struct wl_client *wl_client,
310     struct wl_resource *resource, uint32_t pid)
311 {
312     struct ds_tizen_launch_splash *splash;
313     struct ds_tizen_launch_splash_event_owner ds_event;
314
315     ds_inf("splash set owner. pid:%u", pid);
316
317     splash = wl_resource_get_user_data(resource);
318
319     ds_event.pid = pid;
320     wl_signal_emit(&splash->events.owner, &ds_event);
321 }
322
323 static void
324 splash_handle_launch_v2(struct wl_client *wl_client,
325     struct wl_resource *resource, const char *pfname, uint32_t ftype,
326     uint32_t depth, uint32_t angle, uint32_t indicator,
327     const char *effect_type, const char *theme_type,
328     struct wl_array *options, struct wl_array *extra_config)
329 {
330     struct ds_tizen_launch_effect_event_type_set ds_event;
331     struct ds_tizen_launch_splash *splash;
332     struct ds_tizen_launch_effect *effect;
333
334     ds_inf("splash launch_v2");
335     ds_inf("path %s(%s), indicator(%d), angle(%d), effect_type(%s)",
336         pfname, (ftype == DS_TIZEN_LAUNCH_SPLASH_FILE_TYPE_IMG) ? "IMG" : "EDC", indicator, angle, effect_type);
337     ds_inf("theme_type(%s) options(%p) extra_config(%p)", theme_type, options, extra_config);
338
339     splash = wl_resource_get_user_data(resource);
340     splash->pid = SPLASH_CLIENT_PID;
341     effect = splash->effect;
342     if (effect) {
343         ds_event.pid = SPLASH_CLIENT_PID;
344         ds_event.effect_type = effect_get_effect_type(effect_type);
345
346         ds_inf("Effect type_set. pid:%u type:%s", ds_event.pid, effect_type);
347
348         wl_signal_emit(&effect->events.type_set, &ds_event);
349     }
350
351     //Parse extra config
352     if ((extra_config) && (extra_config->size)) {
353         char *p_char;
354         int len = 0;
355         int size = extra_config->size;
356
357         while (size > 0) {
358             p_char = extra_config->data + len;
359             len = strlen(p_char) + 1;
360             size -= len;
361
362             if (!strcmp(p_char, CUSTOM_EFFECT_CALLEE)) {
363                 //parse next data(appid) from array
364                 if (size > 0) {
365                     p_char = p_char + len;
366                     len = strlen(p_char) + 1;
367                     size -= len;
368
369                     splash->appid = strdup(p_char);
370                     splash->custom_effect_callee = true;
371
372                     ds_inf("custom effect callee set appid(%s)",
373                         splash->appid);
374                     }
375                 else break;
376             }
377         }
378     }
379 }
380
381 static const struct tizen_launch_splash_interface splash_impl =
382 {
383     splash_handle_destroy,
384     splash_handle_launch,
385     splash_handle_owner,
386     splash_handle_launch_v2,
387 };
388
389 static void
390 splash_client_handle_destroy(struct wl_resource *resource)
391 {
392     struct ds_tizen_launch_splash *splash;
393
394     splash = wl_resource_get_user_data(resource);
395
396     ds_inf("splash_client_handle_destroy (client:%p)", splash->client);
397
398     wl_signal_emit(&splash->events.destroy, splash);
399     wl_list_remove(&splash->link);
400     free(splash);
401 }
402
403 struct ds_tizen_launch_splash*
404 splash_create_splash_img(struct ds_tizen_launch_effect_client *client, uint32_t id)
405 {
406     struct ds_tizen_launch_splash *splash;
407
408     splash = calloc(1, sizeof *splash);
409     if (!splash) {
410         wl_client_post_no_memory(client->wl_client);
411         return NULL;
412     }
413
414     splash->resource = wl_resource_create(client->wl_client,
415             &tizen_launch_splash_interface, wl_resource_get_version(client->resource),
416             id);
417     if (!splash->resource) {
418         free(splash);
419         wl_client_post_no_memory(client->wl_client);
420         return NULL;
421     }
422     splash->client = client;
423     splash->effect = client->effect;
424     splash->pid = SPLASH_CLIENT_PID;
425
426     wl_signal_init(&splash->events.destroy);
427     wl_signal_init(&splash->events.owner);
428
429     wl_resource_set_implementation(splash->resource, &splash_impl,
430             splash, splash_client_handle_destroy);
431
432     wl_list_insert(&client->splashs, &splash->link);
433
434     ds_inf("New Splash img %p (res %p)", splash, splash->resource);
435
436     return splash;
437 }
438
439 static void
440 effect_handle_create_splash_img(struct wl_client *wl_client,
441     struct wl_resource *resource, uint32_t id)
442 {
443     struct ds_tizen_launch_effect *effect;
444     struct ds_tizen_launch_effect_client *client;
445     struct ds_tizen_launch_splash *splash;
446
447     client = wl_resource_get_user_data(resource);
448     splash = splash_create_splash_img(client, id);
449     if (!splash) return;
450
451     effect = client->effect;
452     wl_signal_emit(&effect->events.new_splash, splash);
453 }
454
455 static void
456 effect_handle_type_set(struct wl_client *wl_client,
457     struct wl_resource *resource, const char *effect_type, uint32_t pid,
458     struct wl_array *options)
459 {
460     struct ds_tizen_launch_effect *effect;
461     struct ds_tizen_launch_effect_client *client;
462     struct ds_tizen_launch_effect_event_type_set ds_event;
463
464     client = wl_resource_get_user_data(resource);
465     effect = client->effect;
466
467     ds_event.pid = pid;
468     ds_event.effect_type = effect_get_effect_type(effect_type);
469
470     ds_inf("Effect type_set. pid:%u type:%s", pid, effect_type);
471
472     wl_signal_emit(&effect->events.type_set, &ds_event);
473 }
474
475 static void
476 effect_handle_type_unset(struct wl_client *wl_client,
477     struct wl_resource *resource, uint32_t pid)
478 {
479     struct ds_tizen_launch_effect *effect;
480     struct ds_tizen_launch_effect_client *client;
481     struct ds_tizen_launch_effect_event_type_unset ds_event;
482
483     client = wl_resource_get_user_data(resource);
484     effect = client->effect;
485
486     ds_event.pid = pid;
487
488     ds_inf("Effect type_unset. pid:%u", pid);
489
490     wl_signal_emit(&effect->events.type_unset, &ds_event);
491 }
492
493 static void
494 effect_handle_destroy(struct wl_client *wl_client,
495     struct wl_resource *resource)
496 {
497     wl_resource_destroy(resource);
498 }
499
500 static const struct tizen_launch_effect_interface effect_impl =
501 {
502     effect_handle_create_splash_img,
503     effect_handle_type_set,
504     effect_handle_type_unset,
505     effect_handle_destroy,
506 };
507
508 static void
509 effect_client_handle_destroy(struct wl_resource *resource)
510 {
511     struct ds_tizen_launch_effect_client *client;
512
513     client = wl_resource_get_user_data(resource);
514
515     ds_inf("effect_client_handle_destroy (client:%p)", client);
516
517     effect_client_destroy(client);
518 }
519
520 static void effect_bind(struct wl_client *wl_client, void *data,
521         uint32_t version, uint32_t id)
522 {
523     struct ds_tizen_launch_effect *effect = data;
524     struct ds_tizen_launch_effect_client *client;
525
526     client = calloc(1, sizeof *client);
527     if (client == NULL) {
528         ds_err("calloc() failed. tizen_,launch_effect");
529         wl_client_post_no_memory(wl_client);
530         return;
531     }
532
533     ds_inf("tizen_effect. client binds. (client:%p)", client);
534
535     client->effect = effect;
536     client->wl_client = wl_client;
537
538     client->resource = wl_resource_create(wl_client,
539             &tizen_launch_effect_interface,
540             MIN(version, TIZEN_EFFECT_VERSION), id);
541
542     if (client->resource == NULL) {
543         ds_err("tizen_effect : wl_resource_create() failed.");
544         free(client);
545         wl_client_post_no_memory(wl_client);
546         return;
547     }
548
549     wl_list_init(&client->splashs);
550
551     wl_resource_set_implementation(client->resource, &effect_impl, client,
552             effect_client_handle_destroy);
553
554     wl_list_insert(&effect->clients, &client->link);
555 }