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