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