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