0d977d2f4d1dad7ac2e110cf83f37c70bb1f9c1c
[platform/core/api/efl-util.git] / src / efl_util.c
1 /*
2  * Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #define LOG_TAG "TIZEN_N_EFL_UTIL"
18
19 #include <efl_util.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <fcntl.h>
27 #include <xf86drm.h>
28 #include <tbm_bufmgr.h>
29 #include <tbm_surface.h>
30 #include <tbm_surface_internal.h>
31 #include <Elementary.h>
32 #include <Ecore_Evas.h>
33 #include <pthread.h>
34
35 #include <Ecore_Wayland.h>
36 #include <wayland-client.h>
37 #include <wayland-tbm-client.h>
38 #include <tizen-extension-client-protocol.h>
39 #include <screenshooter-client-protocol.h>
40
41 #include <efl_util_screenshot_extension.h>
42
43 #include <dlog.h>
44 #ifdef LOG_TAG
45 #undef LOG_TAG
46 #endif
47
48 #define LOG_TAG "TIZEN_N_EFL_UTIL"
49
50
51 /* callback handler index */
52 #define CBH_NOTI_LEV 0
53 #define CBH_SCR_MODE 1
54 #define CBH_MAX      2
55
56 typedef void (*Efl_Util_Cb)(Evas_Object *, int, void *);
57
58 typedef struct _Efl_Util_Callback_Info
59 {
60    Evas_Object *win;
61    Efl_Util_Cb cb;
62    void *data;
63 } Efl_Util_Callback_Info;
64
65 typedef struct _Efl_Util_Wl_Surface_Lv_Info
66 {
67    void *surface; /* wl_surface */
68    int level;
69    Eina_Bool wait_for_done;
70    uint32_t state;
71 } Efl_Util_Wl_Surface_Lv_Info;
72
73 typedef struct _Efl_Util_Wl_Surface_Scr_Mode_Info
74 {
75    void *surface; /* wl_surface */
76    unsigned int mode;
77    Eina_Bool wait_for_done;
78    uint32_t state;
79 } Efl_Util_Wl_Surface_Scr_Mode_Info;
80
81 typedef struct _Efl_Util_Wl_Surface_Brightness_Info
82 {
83    void *surface; /* wl_surface */
84    int brightness;
85    Eina_Bool wait_for_done;
86    uint32_t state;
87 } Efl_Util_Wl_Surface_Brightness_Info;
88
89 typedef struct _Efl_Util_Wl_Output_Info
90 {
91     struct wl_output *output;
92     int offset_x, offset_y, width, height;
93 } Efl_Util_Wl_Output_Info;
94
95 typedef struct _Efl_Util_Data
96 {
97    /* wayland related stuffs */
98    struct
99    {
100       Eina_Bool init;
101       int ref_count;
102
103       struct wl_display *dpy;
104       struct wl_registry *reg;
105
106       struct wl_event_queue *queue;
107
108       struct
109       {
110          struct tizen_policy *proto;
111          Eina_Hash *hash_noti_lv;
112          Eina_Hash *hash_scr_mode;
113       } policy;
114       struct
115       {
116          struct wl_event_queue *queue;
117          struct screenshooter *screenshooter;
118          struct tizen_screenshooter *tz_screenshooter;
119          struct wayland_tbm_client *tbm_client;
120          Eina_List *output_list;
121          uint32_t noti;
122       } shot;
123       struct
124       {
125          struct tizen_input_device_manager *devicemgr;
126          int request_notified;
127          Eina_List *device_list;
128       } devmgr;
129       struct
130       {
131          struct tizen_display_policy *proto;
132          Eina_Hash *hash_brightness;
133       } display_policy;
134    } wl;
135
136    struct
137    {
138       Eina_List *info_list; /* list of callback info */
139       unsigned int atom; /* x11 atom */
140    } cb_handler[CBH_MAX];
141 } Efl_Util_Data;
142
143 static Efl_Util_Data _eflutil =
144 {
145    {
146       EINA_FALSE,
147       0,
148       NULL, NULL, NULL,
149       { NULL, NULL, NULL }, /* tizen_policy protocol */
150       { NULL, NULL, NULL, NULL, NULL, 0 }, /* screenshooter protocol */
151       { NULL, -1 } /* tizen_input_device_manager protocol */
152    },
153    {
154       { NULL, 0 }, /* handler for notification level */
155       { NULL, 0 }  /* handler for screen mode */
156    },
157 };
158
159 static Eina_Bool               _cb_info_add(Evas_Object *win, Efl_Util_Cb cb, void *data, int idx);
160 static Eina_Bool               _cb_info_del_by_win(Evas_Object *win, int idx);
161 static Eina_List              *_cb_info_list_get(int idx);
162 static Efl_Util_Callback_Info *_cb_info_find_by_win(Evas_Object *win, int idx);
163 static Eina_Bool               _wl_init(void);
164 static void                    _wl_shutdown(void);
165
166 static void                    _cb_wl_reg_global(void *data, struct wl_registry *reg, unsigned int name, const char *interface, unsigned int version);
167 static void                    _cb_wl_reg_global_remove(void *data, struct wl_registry *reg, unsigned int name);
168 static void                    _cb_wl_reg_screenshooter_global(void *data, struct wl_registry *reg, unsigned int name, const char *interface, unsigned int version);
169 static void                    _cb_wl_reg_screenshooter_global_remove(void *data, struct wl_registry *reg, unsigned int name);
170 static Efl_Util_Callback_Info *_cb_info_find_by_wlsurf(void *wlsurf, int idx);
171 static void                    _cb_wl_tz_policy_conformant(void *data, struct tizen_policy *tizen_policy, struct wl_surface *surface, uint32_t is_conformant);
172 static void                    _cb_wl_tz_policy_conformant_area(void *data, struct tizen_policy *tizen_policy, struct wl_surface *surface, uint32_t conformant_part, uint32_t state, int32_t x, int32_t y, int32_t w, int32_t h);
173 static void                    _cb_wl_tz_policy_notification_done(void *data, struct tizen_policy *tizen_policy, struct wl_surface *surface, int32_t level, uint32_t state);
174 static void                    _cb_wl_tz_policy_transient_for_done(void *data, struct tizen_policy *tizen_policy, uint32_t child_id);
175 static void                    _cb_wl_tz_policy_scr_mode_done(void *data, struct tizen_policy *tizen_policy, struct wl_surface *surface, uint32_t mode, uint32_t state);
176 static void                    _cb_wl_tz_policy_iconify_state_changed(void *data, struct tizen_policy *tizen_policy, struct wl_surface *surface_resource, uint32_t iconified, uint32_t force);
177 static void                    _cb_wl_tz_policy_supported_aux_hints(void *data, struct tizen_policy *tizen_policy, struct wl_surface *surface_resource, struct wl_array *hints, uint32_t num_hints);
178 static void                    _cb_wl_tz_policy_allowed_aux_hint(void *data, struct tizen_policy *tizen_policy, struct wl_surface *surface_resource, int id);
179 static void                    _cb_wl_tz_policy_aux_message(void *data, struct tizen_policy *tizen_policy, struct wl_surface *surface_resource, const char *key, const char *val, struct wl_array *options);
180
181 static void                    _cb_wl_tz_display_policy_brightness_done(void *data, struct tizen_display_policy *tizen_display_policy, struct wl_surface *surface_resource, int32_t brightness, uint32_t state);
182
183 static void                    _cb_device_add(void *data EINA_UNUSED, struct tizen_input_device_manager *tizen_input_device_manager EINA_UNUSED, uint32_t serial  EINA_UNUSED, const char *identifier  EINA_UNUSED, struct tizen_input_device *device  EINA_UNUSED, struct wl_seat *seat EINA_UNUSED);
184 static void                    _cb_device_remove(void *data EINA_UNUSED, struct tizen_input_device_manager *tizen_input_device_manager EINA_UNUSED, uint32_t serial EINA_UNUSED, const char *identifier  EINA_UNUSED, struct tizen_input_device *device EINA_UNUSED, struct wl_seat *seat EINA_UNUSED);
185 static void                    _cb_error(void *data EINA_UNUSED, struct tizen_input_device_manager *tizen_input_device_manager EINA_UNUSED, uint32_t errorcode);
186 static void                    _cb_block_expired(void *data EINA_UNUSED, struct tizen_input_device_manager *tizen_input_device_manager EINA_UNUSED);
187 static void                    _cb_device_info(void *data EINA_UNUSED, struct tizen_input_device *tizen_input_device EINA_UNUSED, const char *name EINA_UNUSED, uint32_t clas EINA_UNUSED, uint32_t subclas EINA_UNUSED, struct wl_array *axes EINA_UNUSED);
188 static void                    _cb_event_device(void *data EINA_UNUSED, struct tizen_input_device *tizen_input_device EINA_UNUSED, unsigned int serial EINA_UNUSED, const char *name EINA_UNUSED, uint32_t time EINA_UNUSED);
189 static void                    _cb_axis(void *data EINA_UNUSED, struct tizen_input_device *tizen_input_device EINA_UNUSED, uint32_t axis_type EINA_UNUSED, wl_fixed_t value EINA_UNUSED);
190
191 static const struct wl_registry_listener _wl_reg_listener =
192 {
193    _cb_wl_reg_global,
194    _cb_wl_reg_global_remove
195 };
196
197 static const struct wl_registry_listener _wl_reg_screenshooter_listener =
198 {
199    _cb_wl_reg_screenshooter_global,
200    _cb_wl_reg_screenshooter_global_remove
201 };
202
203 struct tizen_policy_listener _wl_tz_policy_listener =
204 {
205    _cb_wl_tz_policy_conformant,
206    _cb_wl_tz_policy_conformant_area,
207    _cb_wl_tz_policy_notification_done,
208    _cb_wl_tz_policy_transient_for_done,
209    _cb_wl_tz_policy_scr_mode_done,
210    _cb_wl_tz_policy_iconify_state_changed,
211    _cb_wl_tz_policy_supported_aux_hints,
212    _cb_wl_tz_policy_allowed_aux_hint,
213    _cb_wl_tz_policy_aux_message,
214 };
215
216 struct tizen_input_device_manager_listener _wl_tz_devmgr_listener =
217 {
218    _cb_device_add,
219    _cb_device_remove,
220    _cb_error,
221    _cb_block_expired
222 };
223
224 struct tizen_input_device_listener _wl_tz_dev_listener =
225 {
226    _cb_device_info,
227    _cb_event_device,
228    _cb_axis,
229 };
230
231 struct tizen_display_policy_listener _wl_tz_display_policy_listener =
232 {
233    _cb_wl_tz_display_policy_brightness_done,
234 };
235
236 static Eina_Bool
237 _cb_info_add(Evas_Object *win,
238              Efl_Util_Cb cb,
239              void *data,
240              int idx)
241 {
242    Efl_Util_Callback_Info *info;
243
244    info = _cb_info_find_by_win(win, idx);
245    if (info)
246      {
247         _eflutil.cb_handler[idx].info_list
248            = eina_list_remove(_eflutil.cb_handler[idx].info_list,
249                               info);
250         free(info);
251      }
252
253    info = (Efl_Util_Callback_Info *)calloc(1, sizeof(Efl_Util_Callback_Info));
254    if (!info) return EINA_FALSE;
255
256    info->win = win;
257    info->cb = cb;
258    info->data = data;
259
260    _eflutil.cb_handler[idx].info_list
261       = eina_list_append(_eflutil.cb_handler[idx].info_list,
262                          info);
263
264    return EINA_TRUE;
265 }
266
267 static Eina_Bool
268 _cb_info_del_by_win(Evas_Object *win,
269                     int idx)
270 {
271    Efl_Util_Callback_Info *info;
272
273    info = _cb_info_find_by_win(win, idx);
274    if (!info) return EINA_FALSE;
275
276    _eflutil.cb_handler[idx].info_list
277       = eina_list_remove(_eflutil.cb_handler[idx].info_list,
278                          info);
279    free(info);
280
281    return EINA_TRUE;
282 }
283
284 static Eina_List *
285 _cb_info_list_get(int idx)
286 {
287    return _eflutil.cb_handler[idx].info_list;
288 }
289
290 static Efl_Util_Callback_Info *
291 _cb_info_find_by_win(Evas_Object *win,
292                      int idx)
293 {
294    Eina_List *l, *ll;
295    Efl_Util_Callback_Info *info;
296
297    l = _cb_info_list_get(idx);
298    EINA_LIST_FOREACH(l, ll, info)
299      {
300         if (info->win == win) return info;
301      }
302
303    return NULL;
304 }
305
306 static Eina_Bool
307 _wl_init(void)
308 {
309    _eflutil.wl.ref_count++;
310
311    if (_eflutil.wl.init) return EINA_TRUE;
312
313    ecore_wl_init(NULL);
314
315    _eflutil.wl.dpy = ecore_wl_display_get();
316    EINA_SAFETY_ON_NULL_GOTO(_eflutil.wl.dpy, fail);
317
318    _eflutil.wl.queue = wl_display_create_queue(_eflutil.wl.dpy);
319    EINA_SAFETY_ON_NULL_GOTO(_eflutil.wl.queue, fail);
320
321    _eflutil.wl.reg = wl_display_get_registry(_eflutil.wl.dpy);
322    EINA_SAFETY_ON_NULL_GOTO(_eflutil.wl.reg, fail);
323
324    wl_proxy_set_queue((struct wl_proxy*)_eflutil.wl.reg, _eflutil.wl.queue);
325    wl_registry_add_listener(_eflutil.wl.reg, &_wl_reg_listener, NULL);
326
327    _eflutil.wl.init = EINA_TRUE;
328
329    return EINA_TRUE;
330 fail:
331    if (_eflutil.wl.queue)
332      {
333         wl_event_queue_destroy(_eflutil.wl.queue);
334         _eflutil.wl.queue = NULL;
335      }
336
337    if (_eflutil.wl.reg)
338      {
339         wl_registry_destroy(_eflutil.wl.reg);
340         _eflutil.wl.reg = NULL;
341      }
342
343    _eflutil.wl.dpy = NULL;
344
345    ecore_wl_shutdown();
346    return EINA_FALSE;
347 }
348
349 static void
350 _wl_shutdown(void)
351 {
352    Eina_List *l, *ll;
353    struct tizen_input_device *data;
354    Efl_Util_Wl_Output_Info *output;
355
356    if (!_eflutil.wl.init) return;
357
358    _eflutil.wl.ref_count--;
359    if (_eflutil.wl.ref_count > 0)
360      return;
361
362    // tizen_policy
363    if (_eflutil.wl.policy.proto)
364      tizen_policy_destroy(_eflutil.wl.policy.proto);
365    _eflutil.wl.policy.proto = NULL;
366
367    eina_hash_free(_eflutil.wl.policy.hash_noti_lv);
368    _eflutil.wl.policy.hash_noti_lv = NULL;
369    eina_hash_free(_eflutil.wl.policy.hash_scr_mode);
370    _eflutil.wl.policy.hash_scr_mode = NULL;
371
372    // wl_output
373    if (_eflutil.wl.shot.output_list)
374      {
375         EINA_LIST_FREE(_eflutil.wl.shot.output_list, output)
376           {
377              wl_output_destroy(output->output);
378              free(output);
379           }
380      }
381    _eflutil.wl.shot.output_list = NULL;
382
383    // screenshooter
384    if (_eflutil.wl.shot.screenshooter)
385      screenshooter_destroy(_eflutil.wl.shot.screenshooter);
386    _eflutil.wl.shot.screenshooter = NULL;
387
388    // tizen_input_device_manager
389    EINA_LIST_FOREACH_SAFE(_eflutil.wl.devmgr.device_list, l, ll, data)
390      {
391         tizen_input_device_release(data);
392         _eflutil.wl.devmgr.device_list = eina_list_remove_list(_eflutil.wl.devmgr.device_list, l);
393      }
394    ecore_wl_sync();
395    if (_eflutil.wl.devmgr.devicemgr)
396      tizen_input_device_manager_destroy(_eflutil.wl.devmgr.devicemgr);
397    _eflutil.wl.devmgr.devicemgr = NULL;
398
399    // tizen_display_policy
400    if (_eflutil.wl.display_policy.proto)
401      tizen_display_policy_destroy(_eflutil.wl.display_policy.proto);
402    _eflutil.wl.display_policy.proto = NULL;
403
404    eina_hash_free(_eflutil.wl.display_policy.hash_brightness);
405    _eflutil.wl.display_policy.hash_brightness = NULL;
406
407    if (_eflutil.wl.reg)
408      {
409         wl_proxy_set_queue((struct wl_proxy*)_eflutil.wl.reg, NULL);
410         wl_registry_destroy(_eflutil.wl.reg);
411         _eflutil.wl.reg = NULL;
412      }
413
414    if (_eflutil.wl.queue)
415      {
416         wl_event_queue_destroy(_eflutil.wl.queue);
417         _eflutil.wl.queue = NULL;
418      }
419
420    _eflutil.wl.dpy = NULL;
421    _eflutil.wl.init = EINA_FALSE;
422
423    ecore_wl_shutdown();
424 }
425
426 static void
427 _cb_wl_output_geometry(void *data, struct wl_output *wl_output, int x, int y,
428                        int physical_width, int physical_height, int subpixel,
429                        const char *make, const char *model, int transform)
430 {
431    Efl_Util_Wl_Output_Info *output = wl_output_get_user_data(wl_output);
432    if (wl_output == output->output)
433      {
434         output->offset_x = x;
435         output->offset_y = y;
436      }
437 }
438
439 static void
440 _cb_wl_output_mode(void *data, struct wl_output *wl_output, uint32_t flags,
441                    int width, int height, int refresh)
442 {
443    Efl_Util_Wl_Output_Info *output = wl_output_get_user_data(wl_output);
444    if (wl_output == output->output && (flags & WL_OUTPUT_MODE_CURRENT))
445      {
446         output->width = width;
447         output->height = height;
448      }
449 }
450
451 static void
452 _cb_wl_output_done(void *data, struct wl_output *wl_output)
453 {
454 }
455
456 static void
457 _cb_wl_output_scale(void *data, struct wl_output *wl_output, int32_t factor)
458 {
459 }
460
461 static const struct wl_output_listener output_listener =
462 {
463     _cb_wl_output_geometry,
464     _cb_wl_output_mode,
465     _cb_wl_output_done,
466     _cb_wl_output_scale
467 };
468
469 static void
470 _cb_wl_screenshot_done(void *data, struct screenshooter *screenshooter)
471 {
472    Eina_Bool *shot_done = (Eina_Bool*)data;
473    if (shot_done)
474      *shot_done = EINA_TRUE;
475 }
476
477 static const struct screenshooter_listener screenshooter_listener =
478 {
479     _cb_wl_screenshot_done
480 };
481
482 static void
483 _cb_tz_screenshot_format(void *data, struct tizen_screenshooter *tz_screenshooter, uint32_t format)
484 {
485 }
486
487 static void
488 _cb_tz_screenshot_noti(void *data, struct tizen_screenshooter *tz_screenshooter, uint32_t noti)
489 {
490    _eflutil.wl.shot.noti = noti;
491 }
492
493 static const struct tizen_screenshooter_listener tz_screenshooter_listener =
494 {
495     _cb_tz_screenshot_format,
496     _cb_tz_screenshot_noti
497 };
498
499 static void
500 _cb_wl_reg_global(void *data,
501                   struct wl_registry *reg,
502                   unsigned int name,
503                   const char *interface,
504                   unsigned int version)
505 {
506    if (!strcmp(interface, "tizen_policy"))
507      {
508         struct tizen_policy *proto;
509         proto = wl_registry_bind(reg,
510                                   name,
511                                   &tizen_policy_interface,
512                                   1);
513         if (!proto) return;
514
515         tizen_policy_add_listener(proto,
516                                   &_wl_tz_policy_listener,
517                                   NULL);
518
519         _eflutil.wl.policy.hash_noti_lv = eina_hash_pointer_new(free);
520         _eflutil.wl.policy.hash_scr_mode = eina_hash_pointer_new(free);
521         _eflutil.wl.policy.proto = proto;
522      }
523    else if (strcmp(interface, "wl_output") == 0)
524      {
525         Efl_Util_Wl_Output_Info *output = calloc(1, sizeof(Efl_Util_Wl_Output_Info));
526         EINA_SAFETY_ON_NULL_RETURN(output);
527
528         _eflutil.wl.shot.output_list = eina_list_append(_eflutil.wl.shot.output_list, output);
529
530         output->output = wl_registry_bind(reg, name, &wl_output_interface, version);
531         wl_output_add_listener(output->output, &output_listener, output);
532      }
533    else if (strcmp(interface, "tizen_input_device_manager") == 0)
534      {
535         _eflutil.wl.devmgr.devicemgr = wl_registry_bind(reg, name, &tizen_input_device_manager_interface, version);
536         tizen_input_device_manager_add_listener(_eflutil.wl.devmgr.devicemgr, &_wl_tz_devmgr_listener, NULL);
537      }
538    else if (!strcmp(interface, "tizen_display_policy"))
539      {
540         _eflutil.wl.display_policy.proto = wl_registry_bind(reg, name, &tizen_display_policy_interface, version);
541         if (!_eflutil.wl.display_policy.proto) return;
542
543         tizen_display_policy_add_listener(_eflutil.wl.display_policy.proto,
544                                           &_wl_tz_display_policy_listener,
545                                           NULL);
546
547         _eflutil.wl.display_policy.hash_brightness = eina_hash_pointer_new(free);
548      }
549
550 }
551 /* LCOV_EXCL_START */
552 static void
553 _cb_wl_reg_global_remove(void *data,
554                          struct wl_registry *reg,
555                          unsigned int name)
556 {
557    Eina_List *l, *ll;
558    struct tizen_input_device *ddata;
559    Efl_Util_Wl_Output_Info *output;
560
561    // tizen_policy
562    if (_eflutil.wl.policy.proto)
563      tizen_policy_destroy(_eflutil.wl.policy.proto);
564    _eflutil.wl.policy.proto = NULL;
565
566    eina_hash_free(_eflutil.wl.policy.hash_noti_lv);
567    _eflutil.wl.policy.hash_noti_lv = NULL;
568    eina_hash_free(_eflutil.wl.policy.hash_scr_mode);
569    _eflutil.wl.policy.hash_scr_mode = NULL;
570
571    // wl_output
572    if (_eflutil.wl.shot.output_list)
573      {
574         EINA_LIST_FREE(_eflutil.wl.shot.output_list, output)
575           {
576              wl_output_destroy(output->output);
577              free(output);
578           }
579      }
580    _eflutil.wl.shot.output_list = NULL;
581
582    // screenshooter
583    if (_eflutil.wl.shot.screenshooter)
584      screenshooter_destroy(_eflutil.wl.shot.screenshooter);
585    _eflutil.wl.shot.screenshooter = NULL;
586
587    // tizen_input_device_manager
588    EINA_LIST_FOREACH_SAFE(_eflutil.wl.devmgr.device_list, l, ll, ddata)
589      {
590         tizen_input_device_release(ddata);
591         _eflutil.wl.devmgr.device_list = eina_list_remove_list(_eflutil.wl.devmgr.device_list, l);
592      }
593    if (_eflutil.wl.devmgr.devicemgr)
594      tizen_input_device_manager_destroy(_eflutil.wl.devmgr.devicemgr);
595    _eflutil.wl.devmgr.devicemgr = NULL;
596
597    // tizen_display_policy
598    if (_eflutil.wl.display_policy.proto)
599      tizen_display_policy_destroy(_eflutil.wl.display_policy.proto);
600    _eflutil.wl.display_policy.proto = NULL;
601
602    eina_hash_free(_eflutil.wl.display_policy.hash_brightness);
603    _eflutil.wl.display_policy.hash_brightness = NULL;
604 }
605 /* LCOV_EXCL_STOP */
606
607 static void
608 _cb_wl_reg_screenshooter_global(void *data,
609                   struct wl_registry *reg,
610                   unsigned int name,
611                   const char *interface,
612                   unsigned int version)
613 {
614    if (strcmp(interface, "screenshooter") == 0)
615      {
616         _eflutil.wl.shot.screenshooter = wl_registry_bind(reg, name, &screenshooter_interface, version);
617         screenshooter_add_listener(_eflutil.wl.shot.screenshooter, &screenshooter_listener, NULL);
618      }
619    else if (strcmp(interface, "tizen_screenshooter") == 0)
620      {
621         _eflutil.wl.shot.tz_screenshooter = wl_registry_bind(reg, name, &tizen_screenshooter_interface, version);
622         tizen_screenshooter_add_listener(_eflutil.wl.shot.tz_screenshooter, &tz_screenshooter_listener, NULL);
623
624         wl_display_roundtrip_queue(_eflutil.wl.dpy, _eflutil.wl.shot.queue);
625      }
626 }
627
628 /* LCOV_EXCL_START */
629 static void
630 _cb_wl_reg_screenshooter_global_remove(void *data,
631                          struct wl_registry *reg,
632                          unsigned int name)
633 {
634 }
635
636 static Efl_Util_Callback_Info *
637 _cb_info_find_by_wlsurf(void *wlsurf,
638                         int idx)
639 {
640    Eina_List *l, *ll;
641    Efl_Util_Callback_Info *info;
642    Ecore_Wl_Window *wlwin2 = NULL;
643    void *wlsurf2 = NULL;
644
645    l = _cb_info_list_get(idx);
646    EINA_LIST_FOREACH(l, ll, info)
647      {
648         wlwin2 = elm_win_wl_window_get(info->win);
649         wlsurf2 = ecore_wl_window_surface_get(wlwin2);
650         if (wlsurf== wlsurf2) return info;
651      }
652
653    return NULL;
654 }
655
656 static void
657 _cb_wl_tz_policy_conformant(void *data, struct tizen_policy *tizen_policy,
658                             struct wl_surface *surface, uint32_t is_conformant)
659 {
660 }
661
662 static void
663 _cb_wl_tz_policy_conformant_area(void *data, struct tizen_policy *tizen_policy,
664                                  struct wl_surface *surface, uint32_t conformant_part,
665                                  uint32_t state, int32_t x, int32_t y, int32_t w, int32_t h)
666 {
667 }
668 /* LCOV_EXCL_STOP */
669
670 static void
671 _cb_wl_tz_policy_notification_done(void *data,
672                                    struct tizen_policy *tizen_policy,
673                                    struct wl_surface *surface,
674                                    int32_t level,
675                                    uint32_t state)
676 {
677    Efl_Util_Wl_Surface_Lv_Info *lv_info;
678    Efl_Util_Callback_Info *cb_info;
679
680    lv_info = eina_hash_find(_eflutil.wl.policy.hash_noti_lv, &surface);
681    if (lv_info)
682      {
683         lv_info->level = level;
684         lv_info->wait_for_done = EINA_FALSE;
685         lv_info->state = state;
686      }
687
688    if (state != TIZEN_POLICY_ERROR_STATE_PERMISSION_DENIED) return;
689
690    cb_info = _cb_info_find_by_wlsurf((void *)surface, CBH_NOTI_LEV);
691    if (!cb_info) return;
692    if (!cb_info->cb) return;
693
694    cb_info->cb(cb_info->win,
695                EFL_UTIL_ERROR_PERMISSION_DENIED,
696                cb_info->data);
697 }
698
699 /* LCOV_EXCL_START */
700 static void
701 _cb_wl_tz_policy_transient_for_done(void *data, struct tizen_policy *tizen_policy, uint32_t child_id)
702 {
703 }
704 /* LCOV_EXCL_STOP */
705
706 static void
707 _cb_wl_tz_policy_scr_mode_done(void *data,
708                                struct tizen_policy *tizen_policy,
709                                struct wl_surface *surface,
710                                uint32_t mode,
711                                uint32_t state)
712 {
713
714    Efl_Util_Wl_Surface_Scr_Mode_Info *scr_mode_info;
715    Efl_Util_Callback_Info *cb_info;
716
717    scr_mode_info = eina_hash_find(_eflutil.wl.policy.hash_scr_mode, &surface);
718    if (scr_mode_info)
719      {
720         scr_mode_info->mode = mode;
721         scr_mode_info->wait_for_done = EINA_FALSE;
722         scr_mode_info->state = state;
723      }
724
725    if (state != TIZEN_POLICY_ERROR_STATE_PERMISSION_DENIED) return;
726
727    cb_info = _cb_info_find_by_wlsurf((void *)surface, CBH_SCR_MODE);
728    if (!cb_info) return;
729    if (!cb_info->cb) return;
730
731    cb_info->cb(cb_info->win,
732                EFL_UTIL_ERROR_PERMISSION_DENIED,
733                cb_info->data);
734 }
735
736 /* LCOV_EXCL_START */
737 static void                    _cb_wl_tz_policy_iconify_state_changed(void *data, struct tizen_policy *tizen_policy, struct wl_surface *surface_resource, uint32_t iconified, uint32_t force)
738 {
739 }
740
741 static void                    _cb_wl_tz_policy_supported_aux_hints(void *data, struct tizen_policy *tizen_policy, struct wl_surface *surface_resource, struct wl_array *hints, uint32_t num_hints)
742 {
743 }
744
745 static void                    _cb_wl_tz_policy_allowed_aux_hint(void *data, struct tizen_policy *tizen_policy, struct wl_surface *surface_resource, int id)
746 {
747 }
748
749 static void                    _cb_wl_tz_policy_aux_message(void *data, struct tizen_policy *tizen_policy, struct wl_surface *surface_resource, const char *key, const char *val, struct wl_array *options)
750 {
751 }
752 /* LCOV_EXCL_STOP */
753
754 static void
755 _cb_wl_tz_display_policy_brightness_done(void *data,
756                                  struct tizen_display_policy *tizen_display_policy,
757                                  struct wl_surface *surface,
758                                  int32_t brightness,
759                                  uint32_t state)
760 {
761    Efl_Util_Wl_Surface_Brightness_Info *brightness_info;
762
763    brightness_info = eina_hash_find(_eflutil.wl.display_policy.hash_brightness, &surface);
764    if (brightness_info)
765      {
766         brightness_info->brightness = brightness;
767         brightness_info->wait_for_done = EINA_FALSE;
768         brightness_info->state = state;
769      }
770 }
771
772 static void
773 _cb_window_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
774 {
775    Efl_Util_Wl_Surface_Lv_Info *lv_info;
776
777    lv_info = data;
778    if (EINA_UNLIKELY(!lv_info))
779      return;
780
781    eina_hash_del(_eflutil.wl.policy.hash_noti_lv, &lv_info->surface, lv_info);
782
783    eina_hash_population(_eflutil.wl.policy.hash_noti_lv);
784
785    if (eina_hash_population(_eflutil.wl.policy.hash_noti_lv) == 0)
786      {
787         _wl_shutdown();
788      }
789 }
790
791 static Eina_Bool
792 _init_tizen_policy_proto(void)
793 {
794    int ret = 0;
795
796    if (!_eflutil.wl.policy.proto)
797      {
798         ret = _wl_init();
799         EINA_SAFETY_ON_FALSE_RETURN_VAL(ret, EINA_FALSE);
800
801         ret = 0;
802         while (!_eflutil.wl.policy.proto && ret != -1)
803           ret = wl_display_dispatch_queue(_eflutil.wl.dpy, _eflutil.wl.queue);
804
805         EINA_SAFETY_ON_NULL_RETURN_VAL(_eflutil.wl.policy.proto, EINA_FALSE);
806      }
807
808    return EINA_TRUE;
809 }
810
811 API int
812 efl_util_set_notification_window_level(Evas_Object *window,
813                                        efl_util_notification_level_e level)
814 {
815    Eina_Bool ret;
816    Elm_Win_Type type;
817    Ecore_Wl_Window *wlwin;
818    struct wl_surface *surface;
819    Efl_Util_Wl_Surface_Lv_Info *lv_info;
820    Ecore_Wl_Window_Type wl_type;
821
822    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EFL_UTIL_ERROR_INVALID_PARAMETER);
823    EINA_SAFETY_ON_FALSE_RETURN_VAL((level >= EFL_UTIL_NOTIFICATION_LEVEL_NONE) &&
824                                    (level <= EFL_UTIL_NOTIFICATION_LEVEL_TOP),
825                                    EFL_UTIL_ERROR_INVALID_PARAMETER);
826
827    if (level == EFL_UTIL_NOTIFICATION_LEVEL_1)
828      {
829         dlog_print(DLOG_WARN, LOG_TAG,
830           "DEPRECATION WARNING: EFL_UTIL_NOTIFICATION_LEVEL_1 is deprecated and will be removed from next release. Use EFL_UTIL_NOTIFICATION_LEVEL_DEFAULT instead.");
831      }
832    else if (level == EFL_UTIL_NOTIFICATION_LEVEL_2)
833      {
834         dlog_print(DLOG_WARN, LOG_TAG,
835           "DEPRECATION WARNING: EFL_UTIL_NOTIFICATION_LEVEL_2 is deprecated and will be removed from next release. Use EFL_UTIL_NOTIFICATION_LEVEL_MEDIUM instead.");
836      }
837    else if (level == EFL_UTIL_NOTIFICATION_LEVEL_3)
838      {
839         dlog_print(DLOG_WARN, LOG_TAG,
840           "DEPRECATION WARNING: EFL_UTIL_NOTIFICATION_LEVEL_3 is deprecated and will be removed from next release. Use EFL_UTIL_NOTIFICATION_LEVEL_TOP instead.");
841      }
842
843    wlwin = elm_win_wl_window_get(window);
844    EINA_SAFETY_ON_NULL_RETURN_VAL(wlwin, EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE);
845
846    type = elm_win_type_get(window);
847    if (type != ELM_WIN_NOTIFICATION)
848      {
849         wl_type = ecore_wl_window_type_get(wlwin);
850         EINA_SAFETY_ON_FALSE_RETURN_VAL((wl_type == ECORE_WL_WINDOW_TYPE_NOTIFICATION),
851                                         EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE);
852      }
853
854    ret = _init_tizen_policy_proto();
855    EINA_SAFETY_ON_FALSE_RETURN_VAL(ret, EFL_UTIL_ERROR_NOT_SUPPORTED);
856
857    surface = ecore_wl_window_surface_get(wlwin);
858    EINA_SAFETY_ON_NULL_RETURN_VAL(surface,
859                                   EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE);
860
861    lv_info = eina_hash_find(_eflutil.wl.policy.hash_noti_lv, &surface);
862    if (!lv_info)
863      {
864         lv_info = calloc(1, sizeof(Efl_Util_Wl_Surface_Lv_Info));
865         EINA_SAFETY_ON_NULL_RETURN_VAL(lv_info, EFL_UTIL_ERROR_OUT_OF_MEMORY);
866
867         lv_info->surface = surface;
868         lv_info->level = (int)level;
869         lv_info->wait_for_done = EINA_TRUE;
870         lv_info->state = TIZEN_POLICY_ERROR_STATE_NONE;
871         eina_hash_add(_eflutil.wl.policy.hash_noti_lv,
872                       &surface,
873                       lv_info);
874
875         evas_object_event_callback_add(window, EVAS_CALLBACK_DEL,
876                                        _cb_window_del, lv_info);
877      }
878    else
879      {
880         lv_info->level = (int)level;
881         lv_info->wait_for_done = EINA_TRUE;
882         lv_info->state = TIZEN_POLICY_ERROR_STATE_NONE;
883      }
884
885
886    tizen_policy_set_notification_level(_eflutil.wl.policy.proto,
887                                        surface, (int)level);
888
889    if (lv_info->wait_for_done)
890      {
891         int count = 0;
892         while (lv_info->wait_for_done && (count < 3))
893           {
894              ecore_wl_flush();
895              wl_display_dispatch_queue(_eflutil.wl.dpy, _eflutil.wl.queue);
896              count++;
897           }
898
899         if (lv_info->wait_for_done)
900           {
901              return EFL_UTIL_ERROR_INVALID_PARAMETER;
902           }
903         else
904           {
905              if (lv_info->state == TIZEN_POLICY_ERROR_STATE_PERMISSION_DENIED)
906                {
907                   return EFL_UTIL_ERROR_PERMISSION_DENIED;
908                }
909           }
910      }
911
912    return EFL_UTIL_ERROR_NONE;
913 }
914
915 API int
916 efl_util_get_notification_window_level(Evas_Object *window,
917                                        efl_util_notification_level_e *level)
918 {
919    Eina_Bool ret;
920    Elm_Win_Type type;
921    Ecore_Wl_Window *wlwin;
922    struct wl_surface *surface;
923    Efl_Util_Wl_Surface_Lv_Info *lv_info;
924    Ecore_Wl_Window_Type wl_type;
925
926    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EFL_UTIL_ERROR_INVALID_PARAMETER);
927    EINA_SAFETY_ON_NULL_RETURN_VAL(level, EFL_UTIL_ERROR_INVALID_PARAMETER);
928
929    wlwin = elm_win_wl_window_get(window);
930    EINA_SAFETY_ON_NULL_RETURN_VAL(wlwin, EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE);
931
932    type = elm_win_type_get(window);
933    if (type != ELM_WIN_NOTIFICATION)
934      {
935         wl_type = ecore_wl_window_type_get(wlwin);
936         EINA_SAFETY_ON_FALSE_RETURN_VAL((wl_type == ECORE_WL_WINDOW_TYPE_NOTIFICATION),
937                                         EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE);
938      }
939
940    surface = ecore_wl_window_surface_get(wlwin);
941    EINA_SAFETY_ON_NULL_RETURN_VAL(surface,
942                                   EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE);
943
944    ret = _init_tizen_policy_proto();
945    EINA_SAFETY_ON_FALSE_RETURN_VAL(ret, EFL_UTIL_ERROR_NOT_SUPPORTED);
946
947    lv_info = eina_hash_find(_eflutil.wl.policy.hash_noti_lv, &surface);
948    if (lv_info)
949      {
950         if (lv_info->wait_for_done)
951           {
952              int count = 0;
953              while ((lv_info->wait_for_done) && (count < 3))
954                {
955                   ecore_wl_flush();
956                   wl_display_dispatch_queue(_eflutil.wl.dpy, _eflutil.wl.queue);
957                   count++;
958                }
959
960              if (lv_info->wait_for_done)
961                {
962                   *level = EFL_UTIL_NOTIFICATION_LEVEL_DEFAULT;
963                   return EFL_UTIL_ERROR_INVALID_PARAMETER;
964                }
965           }
966
967         switch (lv_info->level)
968           {
969            case TIZEN_POLICY_LEVEL_1:       *level = EFL_UTIL_NOTIFICATION_LEVEL_1;       break;
970            case TIZEN_POLICY_LEVEL_2:       *level = EFL_UTIL_NOTIFICATION_LEVEL_2;       break;
971            case TIZEN_POLICY_LEVEL_3:       *level = EFL_UTIL_NOTIFICATION_LEVEL_3;       break;
972            case TIZEN_POLICY_LEVEL_NONE:    *level = EFL_UTIL_NOTIFICATION_LEVEL_NONE;    break;
973            case TIZEN_POLICY_LEVEL_DEFAULT: *level = EFL_UTIL_NOTIFICATION_LEVEL_DEFAULT; break;
974            case TIZEN_POLICY_LEVEL_MEDIUM:  *level = EFL_UTIL_NOTIFICATION_LEVEL_MEDIUM;  break;
975            case TIZEN_POLICY_LEVEL_HIGH:    *level = EFL_UTIL_NOTIFICATION_LEVEL_HIGH;    break;
976            case TIZEN_POLICY_LEVEL_TOP:     *level = EFL_UTIL_NOTIFICATION_LEVEL_TOP;     break;
977            default:                         *level = EFL_UTIL_NOTIFICATION_LEVEL_DEFAULT;
978             return EFL_UTIL_ERROR_INVALID_PARAMETER;
979           }
980         return EFL_UTIL_ERROR_NONE;
981      }
982    else
983      *level = EFL_UTIL_NOTIFICATION_LEVEL_DEFAULT;
984
985    return EFL_UTIL_ERROR_NONE;
986 }
987
988 API int
989 efl_util_set_notification_window_level_error_cb(Evas_Object *window,
990                                                 efl_util_notification_window_level_error_cb callback,
991                                                 void *user_data)
992 {
993    dlog_print(DLOG_WARN, LOG_TAG,
994      "DEPRECATION WARNING: efl_util_set_notification_window_level_error_cb() is deprecated and will be removed from next release. Use the return value of efl_util_set_notification_window_level() instead.");
995
996    Eina_Bool ret = EINA_FALSE;
997
998    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EFL_UTIL_ERROR_INVALID_PARAMETER);
999    EINA_SAFETY_ON_NULL_RETURN_VAL(callback, EFL_UTIL_ERROR_INVALID_PARAMETER);
1000
1001    ret = _cb_info_add(window,
1002                       (Efl_Util_Cb)callback,
1003                       user_data,
1004                       CBH_NOTI_LEV);
1005    if (!ret) return EFL_UTIL_ERROR_OUT_OF_MEMORY;
1006
1007    return EFL_UTIL_ERROR_NONE;
1008 }
1009
1010 API int
1011 efl_util_unset_notification_window_level_error_cb(Evas_Object *window)
1012 {
1013    dlog_print(DLOG_WARN, LOG_TAG,
1014      "DEPRECATION WARNING: efl_util_unset_notification_window_level_error_cb() is deprecated and will be removed from next release. Use the return value of efl_util_set_notification_window_level() instead.");
1015
1016    Eina_Bool ret = EINA_FALSE;
1017
1018    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EFL_UTIL_ERROR_INVALID_PARAMETER);
1019
1020    ret = _cb_info_del_by_win(window, CBH_NOTI_LEV);
1021    if (!ret) return EFL_UTIL_ERROR_INVALID_PARAMETER;
1022
1023    return EFL_UTIL_ERROR_NONE;
1024 }
1025
1026 API int
1027 efl_util_set_window_opaque_state(Evas_Object *window,
1028                                  int opaque)
1029 {
1030    Eina_Bool ret;
1031    Ecore_Wl_Window *wlwin;
1032    struct wl_surface *surface;
1033
1034    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EFL_UTIL_ERROR_INVALID_PARAMETER);
1035    EINA_SAFETY_ON_FALSE_RETURN_VAL(((opaque >= 0) && (opaque <= 1)),
1036                                    EFL_UTIL_ERROR_INVALID_PARAMETER);
1037
1038    wlwin = elm_win_wl_window_get(window);
1039    if (!wlwin)
1040       return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
1041
1042    surface  = ecore_wl_window_surface_get(wlwin);
1043    if (!surface)
1044       return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
1045
1046    ret = _init_tizen_policy_proto();
1047    EINA_SAFETY_ON_FALSE_RETURN_VAL(ret, EFL_UTIL_ERROR_NOT_SUPPORTED);
1048
1049    tizen_policy_set_opaque_state(_eflutil.wl.policy.proto, surface, opaque);
1050
1051    return EFL_UTIL_ERROR_NONE;
1052 }
1053
1054 API int
1055 efl_util_set_window_screen_mode(Evas_Object *window,
1056                                 efl_util_screen_mode_e mode)
1057 {
1058    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EFL_UTIL_ERROR_INVALID_PARAMETER);
1059    EINA_SAFETY_ON_FALSE_RETURN_VAL(((mode >= EFL_UTIL_SCREEN_MODE_DEFAULT) &&
1060                                     (mode <= EFL_UTIL_SCREEN_MODE_ALWAYS_ON)),
1061                                    EFL_UTIL_ERROR_INVALID_PARAMETER);
1062
1063    Ecore_Wl_Window *wlwin;
1064    struct wl_surface *surface;
1065    Efl_Util_Wl_Surface_Scr_Mode_Info *scr_mode_info;
1066    Eina_Bool ret;
1067
1068    wlwin = elm_win_wl_window_get(window);
1069    EINA_SAFETY_ON_NULL_RETURN_VAL(wlwin, EFL_UTIL_ERROR_INVALID_PARAMETER);
1070
1071    surface = ecore_wl_window_surface_get(wlwin);
1072    EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EFL_UTIL_ERROR_INVALID_PARAMETER);
1073
1074    ret = _init_tizen_policy_proto();
1075    EINA_SAFETY_ON_FALSE_RETURN_VAL(ret, EFL_UTIL_ERROR_NOT_SUPPORTED);
1076
1077    scr_mode_info = eina_hash_find(_eflutil.wl.policy.hash_scr_mode, &surface);
1078    if (!scr_mode_info)
1079      {
1080         scr_mode_info = calloc(1, sizeof(Efl_Util_Wl_Surface_Scr_Mode_Info));
1081         EINA_SAFETY_ON_NULL_RETURN_VAL(scr_mode_info, EFL_UTIL_ERROR_OUT_OF_MEMORY);
1082
1083         scr_mode_info->surface = surface;
1084         scr_mode_info->mode = (unsigned int)mode;
1085         scr_mode_info->wait_for_done = EINA_TRUE;
1086         scr_mode_info->state = TIZEN_POLICY_ERROR_STATE_NONE;
1087
1088         eina_hash_add(_eflutil.wl.policy.hash_scr_mode,
1089                       &surface,
1090                       scr_mode_info);
1091      }
1092    else
1093      {
1094         scr_mode_info->mode = (unsigned int)mode;
1095         scr_mode_info->wait_for_done = EINA_TRUE;
1096         scr_mode_info->state = TIZEN_POLICY_ERROR_STATE_NONE;
1097      }
1098
1099    tizen_policy_set_window_screen_mode(_eflutil.wl.policy.proto,
1100                                        surface, (unsigned int)mode);
1101    if (scr_mode_info->wait_for_done)
1102      {
1103         int count = 0;
1104         while (scr_mode_info->wait_for_done && (count < 3))
1105           {
1106              ecore_wl_flush();
1107              wl_display_dispatch_queue(_eflutil.wl.dpy, _eflutil.wl.queue);
1108              count++;
1109           }
1110
1111         if (scr_mode_info->wait_for_done)
1112           {
1113              return EFL_UTIL_ERROR_INVALID_PARAMETER;
1114           }
1115         else
1116           {
1117              if (scr_mode_info->state == TIZEN_POLICY_ERROR_STATE_PERMISSION_DENIED)
1118                {
1119                   return EFL_UTIL_ERROR_PERMISSION_DENIED;
1120                }
1121           }
1122      }
1123
1124    return EFL_UTIL_ERROR_NONE;
1125 }
1126
1127 API int
1128 efl_util_get_window_screen_mode(Evas_Object *window,
1129                                 efl_util_screen_mode_e *mode)
1130 {
1131    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EFL_UTIL_ERROR_INVALID_PARAMETER);
1132    EINA_SAFETY_ON_NULL_RETURN_VAL(mode, EFL_UTIL_ERROR_INVALID_PARAMETER);
1133
1134    Ecore_Wl_Window *wlwin;
1135    struct wl_surface *surface;
1136    Efl_Util_Wl_Surface_Scr_Mode_Info *scr_mode_info;
1137    Eina_Bool ret;
1138
1139    wlwin = elm_win_wl_window_get(window);
1140    EINA_SAFETY_ON_NULL_RETURN_VAL(wlwin, EFL_UTIL_ERROR_INVALID_PARAMETER);
1141
1142    surface = ecore_wl_window_surface_get(wlwin);
1143    EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EFL_UTIL_ERROR_INVALID_PARAMETER);
1144
1145    ret = _init_tizen_policy_proto();
1146    EINA_SAFETY_ON_FALSE_RETURN_VAL(ret, EFL_UTIL_ERROR_NOT_SUPPORTED);
1147
1148    scr_mode_info = eina_hash_find(_eflutil.wl.policy.hash_scr_mode, &surface);
1149    if (scr_mode_info)
1150      {
1151         if (scr_mode_info->wait_for_done)
1152           {
1153              while (scr_mode_info->wait_for_done)
1154                {
1155                   ecore_wl_flush();
1156                   wl_display_dispatch_queue(_eflutil.wl.dpy, _eflutil.wl.queue);
1157                }
1158           }
1159
1160         switch (scr_mode_info->mode)
1161           {
1162            case TIZEN_POLICY_MODE_DEFAULT:
1163               *mode = EFL_UTIL_SCREEN_MODE_DEFAULT;
1164               break;
1165
1166            case TIZEN_POLICY_MODE_ALWAYS_ON:
1167               *mode = EFL_UTIL_SCREEN_MODE_ALWAYS_ON;
1168               break;
1169
1170            default:
1171               *mode = EFL_UTIL_SCREEN_MODE_DEFAULT;
1172               return EFL_UTIL_ERROR_INVALID_PARAMETER;
1173           }
1174
1175         return EFL_UTIL_ERROR_NONE;
1176      }
1177    else
1178      {
1179         *mode = EFL_UTIL_SCREEN_MODE_DEFAULT;
1180         return EFL_UTIL_ERROR_INVALID_PARAMETER;
1181      }
1182 }
1183
1184 #ifndef TIZEN_WEARABLE
1185 API int
1186 efl_util_set_window_screen_mode_error_cb(Evas_Object *window,
1187                                          efl_util_window_screen_mode_error_cb callback,
1188                                          void *user_data)
1189 {
1190    dlog_print(DLOG_WARN, LOG_TAG,
1191      "DEPRECATION WARNING: efl_util_set_window_screen_mode_error_cb() is deprecated and will be removed from next release. Use the return value of efl_util_set_window_screen_mode() instead.");
1192
1193    Eina_Bool ret = EINA_FALSE;
1194
1195    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EFL_UTIL_ERROR_INVALID_PARAMETER);
1196    EINA_SAFETY_ON_NULL_RETURN_VAL(callback, EFL_UTIL_ERROR_INVALID_PARAMETER);
1197
1198    ret = _cb_info_add(window,
1199                       (Efl_Util_Cb)callback,
1200                       user_data,
1201                       CBH_SCR_MODE);
1202    if (!ret) return EFL_UTIL_ERROR_OUT_OF_MEMORY;
1203
1204    return EFL_UTIL_ERROR_NONE;
1205 }
1206
1207 API int
1208 efl_util_unset_window_screen_mode_error_cb(Evas_Object *window)
1209 {
1210    dlog_print(DLOG_WARN, LOG_TAG,
1211      "DEPRECATION WARNING: efl_util_unset_window_screen_mode_error_cb() is deprecated and will be removed from next release. Use the return value of efl_util_set_window_screen_mode() instead.");
1212
1213    Eina_Bool ret = EINA_FALSE;
1214
1215    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EFL_UTIL_ERROR_INVALID_PARAMETER);
1216
1217    ret = _cb_info_del_by_win(window, CBH_SCR_MODE);
1218    if (!ret) return EFL_UTIL_ERROR_INVALID_PARAMETER;
1219
1220    return EFL_UTIL_ERROR_NONE;
1221 }
1222 #endif
1223
1224 static Eina_Bool
1225 _init_tizen_display_policy_proto(void)
1226 {
1227    int ret = 0;
1228
1229    if (!_eflutil.wl.display_policy.proto)
1230      {
1231         ret = _wl_init();
1232         EINA_SAFETY_ON_FALSE_RETURN_VAL(ret, EINA_FALSE);
1233
1234         ret = 0;
1235         while (!_eflutil.wl.display_policy.proto && ret != -1)
1236           ret = wl_display_dispatch_queue(_eflutil.wl.dpy, _eflutil.wl.queue);
1237
1238         EINA_SAFETY_ON_NULL_RETURN_VAL(_eflutil.wl.display_policy.proto, EINA_FALSE);
1239      }
1240
1241    return EINA_TRUE;
1242 }
1243
1244 API int
1245 efl_util_set_window_brightness(Evas_Object *window, int brightness)
1246 {
1247    Ecore_Wl_Window *wlwin;
1248    struct wl_surface *surface;
1249    Efl_Util_Wl_Surface_Brightness_Info *brightness_info;
1250    Eina_Bool ret;
1251
1252    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EFL_UTIL_ERROR_INVALID_PARAMETER);
1253    EINA_SAFETY_ON_FALSE_RETURN_VAL(brightness <= 100, EFL_UTIL_ERROR_INVALID_PARAMETER);
1254
1255    wlwin = elm_win_wl_window_get(window);
1256    EINA_SAFETY_ON_NULL_RETURN_VAL(wlwin, EFL_UTIL_ERROR_INVALID_PARAMETER);
1257
1258    surface = ecore_wl_window_surface_get(wlwin);
1259    EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EFL_UTIL_ERROR_INVALID_PARAMETER);
1260
1261    ret = _init_tizen_display_policy_proto();
1262    EINA_SAFETY_ON_FALSE_RETURN_VAL(ret, EFL_UTIL_ERROR_NOT_SUPPORTED);
1263
1264    brightness_info = eina_hash_find(_eflutil.wl.display_policy.hash_brightness, &surface);
1265    if (!brightness_info)
1266      {
1267         brightness_info = calloc(1, sizeof(Efl_Util_Wl_Surface_Brightness_Info));
1268         EINA_SAFETY_ON_NULL_RETURN_VAL(brightness_info, EFL_UTIL_ERROR_OUT_OF_MEMORY);
1269
1270         brightness_info->surface = surface;
1271         brightness_info->brightness = brightness;
1272         brightness_info->wait_for_done = EINA_TRUE;
1273         brightness_info->state = TIZEN_DISPLAY_POLICY_ERROR_STATE_NONE;
1274
1275         eina_hash_add(_eflutil.wl.display_policy.hash_brightness,
1276                       &surface,
1277                       brightness_info);
1278      }
1279    else
1280      {
1281         brightness_info->brightness = brightness;
1282         brightness_info->wait_for_done = EINA_TRUE;
1283         brightness_info->state = TIZEN_DISPLAY_POLICY_ERROR_STATE_NONE;
1284      }
1285
1286    tizen_display_policy_set_window_brightness(_eflutil.wl.display_policy.proto,
1287                                               surface, brightness);
1288    if (brightness_info->wait_for_done)
1289      {
1290         int count = 0;
1291         while (brightness_info->wait_for_done && (count < 3))
1292           {
1293              ecore_wl_flush();
1294              wl_display_dispatch_queue(_eflutil.wl.dpy, _eflutil.wl.queue);
1295              count++;
1296           }
1297
1298         if (brightness_info->wait_for_done)
1299           {
1300              return EFL_UTIL_ERROR_INVALID_PARAMETER;
1301           }
1302         else
1303           {
1304              if (brightness_info->state == TIZEN_DISPLAY_POLICY_ERROR_STATE_PERMISSION_DENIED)
1305                {
1306                   return EFL_UTIL_ERROR_PERMISSION_DENIED;
1307                }
1308           }
1309      }
1310
1311    return EFL_UTIL_ERROR_NONE;
1312 }
1313
1314 API int
1315 efl_util_get_window_brightness(Evas_Object *window, int *brightness)
1316 {
1317    Ecore_Wl_Window *wlwin;
1318    struct wl_surface *surface;
1319    Efl_Util_Wl_Surface_Brightness_Info *brightness_info;
1320    Eina_Bool ret;
1321
1322    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EFL_UTIL_ERROR_INVALID_PARAMETER);
1323    EINA_SAFETY_ON_NULL_RETURN_VAL(brightness, EFL_UTIL_ERROR_INVALID_PARAMETER);
1324
1325    wlwin = elm_win_wl_window_get(window);
1326    EINA_SAFETY_ON_NULL_RETURN_VAL(wlwin, EFL_UTIL_ERROR_INVALID_PARAMETER);
1327
1328    surface = ecore_wl_window_surface_get(wlwin);
1329    EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EFL_UTIL_ERROR_INVALID_PARAMETER);
1330
1331    ret = _init_tizen_display_policy_proto();
1332    EINA_SAFETY_ON_FALSE_RETURN_VAL(ret, EFL_UTIL_ERROR_NOT_SUPPORTED);
1333
1334    brightness_info = eina_hash_find(_eflutil.wl.display_policy.hash_brightness, &surface);
1335    if (brightness_info)
1336      {
1337         if (brightness_info->wait_for_done)
1338           {
1339              while (brightness_info->wait_for_done)
1340                {
1341                   ecore_wl_flush();
1342                   wl_display_dispatch_queue(_eflutil.wl.dpy, _eflutil.wl.queue);
1343                }
1344           }
1345          *brightness = brightness_info->brightness;
1346      }
1347    else
1348      *brightness = -1;
1349
1350    return EFL_UTIL_ERROR_NONE;
1351 }
1352
1353
1354 struct _efl_util_inputgen_h
1355 {
1356    unsigned int init_type;
1357 };
1358
1359 static void
1360 _cb_device_add(void *data EINA_UNUSED,
1361                struct tizen_input_device_manager *tizen_input_device_manager EINA_UNUSED,
1362                uint32_t serial EINA_UNUSED,
1363                const char *identifier EINA_UNUSED,
1364                struct tizen_input_device *device,
1365                struct wl_seat *seat EINA_UNUSED)
1366 {
1367    Eina_List *l;
1368    struct tizen_input_device *ddata;
1369
1370    EINA_LIST_FOREACH(_eflutil.wl.devmgr.device_list, l, ddata)
1371      {
1372         if (device == ddata) return;
1373      }
1374    tizen_input_device_add_listener(device, &_wl_tz_dev_listener, NULL);
1375    _eflutil.wl.devmgr.device_list = eina_list_append(_eflutil.wl.devmgr.device_list, device);
1376 }
1377
1378 /* LCOV_EXCL_START */
1379 static void
1380 _cb_device_remove(void *data EINA_UNUSED,
1381                struct tizen_input_device_manager *tizen_input_device_manager EINA_UNUSED,
1382                uint32_t serial  EINA_UNUSED,
1383                const char *identifier  EINA_UNUSED,
1384                struct tizen_input_device *device,
1385                struct wl_seat *seat  EINA_UNUSED)
1386 {
1387    Eina_List *l, *ll;
1388    struct tizen_input_device *ddata;
1389
1390    EINA_LIST_FOREACH_SAFE(_eflutil.wl.devmgr.device_list, l, ll, ddata)
1391      {
1392         if (device == ddata)
1393           {
1394              _eflutil.wl.devmgr.device_list = eina_list_remove_list(_eflutil.wl.devmgr.device_list, l);
1395              tizen_input_device_release(device);
1396           }
1397      }
1398 }
1399 /* LCOV_EXCL_STOP */
1400
1401 static void
1402 _cb_error(void *data EINA_UNUSED,
1403           struct tizen_input_device_manager *tizen_input_device_manager EINA_UNUSED,
1404           uint32_t errorcode)
1405 {
1406    _eflutil.wl.devmgr.request_notified = errorcode;
1407 }
1408
1409 /* LCOV_EXCL_START */
1410 static void
1411 _cb_block_expired(void *data EINA_UNUSED,
1412                   struct tizen_input_device_manager *tizen_input_device_manager EINA_UNUSED)
1413 {
1414    ;
1415 }
1416 /* LCOV_EXCL_STOP */
1417
1418 /* LCOV_EXCL_START */
1419 static void
1420 _cb_device_info(void *data EINA_UNUSED,
1421                 struct tizen_input_device *tizen_input_device EINA_UNUSED,
1422                 const char *name EINA_UNUSED, uint32_t clas EINA_UNUSED,
1423                 uint32_t subclas EINA_UNUSED, struct wl_array *axes EINA_UNUSED)
1424 {
1425    ;
1426 }
1427
1428 static void
1429 _cb_event_device(void *data EINA_UNUSED,
1430                  struct tizen_input_device *tizen_input_device EINA_UNUSED,
1431                  unsigned int serial EINA_UNUSED,
1432                  const char *name EINA_UNUSED, uint32_t time EINA_UNUSED)
1433 {
1434    ;
1435 }
1436
1437 static void
1438 _cb_axis(void *data EINA_UNUSED,
1439          struct tizen_input_device *tizen_input_device EINA_UNUSED,
1440          uint32_t axis_type EINA_UNUSED, wl_fixed_t value EINA_UNUSED)
1441 {
1442    ;
1443 }
1444 /* LCOV_EXCL_STOP */
1445
1446 static efl_util_error_e
1447 _efl_util_input_convert_input_generator_error(int ret)
1448 {
1449    switch (ret)
1450      {
1451         case TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE:
1452            return EFL_UTIL_ERROR_NONE;
1453         case TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_PERMISSION:
1454            return EFL_UTIL_ERROR_PERMISSION_DENIED;
1455         case TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES:
1456            return EFL_UTIL_ERROR_OUT_OF_MEMORY;
1457         case TIZEN_INPUT_DEVICE_MANAGER_ERROR_INVALID_PARAMETER:
1458            return EFL_UTIL_ERROR_INVALID_PARAMETER;
1459         default :
1460            return EFL_UTIL_ERROR_NONE;
1461      }
1462 }
1463
1464 API efl_util_inputgen_h
1465 efl_util_input_initialize_generator(unsigned int dev_type)
1466 {
1467    int ret = EFL_UTIL_ERROR_NONE;
1468    efl_util_inputgen_h inputgen_h = NULL;
1469
1470    if (!dev_type ||
1471         dev_type & ~(EFL_UTIL_INPUT_DEVTYPE_TOUCHSCREEN
1472                     | EFL_UTIL_INPUT_DEVTYPE_KEYBOARD
1473                     | EFL_UTIL_INPUT_DEVTYPE_POINTER))
1474      {
1475         set_last_result(EFL_UTIL_ERROR_NO_SUCH_DEVICE);
1476         goto out;
1477      }
1478
1479    inputgen_h = (efl_util_inputgen_h)calloc(1, sizeof(struct _efl_util_inputgen_h));
1480    if (!inputgen_h)
1481      {
1482         set_last_result(EFL_UTIL_ERROR_OUT_OF_MEMORY);
1483         goto out;
1484      }
1485
1486    inputgen_h->init_type |= dev_type;
1487
1488    ret = _wl_init();
1489    if (ret == (int)EINA_FALSE)
1490      {
1491         set_last_result(EFL_UTIL_ERROR_INVALID_PARAMETER);
1492         goto out;
1493      }
1494
1495    while (!_eflutil.wl.devmgr.devicemgr)
1496      wl_display_dispatch_queue(_eflutil.wl.dpy, _eflutil.wl.queue);
1497
1498    tizen_input_device_manager_init_generator(_eflutil.wl.devmgr.devicemgr);
1499
1500    while (_eflutil.wl.devmgr.request_notified == -1)
1501      wl_display_dispatch_queue(_eflutil.wl.dpy, _eflutil.wl.queue);
1502
1503    ret = _efl_util_input_convert_input_generator_error(_eflutil.wl.devmgr.request_notified);
1504    _eflutil.wl.devmgr.request_notified = -1;
1505
1506    set_last_result(ret);
1507    if (ret != TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE)
1508      goto out;
1509
1510    return inputgen_h;
1511
1512 out:
1513    if (inputgen_h)
1514      {
1515         free(inputgen_h);
1516         inputgen_h = NULL;
1517      }
1518    return NULL;
1519 }
1520
1521 API int
1522 efl_util_input_deinitialize_generator(efl_util_inputgen_h inputgen_h)
1523 {
1524    int ret = EFL_UTIL_ERROR_NONE;
1525    EINA_SAFETY_ON_NULL_RETURN_VAL(inputgen_h, EFL_UTIL_ERROR_INVALID_PARAMETER);
1526
1527    free(inputgen_h);
1528    inputgen_h = NULL;
1529
1530    EINA_SAFETY_ON_NULL_RETURN_VAL(_eflutil.wl.devmgr.devicemgr, EFL_UTIL_ERROR_INVALID_PARAMETER);
1531
1532    tizen_input_device_manager_deinit_generator(_eflutil.wl.devmgr.devicemgr);
1533
1534    while (_eflutil.wl.devmgr.request_notified == -1)
1535      wl_display_dispatch_queue(_eflutil.wl.dpy, _eflutil.wl.queue);
1536
1537    ret = _efl_util_input_convert_input_generator_error(_eflutil.wl.devmgr.request_notified);
1538    _eflutil.wl.devmgr.request_notified = -1;
1539
1540    _wl_shutdown();
1541
1542    return ret;
1543 }
1544
1545 API int
1546 efl_util_input_generate_key(efl_util_inputgen_h inputgen_h, const char *key_name, int pressed)
1547 {
1548    int ret = EFL_UTIL_ERROR_NONE;
1549
1550    EINA_SAFETY_ON_NULL_RETURN_VAL(inputgen_h, EFL_UTIL_ERROR_INVALID_PARAMETER);
1551    EINA_SAFETY_ON_NULL_RETURN_VAL(key_name, EFL_UTIL_ERROR_INVALID_PARAMETER);
1552    EINA_SAFETY_ON_FALSE_RETURN_VAL(pressed == 0 || pressed == 1, EFL_UTIL_ERROR_INVALID_PARAMETER);
1553    EINA_SAFETY_ON_FALSE_RETURN_VAL(inputgen_h->init_type & EFL_UTIL_INPUT_DEVTYPE_KEYBOARD, EFL_UTIL_ERROR_NO_SUCH_DEVICE);
1554
1555    EINA_SAFETY_ON_NULL_RETURN_VAL(_eflutil.wl.devmgr.devicemgr, EFL_UTIL_ERROR_INVALID_PARAMETER);
1556
1557    tizen_input_device_manager_generate_key(_eflutil.wl.devmgr.devicemgr, key_name, pressed);
1558
1559    while (_eflutil.wl.devmgr.request_notified == -1)
1560      wl_display_dispatch_queue(_eflutil.wl.dpy, _eflutil.wl.queue);
1561
1562    ret = _efl_util_input_convert_input_generator_error(_eflutil.wl.devmgr.request_notified);
1563    _eflutil.wl.devmgr.request_notified = -1;
1564
1565    return ret;
1566 }
1567
1568 API int
1569 efl_util_input_generate_touch(efl_util_inputgen_h inputgen_h, int idx,
1570                               efl_util_input_touch_type_e touch_type, int x, int y)
1571 {
1572    int ret;
1573    enum tizen_input_device_manager_pointer_event_type type;
1574
1575    EINA_SAFETY_ON_NULL_RETURN_VAL(inputgen_h, EFL_UTIL_ERROR_INVALID_PARAMETER);
1576    EINA_SAFETY_ON_FALSE_RETURN_VAL(idx >= 0, EFL_UTIL_ERROR_INVALID_PARAMETER);
1577    EINA_SAFETY_ON_FALSE_RETURN_VAL((x > 0 && y > 0), EFL_UTIL_ERROR_INVALID_PARAMETER);
1578    EINA_SAFETY_ON_FALSE_RETURN_VAL(inputgen_h->init_type & EFL_UTIL_INPUT_DEVTYPE_TOUCHSCREEN, EFL_UTIL_ERROR_NO_SUCH_DEVICE);
1579
1580    EINA_SAFETY_ON_NULL_RETURN_VAL(_eflutil.wl.devmgr.devicemgr, EFL_UTIL_ERROR_INVALID_PARAMETER);
1581
1582    switch(touch_type)
1583      {
1584         case EFL_UTIL_INPUT_TOUCH_BEGIN:
1585            type = TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_BEGIN;
1586            break;
1587         case EFL_UTIL_INPUT_TOUCH_UPDATE:
1588            type = TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_UPDATE;
1589            break;
1590         case EFL_UTIL_INPUT_TOUCH_END:
1591            type = TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_END;
1592            break;
1593         default:
1594            return EFL_UTIL_ERROR_INVALID_PARAMETER;
1595      }
1596
1597    tizen_input_device_manager_generate_touch(_eflutil.wl.devmgr.devicemgr, type, x, y, idx);
1598
1599    while (_eflutil.wl.devmgr.request_notified == -1)
1600      wl_display_dispatch_queue(_eflutil.wl.dpy, _eflutil.wl.queue);
1601
1602    ret = _efl_util_input_convert_input_generator_error(_eflutil.wl.devmgr.request_notified);
1603    _eflutil.wl.devmgr.request_notified = -1;
1604
1605    return ret;
1606 }
1607
1608 API int
1609 efl_util_input_generate_pointer(efl_util_inputgen_h inputgen_h, int buttons, efl_util_input_pointer_type_e pointer_type, int x, int y)
1610 {
1611    int ret;
1612    enum tizen_input_device_manager_pointer_event_type type;
1613
1614    EINA_SAFETY_ON_NULL_RETURN_VAL(inputgen_h, EFL_UTIL_ERROR_INVALID_PARAMETER);
1615    EINA_SAFETY_ON_FALSE_RETURN_VAL(buttons > 0, EFL_UTIL_ERROR_INVALID_PARAMETER);
1616    EINA_SAFETY_ON_FALSE_RETURN_VAL((x >= 0 && y >= 0), EFL_UTIL_ERROR_INVALID_PARAMETER);
1617    EINA_SAFETY_ON_FALSE_RETURN_VAL(inputgen_h->init_type & EFL_UTIL_INPUT_DEVTYPE_POINTER, EFL_UTIL_ERROR_NO_SUCH_DEVICE);
1618
1619    EINA_SAFETY_ON_NULL_RETURN_VAL(_eflutil.wl.devmgr.devicemgr, EFL_UTIL_ERROR_INVALID_PARAMETER);
1620
1621    switch(pointer_type)
1622      {
1623         case EFL_UTIL_INPUT_POINTER_BUTTON_DOWN:
1624            type = TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_BEGIN;
1625            break;
1626         case EFL_UTIL_INPUT_POINTER_MOVE:
1627            type = TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_UPDATE;
1628            break;
1629         case EFL_UTIL_INPUT_POINTER_BUTTON_UP:
1630            type = TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_END;
1631            break;
1632         default:
1633            return EFL_UTIL_ERROR_INVALID_PARAMETER;
1634      }
1635
1636    tizen_input_device_manager_generate_pointer(_eflutil.wl.devmgr.devicemgr, type, x, y, buttons);
1637
1638    while (_eflutil.wl.devmgr.request_notified == -1)
1639      wl_display_dispatch_queue(_eflutil.wl.dpy, _eflutil.wl.queue);
1640
1641    ret = _efl_util_input_convert_input_generator_error(_eflutil.wl.devmgr.request_notified);
1642    _eflutil.wl.devmgr.request_notified = -1;
1643
1644    return ret;
1645 }
1646
1647
1648 struct _efl_util_screenshot_h
1649 {
1650    int width;
1651    int height;
1652
1653    Eina_Bool shot_done;
1654
1655    /* tbm bufmgr */
1656    tbm_bufmgr bufmgr;
1657
1658    Eina_Bool auto_rotation;
1659 };
1660
1661 /* scrrenshot handle */
1662 static efl_util_screenshot_h g_screenshot;
1663 static Eina_Bool shot_mutex_init;
1664 static pthread_mutex_t shot_lock;
1665
1666 static Eina_Bool
1667 _screenshot_mutex_init(void)
1668 {
1669    if (shot_mutex_init)
1670      return EINA_TRUE;
1671
1672    if (pthread_mutex_init(&shot_lock, NULL))
1673      {
1674         fprintf(stderr, "[screenshot] fail: mutex init"); /*LCOV_EXCL_LINE*/
1675         return EINA_FALSE; /*LCOV_EXCL_LINE*/
1676      }
1677
1678    shot_mutex_init = EINA_TRUE;
1679
1680    return EINA_TRUE;
1681 }
1682
1683 static Eina_Bool
1684 _screenshot_mutex_destory(void)
1685 {
1686    if (!shot_mutex_init)
1687      return EINA_TRUE;
1688
1689    if (pthread_mutex_destroy(&shot_lock))
1690      {
1691         fprintf(stderr, "[screenshot] fail: mutex destory"); /*LCOV_EXCL_LINE*/
1692         return EINA_FALSE; /*LCOV_EXCL_LINE*/
1693      }
1694
1695    shot_mutex_init = EINA_FALSE;
1696
1697    return EINA_TRUE;
1698 }
1699
1700 void
1701 _screenshot_mutex_lock(void)
1702 {
1703    if (!_screenshot_mutex_init())
1704      return;
1705
1706    pthread_mutex_lock(&shot_lock);
1707 }
1708
1709 void
1710 _screenshot_mutex_unlock(void)
1711 {
1712    pthread_mutex_unlock(&shot_lock);
1713 }
1714
1715 API efl_util_screenshot_h
1716 efl_util_screenshot_initialize(int width, int height)
1717 {
1718    efl_util_screenshot_h screenshot = NULL;
1719    struct wl_display *display_wrapper = NULL;
1720    struct wl_registry *reg = NULL;
1721    int ret = 0;
1722
1723    EINA_SAFETY_ON_FALSE_GOTO(width > 0, fail_param);
1724    EINA_SAFETY_ON_FALSE_GOTO(height > 0, fail_param);
1725
1726    _screenshot_mutex_lock();
1727
1728    if (!_eflutil.wl.shot.screenshooter)
1729      {
1730         ret = _wl_init();
1731         if (ret == (int)EINA_FALSE)
1732           {
1733              set_last_result(EFL_UTIL_ERROR_INVALID_PARAMETER);
1734              _screenshot_mutex_unlock();
1735              return NULL;
1736           }
1737         wl_display_roundtrip_queue(_eflutil.wl.dpy, _eflutil.wl.queue);
1738
1739         display_wrapper = wl_proxy_create_wrapper(_eflutil.wl.dpy);
1740         EINA_SAFETY_ON_NULL_GOTO(display_wrapper, fail_init);
1741
1742         _eflutil.wl.shot.queue = wl_display_create_queue(_eflutil.wl.dpy);
1743         EINA_SAFETY_ON_NULL_GOTO(_eflutil.wl.shot.queue, fail_init);
1744
1745         reg = wl_display_get_registry(display_wrapper);
1746         EINA_SAFETY_ON_NULL_GOTO(reg, fail_init);
1747
1748         wl_proxy_set_queue((struct wl_proxy*)reg, _eflutil.wl.shot.queue);
1749
1750         wl_registry_add_listener(reg, &_wl_reg_screenshooter_listener, NULL);
1751
1752         ret = wl_display_roundtrip_queue(_eflutil.wl.dpy, _eflutil.wl.shot.queue);
1753         EINA_SAFETY_ON_TRUE_GOTO(ret == -1, fail_init);
1754         EINA_SAFETY_ON_NULL_GOTO(_eflutil.wl.shot.screenshooter, fail_init);
1755         EINA_SAFETY_ON_NULL_GOTO(_eflutil.wl.shot.tz_screenshooter, fail_init);
1756
1757         _eflutil.wl.shot.tbm_client = wayland_tbm_client_init(_eflutil.wl.dpy);
1758         EINA_SAFETY_ON_NULL_GOTO(_eflutil.wl.shot.tbm_client, fail_init);
1759      }
1760
1761    if (_eflutil.wl.shot.noti == 0)
1762      {
1763         fprintf(stderr, "[screenshot] fail: privilege error\n"); /* LCOV_EXCL_LINE */
1764         goto fail_init;
1765      }
1766
1767    if (g_screenshot)
1768      {
1769         if (g_screenshot->width != width || g_screenshot->height != height)
1770           {
1771              g_screenshot->width = width;
1772              g_screenshot->height = height;
1773           }
1774
1775         _screenshot_mutex_unlock();
1776
1777         return g_screenshot;
1778      }
1779
1780    screenshot = calloc(1, sizeof(struct _efl_util_screenshot_h));
1781    EINA_SAFETY_ON_NULL_GOTO(screenshot, fail_memory);
1782
1783    screenshot->width = width;
1784    screenshot->height = height;
1785    screenshot->auto_rotation = EINA_TRUE;
1786
1787    screenshot->bufmgr = wayland_tbm_client_get_bufmgr(_eflutil.wl.shot.tbm_client);
1788    EINA_SAFETY_ON_NULL_GOTO(screenshot->bufmgr, fail_init);
1789
1790    g_screenshot = screenshot;
1791    set_last_result(EFL_UTIL_ERROR_NONE);
1792
1793    screenshooter_set_user_data(_eflutil.wl.shot.screenshooter, &screenshot->shot_done);
1794
1795    _screenshot_mutex_unlock();
1796
1797    return g_screenshot;
1798
1799 fail_param:
1800    set_last_result(EFL_UTIL_ERROR_INVALID_PARAMETER);
1801    return NULL;
1802 fail_memory:
1803 /* LCOV_EXCL_START */
1804    if (display_wrapper)
1805      wl_proxy_wrapper_destroy(display_wrapper);
1806    set_last_result(EFL_UTIL_ERROR_OUT_OF_MEMORY);
1807    return NULL;
1808 /* LCOV_EXCL_STOP */
1809 fail_init:
1810    if (screenshot)
1811      efl_util_screenshot_deinitialize(screenshot);
1812    _screenshot_mutex_unlock();
1813    if (display_wrapper)
1814      wl_proxy_wrapper_destroy(display_wrapper);
1815    set_last_result(EFL_UTIL_ERROR_SCREENSHOT_INIT_FAIL);
1816    return NULL;
1817 }
1818
1819 API int
1820 efl_util_screenshot_deinitialize(efl_util_screenshot_h screenshot)
1821 {
1822    _screenshot_mutex_lock();
1823
1824    if (!screenshot)
1825      {
1826         _screenshot_mutex_unlock();
1827         _screenshot_mutex_destory();
1828         return EFL_UTIL_ERROR_INVALID_PARAMETER;
1829      }
1830
1831    free(screenshot);
1832    g_screenshot = NULL;
1833
1834    if (_eflutil.wl.shot.queue)
1835      {
1836         wl_event_queue_destroy(_eflutil.wl.shot.queue);
1837         _eflutil.wl.shot.queue = NULL;
1838      }
1839
1840    if (_eflutil.wl.shot.screenshooter)
1841      {
1842         screenshooter_destroy(_eflutil.wl.shot.screenshooter);
1843         _eflutil.wl.shot.screenshooter = NULL;
1844      }
1845    if (_eflutil.wl.shot.tz_screenshooter)
1846      {
1847         tizen_screenshooter_destroy(_eflutil.wl.shot.tz_screenshooter);
1848         _eflutil.wl.shot.tz_screenshooter = NULL;
1849      }
1850
1851    _screenshot_mutex_unlock();
1852    _screenshot_mutex_destory();
1853
1854    _wl_shutdown();
1855
1856    return EFL_UTIL_ERROR_NONE;
1857 }
1858
1859
1860 API tbm_surface_h
1861 efl_util_screenshot_take_tbm_surface(efl_util_screenshot_h screenshot)
1862 {
1863    tbm_surface_h t_surface = NULL;
1864    struct wl_buffer *buffer = NULL;
1865    Efl_Util_Wl_Output_Info *output;
1866    int ret = 0;
1867
1868    _screenshot_mutex_lock();
1869
1870    if (!screenshot || (screenshot != g_screenshot))
1871      {
1872         set_last_result(EFL_UTIL_ERROR_INVALID_PARAMETER);
1873         _screenshot_mutex_unlock();
1874         return NULL;
1875      }
1876
1877    output = eina_list_nth(_eflutil.wl.shot.output_list, 0);
1878    if (!output)
1879      {
1880         fprintf(stderr, "[screenshot] fail: no output for screenshot\n"); /* LCOV_EXCL_LINE */
1881         goto fail;
1882      }
1883
1884    t_surface = tbm_surface_create(screenshot->width, screenshot->height, TBM_FORMAT_XRGB8888);
1885    if (!t_surface)
1886      {
1887         fprintf(stderr, "[screenshot] fail: tbm_surface_create\n"); /* LCOV_EXCL_LINE */
1888         goto fail;
1889      }
1890
1891    buffer = wayland_tbm_client_create_buffer(_eflutil.wl.shot.tbm_client, t_surface);
1892    if (!buffer)
1893      {
1894         fprintf(stderr, "[screenshot] fail: create wl_buffer for screenshot\n"); /* LCOV_EXCL_LINE */
1895         goto fail;
1896      }
1897
1898    screenshooter_shoot(_eflutil.wl.shot.screenshooter, output->output, buffer);
1899
1900    screenshot->shot_done = EINA_FALSE;
1901    while (!screenshot->shot_done && ret != -1)
1902      ret = wl_display_roundtrip_queue(_eflutil.wl.dpy, _eflutil.wl.shot.queue);
1903
1904    if (ret == -1)
1905      {
1906         fprintf(stderr, "[screenshot] fail: screenshooter_shoot\n"); /* LCOV_EXCL_LINE */
1907         goto fail;
1908      }
1909
1910    wl_buffer_destroy(buffer);
1911
1912    /* reset shot_done for next screenshot */
1913    screenshot->shot_done = EINA_FALSE;
1914
1915    set_last_result(EFL_UTIL_ERROR_NONE);
1916
1917    _screenshot_mutex_unlock();
1918
1919    return t_surface;
1920
1921 fail:
1922    if (t_surface)
1923      tbm_surface_destroy(t_surface);
1924    if (buffer)
1925      wl_buffer_destroy(buffer);
1926
1927    set_last_result(EFL_UTIL_ERROR_SCREENSHOT_EXECUTION_FAIL);
1928
1929    _screenshot_mutex_unlock();
1930
1931    return NULL;
1932 }
1933
1934 API int
1935 efl_util_screenshot_set_auto_rotation(efl_util_screenshot_h screenshot, int set)
1936 {
1937    if (!screenshot || (screenshot != g_screenshot))
1938      return EFL_UTIL_ERROR_INVALID_PARAMETER;
1939
1940    if (!(set == 0 || set == 1))
1941      return EFL_UTIL_ERROR_INVALID_PARAMETER;
1942
1943    if (set)
1944      g_screenshot->auto_rotation = EINA_TRUE;
1945    else
1946      g_screenshot->auto_rotation = EINA_FALSE;
1947
1948    tizen_screenshooter_set_oneshot_auto_rotation(_eflutil.wl.shot.tz_screenshooter, g_screenshot->auto_rotation);
1949
1950    return EFL_UTIL_ERROR_NONE;
1951 }
1952
1953 API int
1954 efl_util_screenshot_get_auto_rotation(efl_util_screenshot_h screenshot, int *set)
1955 {
1956    if (!screenshot || (screenshot != g_screenshot) || !set)
1957      return EFL_UTIL_ERROR_INVALID_PARAMETER;
1958
1959    *set = g_screenshot->auto_rotation;
1960
1961    return EFL_UTIL_ERROR_NONE;
1962 }