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