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