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