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