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