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