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