Add Window screen mode apis with wayland
[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 <Elementary.h>
24 #include <Ecore_Evas.h>
25
26 #if X11
27 #include <Ecore_X.h>
28 #include <utilX.h>
29 #endif /* end of X11 */
30
31 #if WAYLAND
32 #include <Ecore_Wayland.h>
33 #include <wayland-client.h>
34 #include "tizen_notification-client-protocol.h"
35 #include "tizen_window_screen-client-protocol.h"
36 #endif /* end of WAYLAND */
37
38 /* callback handler index */
39 #define CBH_NOTI_LEV 0
40 #define CBH_SCR_MODE 1
41 #define CBH_MAX      2
42
43 typedef void (*Efl_Util_Cb)(Evas_Object *, int, void *);
44
45 typedef struct _Efl_Util_Callback_Info
46 {
47    Evas_Object *win;
48    Efl_Util_Cb cb;
49    void *data;
50 } Efl_Util_Callback_Info;
51
52 typedef struct _Efl_Util_Wl_Surface_Lv_Info
53 {
54    void *surface; /* wl_surface */
55    int level;
56    Eina_Bool wait_for_done;
57 } Efl_Util_Wl_Surface_Lv_Info;
58
59 typedef struct _Efl_Util_Wl_Surface_Scr_Mode_Info
60 {
61    void *surface; /* wl_surface */
62    unsigned int mode;
63    Eina_Bool wait_for_done;
64 } Efl_Util_Wl_Surface_Scr_Mode_Info;
65
66 typedef struct _Efl_Util_Data
67 {
68    Ecore_Event_Handler *handler; /* x11 client message handler */
69    struct
70    {
71       Eina_List *info_list; /* list of callback info */
72       unsigned int atom; /* x11 atom */
73    } cb_handler[CBH_MAX];
74
75    /* wayland related stuffs */
76    struct
77    {
78       Eina_Bool init;
79       #if WAYLAND
80       struct wl_display *dpy;
81       struct
82       {
83          struct tizen_notification *proto;
84          Eina_Hash *hash;
85       } noti_lv;
86       struct
87       {
88          struct tizen_window_screen *proto;
89          Eina_Hash *hash;
90       } win_scr_mode;
91       #endif /* end of WAYLAND */
92    } wl;
93 } Efl_Util_Data;
94
95 static Efl_Util_Data _eflutil =
96 {
97    NULL,
98    {
99       { NULL, 0 }, /* handler for notification level */
100       { NULL, 0 }  /* handler for screen mode */
101    },
102    {
103       EINA_FALSE,
104       #if WAYLAND
105       NULL,
106       { NULL, NULL }, /* tizen_notification protocol */
107       { NULL, NULL }  /* tizen_window_screen protocol */
108       #endif /* end of WAYLAND */
109    }
110 };
111
112 static Eina_Bool               _cb_info_add(Evas_Object *win, Efl_Util_Cb cb, void *data, int idx);
113 static Eina_Bool               _cb_info_del_by_win(Evas_Object *win, int idx);
114 static Eina_List              *_cb_info_list_get(int idx);
115 static Efl_Util_Callback_Info *_cb_info_find_by_win(Evas_Object *win, int idx);
116 #if X11
117 static Efl_Util_Callback_Info *_cb_info_find_by_xwin(unsigned int xwin);
118 static Eina_Bool               _cb_x11_client_msg(void *data, int type, void *event);
119 #endif /* end of X11 */
120 #if WAYLAND
121 static Eina_Bool               _wl_init(void);
122 static void                    _cb_wl_reg_global(void *data, struct wl_registry *reg, unsigned int name, const char *interface, unsigned int version);
123 static void                    _cb_wl_reg_global_remove(void *data, struct wl_registry *reg, unsigned int name);
124 static Efl_Util_Callback_Info *_cb_info_find_by_wlsurf(void *wlsurf, int idx);
125 static void                    _cb_wl_tz_noti_lv_done(void *data, struct tizen_notification *proto, struct wl_surface *surface, int32_t level, uint32_t state);
126 static void                    _cb_wl_tz_win_scr_mode_done(void *data, struct tizen_window_screen *proto, struct wl_surface *surface, uint32_t mode, uint32_t state);
127
128 static const struct wl_registry_listener _wl_reg_listener =
129 {
130    _cb_wl_reg_global,
131    _cb_wl_reg_global_remove
132 };
133
134 struct tizen_notification_listener _wl_tz_noti_lv_listener =
135 {
136    _cb_wl_tz_noti_lv_done
137 };
138
139 struct tizen_window_screen_listener _wl_tz_win_scr_mode_listener =
140 {
141    _cb_wl_tz_win_scr_mode_done
142 };
143 #endif /* end of WAYLAND */
144
145 static Eina_Bool
146 _cb_info_add(Evas_Object *win,
147              Efl_Util_Cb cb,
148              void *data,
149              int idx)
150 {
151    Efl_Util_Callback_Info *info;
152
153    info = _cb_info_find_by_win(win, idx);
154    if (info)
155      {
156         _eflutil.cb_handler[idx].info_list
157            = eina_list_remove(_eflutil.cb_handler[idx].info_list,
158                               info);
159         free(info);
160      }
161
162    info = (Efl_Util_Callback_Info *)calloc(1, sizeof(Efl_Util_Callback_Info));
163    if (!info) return EINA_FALSE;
164
165    info->win = win;
166    info->cb = cb;
167    info->data = data;
168
169    _eflutil.cb_handler[idx].info_list
170       = eina_list_append(_eflutil.cb_handler[idx].info_list,
171                          info);
172
173 #if X11
174    if (!_eflutil.handler)
175      _eflutil.handler = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE,
176                                                 _cb_x11_client_msg,
177                                                 NULL);
178 #endif /* end of X11 */
179
180    return EINA_TRUE;
181 }
182
183 static Eina_Bool
184 _cb_info_del_by_win(Evas_Object *win,
185                     int idx)
186 {
187    Efl_Util_Callback_Info *info;
188    unsigned int count;
189
190    info = _cb_info_find_by_win(win, idx);
191    if (!info) return EINA_FALSE;
192
193    _eflutil.cb_handler[idx].info_list
194       = eina_list_remove(_eflutil.cb_handler[idx].info_list,
195                          info);
196    free(info);
197
198    count = eina_list_count(_eflutil.cb_handler[idx].info_list);
199    if ((count == 0) && (_eflutil.handler))
200      {
201         ecore_event_handler_del(_eflutil.handler);
202         _eflutil.handler = NULL;
203      }
204
205    return EINA_TRUE;
206 }
207
208 static Eina_List *
209 _cb_info_list_get(int idx)
210 {
211    return _eflutil.cb_handler[idx].info_list;
212 }
213
214 static Efl_Util_Callback_Info *
215 _cb_info_find_by_win(Evas_Object *win,
216                      int idx)
217 {
218    Eina_List *l, *ll;
219    Efl_Util_Callback_Info *info;
220
221    l = _cb_info_list_get(idx);
222    EINA_LIST_FOREACH(l, ll, info)
223      {
224         if (info->win == win) return info;
225      }
226
227    return NULL;
228 }
229
230 #if X11
231 static Efl_Util_Callback_Info *
232 _cb_info_find_by_xwin(unsigned int xwin,
233                       int idx)
234 {
235    Eina_List *l, *ll;
236    Efl_Util_Callback_Info *info;
237    unsigned int xwin2;
238
239    l = _cb_info_list_get(idx);
240    EINA_LIST_FOREACH(l, ll, info)
241      {
242         xwin2 = elm_win_xwindow_get(info->win);
243         if (xwin == xwin2) return info;
244      }
245
246    return NULL;
247 }
248
249 static Eina_Bool
250 _cb_x11_client_msg(void *data,
251                    int type,
252                    void *event)
253 {
254    Ecore_X_Event_Client_Message *ev;
255    Ecore_X_Window xwin;
256    Efl_Util_Callback_Info *info;
257
258    ev = event;
259    if (!ev) return ECORE_CALLBACK_PASS_ON;
260
261    xwin = ev->win;
262    if (xwin == 0) return ECORE_CALLBACK_PASS_ON;
263
264    if (ev->message_type == _eflutil.atom.noti_lv)
265      {
266         info = _cb_info_find_by_xwin(xwin, CBH_NOTI_LEV);
267
268         /* permission denied */
269         if ((ev->data.l[1] == 0) &&
270             (info) &&
271             (info->cb))
272           {
273              info->cb(info->win,
274                       EFL_UTIL_ERROR_PERMISSION_DENIED,
275                       info->data);
276           }
277      }
278    else if (ev->message_type == _eflutil.atom.scr_mode)
279      {
280         info = _cb_info_find_by_xwin(xwin, CBH_SCR_MODE);
281
282         /* permission denied */
283         if ((ev->data.l[1] == 0) &&
284             (info) &&
285             (info->cb))
286           {
287              info->cb(info->win,
288                       EFL_UTIL_ERROR_PERMISSION_DENIED,
289                       info->data);
290           }
291      }
292    return ECORE_CALLBACK_PASS_ON;
293 }
294 #endif /* end of X11 */
295
296 #if WAYLAND
297 static Eina_Bool
298 _wl_init(void)
299 {
300    struct wl_registry *reg;
301
302    if (_eflutil.wl.init) return EINA_TRUE;
303
304    _eflutil.wl.dpy = ecore_wl_display_get();
305    EINA_SAFETY_ON_NULL_RETURN_VAL(_eflutil.wl.dpy, EINA_FALSE);
306
307    reg = wl_display_get_registry(_eflutil.wl.dpy);
308    EINA_SAFETY_ON_NULL_RETURN_VAL(reg, EINA_FALSE);
309
310    wl_registry_add_listener(reg, &_wl_reg_listener, NULL);
311
312    _eflutil.wl.init = EINA_TRUE;
313
314    return EINA_TRUE;
315 }
316
317 static void
318 _cb_wl_reg_global(void *data,
319                   struct wl_registry *reg,
320                   unsigned int name,
321                   const char *interface,
322                   unsigned int version)
323 {
324    if (!strcmp(interface, "tizen_notification"))
325      {
326         struct tizen_notification *proto;
327         proto = wl_registry_bind(reg,
328                                  name,
329                                  &tizen_notification_interface,
330                                  1);
331         if (!proto) return;
332
333         tizen_notification_add_listener(proto,
334                                         &_wl_tz_noti_lv_listener,
335                                         NULL);
336
337         _eflutil.wl.noti_lv.hash = eina_hash_pointer_new(free);
338         _eflutil.wl.noti_lv.proto = proto;
339      }
340    else if (!strcmp(interface, "tizen_window_screen"))
341      {
342         struct tizen_window_screen *proto;
343         proto = wl_registry_bind(reg,
344                                  name,
345                                  &tizen_window_screen_interface,
346                                  1);
347         if (!proto) return;
348
349         tizen_window_screen_add_listener(proto,
350                                          &_wl_tz_win_scr_mode_listener,
351                                          NULL);
352
353         _eflutil.wl.win_scr_mode.hash = eina_hash_pointer_new(free);
354         _eflutil.wl.win_scr_mode.proto = proto;
355      }
356 }
357
358 static void
359 _cb_wl_reg_global_remove(void *data,
360                          struct wl_registry *reg,
361                          unsigned int name)
362 {
363    _eflutil.wl.noti_lv.proto = NULL;
364    eina_hash_free(_eflutil.wl.noti_lv.hash);
365    _eflutil.wl.win_scr_mode.proto = NULL;
366    eina_hash_free(_eflutil.wl.win_scr_mode.hash);
367 }
368
369 static Efl_Util_Callback_Info *
370 _cb_info_find_by_wlsurf(void *wlsurf,
371                         int idx)
372 {
373    Eina_List *l, *ll;
374    Efl_Util_Callback_Info *info;
375    Ecore_Wl_Window *wlwin2 = NULL;
376    void *wlsurf2 = NULL;
377
378    l = _cb_info_list_get(idx);
379    EINA_LIST_FOREACH(l, ll, info)
380      {
381         wlwin2 = elm_win_wl_window_get(info->win);
382         wlsurf2 = ecore_wl_window_surface_get(wlwin2);
383         if (wlsurf== wlsurf2) return info;
384      }
385
386    return NULL;
387 }
388
389 static void
390 _cb_wl_tz_noti_lv_done(void *data,
391                        struct tizen_notification *proto,
392                        struct wl_surface *surface,
393                        int32_t level,
394                        uint32_t state)
395 {
396    Efl_Util_Wl_Surface_Lv_Info *lv_info;
397    Efl_Util_Callback_Info *cb_info;
398
399    lv_info = eina_hash_find(_eflutil.wl.noti_lv.hash, &surface);
400    if (lv_info)
401      {
402         lv_info->level = level;
403         lv_info->wait_for_done = EINA_FALSE;
404      }
405
406    if (state != TIZEN_NOTIFICATION_ERROR_STATE_PERMISSION_DENIED) return;
407
408    cb_info = _cb_info_find_by_wlsurf((void *)surface, CBH_NOTI_LEV);
409    if (!cb_info) return;
410    if (!cb_info->cb) return;
411
412    cb_info->cb(cb_info->win,
413                EFL_UTIL_ERROR_PERMISSION_DENIED,
414                cb_info->data);
415 }
416
417 static void
418 _cb_wl_tz_win_scr_mode_done(void *data,
419                           struct tizen_window_screen *proto,
420                           struct wl_surface *surface,
421                           uint32_t mode,
422                           uint32_t state)
423 {
424
425    Efl_Util_Wl_Surface_Scr_Mode_Info *scr_mode_info;
426    Efl_Util_Callback_Info *cb_info;
427
428    scr_mode_info = eina_hash_find(_eflutil.wl.win_scr_mode.hash, &surface);
429    if (scr_mode_info)
430      {
431         scr_mode_info->mode = mode;
432         scr_mode_info->wait_for_done = EINA_FALSE;
433      }
434
435    if (state != TIZEN_WINDOW_SCREEN_ERROR_STATE_PERMISSION_DENIED) return;
436
437    cb_info = _cb_info_find_by_wlsurf((void *)surface, CBH_SCR_MODE);
438    if (!cb_info) return;
439    if (!cb_info->cb) return;
440
441    cb_info->cb(cb_info->win,
442                EFL_UTIL_ERROR_PERMISSION_DENIED,
443                cb_info->data);
444 }
445 #endif /* end of WAYLAND */
446
447 API int
448 efl_util_set_notification_window_level(Evas_Object *window,
449                                        efl_util_notification_level_e level)
450 {
451    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EFL_UTIL_ERROR_INVALID_PARAMETER);
452    EINA_SAFETY_ON_FALSE_RETURN_VAL((level >= EFL_UTIL_NOTIFICATION_LEVEL_1) &&
453                                    (level <= EFL_UTIL_NOTIFICATION_LEVEL_TOP),
454                                    EFL_UTIL_ERROR_INVALID_PARAMETER);
455
456 #if X11
457    Ecore_X_Window xwin = elm_win_xwindow_get(window);
458    if (xwin)
459      {
460         Ecore_X_Window_Type window_type;
461         if (ecore_x_netwm_window_type_get(xwin, &window_type) == EINA_TRUE)
462           {
463              // success to get window type
464              if (window_type != ECORE_X_WINDOW_TYPE_NOTIFICATION)
465                {
466                   // given EFL window's type is not notification type.
467                   return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
468                }
469           }
470         else
471           return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
472
473         utilx_set_system_notification_level(ecore_x_display_get(), xwin, level);
474         return EFL_UTIL_ERROR_NONE;
475      }
476 #endif /* end of X11 */
477
478 #if WAYLAND
479    Elm_Win_Type type;
480    Ecore_Wl_Window *wlwin;
481    struct wl_surface *surface;
482    Efl_Util_Wl_Surface_Lv_Info *lv_info;
483
484    type = elm_win_type_get(window);
485    EINA_SAFETY_ON_FALSE_RETURN_VAL((type == ELM_WIN_NOTIFICATION),
486                                    EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE);
487
488    wlwin = elm_win_wl_window_get(window);
489    if (wlwin)
490      {
491         _wl_init();
492
493         while (!_eflutil.wl.noti_lv.proto)
494           wl_display_dispatch(_eflutil.wl.dpy);
495
496         surface = ecore_wl_window_surface_get(wlwin);
497         EINA_SAFETY_ON_NULL_RETURN_VAL(surface,
498                                        EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE);
499
500         lv_info = eina_hash_find(_eflutil.wl.noti_lv.hash, &surface);
501         if (!lv_info)
502           {
503              lv_info = calloc(1, sizeof(Efl_Util_Wl_Surface_Lv_Info));
504              EINA_SAFETY_ON_NULL_RETURN_VAL(lv_info, EFL_UTIL_ERROR_OUT_OF_MEMORY);
505
506              lv_info->surface = surface;
507              lv_info->level = (int)level;
508              lv_info->wait_for_done = EINA_TRUE;
509
510              eina_hash_add(_eflutil.wl.noti_lv.hash,
511                            &surface,
512                            lv_info);
513           }
514         else
515           {
516              lv_info->level = (int)level;
517              lv_info->wait_for_done = EINA_TRUE;
518           }
519
520         tizen_notification_set_level(_eflutil.wl.noti_lv.proto,
521                                      surface,
522                                      (int)level);
523
524         return EFL_UTIL_ERROR_NONE;
525      }
526 #endif /* end of WAYLAND */
527
528    return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
529 }
530
531 API int
532 efl_util_get_notification_window_level(Evas_Object *window,
533                                        efl_util_notification_level_e *level)
534 {
535    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EFL_UTIL_ERROR_INVALID_PARAMETER);
536    EINA_SAFETY_ON_NULL_RETURN_VAL(level, EFL_UTIL_ERROR_INVALID_PARAMETER);
537
538 #if X11
539    Ecore_X_Window_Type window_type;
540    Utilx_Notification_Level utilx_level;
541    Ecore_X_Window xwin = elm_win_xwindow_get(window);
542    if (xwin)
543      {
544         if (ecore_x_netwm_window_type_get(xwin, &window_type) == EINA_TRUE)
545           {
546              // success to get window type
547              if (window_type != ECORE_X_WINDOW_TYPE_NOTIFICATION)
548                {
549                   // given EFL window's type is not notification type.
550                   return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
551                }
552
553              utilx_level = utilx_get_system_notification_level(ecore_x_display_get(), xwin);
554              if (utilx_level == UTILX_NOTIFICATION_LEVEL_LOW)
555                *level = EFL_UTIL_NOTIFICATION_LEVEL_1;
556              else if(utilx_level == UTILX_NOTIFICATION_LEVEL_NORMAL)
557                *level = EFL_UTIL_NOTIFICATION_LEVEL_2;
558              else if(utilx_level == UTILX_NOTIFICATION_LEVEL_HIGH)
559                *level = EFL_UTIL_NOTIFICATION_LEVEL_3;
560              else
561                return EFL_UTIL_ERROR_INVALID_PARAMETER;
562           }
563         else
564           return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
565
566         return EFL_UTIL_ERROR_NONE;
567      }
568 #endif /* end of X11 */
569
570 #if WAYLAND
571    Elm_Win_Type type;
572    Ecore_Wl_Window *wlwin;
573    struct wl_surface *surface;
574    Efl_Util_Wl_Surface_Lv_Info *lv_info;
575
576    type = elm_win_type_get(window);
577    EINA_SAFETY_ON_FALSE_RETURN_VAL((type == ELM_WIN_NOTIFICATION),
578                                    EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE);
579
580    wlwin = elm_win_wl_window_get(window);
581    if (wlwin)
582      {
583         _wl_init();
584
585         while (!_eflutil.wl.noti_lv.proto)
586           wl_display_dispatch(_eflutil.wl.dpy);
587
588         surface = ecore_wl_window_surface_get(wlwin);
589         EINA_SAFETY_ON_NULL_RETURN_VAL(surface,
590                                        EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE);
591
592         lv_info = eina_hash_find(_eflutil.wl.noti_lv.hash, &surface);
593         if (lv_info)
594           {
595              if (lv_info->wait_for_done)
596                {
597                   if (ecore_wl_window_shell_surface_get(wlwin) ||
598                       ecore_wl_window_xdg_surface_get(wlwin))
599                     {
600                        while (lv_info->wait_for_done)
601                          {
602                             ecore_wl_flush();
603                             wl_display_dispatch(_eflutil.wl.dpy);
604                          }
605                     }
606                   else
607                     {
608                        *level = EFL_UTIL_NOTIFICATION_LEVEL_DEFAULT;
609                        return EFL_UTIL_ERROR_INVALID_PARAMETER;
610                     }
611                }
612
613             switch (lv_info->level)
614               {
615                  case TIZEN_NOTIFICATION_LEVEL_1:       *level = EFL_UTIL_NOTIFICATION_LEVEL_1;       break;
616                  case TIZEN_NOTIFICATION_LEVEL_2:       *level = EFL_UTIL_NOTIFICATION_LEVEL_2;       break;
617                  case TIZEN_NOTIFICATION_LEVEL_3:       *level = EFL_UTIL_NOTIFICATION_LEVEL_3;       break;
618                  case TIZEN_NOTIFICATION_LEVEL_NONE:    *level = EFL_UTIL_NOTIFICATION_LEVEL_NONE;    break;
619                  case TIZEN_NOTIFICATION_LEVEL_DEFAULT: *level = EFL_UTIL_NOTIFICATION_LEVEL_DEFAULT; break;
620                  case TIZEN_NOTIFICATION_LEVEL_MEDIUM:  *level = EFL_UTIL_NOTIFICATION_LEVEL_MEDIUM;  break;
621                  case TIZEN_NOTIFICATION_LEVEL_HIGH:    *level = EFL_UTIL_NOTIFICATION_LEVEL_HIGH;    break;
622                  case TIZEN_NOTIFICATION_LEVEL_TOP:     *level = EFL_UTIL_NOTIFICATION_LEVEL_TOP;     break;
623                  default:                               *level = EFL_UTIL_NOTIFICATION_LEVEL_DEFAULT;
624                    return EFL_UTIL_ERROR_INVALID_PARAMETER;
625               }
626             return EFL_UTIL_ERROR_NONE;
627           }
628         else
629           *level = EFL_UTIL_NOTIFICATION_LEVEL_DEFAULT;
630
631         return EFL_UTIL_ERROR_NONE;
632      }
633 #endif /* end of WAYLAND */
634    return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
635 }
636
637 API int
638 efl_util_set_notification_window_level_error_cb(Evas_Object *window,
639                                                 efl_util_notification_window_level_error_cb callback,
640                                                 void *user_data)
641 {
642    Eina_Bool ret = EINA_FALSE;
643
644    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EFL_UTIL_ERROR_INVALID_PARAMETER);
645    EINA_SAFETY_ON_NULL_RETURN_VAL(callback, EFL_UTIL_ERROR_INVALID_PARAMETER);
646
647    ret = _cb_info_add(window,
648                       (Efl_Util_Cb)callback,
649                       user_data,
650                       CBH_NOTI_LEV);
651    if (!ret) return EFL_UTIL_ERROR_OUT_OF_MEMORY;
652
653 #if X11
654    if (!_eflutil.atom.noti_lv)
655      _eflutil.atom.noti_lv = ecore_x_atom_get("_E_NOTIFICATION_LEVEL_ACCESS_RESULT");
656 #endif /* end of X11 */
657
658    return EFL_UTIL_ERROR_NONE;
659 }
660
661 API int
662 efl_util_unset_notification_window_level_error_cb(Evas_Object *window)
663 {
664    Eina_Bool ret = EINA_FALSE;
665
666    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EFL_UTIL_ERROR_INVALID_PARAMETER);
667
668    ret = _cb_info_del_by_win(window, CBH_NOTI_LEV);
669    if (!ret) return EFL_UTIL_ERROR_INVALID_PARAMETER;
670
671    return EFL_UTIL_ERROR_NONE;
672 }
673
674 API int
675 efl_util_set_window_opaque_state(Evas_Object *window,
676                                  int opaque)
677 {
678    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EFL_UTIL_ERROR_INVALID_PARAMETER);
679    EINA_SAFETY_ON_FALSE_RETURN_VAL(((opaque >= 0) && (opaque <= 1)),
680                                    EFL_UTIL_ERROR_INVALID_PARAMETER);
681
682 #if X11
683    Ecore_X_Window xwin = elm_win_xwindow_get(window);
684    Ecore_X_Display *xdpy = ecore_x_display_get();
685    Utilx_Opaque_State state;
686    int ret;
687
688    EINA_SAFETY_ON_NULL_RETURN_VAL(xwin, EFL_UTIL_ERROR_INVALID_PARAMETER);
689    EINA_SAFETY_ON_NULL_RETURN_VAL(xdpy, EFL_UTIL_ERROR_INVALID_PARAMETER);
690
691    if (opaque)
692      state = UTILX_OPAQUE_STATE_ON;
693    else
694      state = UTILX_OPAQUE_STATE_OFF;
695
696    ret = utilx_set_window_opaque_state(xdpy, xwin, state);
697
698    if (!ret)
699      return EFL_UTIL_ERROR_INVALID_PARAMETER;
700    else
701      return EFL_UTIL_ERROR_NONE;
702 #endif /* end of X11 */
703
704 #if WAYLAND
705    Ecore_Wl_Window *wlwin;
706    int x, y, w, h;
707
708    wlwin = elm_win_wl_window_get(window);
709    if (wlwin)
710      {
711         _wl_init();
712
713         evas_object_geometry_get(window, &x, &y, &w, &h);
714
715         if (opaque)
716           ecore_wl_window_opaque_region_set(wlwin, x, y, w, h);
717         else
718           ecore_wl_window_opaque_region_set(wlwin, 0, 0, 0, 0);
719
720         return EFL_UTIL_ERROR_NONE;
721      }
722
723    return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
724 #endif /* end of WAYLAND */
725 }
726
727 API int
728 efl_util_set_window_screen_mode(Evas_Object *window,
729                                 efl_util_screen_mode_e mode)
730 {
731    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EFL_UTIL_ERROR_INVALID_PARAMETER);
732    EINA_SAFETY_ON_FALSE_RETURN_VAL(((mode >= EFL_UTIL_SCREEN_MODE_DEFAULT) &&
733                                     (mode <= EFL_UTIL_SCREEN_MODE_ALWAYS_ON)),
734                                    EFL_UTIL_ERROR_INVALID_PARAMETER);
735
736 #if X11
737    Evas *e;
738    Ecore_Evas *ee;
739    int id;
740
741    e = evas_object_evas_get(window);
742    EINA_SAFETY_ON_NULL_RETURN_VAL(e, EFL_UTIL_ERROR_INVALID_PARAMETER);
743
744    ee = ecore_evas_ecore_evas_get(e);
745    EINA_SAFETY_ON_NULL_RETURN_VAL(ee, EFL_UTIL_ERROR_INVALID_PARAMETER);
746
747    id = ecore_evas_aux_hint_id_get(ee, "wm.policy.win.lcd.lock");
748    if (mode == EFL_UTIL_SCREEN_MODE_ALWAYS_ON)
749      {
750         if (id == -1)
751           ecore_evas_aux_hint_add(ee, "wm.policy.win.lcd.lock", "1");
752         else
753           ecore_evas_aux_hint_val_set(ee, id, "1");
754      }
755    else if (mode == EFL_UTIL_SCREEN_MODE_DEFAULT)
756      {
757         if (id == -1)
758           ecore_evas_aux_hint_add(ee, "wm.policy.win.lcd.lock", "0");
759         else
760           ecore_evas_aux_hint_val_set(ee, id, "0");
761      }
762    else
763      return EFL_UTIL_ERROR_INVALID_PARAMETER;
764
765    return EFL_UTIL_ERROR_NONE;
766 #endif /* end of X11 */
767
768 #if WAYLAND
769    Ecore_Wl_Window *wlwin;
770    struct wl_surface *surface;
771    Efl_Util_Wl_Surface_Scr_Mode_Info *scr_mode_info;
772
773    wlwin = elm_win_wl_window_get(window);
774    if (wlwin)
775      {
776         _wl_init();
777
778         while (!_eflutil.wl.win_scr_mode.proto)
779           wl_display_dispatch(_eflutil.wl.dpy);
780
781         surface = ecore_wl_window_surface_get(wlwin);
782         EINA_SAFETY_ON_NULL_RETURN_VAL(surface,
783                                        EFL_UTIL_ERROR_INVALID_PARAMETER);
784
785         scr_mode_info = eina_hash_find(_eflutil.wl.win_scr_mode.hash, &surface);
786         if (!scr_mode_info)
787           {
788              scr_mode_info = calloc(1, sizeof(Efl_Util_Wl_Surface_Scr_Mode_Info));
789              EINA_SAFETY_ON_NULL_RETURN_VAL(scr_mode_info, EFL_UTIL_ERROR_OUT_OF_MEMORY);
790
791              scr_mode_info->surface = surface;
792              scr_mode_info->mode = (unsigned int)mode;
793              scr_mode_info->wait_for_done = EINA_TRUE;
794
795              eina_hash_add(_eflutil.wl.win_scr_mode.hash,
796                            &surface,
797                            scr_mode_info);
798           }
799         else
800           {
801              scr_mode_info->mode = (unsigned int)mode;
802              scr_mode_info->wait_for_done = EINA_TRUE;
803           }
804
805         tizen_window_screen_set_mode(_eflutil.wl.win_scr_mode.proto,
806                                      surface,
807                                      (unsigned int)mode);
808
809         return EFL_UTIL_ERROR_NONE;
810      }
811    else
812      return EFL_UTIL_ERROR_INVALID_PARAMETER;
813 #endif /* end of WAYLAND */
814 }
815
816 API int
817 efl_util_get_window_screen_mode(Evas_Object *window,
818                                 efl_util_screen_mode_e *mode)
819 {
820    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EFL_UTIL_ERROR_INVALID_PARAMETER);
821    EINA_SAFETY_ON_NULL_RETURN_VAL(mode, EFL_UTIL_ERROR_INVALID_PARAMETER);
822
823 #if X11
824    Evas *e;
825    Ecore_Evas *ee;
826    const char *str;
827    int id;
828
829    e = evas_object_evas_get(window);
830    EINA_SAFETY_ON_NULL_RETURN_VAL(e, EFL_UTIL_ERROR_INVALID_PARAMETER);
831
832    ee = ecore_evas_ecore_evas_get(e);
833    EINA_SAFETY_ON_NULL_RETURN_VAL(ee, EFL_UTIL_ERROR_INVALID_PARAMETER);
834
835    id = ecore_evas_aux_hint_id_get(ee, "wm.policy.win.lcd.lock");
836    EINA_SAFETY_ON_TRUE_RETURN_VAL((id == -1), EFL_UTIL_ERROR_INVALID_PARAMETER);
837
838    str = ecore_evas_aux_hint_val_get(ee, id);
839    EINA_SAFETY_ON_NULL_RETURN_VAL(str, EFL_UTIL_ERROR_INVALID_PARAMETER);
840
841    if (strncmp(str, "1", strlen("1")) == 0)
842      *mode = EFL_UTIL_SCREEN_MODE_ALWAYS_ON;
843    else
844      *mode = EFL_UTIL_SCREEN_MODE_DEFAULT;
845
846    return EFL_UTIL_ERROR_NONE;
847 #endif /* end of X11 */
848
849 #if WAYLAND
850    Ecore_Wl_Window *wlwin;
851    struct wl_surface *surface;
852    Efl_Util_Wl_Surface_Scr_Mode_Info *scr_mode_info;
853
854    wlwin = elm_win_wl_window_get(window);
855    if (wlwin)
856      {
857         _wl_init();
858
859         while (!_eflutil.wl.win_scr_mode.proto)
860           wl_display_dispatch(_eflutil.wl.dpy);
861
862         surface = ecore_wl_window_surface_get(wlwin);
863         EINA_SAFETY_ON_NULL_RETURN_VAL(surface,
864                                        EFL_UTIL_ERROR_INVALID_PARAMETER);
865
866         scr_mode_info = eina_hash_find(_eflutil.wl.win_scr_mode.hash, &surface);
867         if (scr_mode_info)
868           {
869              if (scr_mode_info->wait_for_done)
870                {
871                   while (scr_mode_info->wait_for_done)
872                     {
873                        ecore_wl_flush();
874                        wl_display_dispatch(_eflutil.wl.dpy);
875                     }
876                }
877
878             switch (scr_mode_info->mode)
879               {
880                  case TIZEN_WINDOW_SCREEN_MODE_DEFAULT:   *mode = EFL_UTIL_SCREEN_MODE_DEFAULT;   break;
881                  case TIZEN_WINDOW_SCREEN_MODE_ALWAYS_ON: *mode = EFL_UTIL_SCREEN_MODE_ALWAYS_ON; break;
882                  default:                                 *mode = EFL_UTIL_SCREEN_MODE_DEFAULT;
883                    return EFL_UTIL_ERROR_INVALID_PARAMETER;
884               }
885             return EFL_UTIL_ERROR_NONE;
886           }
887         else
888           {
889              *mode = EFL_UTIL_SCREEN_MODE_DEFAULT;
890              return EFL_UTIL_ERROR_INVALID_PARAMETER;
891           }
892      }
893    else
894      return EFL_UTIL_ERROR_INVALID_PARAMETER;
895 #endif /* end of WAYLAND */
896 }
897
898 API int
899 efl_util_set_window_screen_mode_error_cb(Evas_Object *window,
900                                          efl_util_window_screen_mode_error_cb callback,
901                                          void *user_data)
902 {
903    Eina_Bool ret = EINA_FALSE;
904
905    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EFL_UTIL_ERROR_INVALID_PARAMETER);
906    EINA_SAFETY_ON_NULL_RETURN_VAL(callback, EFL_UTIL_ERROR_INVALID_PARAMETER);
907
908    ret = _cb_info_add(window,
909                       (Efl_Util_Cb)callback,
910                       user_data,
911                       CBH_SCR_MODE);
912    if (!ret) return EFL_UTIL_ERROR_OUT_OF_MEMORY;
913
914 #if X11
915    if (!_eflutil.atom.scr_mode)
916      _eflutil.atom.scr_mode = ecore_x_atom_get("_E_SCREEN_MODE_ACCESS_RESULT");
917 #endif /* end of X11 */
918
919    return EFL_UTIL_ERROR_NONE;
920 }
921
922 API int
923 efl_util_unset_window_screen_mode_error_cb(Evas_Object *window)
924 {
925    Eina_Bool ret = EINA_FALSE;
926
927    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EFL_UTIL_ERROR_INVALID_PARAMETER);
928
929    ret = _cb_info_del_by_win(window, CBH_SCR_MODE);
930    if (!ret) return EFL_UTIL_ERROR_INVALID_PARAMETER;
931
932    return EFL_UTIL_ERROR_NONE;
933 }
934
935 API int
936 efl_util_input_initialize_generator(efl_util_input_device_type_e dev_type)
937 {
938    return EFL_UTIL_ERROR_NONE;
939 }
940
941 API void
942 efl_util_input_deinitialize_generator(void)
943 {
944    return;
945 }
946
947 API int
948 efl_util_input_generate_key(const char *key_name,
949                             int pressed)
950 {
951    return EFL_UTIL_ERROR_NONE;
952 }
953
954 API int
955 efl_util_input_generate_touch(int idx,
956                               efl_util_input_touch_type_e touch_type,
957                               int x,
958                               int y)
959 {
960    return EFL_UTIL_ERROR_NONE;
961 }
962
963 API efl_util_screenshot_h
964 efl_util_screenshot_initialize(int width,
965                                int height)
966 {
967    return 0;
968 }
969
970 API tbm_surface_h
971 efl_util_screenshot_take_tbm_surface(efl_util_screenshot_h screenshot)
972 {
973    return 0;
974 }
975
976 API int
977 efl_util_screenshot_deinitialize(efl_util_screenshot_h screenshot)
978 {
979    return EFL_UTIL_ERROR_NONE;
980 }