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