3422f74d01714f625c9135a7f8b1685ec6969f36
[platform/upstream/enlightenment.git] / src / bin / e_policy_wl.c
1 #include "e_policy_wl_intern.h"
2 #include "e_policy_intern.h"
3 #include "e_appinfo_intern.h"
4 #include "services/e_service_quickpanel_intern.h"
5 #include "services/e_service_volume_intern.h"
6 #include "services/e_service_lockscreen_intern.h"
7 #include "services/e_service_indicator_intern.h"
8 #include "services/e_service_cbhm_intern.h"
9 #include "services/e_service_scrsaver_intern.h"
10 #include "services/e_service_softkey_intern.h"
11 #include "services/e_service_launcher_intern.h"
12 #include "services/e_service_taskbar_intern.h"
13 #include "services/e_service_kvm_intern.h"
14 #include "e_policy_wl_display_intern.h"
15 #include "e_policy_conformant_intern.h"
16 #include "e_policy_visibility_intern.h"
17 #include "e_subsurface_watcher_intern.h"
18 #include "e_client_intern.h"
19 #include "e_subsurface_watcher_intern.h"
20 #include "e_comp_wl_data_intern.h"
21 #include "e_comp_wl_intern.h"
22 #include "e_comp_wl_subsurface_intern.h"
23 #include "e_comp_intern.h"
24 #include "e_privilege_intern.h"
25 #include "e_magnifier_intern.h"
26 #include "e_hints_intern.h"
27 #include "e_comp_object_intern.h"
28 #include "e_zone_intern.h"
29 #include "e_config_intern.h"
30 #include "e_security_intern.h"
31 #include "e_utils_intern.h"
32 #include "e_screensaver_intern.h"
33 #include "e_hwc_window_intern.h"
34 #include "e_input_intern.h"
35 #include "e_input_thread_client_intern.h"
36
37 #include <device/display.h>
38 #include <wayland-server.h>
39 #include <tizen-extension-server-protocol.h>
40 #include <tizen-launch-server-protocol.h>
41 #include <tzsh_server.h>
42
43 typedef enum _Tzsh_Srv_Role
44 {
45    TZSH_SRV_ROLE_UNKNOWN = -1,
46    TZSH_SRV_ROLE_VOLUME,
47    TZSH_SRV_ROLE_QUICKPANEL_SYSTEM_DEFAULT,
48    TZSH_SRV_ROLE_QUICKPANEL_CONTEXT_MENU,
49    TZSH_SRV_ROLE_QUICKPANEL_APPS_MENU,
50    TZSH_SRV_ROLE_LOCKSCREEN,
51    TZSH_SRV_ROLE_INDICATOR,
52    TZSH_SRV_ROLE_SCREENSAVER_MNG,
53    TZSH_SRV_ROLE_SCREENSAVER,
54    TZSH_SRV_ROLE_CBHM,
55    TZSH_SRV_ROLE_SOFTKEY,
56    TZSH_SRV_ROLE_MAGNIFIER,
57    TZSH_SRV_ROLE_LAUNCHER,
58    TZSH_SRV_ROLE_TASKBAR,
59    TZSH_SRV_ROLE_KVM,
60    TZSH_SRV_ROLE_MAX
61 } Tzsh_Srv_Role;
62
63 typedef enum _Tzsh_Client_Handle_Type
64 {
65    TZSH_CLIENT_HANDLE_TYPE_NONE = 0,
66    TZSH_CLIENT_HANDLE_TYPE_QUICKPANEL = 1,
67    TZSH_CLIENT_HANDLE_TYPE_SHARED_WIDGET_LAUNCH = 2,
68    TZSH_CLIENT_HANDLE_TYPE_SOFTKEY = 3,
69 } Tzsh_Client_Handle_Type;
70
71 typedef enum _Tzsh_Type
72 {
73    TZSH_TYPE_UNKNOWN = 0,
74    TZSH_TYPE_SRV,
75    TZSH_TYPE_CLIENT
76 } Tzsh_Type;
77
78 typedef enum _Tzlaunch_Effect_Type
79 {
80    TZLAUNCH_EFFECT_TYPE_LAUNCH = 0,
81    TZLAUNCH_EFFECT_TYPE_DEPTH_IN
82 } Tzlaunch_Effect_Type;
83
84 typedef struct _E_Policy_Wl_Tzpol
85 {
86    struct wl_resource *res_tzpol; /* tizen_policy_interface */
87    Eina_List          *psurfs;    /* list of E_Policy_Wl_Surface */
88    pid_t               pid;
89    Eina_Bool           bg_state;
90 } E_Policy_Wl_Tzpol;
91
92 typedef struct _E_Policy_Wl_Tz_Dpy_Pol
93 {
94    struct wl_resource *res_tz_dpy_pol;
95    Eina_List          *dpy_surfs;  // list of E_Policy_Wl_Dpy_Surface
96 } E_Policy_Wl_Tz_Dpy_Pol;
97
98 typedef struct _E_Policy_Wl_Tzsh
99 {
100    struct wl_resource *res_tzsh; /* tizen_ws_shell_interface */
101    Eina_List *service_list;
102    Eina_List *client_list;
103 } E_Policy_Wl_Tzsh;
104
105 typedef struct _E_Policy_Wl_Tzsh_Srv
106 {
107    E_Policy_Wl_Tzsh        *tzsh;
108    struct wl_resource *res_tzsh_srv;
109    Tzsh_Srv_Role       role;
110    const char         *name;
111    E_Pixmap *ep;
112    E_Client *ec;
113    E_Zone *zone;
114    Eina_List *events;
115 } E_Policy_Wl_Tzsh_Srv;
116
117 typedef struct _E_Policy_Wl_Tzsh_Client
118 {
119    E_Policy_Wl_Tzsh        *tzsh;
120    struct wl_resource *res_tzsh_client;
121    Tzsh_Client_Handle_Type handle_type;
122    E_Pixmap *ep;
123    E_Client *ec;
124    E_Zone *zone;
125    void *client_data;
126    Eina_List *events;
127 } E_Policy_Wl_Tzsh_Client;
128
129 typedef struct _E_Policy_Wl_Tzsh_Client_Data_Quickpanel
130 {
131    E_Quickpanel_Type type;
132 } E_Policy_Wl_Tzsh_Client_Data_Quickpanel;
133
134 typedef struct _E_Policy_Wl_Tzsh_Client_Data_Softkey
135 {
136    int show_state;
137 } E_Policy_Wl_Tzsh_Client_Data_Softkey;
138
139 typedef struct _E_Policy_Wl_Tzsh_Region
140 {
141    E_Policy_Wl_Tzsh        *tzsh;
142    struct wl_resource *res_tzsh_reg;
143    Eina_Tiler         *tiler;
144    struct wl_listener  destroy_listener;
145 } E_Policy_Wl_Tzsh_Region;
146
147 typedef struct _E_Policy_Wl_Tzsh_Extension
148 {
149    char                    *name;
150    E_Policy_Wl_Tzsh_Ext_Hook_Cb cb;
151 } E_Policy_Wl_Tzsh_Extension;
152
153 typedef struct _E_Policy_Wl_Surface
154 {
155    struct wl_resource *surf;
156    E_Policy_Wl_Tzpol       *tzpol;
157    E_Pixmap           *cp;
158    E_Client           *ec;
159    pid_t               pid;
160    Eina_Bool           pending_notilv;
161    int32_t             notilv;
162    Eina_List          *vislist; /* list of tizen_visibility_interface resources */
163    Eina_List          *poslist; /* list of tizen_position_inteface resources */
164    Eina_Bool           is_background;
165 } E_Policy_Wl_Surface;
166
167 typedef struct _E_Policy_Wl_Dpy_Surface
168 {
169    E_Policy_Wl_Tz_Dpy_Pol  *tz_dpy_pol;
170    struct wl_resource *surf;
171    E_Client           *ec;
172    Eina_Bool           set;
173    int32_t             brightness;
174 } E_Policy_Wl_Dpy_Surface;
175
176 typedef struct _E_Policy_Wl_Tzlaunch_Effect
177 {
178    struct wl_resource *res_tzlaunch_effect;  /* tizen_launch_effect */
179    Eina_List          *splash_list;            /* list of E_Policy_Wl_Tzlaunch_Splash */
180 } E_Policy_Wl_Tzlaunch_Effect;
181
182 typedef struct _E_Policy_Wl_Tzlaunch_Splash
183 {
184    struct wl_resource        *res_tzlaunch_splash; /* tizen_launch_image */
185    E_Policy_Wl_Tzlaunch_Effect *tzlaunch_effect;         /* launcher */
186
187    const char                *path;             /* image resource path */
188    uint32_t                   type;             /* 0: image, 1: edc */
189    uint32_t                   indicator;        /* 0: off, 1: on */
190    uint32_t                   angle;            /* 0, 90, 180, 270 : rotation angle */
191    uint32_t                   pid;
192
193    Evas_Object               *obj;              /* launch screen image */
194    E_Pixmap                  *ep;               /* pixmap for launch screen client */
195    E_Client                  *ec;               /* client for launch screen image */
196    Ecore_Timer               *timeout;          /* launch screen image hide timer */
197    Evas_Object               *indicator_obj;    /* plug object of indicator */
198
199    Eina_Bool                  valid;            /* validation check */
200    Eina_Bool                  replaced;
201    E_Comp_Object_Content_Type content_type;     /* type of content */
202
203    Eina_Bool                  custom_effect_callee; /* custom effect enabled */
204    const char                *appid;
205 } E_Policy_Wl_Tzlaunch_Splash;
206
207 typedef struct _E_Policy_Wl_Tzlaunch_Effect_Info
208 {
209    uint32_t                   pid;              /* pid */
210    int                        effect_type;       /* effect_type */
211 } E_Policy_Wl_Tzlaunch_Effect_Info;
212
213 typedef struct _E_Policy_Wl_Tzlaunch_Appinfo
214 {
215    struct wl_resource        *res_tzlaunch_appinfo; /* tizen_launch_appinfo */
216 } E_Policy_Wl_Tzlaunch_Appinfo;
217
218 typedef enum _Launch_Img_File_type
219 {
220    LAUNCH_IMG_FILE_TYPE_ERROR = -1,
221    LAUNCH_IMG_FILE_TYPE_IMAGE = 0,
222    LAUNCH_IMG_FILE_TYPE_EDJ
223 } Launch_Img_File_type;
224
225 typedef struct _E_Policy_Wl_Tz_Indicator
226 {
227    struct wl_resource *res_tz_indicator;
228    Eina_List          *ec_list;
229 } E_Policy_Wl_Tz_Indicator;
230
231 typedef struct _E_Policy_Wl_Tz_Clipboard
232 {
233    struct wl_resource *res_tz_clipboard;
234    Eina_List *ec_list;
235 } E_Policy_Wl_Tz_Clipboard;
236
237 typedef struct _E_Policy_Wl
238 {
239    Eina_List       *globals;                 /* list of wl_global */
240    Eina_Hash       *tzpols;                  /* list of E_Policy_Wl_Tzpol */
241
242    Eina_List       *tz_dpy_pols;             /* list of E_Policy_Wl_Tz_Dpy_Pol */
243    Eina_List       *pending_vis;             /* list of clients that have pending visibility change*/
244
245    /* tizen_ws_shell_interface */
246    Eina_List       *tzshs;                   /* list of E_Policy_Wl_Tzsh */
247    Eina_List       *tzsh_srvs;               /* list of E_Policy_Wl_Tzsh_Srv */
248    Eina_List       *tzsh_clients;            /* list of E_Policy_Wl_Tzsh_Client */
249    E_Policy_Wl_Tzsh_Srv *srvs[TZSH_SRV_ROLE_MAX]; /* list of registered E_Policy_Wl_Tzsh_Srv */
250    Eina_List       *tz_indicators;
251    Eina_List       *tz_clipboards;           /* list of E_Policy_Wl_Tz_Clipboard */
252
253    /* tizen_launch_effect_interface */
254    Eina_List       *tzlaunch_effect;        /* list of E_Policy_Wl_Tzlaunch_Effect */
255    Eina_List       *tzlaunch_effect_info;  /* list of E_Policy_Wl_Tzlaunch_Effect_Info */
256    /* tizen_launch_appinfo_interface */
257    Eina_List       *tzlaunch_appinfo;       /* list of E_Policy_Wl_Tzlaunch_Appinfo */
258    /* tizen_ws_shell_interface ver_2 */
259    Eina_List       *tzsh_extensions;           /* list of E_Policy_Wl_Tzsh_Extension */
260 } E_Policy_Wl;
261
262 typedef struct _E_Tzsh_QP_Event
263 {
264    int type;
265    int val;
266 } E_Tzsh_QP_Event;
267
268 static E_Policy_Wl *polwl = NULL;
269
270 static Eina_List *handlers = NULL;
271 static Eina_List *polwl_hooks_ec = NULL;
272 static Eina_List *hooks_cw = NULL;
273 static Eina_List *hooks_co = NULL;
274 static struct wl_resource *_scrsaver_mng_res = NULL; // TODO
275 static struct wl_resource *_indicator_srv_res = NULL;
276
277 static int _e_policy_wl_hooks_delete = 0;
278 static int _e_policy_wl_hooks_walking = 0;
279
280 static Eina_Inlist *_e_policy_wl_hooks[] =
281 {
282    [E_POLICY_WL_HOOK_BASE_OUTPUT_RESOLUTION_GET] = NULL,
283 };
284
285 EINTERN int E_EVENT_POLICY_INDICATOR_STATE_CHANGE = -1;
286 EINTERN int E_EVENT_POLICY_INDICATOR_OPACITY_MODE_CHANGE = -1;
287 EINTERN int E_EVENT_POLICY_INDICATOR_VISIBLE_STATE_CHANGE = -1;
288
289 enum _E_Policy_Hint_Type
290 {
291    E_POLICY_HINT_USER_GEOMETRY = 0,
292    E_POLICY_HINT_FIXED_RESIZE = 1,
293    E_POLICY_HINT_DEICONIFY_UPDATE = 2,
294    E_POLICY_HINT_ICONIFY = 3,
295    E_POLICY_HINT_ABOVE_LOCKSCREEN = 4,
296    E_POLICY_HINT_GESTURE_DISABLE = 5,
297    E_POLICY_HINT_EFFECT_DISABLE = 6,
298    E_POLICY_HINT_MSG_USE = 7,
299    E_COMP_HINT_ALWAYS_SELECTIVE = 8,
300    E_POLICY_HINT_DEPENDENT_ROTATION = 9,
301    E_POLICY_HINT_ROT_RENDER_NOPENDING = 10,
302    E_POLICY_HINT_ICONIFY_BUFFER_FLUSH = 11,
303    E_POLICY_HINT_TRANSIENT_FOR_ALWAYS_ON_TOP = 12,
304    E_POLICY_HINT_BELONG_TO_PARENT = 13,
305    E_POLICY_HINT_RESIZE_ASPECT_RATIO = 14,
306    E_POLICY_HINT_DECORATION_SIZE_HEADER = 15,
307    E_POLICY_HINT_DECORATION_SIZE_FOOTER = 16,
308    E_POLICY_HINT_VISIBILITY_IGNORE_GEOMETRY= 17,
309    E_POLICY_HINT_RESIZE_PPU = 18,
310    E_POLICY_HINT_DECORATION_SIZE_SHADOW_TOP = 19,
311    E_POLICY_HINT_DECORATION_SIZE_SHADOW_BOTTOM = 20,
312    E_POLICY_HINT_DECORATION_SIZE_SHADOW_LEFT = 21,
313    E_POLICY_HINT_DECORATION_SIZE_SHADOW_RIGHT = 22,
314 };
315
316 static const char *hint_names[] =
317 {
318    "wm.policy.win.user.geometry",
319    "wm.policy.win.fixed.resize",
320    "wm.policy.win.deiconify.update",
321    "wm.policy.win.iconify",
322    "wm.policy.win.above.lock",
323    "wm.policy.win.gesture.disable",
324    "wm.policy.win.effect.disable",
325    "wm.policy.win.msg.use",
326    "wm.comp.win.always.selective.mode",
327    "wm.policy.win.rot.dependent",
328    "wm.policy.win.rot.render.nopending",
329    "wm.policy.win.iconify.buffer.flush",
330    "wm.policy.win.transient_for.always_on_top",
331    "wm.policy.win.belong_to_parent",
332    "wm.policy.win.resize_aspect_ratio",
333    "wm.policy.win.decoration.size.header",
334    "wm.policy.win.decoration.size.footer",
335    "wm.policy.win.visibility.ignore_geometry",
336    "wm.policy.win.resize.ppu",
337    "wm.policy.win.decoration.size.shadow.top",
338    "wm.policy.win.decoration.size.shadow.bottom",
339    "wm.policy.win.decoration.size.shadow.left",
340    "wm.policy.win.decoration.size.shadow.right",
341 };
342
343 static void                _e_policy_wl_surf_del(E_Policy_Wl_Surface *psurf);
344 static void                _e_policy_wl_tzsh_srv_state_broadcast(E_Policy_Wl_Tzsh_Srv *tzsh_srv, Eina_Bool reg);
345 static Eina_Bool           _e_policy_wl_e_client_is_valid(E_Client *ec);
346 static E_Policy_Wl_Tzsh_Srv    *_e_policy_wl_tzsh_srv_add(E_Policy_Wl_Tzsh *tzsh, Tzsh_Srv_Role role, struct wl_resource *res_tzsh_srv, const char *name, E_Pixmap *ep, E_Client *ec);
347 static void                _e_policy_wl_tzsh_srv_del(E_Policy_Wl_Tzsh_Srv *tzsh_srv);
348 static E_Policy_Wl_Tzsh_Client *_e_policy_wl_tzsh_client_add(E_Policy_Wl_Tzsh *tzsh, struct wl_resource *res_tzsh_client, E_Pixmap *ep, E_Client *ec);
349 static void                _e_policy_wl_tzsh_client_del(E_Policy_Wl_Tzsh_Client *tzsh_client);
350 static void                _e_policy_wl_background_state_set(E_Policy_Wl_Surface *psurf, Eina_Bool state);
351
352 static void                _e_policy_wl_tzlaunch_effect_type_sync(E_Client *ec);
353 static int                 _e_policy_wl_tzlaunch_effect_type_get(const char* effect_type);
354 static void                _e_policy_wl_tzlaunch_effect_type_unset(uint32_t pid);
355
356 static void                _launch_effect_hide(uint32_t pid);
357 static void                _launch_effect_client_del(E_Client *ec);
358 static void                _launch_splash_off(E_Policy_Wl_Tzlaunch_Splash *tzlaunch_splash);
359
360 // --------------------------------------------------------
361 // E_Policy_Wl_Hook
362 // --------------------------------------------------------
363
364 static void
365 _e_policy_wl_hooks_clean()
366 {
367    E_Policy_Wl_Hook *epwh = NULL;
368    Eina_Inlist *l = NULL;
369    unsigned int x;
370
371    for (x = 0; x < E_POLICY_WL_HOOK_LAST; x++)
372      {
373         EINA_INLIST_FOREACH_SAFE(_e_policy_wl_hooks[x], l, epwh)
374           {
375              if (!epwh->delete_me) continue;
376              _e_policy_wl_hooks[x] = eina_inlist_remove(_e_policy_wl_hooks[x], EINA_INLIST_GET(epwh));
377              free(epwh);
378           }
379      }
380 }
381
382 static void
383 _e_policy_wl_hook_call(E_Policy_Wl_Hook_Point hookpoint, pid_t pid)
384 {
385    E_Policy_Wl_Hook *epwh = NULL;
386
387    _e_policy_wl_hooks_walking++;
388    EINA_INLIST_FOREACH(_e_policy_wl_hooks[hookpoint], epwh)
389      {
390         if (epwh->delete_me) continue;
391         epwh->func(epwh->data, pid);
392      }
393    _e_policy_wl_hooks_walking--;
394
395    if ((_e_policy_wl_hooks_walking == 0) && (_e_policy_wl_hooks_delete > 0))
396      _e_policy_wl_hooks_clean();
397 }
398
399 E_API E_Policy_Wl_Hook *
400 e_policy_wl_hook_add(E_Policy_Wl_Hook_Point hookpoint, E_Policy_Wl_Hook_Cb func, const void *data)
401 {
402    E_Policy_Wl_Hook *epwh = NULL;
403
404    EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint < 0, NULL);
405    EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_POLICY_WL_HOOK_LAST, NULL);
406
407    epwh = E_NEW(E_Policy_Wl_Hook, 1);
408    EINA_SAFETY_ON_NULL_RETURN_VAL(epwh, NULL);
409
410    epwh->hookpoint = hookpoint;
411    epwh->func = func;
412    epwh->data = (void *)data;
413    _e_policy_wl_hooks[hookpoint] = eina_inlist_append(_e_policy_wl_hooks[hookpoint], EINA_INLIST_GET(epwh));
414
415    return epwh;
416 }
417
418 E_API void
419 e_policy_wl_hook_del(E_Policy_Wl_Hook *epwh)
420 {
421    epwh->delete_me = 1;
422    if (_e_policy_wl_hooks_walking == 0)
423      {
424         _e_policy_wl_hooks[epwh->hookpoint] = eina_inlist_remove(_e_policy_wl_hooks[epwh->hookpoint], EINA_INLIST_GET(epwh));
425         free(epwh);
426      }
427    else
428      _e_policy_wl_hooks_delete++;
429 }
430
431 // --------------------------------------------------------
432 // E_Policy_Wl_Tzpol
433 // --------------------------------------------------------
434 static Eina_Bool
435 _e_policy_wl_tzpol_background_state_check(pid_t pid)
436 {
437    E_Policy_Wl_Tzpol *tzpol;
438    Eina_Iterator *it;
439    Eina_Bool bg_state = EINA_FALSE;
440
441    if (pid <= 0)
442      return EINA_FALSE;
443
444    it = eina_hash_iterator_data_new(polwl->tzpols);
445    EINA_ITERATOR_FOREACH(it, tzpol)
446      {
447         if (tzpol->pid == pid)
448           {
449              if (tzpol->bg_state)
450                {
451                   bg_state = EINA_TRUE;
452                   break;
453                }
454           }
455      }
456    eina_iterator_free(it);
457
458    return bg_state;
459 }
460
461 static E_Policy_Wl_Tzpol *
462 _e_policy_wl_tzpol_add(struct wl_client *client, struct wl_resource *res_tzpol)
463 {
464    E_Policy_Wl_Tzpol *tzpol;
465    pid_t pid = 0;
466
467    tzpol = E_NEW(E_Policy_Wl_Tzpol, 1);
468    EINA_SAFETY_ON_NULL_RETURN_VAL(tzpol, NULL);
469
470    eina_hash_add(polwl->tzpols, &res_tzpol, tzpol);
471
472    tzpol->res_tzpol = res_tzpol;
473
474    wl_client_get_credentials(client, &pid, NULL, NULL);
475    tzpol->pid = pid;
476
477    tzpol->bg_state = _e_policy_wl_tzpol_background_state_check(pid);
478
479    return tzpol;
480 }
481
482 static void
483 _e_policy_wl_tzpol_del(void *data)
484 {
485    E_Policy_Wl_Tzpol *tzpol;
486    E_Policy_Wl_Surface *psurf;
487
488    tzpol = (E_Policy_Wl_Tzpol *)data;
489
490    EINA_LIST_FREE(tzpol->psurfs, psurf)
491      {
492         _e_policy_wl_surf_del(psurf);
493      }
494
495    memset(tzpol, 0x0, sizeof(E_Policy_Wl_Tzpol));
496    E_FREE(tzpol);
497 }
498
499 static E_Policy_Wl_Tzpol *
500 _e_policy_wl_tzpol_get(struct wl_resource *res_tzpol)
501 {
502    return (E_Policy_Wl_Tzpol *)eina_hash_find(polwl->tzpols, &res_tzpol);
503 }
504
505 static E_Policy_Wl_Surface *
506 _e_policy_wl_tzpol_surf_find(E_Policy_Wl_Tzpol *tzpol, E_Client *ec)
507 {
508    Eina_List *l;
509    E_Policy_Wl_Surface *psurf;
510
511    EINA_LIST_FOREACH(tzpol->psurfs, l, psurf)
512      {
513         if (psurf->ec == ec)
514           return psurf;
515      }
516
517    return NULL;
518 }
519
520 static Eina_Bool
521 _e_policy_wl_surf_is_valid(E_Policy_Wl_Surface *psurf)
522 {
523    E_Policy_Wl_Tzpol *tzpol;
524    E_Policy_Wl_Surface *psurf2;
525    Eina_Iterator *it;
526    Eina_List *l;
527
528    it = eina_hash_iterator_data_new(polwl->tzpols);
529    EINA_ITERATOR_FOREACH(it, tzpol)
530      EINA_LIST_FOREACH(tzpol->psurfs, l, psurf2)
531        {
532           if (psurf2 == psurf)
533             {
534                eina_iterator_free(it);
535                return EINA_TRUE;
536             }
537        }
538    eina_iterator_free(it);
539
540    return EINA_FALSE;
541 }
542
543 // --------------------------------------------------------
544 // E_Policy_Wl_Tzsh
545 // --------------------------------------------------------
546 #ifdef TZSH_DEBUG
547 static void
548 _print_tzsh_service_info(void)
549 {
550    E_Policy_Wl_Tzsh_Srv *tzsh_srv = NULL;
551    Eina_List *l = NULL;
552    int i = 0;
553
554    ELOGF("TZSH", "================ TZSH SERVICE LIST ================", NULL);
555    EINA_LIST_FOREACH(polwl->tzsh_srvs, l, tzsh_srv)
556      {
557         ELOGF("TZSH", "[%d] tzsh_service(%p). tzsh:%p, role:%d, name:%s", tzsh_srv->ec, i, tzsh_srv, tzsh_srv->tzsh, tzsh_srv->role, tzsh_srv->name);
558         i++;
559      }
560    ELOGF("TZSH", "---------------------------------------------------", NULL);
561 }
562
563 static void
564 _print_tzsh_client_info(void)
565 {
566    E_Policy_Wl_Tzsh_Client *tzsh_client = NULL;
567    Eina_List *l = NULL;
568    int i = 0;
569
570    ELOGF("TZSH", "================ TZSH CLIENT LIST  ================", NULL);
571    EINA_LIST_FOREACH(polwl->tzsh_clients, l, tzsh_client)
572      {
573         ELOGF("TZSH", "[%d] tzsh_client(%p). tzsh:%p", tzsh_client->ec, i, tzsh_client, tzsh_client->tzsh);
574         i++;
575      }
576    ELOGF("TZSH", "---------------------------------------------------", NULL);
577 }
578 #endif
579
580 static E_Policy_Wl_Tzsh *
581 _e_policy_wl_tzsh_add(struct wl_resource *res_tzsh)
582 {
583    E_Policy_Wl_Tzsh *tzsh;
584
585    tzsh = E_NEW(E_Policy_Wl_Tzsh, 1);
586    EINA_SAFETY_ON_NULL_RETURN_VAL(tzsh, NULL);
587
588    ELOGF("TZSH", "NEW tzsh:%p, res_tzsh:%p", NULL, tzsh, res_tzsh);
589
590    tzsh->res_tzsh = res_tzsh;
591
592    polwl->tzshs = eina_list_append(polwl->tzshs, tzsh);
593
594 #ifdef TZSH_DEBUG
595    _print_tzsh_service_info();
596    _print_tzsh_client_info();
597 #endif
598
599    return tzsh;
600 }
601
602 static void
603 _e_policy_wl_tzsh_del(E_Policy_Wl_Tzsh *tzsh)
604 {
605    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
606    E_Policy_Wl_Tzsh_Client *tzsh_client;
607    Eina_List *l, *ll;
608
609    polwl->tzshs = eina_list_remove(polwl->tzshs, tzsh);
610
611    EINA_LIST_FOREACH_SAFE(polwl->tzsh_srvs, l, ll, tzsh_srv)
612      {
613         if (tzsh_srv->tzsh != tzsh) continue;
614         _e_policy_wl_tzsh_srv_del(tzsh_srv);
615      }
616
617    if (tzsh->service_list)
618      {
619         EINA_LIST_FOREACH_SAFE(tzsh->service_list, l, ll, tzsh_srv)
620           {
621              _e_policy_wl_tzsh_srv_del(tzsh_srv);
622           }
623         eina_list_free(tzsh->service_list);
624         tzsh->service_list = NULL;
625      }
626
627    EINA_LIST_FOREACH_SAFE(polwl->tzsh_clients, l, ll, tzsh_client)
628      {
629         if (tzsh_client->tzsh != tzsh) continue;
630         _e_policy_wl_tzsh_client_del(tzsh_client);
631      }
632
633    if (tzsh->client_list)
634      {
635         EINA_LIST_FOREACH_SAFE(tzsh->client_list, l, ll, tzsh_client)
636           {
637              _e_policy_wl_tzsh_client_del(tzsh_client);
638           }
639         eina_list_free(tzsh->client_list);
640         tzsh->client_list = NULL;
641      }
642
643 #ifdef TZSH_DEBUG
644    _print_tzsh_service_info();
645    _print_tzsh_client_info();
646 #endif
647
648    ELOGF("TZSH", "FREE tzsh:%p", NULL, tzsh);
649
650    memset(tzsh, 0x0, sizeof(E_Policy_Wl_Tzsh));
651    E_FREE(tzsh);
652 }
653
654 /* notify current registered services to the client */
655 static void
656 _e_policy_wl_tzsh_registered_srv_send(E_Policy_Wl_Tzsh *tzsh)
657 {
658    int i;
659
660    for (i = 0; i < TZSH_SRV_ROLE_MAX; i++)
661      {
662         if (!polwl->srvs[i]) continue;
663
664         tizen_ws_shell_send_service_register
665           (tzsh->res_tzsh, polwl->srvs[i]->name);
666      }
667 }
668
669 static Eina_Bool
670 _e_policy_wl_tzsh_srv_cb_client_zone_set(void *data, int type EINA_UNUSED, void *event)
671 {
672    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
673    E_Event_Client_Zone_Set *ev;
674
675    tzsh_srv = data;
676    ev = event;
677
678    if (tzsh_srv->ec != ev->ec)
679      goto end;
680
681    if (tzsh_srv->zone == ev->zone)
682      goto end;
683
684    ELOGF("TZSH", "Change Zone | e_policy_wl_tzsh_srv %p old(%p) new(%p)",
685          tzsh_srv->ec, tzsh_srv, tzsh_srv->zone, ev->zone);
686
687    tzsh_srv->zone = ev->zone;
688
689 end:
690    return ECORE_CALLBACK_PASS_ON;
691 }
692
693 // --------------------------------------------------------
694 // E_Policy_Wl_Tzsh_Srv
695 // --------------------------------------------------------
696 static E_Policy_Wl_Tzsh_Srv *
697 _e_policy_wl_tzsh_srv_add(E_Policy_Wl_Tzsh *tzsh, Tzsh_Srv_Role role, struct wl_resource *res_tzsh_srv, const char *name, E_Pixmap *ep, E_Client *ec)
698 {
699    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
700
701    tzsh_srv = E_NEW(E_Policy_Wl_Tzsh_Srv, 1);
702    EINA_SAFETY_ON_NULL_RETURN_VAL(tzsh_srv, NULL);
703
704    tzsh_srv->tzsh = tzsh;
705    tzsh_srv->res_tzsh_srv = res_tzsh_srv;
706    tzsh_srv->role = role;
707    tzsh_srv->name = eina_stringshare_add(name);
708    tzsh_srv->ep = ep;
709    tzsh_srv->ec = ec;
710    tzsh_srv->zone = e_comp_zone_find_by_ec(ec);
711    e_object_ref(E_OBJECT(ec));
712    tzsh_srv->tzsh->service_list = eina_list_append(tzsh_srv->tzsh->service_list, tzsh_srv);
713
714    polwl->srvs[role] = tzsh_srv;
715    polwl->tzsh_srvs = eina_list_append(polwl->tzsh_srvs, tzsh_srv);
716
717    ELOGF("TZSH", "CREATE tzsh_srv:%p, res_tzsh_srv:%p", ec, tzsh_srv, res_tzsh_srv);
718
719 #ifdef TZSH_DEBUG
720    _print_tzsh_service_info();
721 #endif
722
723    _e_policy_wl_tzsh_srv_state_broadcast(tzsh_srv, EINA_TRUE);
724
725    E_LIST_HANDLER_APPEND(tzsh_srv->events, E_EVENT_CLIENT_ZONE_SET, _e_policy_wl_tzsh_srv_cb_client_zone_set, tzsh_srv);
726
727    return tzsh_srv;
728 }
729
730 static void
731 _e_policy_wl_tzsh_srv_del(E_Policy_Wl_Tzsh_Srv *tzsh_srv)
732 {
733    E_FREE_LIST(tzsh_srv->events, ecore_event_handler_del);
734
735    polwl->tzsh_srvs = eina_list_remove(polwl->tzsh_srvs, tzsh_srv);
736
737 #ifdef TZSH_DEBUG
738    _print_tzsh_service_info();
739 #endif
740
741    if (tzsh_srv->tzsh && tzsh_srv->tzsh->service_list)
742      tzsh_srv->tzsh->service_list = eina_list_remove(tzsh_srv->tzsh->service_list, tzsh_srv);
743
744    if (polwl->srvs[tzsh_srv->role] == tzsh_srv)
745      polwl->srvs[tzsh_srv->role] = NULL;
746
747    _e_policy_wl_tzsh_srv_state_broadcast(tzsh_srv, EINA_FALSE);
748
749    if (tzsh_srv->name)
750      eina_stringshare_del(tzsh_srv->name);
751
752    if (tzsh_srv->role == TZSH_SRV_ROLE_INDICATOR)
753      {
754         E_Client *ec;
755         ec = tzsh_srv->ec;
756
757         if (ec && ec->internal)
758           {
759              e_pixmap_win_id_del(tzsh_srv->ep);
760              e_object_del(E_OBJECT(ec));
761           }
762
763         _indicator_srv_res = NULL;
764      }
765    else if (tzsh_srv->role == TZSH_SRV_ROLE_SOFTKEY)
766      {
767         E_Client *softkey_ec = NULL;
768
769         softkey_ec = tzsh_srv->ec;
770         if (softkey_ec)
771           {
772              e_service_softkey_client_unset(softkey_ec);
773           }
774      }
775    else if (tzsh_srv->role == TZSH_SRV_ROLE_MAGNIFIER)
776      {
777         E_Client *magnifier_ec = NULL;
778
779         magnifier_ec = tzsh_srv->ec;
780         if (magnifier_ec)
781           {
782              e_magnifier_owner_unset(magnifier_ec);
783              e_magnifier_del();
784           }
785      }
786    else if (tzsh_srv->role == TZSH_SRV_ROLE_LAUNCHER)
787      {
788         E_Client *launcher_ec = NULL;
789
790         launcher_ec = tzsh_srv->ec;
791         if (launcher_ec)
792           {
793              e_service_launcher_client_unset(launcher_ec);
794           }
795      }
796
797    ELOGF("TZSH", "FREE tzsh_srv:%p", tzsh_srv->ec, tzsh_srv);
798
799    if (tzsh_srv->ec)
800      {
801        e_object_unref(E_OBJECT(tzsh_srv->ec));
802        tzsh_srv->ec = NULL;
803      }
804
805    if (tzsh_srv->res_tzsh_srv)
806      wl_resource_set_user_data(tzsh_srv->res_tzsh_srv, NULL);
807
808    memset(tzsh_srv, 0x0, sizeof(E_Policy_Wl_Tzsh_Srv));
809    E_FREE(tzsh_srv);
810 }
811
812 static int
813 _e_policy_wl_tzsh_srv_role_get(const char *name)
814 {
815    Tzsh_Srv_Role role = TZSH_SRV_ROLE_UNKNOWN;
816
817    if      (!e_util_strcmp(name, "volume"                   )) role = TZSH_SRV_ROLE_VOLUME;
818    else if (!e_util_strcmp(name, "quickpanel_system_default")) role = TZSH_SRV_ROLE_QUICKPANEL_SYSTEM_DEFAULT;
819    else if (!e_util_strcmp(name, "quickpanel_context_menu"  )) role = TZSH_SRV_ROLE_QUICKPANEL_CONTEXT_MENU;
820    else if (!e_util_strcmp(name, "quickpanel_apps_menu"     )) role = TZSH_SRV_ROLE_QUICKPANEL_APPS_MENU;
821    else if (!e_util_strcmp(name, "lockscreen"               )) role = TZSH_SRV_ROLE_LOCKSCREEN;
822    else if (!e_util_strcmp(name, "indicator"                )) role = TZSH_SRV_ROLE_INDICATOR;
823    else if (!e_util_strcmp(name, "screensaver_manager"      )) role = TZSH_SRV_ROLE_SCREENSAVER_MNG;
824    else if (!e_util_strcmp(name, "screensaver"              )) role = TZSH_SRV_ROLE_SCREENSAVER;
825    else if (!e_util_strcmp(name, "cbhm"                     )) role = TZSH_SRV_ROLE_CBHM;
826    else if (!e_util_strcmp(name, "softkey"                  )) role = TZSH_SRV_ROLE_SOFTKEY;
827    else if (!e_util_strcmp(name, "magnifier"                )) role = TZSH_SRV_ROLE_MAGNIFIER;
828    else if (!e_util_strcmp(name, "launcher"                 )) role = TZSH_SRV_ROLE_LAUNCHER;
829    else if (!e_util_strcmp(name, "taskbar"                  )) role = TZSH_SRV_ROLE_TASKBAR;
830    else if (!e_util_strcmp(name, "KVM"                      )) role = TZSH_SRV_ROLE_KVM;
831
832    return role;
833 }
834
835 /* broadcast state of registered service to all subscribers */
836 static void
837 _e_policy_wl_tzsh_srv_state_broadcast(E_Policy_Wl_Tzsh_Srv *tzsh_srv, Eina_Bool reg)
838 {
839    E_Policy_Wl_Tzsh *tzsh;
840    Eina_List *l;
841
842    EINA_LIST_FOREACH(polwl->tzshs, l, tzsh)
843      {
844         if (tzsh_srv->tzsh == tzsh)
845           continue;
846
847         if (reg)
848           tizen_ws_shell_send_service_register
849             (tzsh->res_tzsh, tzsh_srv->name);
850         else
851           tizen_ws_shell_send_service_unregister
852             (tzsh->res_tzsh, tzsh_srv->name);
853      }
854 }
855
856 // --------------------------------------------------------
857 // E_Policy_Wl_Tzsh_Client
858 // --------------------------------------------------------
859 static Eina_Bool
860 _e_policy_wl_tzsh_client_cb_client_zone_set(void *data, int type EINA_UNUSED, void *event)
861 {
862    E_Policy_Wl_Tzsh_Client *tzsh_client;
863    E_Event_Client_Zone_Set *ev;
864
865    tzsh_client = data;
866    ev = event;
867
868    if (tzsh_client->ec != ev->ec)
869      goto end;
870
871    if (tzsh_client->zone == ev->zone)
872      goto end;
873
874    ELOGF("TZSH", "Change Zone | e_policy_wl_tzsh_client %p old(%p) new(%p)",
875          tzsh_client->ec, tzsh_client, tzsh_client->zone, ev->zone);
876
877    tzsh_client->zone = ev->zone;
878
879 end:
880    return ECORE_CALLBACK_PASS_ON;
881 }
882
883 static E_Policy_Wl_Tzsh_Client *
884 _e_policy_wl_tzsh_client_add(E_Policy_Wl_Tzsh *tzsh, struct wl_resource *res_tzsh_client, E_Pixmap *ep, E_Client *ec)
885 {
886    E_Policy_Wl_Tzsh_Client *tzsh_client;
887
888    tzsh_client = E_NEW(E_Policy_Wl_Tzsh_Client, 1);
889    EINA_SAFETY_ON_NULL_RETURN_VAL(tzsh_client, NULL);
890
891    tzsh_client->tzsh = tzsh;
892    tzsh_client->res_tzsh_client = res_tzsh_client;
893    tzsh_client->ep = ep;
894    tzsh_client->ec = ec;
895    tzsh_client->zone = e_comp_zone_find_by_ec(ec);
896    tzsh_client->tzsh->client_list = eina_list_append(tzsh_client->tzsh->client_list, tzsh_client);
897
898    polwl->tzsh_clients = eina_list_append(polwl->tzsh_clients, tzsh_client);
899
900    E_LIST_HANDLER_APPEND(tzsh_client->events, E_EVENT_CLIENT_ZONE_SET, _e_policy_wl_tzsh_client_cb_client_zone_set, tzsh_client);
901
902 #ifdef TZSH_DEBUG
903    _print_tzsh_client_info();
904 #endif
905
906    return tzsh_client;
907 }
908
909 static void
910 _e_policy_wl_tzsh_client_del(E_Policy_Wl_Tzsh_Client *tzsh_client)
911 {
912    if (!tzsh_client) return;
913
914    E_FREE_LIST(tzsh_client->events, ecore_event_handler_del);
915
916    if (tzsh_client->tzsh && tzsh_client->tzsh->client_list)
917      tzsh_client->tzsh->client_list = eina_list_remove(tzsh_client->tzsh->client_list, tzsh_client);
918
919    if (!eina_list_data_find(polwl->tzsh_clients, tzsh_client))
920      return;
921
922    polwl->tzsh_clients = eina_list_remove(polwl->tzsh_clients, tzsh_client);
923 #ifdef TZSH_DEBUG
924    _print_tzsh_client_info();
925 #endif
926
927    if (tzsh_client->res_tzsh_client)
928      wl_resource_set_user_data(tzsh_client->res_tzsh_client, NULL);
929
930    memset(tzsh_client, 0x0, sizeof(E_Policy_Wl_Tzsh_Client));
931    E_FREE(tzsh_client);
932 }
933
934 static E_Policy_Wl_Tzsh_Extension*
935 _e_policy_wl_tzsh_extension_get(const char *name)
936 {
937    E_Policy_Wl_Tzsh_Extension *tzsh_ext;
938    Eina_List *l;
939
940    EINA_LIST_FOREACH(polwl->tzsh_extensions, l, tzsh_ext)
941      {
942         if (strcmp(tzsh_ext->name, name)) continue;
943
944         return tzsh_ext;
945      }
946
947    return NULL;
948 }
949
950
951 // --------------------------------------------------------
952 // E_Policy_Wl_Surface
953 // --------------------------------------------------------
954 static E_Policy_Wl_Surface *
955 _e_policy_wl_surf_add(E_Client *ec, struct wl_resource *res_tzpol)
956 {
957    E_Comp_Wl_Client_Data *cdata;
958    E_Policy_Wl_Surface *psurf = NULL;
959    E_Policy_Wl_Tzpol *tzpol;
960
961    tzpol = _e_policy_wl_tzpol_get(res_tzpol);
962    EINA_SAFETY_ON_NULL_RETURN_VAL(tzpol, NULL);
963
964    psurf = _e_policy_wl_tzpol_surf_find(tzpol, ec);
965    if (psurf) return psurf;
966
967    psurf = E_NEW(E_Policy_Wl_Surface, 1);
968    EINA_SAFETY_ON_NULL_RETURN_VAL(psurf, NULL);
969
970    psurf->tzpol = tzpol;
971    psurf->cp = ec->pixmap;
972    psurf->ec = ec;
973    psurf->pid = ec->netwm.pid;
974
975    cdata = e_client_cdata_get(ec);
976    if (wl_resource_get_client(cdata->surface) == wl_resource_get_client(res_tzpol))
977        psurf->surf = cdata->surface;
978
979    tzpol->psurfs = eina_list_append(tzpol->psurfs, psurf);
980
981    if (tzpol->bg_state)
982      _e_policy_wl_background_state_set(psurf, EINA_TRUE);
983
984    return psurf;
985 }
986
987 static void
988 _e_policy_wl_surf_del(E_Policy_Wl_Surface *psurf)
989 {
990    eina_list_free(psurf->vislist);
991    eina_list_free(psurf->poslist);
992
993    memset(psurf, 0x0, sizeof(E_Policy_Wl_Surface));
994    E_FREE(psurf);
995 }
996
997 static void
998 _e_policy_wl_surf_client_set(E_Client *ec)
999 {
1000    E_Policy_Wl_Tzpol *tzpol;
1001    E_Policy_Wl_Surface *psurf;
1002    Eina_Iterator *it;
1003
1004    it = eina_hash_iterator_data_new(polwl->tzpols);
1005    EINA_ITERATOR_FOREACH(it, tzpol)
1006      {
1007         psurf = _e_policy_wl_tzpol_surf_find(tzpol, ec);
1008         if (psurf)
1009           {
1010              if ((psurf->ec) && (psurf->ec != ec))
1011                {
1012                   ELOGF("POLSURF",
1013                         "CRI ERR!!|s:%8p|tzpol:%8p|ps:%8p|new_ec:%8p|new_cp:%8p",
1014                         psurf->ec,
1015                         psurf->surf,
1016                         psurf->tzpol,
1017                         psurf,
1018                         ec,
1019                         ec->pixmap);
1020                }
1021
1022              psurf->ec = ec;
1023           }
1024      }
1025    eina_iterator_free(it);
1026
1027    return;
1028 }
1029
1030 static E_Pixmap *
1031 _e_policy_wl_e_pixmap_get_from_id(struct wl_client *client, uint32_t id)
1032 {
1033    E_Pixmap *cp;
1034    E_Client *ec;
1035    struct wl_resource *res_surf;
1036
1037    res_surf = wl_client_get_object(client, id);
1038    if (!res_surf)
1039      {
1040         ERR("Could not get surface resource");
1041         return NULL;
1042      }
1043
1044    ec = e_client_from_surface_resource(res_surf);
1045    if (!ec)
1046      {
1047         ERR("Could not get surface's user data");
1048         return NULL;
1049      }
1050
1051    /* check E_Pixmap */
1052    cp = e_pixmap_find(E_PIXMAP_TYPE_WL, (uintptr_t)res_surf);
1053    if (cp != ec->pixmap)
1054      {
1055         ELOGF("POLWL",
1056               "CRI ERR!!|cp2:%8p|ec2:%8p|res_surf:%8p",
1057               ec,
1058               cp,
1059               e_pixmap_client_get(cp),
1060               res_surf);
1061         return NULL;
1062      }
1063
1064    return cp;
1065 }
1066
1067 static Eina_Bool
1068 _e_policy_wl_e_client_is_valid(E_Client *ec)
1069 {
1070    E_Client *ec2;
1071    Eina_List *l;
1072    Eina_Bool del = EINA_FALSE;
1073    Eina_Bool found = EINA_FALSE;
1074
1075    EINA_LIST_FOREACH(e_comp->clients, l, ec2)
1076      {
1077         if (ec2 == ec)
1078           {
1079              if (e_object_is_del(E_OBJECT(ec2)))
1080                del = EINA_TRUE;
1081              found = EINA_TRUE;
1082              break;
1083           }
1084      }
1085
1086    return ((!del) && (found));
1087 }
1088
1089 static Eina_List *
1090 _e_policy_wl_e_clients_find_by_pid(pid_t pid)
1091 {
1092    E_Client *ec;
1093    Eina_List *clients = NULL, *l;
1094
1095    EINA_LIST_FOREACH(e_comp->clients, l, ec)
1096      {
1097         if (e_object_is_del(E_OBJECT(ec))) continue;
1098         if (ec->netwm.pid != pid) continue;
1099         clients = eina_list_append(clients, ec);
1100      }
1101
1102    return clients;
1103 }
1104
1105 // --------------------------------------------------------
1106 // visibility
1107 // --------------------------------------------------------
1108 static void
1109 _tzvis_iface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzvis)
1110 {
1111    wl_resource_destroy(res_tzvis);
1112 }
1113
1114 static const struct tizen_visibility_interface _tzvis_iface =
1115 {
1116    _tzvis_iface_cb_destroy
1117 };
1118
1119 static void
1120 _tzvis_iface_cb_vis_destroy(struct wl_resource *res_tzvis)
1121 {
1122    E_Policy_Wl_Surface *psurf;
1123    Eina_Bool r;
1124
1125    psurf = wl_resource_get_user_data(res_tzvis);
1126    EINA_SAFETY_ON_NULL_RETURN(psurf);
1127
1128    r = _e_policy_wl_surf_is_valid(psurf);
1129    if (!r) return;
1130
1131    psurf->vislist = eina_list_remove(psurf->vislist, res_tzvis);
1132 }
1133
1134 static void
1135 _tzpol_iface_cb_vis_get(struct wl_client *client, struct wl_resource *res_tzpol, uint32_t id, struct wl_resource *surf)
1136 {
1137    E_Client *ec;
1138    E_Policy_Wl_Surface *psurf;
1139    struct wl_resource *res_tzvis;
1140
1141    ec = e_client_from_surface_resource(surf);
1142    EINA_SAFETY_ON_NULL_RETURN(ec);
1143
1144    psurf = _e_policy_wl_surf_add(ec, res_tzpol);
1145    EINA_SAFETY_ON_NULL_RETURN(psurf);
1146
1147    res_tzvis = wl_resource_create(client,
1148                                   &tizen_visibility_interface,
1149                                   wl_resource_get_version(res_tzpol),
1150                                   id);
1151    if (!res_tzvis)
1152      {
1153         wl_client_post_no_memory(client);
1154         return;
1155      }
1156
1157    wl_resource_set_implementation(res_tzvis,
1158                                   &_tzvis_iface,
1159                                   psurf,
1160                                   _tzvis_iface_cb_vis_destroy);
1161
1162    psurf->vislist = eina_list_append(psurf->vislist, res_tzvis);
1163
1164    if (eina_list_data_find(polwl->pending_vis, ec))
1165      {
1166         e_policy_wl_visibility_send(ec, e_client_visibility_get(ec));
1167      }
1168 }
1169
1170 EINTERN void
1171 e_policy_wl_visibility_send(E_Client *ec, int vis)
1172 {
1173    E_Comp_Wl_Client_Data *cdata;
1174    E_Policy_Wl_Tzpol *tzpol;
1175    E_Policy_Wl_Surface *psurf;
1176    struct wl_resource *res_tzvis;
1177    Eina_List *l, *ll;
1178    Eina_Iterator *it;
1179    E_Client *ec2;
1180    Ecore_Window win;
1181    Eina_Bool sent = EINA_FALSE;
1182    int ver = 1;
1183    int sent_vis = E_VISIBILITY_UNKNOWN;
1184
1185    EINA_SAFETY_ON_TRUE_RETURN(vis == E_VISIBILITY_UNKNOWN);
1186    if (ec && (ec->visibility.last_sent_type == vis))
1187      return;
1188
1189    win = e_client_util_win_get(ec);
1190
1191    it = eina_hash_iterator_data_new(polwl->tzpols);
1192    EINA_ITERATOR_FOREACH(it, tzpol)
1193      EINA_LIST_FOREACH(tzpol->psurfs, l, psurf)
1194        {
1195           ec2 = e_pixmap_client_get(psurf->cp);
1196           if (ec2 != ec) continue;
1197
1198           EINA_LIST_FOREACH(psurf->vislist, ll, res_tzvis)
1199             {
1200                // below code is workaround for checking visibility by display off or not
1201                if (e_comp_client_zone_is_displaying(ec))
1202                   e_policy_aux_message_send(ec, "dpms_wm", "on", NULL);
1203                else
1204                   e_policy_aux_message_send(ec, "dpms_wm", "off", NULL);
1205
1206                ver = wl_resource_get_version(res_tzvis);
1207                sent_vis = vis;
1208
1209                if (vis == E_VISIBILITY_PRE_UNOBSCURED)
1210                  {
1211                     if (ver >= 5)
1212                       {
1213                          ec->visibility.last_sent_type = vis;
1214                          tizen_visibility_send_changed(res_tzvis, vis, 0);
1215                       }
1216                     else
1217                       sent_vis = -2;
1218                  }
1219                else
1220                  {
1221                     if ((vis >= E_VISIBILITY_UNOBSCURED) && (vis <= E_VISIBILITY_FULLY_OBSCURED))
1222                       {
1223                          ec->visibility.last_sent_type = vis;
1224                          tizen_visibility_send_notify(res_tzvis, vis);
1225                       }
1226                     else
1227                       sent_vis = -3;
1228                  }
1229
1230                cdata = e_client_cdata_get(ec);
1231                if (cdata && cdata->mapped)
1232                  {
1233                     _launch_effect_hide(ec->netwm.pid);
1234                  }
1235
1236                ELOGF("POL_VIS",
1237                      "SEND     |win:0x%08zx|res_tzvis:%8p|ver:%d|sent_vis:%d|pid:%d|cdata:%8p|title:%s, name:%s",
1238                      ec,
1239                      win,
1240                      res_tzvis,
1241                      ver,
1242                      sent_vis,
1243                      ec->netwm.pid, cdata, ec->icccm.title, ec->netwm.name);
1244                sent = EINA_TRUE;
1245             }
1246        }
1247    eina_iterator_free(it);
1248
1249    polwl->pending_vis = eina_list_remove(polwl->pending_vis, ec);
1250    if (!sent)
1251      polwl->pending_vis = eina_list_append(polwl->pending_vis, ec);
1252 }
1253
1254 EINTERN Eina_Bool
1255 e_policy_wl_iconify_state_supported_get(E_Client *ec)
1256 {
1257    E_Policy_Wl_Tzpol *tzpol;
1258    E_Policy_Wl_Surface *psurf;
1259    E_Client *ec2;
1260    Eina_List *l;
1261    Eina_Iterator *it;
1262    Eina_Bool found = EINA_FALSE;
1263
1264    it = eina_hash_iterator_data_new(polwl->tzpols);
1265    EINA_ITERATOR_FOREACH(it, tzpol)
1266       EINA_LIST_FOREACH(tzpol->psurfs, l, psurf)
1267         {
1268            ec2 = e_pixmap_client_get(psurf->cp);
1269            if (ec2 == ec)
1270              {
1271                 found = EINA_TRUE;
1272                 break;
1273              }
1274         }
1275    eina_iterator_free(it);
1276
1277    return found;
1278 }
1279
1280 E_API void
1281 e_policy_wl_iconify_state_change_send(E_Client *ec, int iconic)
1282 {
1283    E_Policy_Wl_Tzpol *tzpol;
1284    E_Policy_Wl_Surface *psurf;
1285    E_Client *ec2;
1286    Eina_List *l;
1287    Eina_Iterator *it;
1288
1289    if (ec->exp_iconify.skip_iconify) return;
1290    if (ec->exp_iconify.skip_by_remote) return;
1291
1292    if (e_config->transient.iconify)
1293      {
1294         E_Comp_Wl_Client_Data *cdata;
1295         E_Client *child;
1296         Eina_List *list = eina_list_clone(ec->transients);
1297
1298         EINA_LIST_FREE(list, child)
1299           {
1300              cdata = e_client_cdata_get(child);
1301              if (cdata && !cdata->mapped) continue;
1302
1303              if ((child->iconic == ec->iconic) &&
1304                  (e_client_is_iconified_by_client(child) == e_client_is_iconified_by_client(ec)))
1305                e_policy_wl_iconify_state_change_send(child, iconic);
1306
1307           }
1308      }
1309
1310    it = eina_hash_iterator_data_new(polwl->tzpols);
1311    EINA_ITERATOR_FOREACH(it, tzpol)
1312      EINA_LIST_FOREACH(tzpol->psurfs, l, psurf)
1313        {
1314           ec2 = e_pixmap_client_get(psurf->cp);
1315           if (ec2 != ec) continue;
1316           if (!psurf->surf) continue;
1317
1318           tizen_policy_send_iconify_state_changed(tzpol->res_tzpol, psurf->surf, iconic, 1);
1319           ELOGF("ICONIFY",
1320                 "SEND     |iconic:%d  |argb:%d       |sur:%p",
1321                 ec,
1322                 iconic, ec->argb, psurf->surf);
1323           ec->exp_iconify.last_sent_iconic = iconic;
1324           break;
1325        }
1326    eina_iterator_free(it);
1327 }
1328
1329 // --------------------------------------------------------
1330 // position
1331 // --------------------------------------------------------
1332 static void
1333 _tzpos_iface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpos)
1334 {
1335    wl_resource_destroy(res_tzpos);
1336 }
1337
1338 static void
1339 _tzpos_iface_cb_set(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpos, int32_t x, int32_t y)
1340 {
1341    E_Client *ec;
1342    E_Policy_Wl_Surface *psurf;
1343    E_Desk *desk;
1344
1345    psurf = wl_resource_get_user_data(res_tzpos);
1346    EINA_SAFETY_ON_NULL_RETURN(psurf);
1347
1348    ec = e_pixmap_client_get(psurf->cp);
1349    EINA_SAFETY_ON_NULL_RETURN(ec);
1350    EINA_SAFETY_ON_NULL_RETURN(ec->frame);
1351
1352    if (e_policy_client_is_keyboard(ec))
1353      {
1354         ELOGF("TZPOL", "Keyboard pos set (%d, %d). No operation. return.", ec, x, y);
1355         return;
1356      }
1357
1358    desk = e_comp_desk_find_by_ec(ec);
1359    EINA_SAFETY_ON_NULL_RETURN(desk);
1360
1361    if (!ec->lock_client_location)
1362      {
1363         if (e_client_pending_geometry_has(ec))
1364           {
1365              // if there is geometry pending list, add move job at the end of the list.
1366              // so client to be applied new position at the same time with the pending requests
1367              // pending geometries are flushed when 'wl surface commit' and matched serial are delivered.
1368              int w, h;
1369              e_client_pending_geometry_last_geometry_get(ec, NULL, NULL, &w, &h);
1370              e_comp_wl_commit_sync_client_geometry_add(ec, ec->surface_sync.serial, x, y, w, h);
1371           }
1372         else
1373           {
1374              ec->client.x = desk->geom.x + x;
1375              ec->client.y = desk->geom.y + y;
1376              e_client_pos_set(ec, ec->client.x, ec->client.y);
1377              ec->placed = 1;
1378              ec->changes.pos = 1;
1379           }
1380         ec->changes.tz_position = 1;
1381         EC_CHANGED(ec);
1382      }
1383
1384    e_policy_hook_call(E_POLICY_HOOK_CLIENT_POSITION_SET, ec);
1385 }
1386
1387 static const struct tizen_position_interface _tzpos_iface =
1388 {
1389    _tzpos_iface_cb_destroy,
1390    _tzpos_iface_cb_set,
1391 };
1392
1393 static void
1394 _tzpol_iface_cb_pos_destroy(struct wl_resource *res_tzpos)
1395 {
1396    E_Policy_Wl_Surface *psurf;
1397    Eina_Bool r;
1398
1399    psurf = wl_resource_get_user_data(res_tzpos);
1400    EINA_SAFETY_ON_NULL_RETURN(psurf);
1401
1402    r = _e_policy_wl_surf_is_valid(psurf);
1403    if (!r) return;
1404
1405    psurf->poslist = eina_list_remove(psurf->poslist, res_tzpos);
1406 }
1407
1408 static void
1409 _tzpol_iface_cb_pos_get(struct wl_client *client, struct wl_resource *res_tzpol, uint32_t id, struct wl_resource *surf)
1410 {
1411    E_Client *ec;
1412    E_Policy_Wl_Surface *psurf;
1413    struct wl_resource *res_tzpos;
1414
1415    ec = e_client_from_surface_resource(surf);
1416    EINA_SAFETY_ON_NULL_RETURN(ec);
1417
1418    psurf = _e_policy_wl_surf_add(ec, res_tzpol);
1419    EINA_SAFETY_ON_NULL_RETURN(psurf);
1420
1421    res_tzpos = wl_resource_create(client,
1422                                   &tizen_position_interface,
1423                                   wl_resource_get_version(res_tzpol),
1424                                   id);
1425    if (!res_tzpos)
1426      {
1427         wl_client_post_no_memory(client);
1428         return;
1429      }
1430
1431    wl_resource_set_implementation(res_tzpos,
1432                                   &_tzpos_iface,
1433                                   psurf,
1434                                   _tzpol_iface_cb_pos_destroy);
1435
1436    psurf->poslist = eina_list_append(psurf->poslist, res_tzpos);
1437
1438    // if ec's pos is not same to client's geometry (ec->comp_data->shell.window),
1439    // then send tizen_position changed event
1440    if (ec->comp_data)
1441      {
1442         if ((ec->x != ec->comp_data->shell.window.x) ||
1443             (ec->y != ec->comp_data->shell.window.y))
1444           e_policy_wl_position_send(ec);
1445      }
1446 }
1447
1448 EINTERN void
1449 e_policy_wl_position_send(E_Client *ec)
1450 {
1451    E_Policy_Wl_Tzpol *tzpol;
1452    E_Policy_Wl_Surface *psurf;
1453    struct wl_resource *res_tzpos;
1454    Eina_List *l, *ll;
1455    Eina_Iterator *it;
1456    Ecore_Window win;
1457
1458    EINA_SAFETY_ON_NULL_RETURN(ec);
1459
1460    win = e_client_util_win_get(ec);
1461
1462    it = eina_hash_iterator_data_new(polwl->tzpols);
1463    EINA_ITERATOR_FOREACH(it, tzpol)
1464      EINA_LIST_FOREACH(tzpol->psurfs, l, psurf)
1465        {
1466           if (e_pixmap_client_get(psurf->cp) != ec) continue;
1467
1468           EINA_LIST_FOREACH(psurf->poslist, ll, res_tzpos)
1469             {
1470                tizen_position_send_changed(res_tzpos, ec->client.x, ec->client.y);
1471                ELOGF("TZPOS",
1472                      "SEND     |win:0x%08zx|res_tzpos:%8p|ec->x:%d, ec->y:%d, ec->client.x:%d, ec->client.y:%d",
1473                      ec,
1474                      win,
1475                      res_tzpos,
1476                      ec->x, ec->y,
1477                      ec->client.x, ec->client.y);
1478             }
1479        }
1480    eina_iterator_free(it);
1481 }
1482
1483 // --------------------------------------------------------
1484 // stack: activate, raise, lower
1485 // --------------------------------------------------------
1486
1487 E_API void
1488 e_policy_wl_activate(E_Client *ec)
1489 {
1490    EINA_SAFETY_ON_NULL_RETURN(ec);
1491    EINA_SAFETY_ON_NULL_RETURN(ec->frame);
1492
1493    ELOGF("TZPOL", "REAL ACTIVATE", ec);
1494
1495    e_policy_visibility_client_lower_job_cancel(ec);
1496
1497    if ((!starting) && (!ec->focused))
1498      {
1499         if (!e_policy_visibility_client_activate(ec))
1500           {
1501              if ((ec->iconic) && (!e_client_is_iconified_by_client(ec)))
1502                e_policy_wl_iconify_state_change_send(ec, 0);
1503
1504              if (!ec->visibility.force_obscured)
1505                e_client_activate(ec);
1506           }
1507      }
1508    else
1509      {
1510         if (!ec->lock_user_stacking)
1511           e_client_raise(ec);
1512      }
1513
1514    if (e_policy_client_is_lockscreen(ec))
1515      e_policy_stack_clients_restack_above_lockscreen(ec, EINA_TRUE);
1516    else
1517      e_policy_stack_check_above_lockscreen(ec, ec->layer);
1518 }
1519
1520 static void
1521 _tzpol_iface_cb_activate(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol EINA_UNUSED, struct wl_resource *surf)
1522 {
1523    E_Client *ec;
1524    E_Comp_Wl_Client_Data *cdata;
1525
1526    ec = e_client_from_surface_resource(surf);
1527    EINA_SAFETY_ON_NULL_RETURN(ec);
1528    EINA_SAFETY_ON_NULL_RETURN(ec->frame);
1529
1530    ELOGF("TZPOL", "ACTIVATE", ec);
1531
1532    if (ec->parent)
1533      e_policy_stack_transient_child_raise(ec);
1534
1535    e_policy_hook_call(E_POLICY_HOOK_CLIENT_ACTIVE_REQ, ec);
1536
1537    ec->post_lower = EINA_FALSE;
1538    cdata = e_client_cdata_get(ec);
1539    if (cdata && !cdata->mapped)
1540      {
1541         if (e_config->raise_before_show)
1542           e_client_raise(ec);
1543         else
1544           ec->post_raise = EINA_TRUE;
1545      }
1546    e_policy_wl_activate(ec);
1547 }
1548
1549 EINTERN void
1550 e_policy_wl_stack_changed_send(E_Client *ec)
1551 {
1552    E_Client *above = NULL;
1553    E_Client *below = NULL;
1554    int above_pid = -1;
1555    int below_pid = -1;
1556
1557    above = e_client_above_get(ec);
1558    while (above)
1559      {
1560         if ((!e_object_is_del(E_OBJECT(above))) &&
1561             (!e_client_util_ignored_get(above)) &&
1562             (above->visible) &&
1563             (above->frame))
1564           break;
1565
1566         above = e_client_above_get(above);
1567      }
1568
1569    below = e_client_below_get(ec);
1570    while (below)
1571      {
1572         if ((!e_object_is_del(E_OBJECT(below))) &&
1573             (!e_client_util_ignored_get(below)) &&
1574             (below->visible) &&
1575             (below->frame))
1576           break;
1577
1578         below = e_client_below_get(below);
1579      }
1580
1581    if (above) above_pid = above->netwm.pid;
1582    if (below) below_pid = below->netwm.pid;
1583
1584    ELOGF("TZPOL", "Send stack_changed by activate_below. above(win:%zx, pid:%d), below(win:%zx, pid:%d)",
1585          ec, e_client_util_win_get(above), above_pid, e_client_util_win_get(below), below_pid);
1586
1587
1588    e_policy_aux_message_send_from_int(ec, "stack_changed", "activate_below", 2, above_pid, below_pid);
1589
1590 }
1591
1592 static void
1593 _tzpol_iface_cb_activate_below_by_res_id(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol,  uint32_t res_id, uint32_t below_res_id)
1594 {
1595    E_Client *ec = NULL;
1596    E_Client *below_ec = NULL;
1597    E_Client *parent_ec = NULL;
1598    E_Client *focus_ec = NULL;
1599    E_Comp_Wl_Client_Data *cdata;
1600    Eina_Bool check_ancestor = EINA_FALSE;
1601    Eina_Bool intercepted = EINA_FALSE;
1602
1603    ec = e_pixmap_find_client_by_res_id(res_id);
1604    EINA_SAFETY_ON_NULL_RETURN(ec);
1605    EINA_SAFETY_ON_NULL_RETURN(ec->frame);
1606
1607    below_ec = e_pixmap_find_client_by_res_id(below_res_id);
1608    EINA_SAFETY_ON_NULL_RETURN(below_ec);
1609    EINA_SAFETY_ON_NULL_RETURN(below_ec->frame);
1610
1611    ELOGF("TZPOL",
1612          "ACTIVATE_BELOW|win:0x%08zx(res_id:%d)|below_win:0x%08zx(res_id:%d)",
1613          NULL, e_client_util_win_get(ec), res_id, e_client_util_win_get(below_ec), below_res_id);
1614
1615    intercepted = e_policy_interceptor_call(E_POLICY_INTERCEPT_ACTIVATE_BELOW,
1616                                            ec, below_ec);
1617    if (intercepted)
1618      {
1619         ELOGF("TZPOL", "ACTIVATE_BELOW|Handled by Intercept function", ec);
1620         return;
1621      }
1622
1623    if (ec->layer > below_ec->layer) return;
1624
1625    parent_ec = ec->parent;
1626    while (parent_ec)
1627      {
1628         if (parent_ec == below_ec)
1629           {
1630              check_ancestor = EINA_TRUE;
1631              break;
1632           }
1633         parent_ec = parent_ec->parent;
1634      }
1635    if (check_ancestor) return;
1636
1637    if ((!starting) && (!ec->focused))
1638      {
1639         if ((ec->iconic) && (!e_client_is_iconified_by_client(ec)))
1640           e_policy_wl_iconify_state_change_send(ec, 0);
1641
1642         e_client_uniconify(ec);
1643      }
1644
1645    e_policy_stack_below(ec, below_ec);
1646
1647    cdata = e_client_cdata_get(ec);
1648    if (cdata && !cdata->mapped)
1649      {
1650         ELOGF("TZPOL", "POST_RAISE_LOWER SET... raise:%d, lower:%d", ec, EINA_FALSE, EINA_FALSE);
1651         e_client_post_raise_lower_set(ec, EINA_FALSE, EINA_FALSE);
1652      }
1653
1654    e_policy_wl_stack_changed_send(ec);
1655
1656    // check focus
1657    focus_ec = e_client_focused_get();
1658    if (focus_ec == below_ec)
1659      e_client_focus_latest_set(ec);
1660 }
1661
1662 static void
1663 _tzpol_iface_cb_activate_above_by_res_id(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol,  uint32_t res_id, uint32_t above_res_id)
1664 {
1665    E_Client *ec = NULL;
1666    E_Comp_Wl_Client_Data *cdata;
1667    E_Client *above_ec = NULL;
1668    E_Client *parent_ec = NULL;
1669    Eina_Bool check_ancestor = EINA_FALSE;
1670    Eina_Bool intercepted = EINA_FALSE;
1671
1672    ec = e_pixmap_find_client_by_res_id(res_id);
1673    EINA_SAFETY_ON_NULL_RETURN(ec);
1674    EINA_SAFETY_ON_NULL_RETURN(ec->frame);
1675
1676    above_ec = e_pixmap_find_client_by_res_id(above_res_id);
1677    EINA_SAFETY_ON_NULL_RETURN(above_ec);
1678    EINA_SAFETY_ON_NULL_RETURN(above_ec->frame);
1679
1680    ELOGF("TZPOL",
1681          "ACTIVATE_ABOVE|win:0x%08zx(res_id:%d)|above_win:0x%08zx(res_id:%d)",
1682          NULL, e_client_util_win_get(ec), res_id, e_client_util_win_get(above_ec), above_res_id);
1683
1684    intercepted = e_policy_interceptor_call(E_POLICY_INTERCEPT_ACTIVATE_ABOVE,
1685                                            ec, above_ec);
1686    if (intercepted)
1687      {
1688         ELOGF("TZPOL", "ACTIVATE_ABOVE|Handled by Intercept function", ec);
1689         return;
1690      }
1691
1692    if (ec->layer < above_ec->layer) return;
1693
1694    /* check child */
1695    parent_ec = above_ec->parent;
1696    while (parent_ec)
1697      {
1698         if (parent_ec == ec)
1699           {
1700              check_ancestor = EINA_TRUE;
1701              break;
1702           }
1703         parent_ec = parent_ec->parent;
1704      }
1705    if (check_ancestor) return;
1706
1707    if (ec->parent && (ec->parent == above_ec))
1708      {
1709         if (e_client_transient_policy_get(ec) == E_TRANSIENT_BELOW)
1710           {
1711              ELOGF("TZPOL", "ACTIVATE_ABOVE|Denied. Above is transient_below parent", ec);
1712              return;
1713           }
1714      }
1715
1716    if (!starting)
1717      {
1718         if ((ec->iconic) && (!e_client_is_iconified_by_client(ec)))
1719           e_policy_wl_iconify_state_change_send(ec, 0);
1720
1721         e_client_uniconify(ec);
1722      }
1723
1724    e_policy_stack_above(ec, above_ec);
1725
1726    cdata = e_client_cdata_get(ec);
1727    if (cdata && !cdata->mapped)
1728      {
1729         ELOGF("TZPOL", "POST_RAISE_LOWER SET... raise:%d, lower:%d", ec, EINA_FALSE, EINA_FALSE);
1730         e_client_post_raise_lower_set(ec, EINA_FALSE, EINA_FALSE);
1731      }
1732 }
1733
1734 static void
1735 _tzpol_iface_cb_raise(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol EINA_UNUSED, struct wl_resource *surf)
1736 {
1737    E_Client *ec;
1738    E_Comp_Wl_Client_Data *cdata;
1739
1740    ec = e_client_from_surface_resource(surf);
1741    EINA_SAFETY_ON_NULL_RETURN(ec);
1742    EINA_SAFETY_ON_NULL_RETURN(ec->frame);
1743
1744    ELOGF("TZPOL", "RAISE", ec);
1745
1746    if (ec->parent)
1747      e_policy_stack_transient_child_raise(ec);
1748
1749    e_policy_hook_call(E_POLICY_HOOK_CLIENT_RAISE_REQ, ec);
1750
1751    e_client_raise(ec);
1752
1753    cdata = e_client_cdata_get(ec);
1754    if (cdata && !cdata->mapped)
1755      {
1756         if (e_config->raise_before_show)
1757           {
1758              ELOGF("TZPOL", "POST_RAISE_LOWER SET... raise:%d, lower:%d", ec, EINA_FALSE, EINA_FALSE);
1759              e_client_post_raise_lower_set(ec, EINA_FALSE, EINA_FALSE);
1760           }
1761         else
1762           {
1763              ELOGF("TZPOL", "POST_RAISE_LOWER SET... raise:%d, lower:%d", ec, EINA_TRUE, EINA_FALSE);
1764              e_client_post_raise_lower_set(ec, EINA_TRUE, EINA_FALSE);
1765           }
1766      }
1767
1768    e_policy_hook_call(E_POLICY_HOOK_CLIENT_RAISE_REQ_DONE, ec);
1769 }
1770
1771 static void
1772 _tzpol_iface_cb_lower(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol EINA_UNUSED, struct wl_resource *surf)
1773 {
1774    E_Client *ec = NULL;
1775    E_Comp_Wl_Client_Data *cdata;
1776
1777    ec = e_client_from_surface_resource(surf);
1778    EINA_SAFETY_ON_NULL_RETURN(ec);
1779    EINA_SAFETY_ON_NULL_RETURN(ec->frame);
1780
1781    ELOGF("TZPOL", "LOWER", ec);
1782
1783    if (ec->parent)
1784      e_policy_stack_transient_child_lower(ec);
1785
1786    e_policy_hook_call(E_POLICY_HOOK_CLIENT_LOWER_REQ, ec);
1787
1788    if (e_policy_visibility_client_lower(ec))
1789      return;
1790
1791    cdata = e_client_cdata_get(ec);
1792    if (cdata && !cdata->mapped)
1793      {
1794         ELOGF("TZPOL", "POST_RAISE_LOWER SET... raise:%d, lower:%d", ec, EINA_FALSE, EINA_TRUE);
1795         e_client_post_raise_lower_set(ec, EINA_FALSE, EINA_TRUE);
1796      }
1797
1798    e_client_lower(ec);
1799 }
1800
1801 static void
1802 _tzpol_iface_cb_lower_by_res_id(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol,  uint32_t res_id)
1803 {
1804    E_Client *ec = NULL;
1805    E_Comp_Wl_Client_Data *cdata;
1806
1807    ec = e_pixmap_find_client_by_res_id(res_id);
1808    EINA_SAFETY_ON_NULL_RETURN(ec);
1809    EINA_SAFETY_ON_NULL_RETURN(ec->frame);
1810
1811    ELOGF("TZPOL", "LOWER by res id:%d", ec, res_id);
1812
1813    if (ec->parent)
1814      e_policy_stack_transient_child_lower(ec);
1815
1816    e_client_lower(ec);
1817
1818    cdata = e_client_cdata_get(ec);
1819    if (cdata && !cdata->mapped)
1820      {
1821         ELOGF("TZPOL", "POST_RAISE_LOWER SET... raise:%d, lower:%d", ec, EINA_FALSE, EINA_TRUE);
1822         e_client_post_raise_lower_set(ec, EINA_FALSE, EINA_TRUE);
1823      }
1824 }
1825
1826 // --------------------------------------------------------
1827 // focus
1828 // --------------------------------------------------------
1829 static void
1830 _tzpol_iface_cb_focus_skip_set(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol EINA_UNUSED, struct wl_resource *surf)
1831 {
1832    E_Client *ec;
1833
1834    ec = e_client_from_surface_resource(surf);
1835    EINA_SAFETY_ON_NULL_RETURN(ec);
1836
1837    e_client_focus_skip_set(ec, EINA_TRUE, EINA_TRUE);
1838 }
1839
1840 static void
1841 _tzpol_iface_cb_focus_skip_unset(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol EINA_UNUSED, struct wl_resource *surf)
1842 {
1843    E_Client *ec;
1844
1845    ec = e_client_from_surface_resource(surf);
1846    EINA_SAFETY_ON_NULL_RETURN(ec);
1847
1848    e_client_focus_skip_set(ec, EINA_FALSE, EINA_TRUE);
1849 }
1850
1851 static void
1852 _e_policy_wl_input_thread_cursor_set(void *data)
1853 {
1854    E_Input_Thread_Request_EClient_Data *ec_data = data;
1855    EINA_SAFETY_ON_NULL_RETURN(ec_data);
1856
1857    INF("[input thread|%s] ec(%p), is_cursor(%d)\n", __func__, ec_data->ec, ec_data->is_cursor);
1858    e_input_thread_client_is_cursor_set(e_input_thread_client_get(ec_data->ec), ec_data->is_cursor);
1859 }
1860
1861 // --------------------------------------------------------
1862 // role
1863 // --------------------------------------------------------
1864 static void
1865 _tzpol_iface_cb_role_set(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol EINA_UNUSED, struct wl_resource *surf, const char *role)
1866 {
1867    E_Client *ec;
1868    E_Comp_Wl_Client_Data *cdata;
1869    E_Input_Thread_Request_EClient_Data ec_data;
1870    memset(&ec_data, 0, sizeof(E_Input_Thread_Request_EClient_Data));
1871
1872    EINA_SAFETY_ON_NULL_RETURN(role);
1873
1874    ec = e_client_from_surface_resource(surf);
1875    EINA_SAFETY_ON_NULL_RETURN(ec);
1876    EINA_SAFETY_ON_NULL_RETURN(ec->frame);
1877
1878    ELOGF("TZPOL", "ROLE SET (role:%s)", ec, role);
1879    e_client_window_role_set(ec, role);
1880
1881    /* TODO: support multiple roles */
1882    if (!e_util_strcmp("tv-volume-popup", role))
1883      {
1884         e_client_layer_set(ec, E_LAYER_CLIENT_NOTIFICATION_LOW);
1885         ec->lock_client_location = 1;
1886      }
1887    else if (!e_util_strcmp("e_demo", role))
1888      {
1889         e_client_layer_set(ec, E_LAYER_CLIENT_NOTIFICATION_HIGH);
1890         ec->lock_client_location = 1;
1891      }
1892    else if (!e_util_strcmp("cbhm", role))
1893      {
1894         cdata = e_client_cdata_get(ec);
1895         if (!cdata) return;
1896         e_comp_wl->selection.cbhm = cdata->surface;
1897      }
1898    else if (!e_util_strcmp("wl_pointer-cursor", role))
1899      {
1900         ELOGF("TZPOL", "Set CURSOR role", ec);
1901         e_client_layer_set(ec, E_LAYER_CLIENT_CURSOR);
1902         ec->is_cursor = EINA_TRUE;
1903         e_client_desk_iconify_skip_set(ec, EINA_TRUE);
1904
1905         ec_data.ec = ec;
1906         ec_data.is_cursor = 1;
1907         INF("[%s] ec(%p), is_cursor(%d)\n", __func__, ec, ec->is_cursor);
1908         e_input_thread_safe_call(_e_policy_wl_input_thread_cursor_set, &ec_data, sizeof(E_Input_Thread_Request_EClient_Data));
1909      }
1910 }
1911
1912 static void
1913 _tzpol_iface_cb_type_set(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol, struct wl_resource *surf, uint32_t type)
1914 {
1915    E_Client *ec;
1916    E_Window_Type win_type;
1917
1918    ec = e_client_from_surface_resource(surf);
1919    EINA_SAFETY_ON_NULL_RETURN(ec);
1920
1921    switch (type)
1922      {
1923       /* TODO: support other types */
1924       case TIZEN_POLICY_WIN_TYPE_TOPLEVEL:
1925          win_type = E_WINDOW_TYPE_NORMAL;
1926          if (ec->layer != E_LAYER_CLIENT_NORMAL)
1927            {
1928               e_client_layer_set(ec, E_LAYER_CLIENT_NORMAL);
1929            }
1930          break;
1931
1932       case TIZEN_POLICY_WIN_TYPE_NOTIFICATION:
1933          win_type = E_WINDOW_TYPE_NOTIFICATION;
1934          break;
1935
1936       case TIZEN_POLICY_WIN_TYPE_UTILITY:
1937          win_type = E_WINDOW_TYPE_UTILITY;
1938          break;
1939
1940       case TIZEN_POLICY_WIN_TYPE_DIALOG:
1941          win_type = E_WINDOW_TYPE_DIALOG;
1942          break;
1943
1944       case TIZEN_POLICY_WIN_TYPE_DESKTOP:
1945          win_type = E_WINDOW_TYPE_DESKTOP;
1946          e_client_desk_iconify_skip_set(ec, EINA_TRUE);
1947          if (ec->layer != E_LAYER_CLIENT_DESKTOP)
1948            {
1949               e_client_layer_set(ec, E_LAYER_CLIENT_DESKTOP);
1950            }
1951          break;
1952
1953       default: return;
1954      }
1955
1956    ELOGF("TZPOL",
1957          "TYPE_SET |win:0x%08zx|s:%8p|res_tzpol:%8p|tizen_win_type:%d, e_win_type:%d",
1958          ec,
1959          e_client_util_win_get(ec),
1960          surf,
1961          res_tzpol,
1962          type, win_type);
1963
1964    ec->netwm.type = win_type;
1965
1966    e_policy_hook_call(E_POLICY_HOOK_CLIENT_TYPE_SET, ec);
1967
1968    EC_CHANGED(ec);
1969 }
1970 // --------------------------------------------------------
1971 // conformant
1972 // --------------------------------------------------------
1973 static void
1974 _tzpol_iface_cb_conformant_set(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol, struct wl_resource *surf)
1975 {
1976    E_Client *ec;
1977
1978    ec = e_client_from_surface_resource(surf);
1979    EINA_SAFETY_ON_NULL_RETURN(ec);
1980
1981    e_policy_conformant_client_add(ec, res_tzpol);
1982 }
1983
1984 static void
1985 _tzpol_iface_cb_conformant_unset(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol EINA_UNUSED, struct wl_resource *surf)
1986 {
1987    E_Client *ec;
1988
1989    ec = e_client_from_surface_resource(surf);
1990    EINA_SAFETY_ON_NULL_RETURN(ec);
1991
1992    e_policy_conformant_client_del(ec);
1993 }
1994
1995 static void
1996 _tzpol_iface_cb_conformant_get(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol, struct wl_resource *surf)
1997 {
1998    E_Client *ec;
1999
2000    ec = e_client_from_surface_resource(surf);
2001    EINA_SAFETY_ON_NULL_RETURN(ec);
2002
2003    tizen_policy_send_conformant(res_tzpol, surf, e_policy_conformant_client_check(ec));
2004 }
2005
2006 // --------------------------------------------------------
2007 // notification level
2008 // --------------------------------------------------------
2009 static void
2010 _tzpol_notilv_set(E_Client *ec, int lv)
2011 {
2012    short cur_ly;
2013    short ly;
2014
2015    switch (lv)
2016      {
2017       case  0: ly = E_LAYER_CLIENT_NOTIFICATION_LOW;    break;
2018       case  1: ly = E_LAYER_CLIENT_NOTIFICATION_NORMAL; break;
2019       case  2: ly = E_LAYER_CLIENT_NOTIFICATION_TOP;    break;
2020       case -1: ly = E_LAYER_CLIENT_NORMAL;              break;
2021       case 10: ly = E_LAYER_CLIENT_NOTIFICATION_LOW;    break;
2022       case 20: ly = E_LAYER_CLIENT_NOTIFICATION_NORMAL; break;
2023       case 30: ly = E_LAYER_CLIENT_NOTIFICATION_HIGH;   break;
2024       case 40: ly = E_LAYER_CLIENT_NOTIFICATION_TOP;    break;
2025       default: ly = E_LAYER_CLIENT_NOTIFICATION_LOW;    break;
2026      }
2027
2028 #ifdef REFACTOR_DESK_AREA
2029    cur_ly = e_client_layer_get(ec);
2030 #else
2031    cur_ly = e_client_desk_area_original_layer_get(ec);
2032 #endif
2033
2034    if (cur_ly != ly)
2035      {
2036         if (ly == E_LAYER_CLIENT_NORMAL)
2037           e_policy_animatable_lock(ec, E_POLICY_ANIMATABLE_LAYER, 0);
2038         else
2039           e_policy_animatable_lock(ec, E_POLICY_ANIMATABLE_LAYER, 1);
2040
2041         e_client_layer_set(ec, ly);
2042      }
2043    e_policy_hook_call(E_POLICY_HOOK_CLIENT_NOTILAYER_SET, ec);
2044 }
2045
2046 static void
2047 _tzpol_iface_cb_notilv_set(struct wl_client *client, struct wl_resource *res_tzpol, struct wl_resource *surf, int32_t lv)
2048 {
2049    E_Client *ec;
2050    E_Policy_Wl_Surface *psurf;
2051    pid_t pid = 0;
2052    uid_t uid = 0;
2053    Eina_Bool res;
2054
2055    ec = e_client_from_surface_resource(surf);
2056    EINA_SAFETY_ON_NULL_RETURN(ec);
2057
2058    psurf = _e_policy_wl_surf_add(ec, res_tzpol);
2059    EINA_SAFETY_ON_NULL_RETURN(psurf);
2060
2061    wl_client_get_credentials(client, &pid, &uid, NULL);
2062    res = e_security_privilege_check(pid, uid,
2063                                     E_PRIVILEGE_NOTIFICATION_LEVEL_SET);
2064    if (!res)
2065      {
2066         ELOGF("TZPOL",
2067               "Privilege Check Failed! DENY set_notification_level",
2068               ec);
2069
2070         tizen_policy_send_notification_done
2071            (res_tzpol,
2072             surf,
2073             -1,
2074             TIZEN_POLICY_ERROR_STATE_PERMISSION_DENIED);
2075         return;
2076      }
2077
2078    ELOGF("TZPOL", "NOTI_LEVEL|level:%d", ec, lv);
2079    _tzpol_notilv_set(ec, lv);
2080
2081    psurf->notilv = lv;
2082
2083    tizen_policy_send_notification_done
2084      (res_tzpol, surf, lv, TIZEN_POLICY_ERROR_STATE_NONE);
2085
2086    if (e_policy_client_is_lockscreen(ec))
2087      e_policy_stack_clients_restack_above_lockscreen(ec, EINA_TRUE);
2088    else
2089      e_policy_stack_check_above_lockscreen(ec, ec->layer);
2090 }
2091
2092 EINTERN void
2093 e_policy_wl_notification_level_fetch(E_Client *ec)
2094 {
2095    E_Pixmap *cp;
2096    E_Policy_Wl_Surface *psurf;
2097    E_Policy_Wl_Tzpol *tzpol;
2098    Eina_Iterator *it;
2099    Eina_List *l;
2100    Eina_Bool changed_stack = EINA_FALSE;
2101
2102    EINA_SAFETY_ON_NULL_RETURN(ec);
2103
2104    cp = ec->pixmap;
2105    EINA_SAFETY_ON_NULL_RETURN(cp);
2106
2107    // TODO: use pending_notilv_list instead of loop
2108    it = eina_hash_iterator_data_new(polwl->tzpols);
2109    EINA_ITERATOR_FOREACH(it, tzpol)
2110      EINA_LIST_FOREACH(tzpol->psurfs, l, psurf)
2111        {
2112           if (psurf->cp != cp) continue;
2113           if (!psurf->pending_notilv) continue;
2114
2115           psurf->pending_notilv = EINA_FALSE;
2116           _tzpol_notilv_set(ec, psurf->notilv);
2117           changed_stack = EINA_TRUE;
2118        }
2119    eina_iterator_free(it);
2120
2121    if (changed_stack && e_policy_client_is_lockscreen(ec))
2122      e_policy_stack_clients_restack_above_lockscreen(ec, EINA_TRUE);
2123 }
2124
2125 // --------------------------------------------------------
2126 // transient for
2127 // --------------------------------------------------------
2128 static void
2129 _tzpol_iface_cb_transient_for_set(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol, uint32_t child_id, uint32_t parent_id)
2130 {
2131    E_Client *ec, *parent_ec;
2132    E_Comp_Wl_Client_Data *cdata, *p_cdata;
2133
2134    ELOGF("TZPOL",
2135          "TF_SET   |res_tzpol:%8p|parent_id:%8d  |child_id:%8d",
2136          NULL, res_tzpol, parent_id, child_id);
2137
2138    ec = e_pixmap_find_client_by_res_id(child_id);
2139    EINA_SAFETY_ON_NULL_RETURN(ec);
2140    cdata = e_client_cdata_get(ec);
2141
2142    parent_ec = e_pixmap_find_client_by_res_id(parent_id);
2143    EINA_SAFETY_ON_NULL_RETURN(parent_ec);
2144    p_cdata = e_client_cdata_get(parent_ec);
2145
2146    ELOGF("TZPOL",
2147          "          |res_tzpol:%8p|parent_surf:%8p|child_surf:%8p",
2148          NULL, res_tzpol, (p_cdata ? p_cdata->surface : NULL), (cdata ? cdata->surface : NULL));
2149
2150    e_policy_stack_transient_for_set(ec, parent_ec);
2151    tizen_policy_send_transient_for_done(res_tzpol, child_id);
2152 }
2153
2154 static void
2155 _tzpol_iface_cb_transient_for_unset(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol, uint32_t child_id)
2156 {
2157    E_Client *ec;
2158
2159    ELOGF("TZPOL",
2160          "TF_UNSET |res_tzpol:%8p|child:%d",
2161          NULL, res_tzpol, child_id);
2162
2163    ec = e_pixmap_find_client_by_res_id(child_id);
2164    EINA_SAFETY_ON_NULL_RETURN(ec);
2165
2166    e_policy_stack_transient_for_set(ec, NULL);
2167    tizen_policy_send_transient_for_done(res_tzpol, child_id);
2168 }
2169
2170 // --------------------------------------------------------
2171 // window screen mode
2172 // --------------------------------------------------------
2173 static void
2174 _tzpol_iface_cb_win_scrmode_set(struct wl_client *client, struct wl_resource *res_tzpol, struct wl_resource *surf, uint32_t mode)
2175 {
2176    E_Client *ec;
2177    pid_t pid = 0;
2178    uid_t uid = 0;
2179    Eina_Bool res;
2180
2181    ec = e_client_from_surface_resource(surf);
2182    EINA_SAFETY_ON_NULL_RETURN(ec);
2183
2184    wl_client_get_credentials(client, &pid, &uid, NULL);
2185    res = e_security_privilege_check(pid, uid,
2186                                     E_PRIVILEGE_SCREEN_MODE_SET);
2187    if (!res)
2188      {
2189         ELOGF("TZPOL",
2190               "Privilege Check Failed! DENY set_screen_mode",
2191               ec);
2192
2193         tizen_policy_send_window_screen_mode_done
2194            (res_tzpol,
2195             surf,
2196             -1,
2197             TIZEN_POLICY_ERROR_STATE_PERMISSION_DENIED);
2198         return;
2199      }
2200
2201    ELOGF("TZPOL", "SCR_MODE |mode:%d", ec, mode);
2202
2203    e_policy_display_screen_mode_set(ec, mode);
2204    e_policy_wl_win_scrmode_apply();
2205
2206    tizen_policy_send_window_screen_mode_done
2207      (res_tzpol, surf, mode, TIZEN_POLICY_ERROR_STATE_NONE);
2208 }
2209
2210 EINTERN void
2211 e_policy_wl_win_scrmode_apply(void)
2212 {
2213    e_policy_display_screen_mode_apply();
2214 }
2215
2216 // --------------------------------------------------------
2217 // subsurface
2218 // --------------------------------------------------------
2219
2220 static const struct wl_subsurface_interface _tzpol_subsurface_fake_impl;
2221
2222 static void
2223 _tzpol_iface_cb_subsurf_place_below_parent(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol EINA_UNUSED, struct wl_resource *subsurf)
2224 {
2225    if (wl_resource_instance_of(subsurf, &wl_subsurface_interface, &_tzpol_subsurface_fake_impl))
2226      return;
2227
2228    e_comp_wl_subsurface_resource_place_below_parent(subsurf);
2229 }
2230
2231 static void
2232 _tzpol_iface_cb_subsurf_stand_alone_set(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol EINA_UNUSED, struct wl_resource *subsurf)
2233 {
2234    if (wl_resource_instance_of(subsurf, &wl_subsurface_interface, &_tzpol_subsurface_fake_impl))
2235      return;
2236
2237    e_comp_wl_subsurface_resource_stand_alone_mode_set(subsurf);
2238 }
2239
2240 static void
2241 _tzpol_subsurface_fake_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
2242 {
2243    wl_resource_destroy(resource);
2244 }
2245
2246 static void
2247 _tzpol_subsurface_fake_cb_position_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, int32_t x EINA_UNUSED, int32_t y EINA_UNUSED)
2248 {
2249 }
2250
2251 static void
2252 _tzpol_subsurface_fake_cb_place_above(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, struct wl_resource *sibling_resource EINA_UNUSED)
2253 {
2254 }
2255
2256 static void
2257 _tzpol_subsurface_fake_cb_place_below(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, struct wl_resource *sibling_resource EINA_UNUSED)
2258 {
2259 }
2260
2261 static void
2262 _tzpol_subsurface_fake_cb_sync_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED)
2263 {
2264 }
2265
2266 static void
2267 _tzpol_subsurface_fake_cb_desync_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED)
2268 {
2269 }
2270
2271 static const struct wl_subsurface_interface _tzpol_subsurface_fake_impl =
2272 {
2273    _tzpol_subsurface_fake_cb_destroy,
2274    _tzpol_subsurface_fake_cb_position_set,
2275    _tzpol_subsurface_fake_cb_place_above,
2276    _tzpol_subsurface_fake_cb_place_below,
2277    _tzpol_subsurface_fake_cb_sync_set,
2278    _tzpol_subsurface_fake_cb_desync_set,
2279 };
2280
2281 static Eina_Bool
2282 _tzpol_subsurface_add_with_fake_impl(struct wl_client *client, uint32_t id)
2283 {
2284    struct wl_resource *resource;
2285
2286    resource = wl_resource_create(client, &wl_subsurface_interface, 1, id);
2287    if (!resource)
2288      return EINA_FALSE;
2289
2290    wl_resource_set_implementation(resource,
2291                                   &_tzpol_subsurface_fake_impl,
2292                                   NULL, NULL);
2293
2294    return EINA_TRUE;
2295 }
2296
2297 static void
2298 _tzpol_iface_cb_subsurface_get(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *surface, uint32_t parent_id)
2299 {
2300    E_Client *ec, *epc;
2301    E_Comp_Wl_Client_Data *cdata;
2302    Eina_Bool res;
2303
2304    ELOGF("TZPOL",
2305          "SUBSURF   |wl_surface@%d|parent_id:%d",
2306          NULL, wl_resource_get_id(surface), parent_id);
2307
2308    ec = e_client_from_surface_resource(surface);
2309
2310    epc = e_pixmap_find_client_by_res_id(parent_id);
2311    if ((!epc) ||
2312        (e_object_is_del(E_OBJECT(epc))))
2313      {
2314         ELOGF("TZPOL", "SUBSURF   | Invalid parent(%p). "
2315               "Create with fake implementation", ec, epc);
2316
2317         e_subsurface_watcher_invalid_parent_notify(surface);
2318
2319         /* We have to create a subsurface resource here even though it's error case
2320          * because server will send the fatal error when a client destroy a subsurface object.
2321          * Otherwise, server will kill a client by the fatal error.
2322          */
2323         if (!_tzpol_subsurface_add_with_fake_impl(client, id))
2324           wl_resource_post_no_memory(resource);
2325
2326         return;
2327      }
2328
2329    /* This check code is for detecting an error case which tries to create
2330     * sub-surface relationship with invalid parent. */
2331    if ((!epc->comp_data) ||
2332        (!epc->comp_data->wl_surface))
2333      {
2334         ELOGF("TZPOL", "Parent(%p internal? %s) doesn't have comp_data. "
2335               "Possibly it's not the surface created by client. "
2336               "Cannot be the parent of sub-surface.",
2337               ec, epc, epc->internal ? "TRUE" : "FALSE");
2338         wl_resource_post_error(resource,
2339                                WL_SUBSURFACE_ERROR_BAD_SURFACE,
2340                                "Invalid parent_id@%d. Possibly it's not the "
2341                                "surface created by client.(internal? %s) "
2342                                "Cannot be the parent of sub-surface.",
2343                                parent_id, epc->internal ? "TRUE" : "FALSE");
2344         return;
2345      }
2346
2347    res = e_comp_wl_subsurface_add(resource, id, surface,
2348                                   epc->comp_data->wl_surface);
2349    if (!res)
2350      {
2351         ERR("Failed to add subsurface for surface@%d", wl_resource_get_id(surface));
2352         return;
2353      }
2354
2355    /* ec's parent comes from another process */
2356    cdata = e_client_cdata_get(ec);
2357    if (cdata)
2358      cdata->has_extern_parent = EINA_TRUE;
2359 }
2360
2361 static void
2362 _tzpol_iface_cb_opaque_state_set(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface, int32_t state)
2363 {
2364    E_Client *ec;
2365
2366    ec = e_client_from_surface_resource(surface);
2367    EINA_SAFETY_ON_NULL_RETURN(ec);
2368
2369    ELOGF("TZPOL", "OPAQUE   |opaque_state:%d", ec, state);
2370    if(ec->visibility.opaque == state)
2371      return;
2372    ec->visibility.opaque = state;
2373
2374    EC_CHANGED(ec);
2375 }
2376
2377 // --------------------------------------------------------
2378 // iconify
2379 // --------------------------------------------------------
2380
2381 E_API void
2382 e_policy_wl_iconify(E_Client *ec)
2383 {
2384    EINA_SAFETY_ON_NULL_RETURN(ec);
2385    EINA_SAFETY_ON_NULL_RETURN(ec->frame);
2386
2387    ELOGF("TZPOL", "Set ICONIFY BY CLIENT", ec);
2388
2389    if (e_policy_visibility_client_iconify(ec))
2390      {
2391         ec->exp_iconify.by_client = 1;
2392         e_client_iconified_type_set(ec, E_ICONIFIED_TYPE_ICONIFY_BY_CLIENT);
2393         return;
2394      }
2395    ec->exp_iconify.by_client = 1;
2396    e_client_iconified_type_set(ec, E_ICONIFIED_TYPE_ICONIFY_BY_CLIENT);
2397
2398    e_client_iconify(ec);
2399
2400    EC_CHANGED(ec);
2401 }
2402
2403 EINTERN void
2404 e_policy_wl_uniconify(E_Client *ec)
2405 {
2406    EINA_SAFETY_ON_NULL_RETURN(ec);
2407    EINA_SAFETY_ON_NULL_RETURN(ec->frame);
2408
2409    if (e_policy_visibility_client_uniconify(ec, 1))
2410      return;
2411
2412    if ((ec->iconic) && (!e_client_is_iconified_by_client(ec)))
2413      e_policy_wl_iconify_state_change_send(ec, 0);
2414
2415    if (ec->visibility.force_obscured)
2416      {
2417         ec->exp_iconify.by_client = 0;
2418         e_client_iconified_type_set(ec, E_ICONIFIED_TYPE_NONE);
2419         return;
2420      }
2421
2422    e_client_uniconify(ec);
2423    ELOGF("TZPOL", "Un-Set ICONIFY BY CLIENT", ec);
2424    ec->exp_iconify.by_client = 0;
2425    e_client_iconified_type_set(ec, E_ICONIFIED_TYPE_NONE);
2426
2427    EC_CHANGED(ec);
2428 }
2429
2430 static void
2431 _tzpol_iface_cb_iconify(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol EINA_UNUSED, struct wl_resource *surf)
2432 {
2433    E_Client *ec;
2434
2435    ec = e_client_from_surface_resource(surf);
2436    EINA_SAFETY_ON_NULL_RETURN(ec);
2437
2438    ELOGF("TZPOL", "ICONIFY", ec);
2439
2440    e_policy_hook_call(E_POLICY_HOOK_CLIENT_ICONIFY_REQ, ec);
2441    e_policy_wl_iconify(ec);
2442 }
2443
2444 static void
2445 _tzpol_iface_cb_uniconify(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol EINA_UNUSED, struct wl_resource *surf)
2446 {
2447    E_Client *ec;
2448
2449    ec = e_client_from_surface_resource(surf);
2450    EINA_SAFETY_ON_NULL_RETURN(ec);
2451
2452    ELOGF("TZPOL", "UNICONIFY", ec);
2453
2454    e_policy_hook_call(E_POLICY_HOOK_CLIENT_UNICONIFY_REQ, ec);
2455    e_policy_wl_uniconify(ec);
2456 }
2457
2458 static void
2459 _e_policy_wl_allowed_aux_hint_send(struct wl_resource *res_tzpol, struct wl_resource *surf, int32_t id)
2460 {
2461    E_Client *ec;
2462
2463    ec = e_client_from_surface_resource(surf);
2464    EINA_SAFETY_ON_NULL_RETURN(ec);
2465
2466    ELOGF("TZPOL", "SEND     |res_tzpol:%8p|id:%d, hint allowed ", ec, res_tzpol, id);
2467    tizen_policy_send_allowed_aux_hint(res_tzpol, surf, id);
2468 }
2469
2470 static void
2471 _e_policy_wl_aux_hint_apply(E_Client *ec)
2472 {
2473    E_Comp_Wl_Client_Data *cdata;
2474    E_Comp_Wl_Aux_Hint *hint;
2475    Eina_List *l;
2476
2477    cdata = e_client_cdata_get(ec);
2478    if (!cdata) return;
2479    if (!cdata->aux_hint.changed) return;
2480
2481    EINA_LIST_FOREACH(cdata->aux_hint.hints, l, hint)
2482      {
2483         if (!hint->changed) continue;
2484         EC_CHANGED(ec);
2485
2486         if (!strcmp(hint->hint, hint_names[E_POLICY_HINT_USER_GEOMETRY]))
2487           {
2488              if (hint->deleted)
2489                {
2490                   e_policy_user_geometry_set(ec, E_POLICY_USERGEOM_HINT, EINA_FALSE);
2491                   continue;
2492                }
2493
2494              if (!strcmp(hint->val, "1"))
2495                {
2496                   e_policy_user_geometry_set(ec, E_POLICY_USERGEOM_HINT, EINA_TRUE);
2497                }
2498              else if (strcmp(hint->val, "1"))
2499                {
2500                   e_policy_user_geometry_set(ec, E_POLICY_USERGEOM_HINT, EINA_FALSE);
2501                }
2502           }
2503         else if (!strcmp(hint->hint, hint_names[E_POLICY_HINT_FIXED_RESIZE]))
2504           {
2505              /* TODO: support other aux_hints */
2506           }
2507         else if (!strcmp(hint->hint, hint_names[E_POLICY_HINT_DEICONIFY_UPDATE]))
2508           {
2509              if (!strcmp(hint->val, "1"))
2510                ec->exp_iconify.deiconify_update = EINA_TRUE;
2511              else
2512                ec->exp_iconify.deiconify_update = EINA_FALSE;
2513
2514           }
2515         else if (!strcmp(hint->hint, hint_names[E_POLICY_HINT_GESTURE_DISABLE]))
2516           {
2517              if (hint->deleted)
2518                {
2519                   ec->gesture_disable = EINA_FALSE;
2520                   continue;
2521                }
2522
2523              if (atoi(hint->val) == 1)
2524                {
2525                   ec->gesture_disable = EINA_TRUE;
2526                }
2527              else
2528                {
2529                   ec->gesture_disable = EINA_FALSE;
2530                }
2531           }
2532         else if (!strcmp(hint->hint, hint_names[E_POLICY_HINT_ICONIFY]))
2533           {
2534              if (hint->deleted)
2535                {
2536                   ec->exp_iconify.skip_iconify = 0;
2537                   EC_CHANGED(ec);
2538                   continue;
2539                }
2540
2541              if (!strcmp(hint->val, "disable"))
2542                {
2543                   ec->exp_iconify.skip_iconify = 1;
2544                   EC_CHANGED(ec);
2545                }
2546              else if (!strcmp(hint->val, "enable"))
2547                {
2548                   ec->exp_iconify.skip_iconify = 0;
2549                   EC_CHANGED(ec);
2550                }
2551           }
2552         else if (!strcmp(hint->hint, hint_names[E_POLICY_HINT_ABOVE_LOCKSCREEN]))
2553           {
2554              if ((hint->deleted) ||
2555                  (!strcmp(hint->val, "0")))
2556                {
2557                   E_Layer original_layer = ec->changable_layer[E_CHANGABLE_LAYER_TYPE_ABOVE_NOTIFICATION].saved_layer;
2558                   if (ec->changable_layer[E_CHANGABLE_LAYER_TYPE_ABOVE_NOTIFICATION].set &&
2559                       ec->changable_layer[E_CHANGABLE_LAYER_TYPE_ABOVE_NOTIFICATION].saved)
2560                     {
2561                        // restore original layer
2562                        if (original_layer != evas_object_layer_get(ec->frame))
2563                          {
2564                             Eina_Bool pend = EINA_FALSE;
2565                             pend = e_policy_visibility_client_layer_lower(ec, original_layer);
2566                             if (!pend)
2567                               {
2568                                  e_client_layer_set(ec, original_layer);
2569                               }
2570                          }
2571                     }
2572                   ec->changable_layer[E_CHANGABLE_LAYER_TYPE_ABOVE_NOTIFICATION].set = 0;
2573                   ec->changable_layer[E_CHANGABLE_LAYER_TYPE_ABOVE_NOTIFICATION].saved = 0;
2574                   ec->changable_layer[E_CHANGABLE_LAYER_TYPE_ABOVE_NOTIFICATION].saved_layer = 0;
2575                   EC_CHANGED(ec);
2576                }
2577              else if (!strcmp(hint->val, "1"))
2578                {
2579                   if (!ec->changable_layer[E_CHANGABLE_LAYER_TYPE_ABOVE_NOTIFICATION].saved)
2580                     {
2581                        ec->changable_layer[E_CHANGABLE_LAYER_TYPE_ABOVE_NOTIFICATION].set = 1;
2582                        ec->changable_layer[E_CHANGABLE_LAYER_TYPE_ABOVE_NOTIFICATION].saved = 0;
2583                        ec->changable_layer[E_CHANGABLE_LAYER_TYPE_ABOVE_NOTIFICATION].saved_layer = ec->layer;
2584                        EC_CHANGED(ec);
2585                     }
2586                }
2587           }
2588         else if (!strcmp(hint->hint, hint_names[E_POLICY_HINT_EFFECT_DISABLE]))
2589           {
2590              if ((hint->deleted) ||
2591                  (!strcmp(hint->val, "0")))
2592                {
2593                   e_policy_animatable_lock(ec, E_POLICY_ANIMATABLE_HINT, 0);
2594                }
2595              else if (!strcmp(hint->val, "1"))
2596                {
2597                   e_policy_animatable_lock(ec, E_POLICY_ANIMATABLE_HINT, 1);
2598                }
2599           }
2600         else if (!strcmp(hint->hint, hint_names[E_POLICY_HINT_MSG_USE]))
2601           {
2602              if ((hint->deleted) || (!strcmp(hint->val, "0")))
2603                cdata->aux_hint.use_msg = EINA_FALSE;
2604              else if (!strcmp(hint->val, "1"))
2605                cdata->aux_hint.use_msg = EINA_TRUE;
2606           }
2607         else if (!strcmp(hint->hint, hint_names[E_COMP_HINT_ALWAYS_SELECTIVE]))
2608           {
2609              if ((hint->deleted) || (!strcmp(hint->val, "0")))
2610                {
2611                   cdata->never_hwc = EINA_FALSE;
2612                   if (ec->hwc_window)
2613                     e_hwc_window_never_hwc_set(ec->hwc_window, EINA_FALSE);
2614                }
2615              else if (!strcmp(hint->val, "1"))
2616                {
2617                   cdata->never_hwc = EINA_TRUE;
2618                   if (ec->hwc_window)
2619                     e_hwc_window_never_hwc_set(ec->hwc_window, EINA_TRUE);
2620                }
2621
2622              e_comp_render_queue();
2623           }
2624         else if (!strcmp(hint->hint, hint_names[E_POLICY_HINT_DEPENDENT_ROTATION]))
2625           {
2626              if ((hint->deleted) || (!strcmp(hint->val, "0")))
2627                ec->e.state.rot.type = E_CLIENT_ROTATION_TYPE_NORMAL;
2628              else if (!strcmp(hint->val, "1"))
2629                ec->e.state.rot.type = E_CLIENT_ROTATION_TYPE_DEPENDENT;
2630           }
2631         else if (!strcmp(hint->hint, hint_names[E_POLICY_HINT_ROT_RENDER_NOPENDING]))
2632           {
2633              if ((hint->deleted) || (!strcmp(hint->val, "0")))
2634                {
2635                   ELOGF("ROTATION", "nopending render:0", ec);
2636                   ec->e.state.rot.nopending_render = 0;
2637                }
2638              else if (!strcmp(hint->val, "1"))
2639                {
2640                   ELOGF("ROTATION", "nopending render:1", ec);
2641                   ec->e.state.rot.nopending_render = 1;
2642                }
2643           }
2644         else if (!strncmp(hint->hint, hint_names[E_POLICY_HINT_ICONIFY_BUFFER_FLUSH], strlen(hint->hint)))
2645           {
2646              if (!strncmp(hint->val, "1", 1))
2647                ec->exp_iconify.buffer_flush = EINA_TRUE;
2648              else
2649                ec->exp_iconify.buffer_flush = EINA_FALSE;
2650           }
2651         else if (!strncmp(hint->hint, hint_names[E_POLICY_HINT_TRANSIENT_FOR_ALWAYS_ON_TOP], strlen(hint->hint)))
2652           {
2653              if (!strncmp(hint->val, "1", 1))
2654                {
2655                   ELOGF("TF_SET", "Transient for Always_on_top enabled", ec);
2656                   ec->transient_for_always_on_top = EINA_TRUE;
2657                }
2658              else
2659                {
2660                   ELOGF("TF_SET", "Transient for Always_on_top disabled", ec);
2661                   ec->transient_for_always_on_top = EINA_FALSE;
2662                }
2663           }
2664         else if (!strncmp(hint->hint, hint_names[E_POLICY_HINT_BELONG_TO_PARENT], strlen(hint->hint)))
2665           {
2666              if (!strncmp(hint->val, "1", 1))
2667                {
2668                   ELOGF("TF_SET", "Set belong_to_parent", ec);
2669                   e_client_belong_to_parent_set(ec, EINA_TRUE);
2670                }
2671              else
2672                {
2673                   ELOGF("TF_SET", "Unset belong_to_parent", ec);
2674                   e_client_belong_to_parent_set(ec, EINA_FALSE);
2675                }
2676           }
2677         else if (!strncmp(hint->hint, hint_names[E_POLICY_HINT_RESIZE_ASPECT_RATIO], strlen(hint->hint)))
2678           {
2679              if (!strncmp(hint->val, "1", 1))
2680                {
2681                   ELOGF("RESIZE", "Set resize aspect ratio.. ratio(%dx%d)", ec, ec->w, ec->h);
2682                   ec->manage_resize.enable_aspect_ratio = EINA_TRUE;
2683                   ec->manage_resize.aw = ec->w;
2684                   ec->manage_resize.ah = ec->h;
2685                }
2686              else
2687                {
2688                   ELOGF("RESIZE", "Unset resize aspect ratio", ec);
2689                   ec->manage_resize.enable_aspect_ratio = EINA_FALSE;
2690                }
2691           }
2692         else if (!strncmp(hint->hint, hint_names[E_POLICY_HINT_DECORATION_SIZE_HEADER], strlen(hint->hint)))
2693           {
2694              int height = atoi(hint->val);
2695              if (height > 0)
2696                {
2697                   ELOGF("CSD", "Set decoration HEADER size.. size(%d)", ec, height);
2698                   ec->manage_resize.header_h = height;
2699                }
2700              else
2701                {
2702                   ELOGF("CSD", "Unset decoration HEADER size", ec);
2703                   ec->manage_resize.header_h = 0;
2704                }
2705           }
2706         else if (!strncmp(hint->hint, hint_names[E_POLICY_HINT_DECORATION_SIZE_FOOTER], strlen(hint->hint)))
2707           {
2708              int height = atoi(hint->val);
2709              if (height > 0)
2710                {
2711                   ELOGF("CSD", "Set decoration FOOTER size.. size(%d)", ec, height);
2712                   ec->manage_resize.footer_h = height;
2713                }
2714              else
2715                {
2716                   ELOGF("CSD", "Unset decoration FOOTER size", ec);
2717                   ec->manage_resize.footer_h = 0;
2718                }
2719           }
2720         else if (!strncmp(hint->hint, hint_names[E_POLICY_HINT_VISIBILITY_IGNORE_GEOMETRY], strlen(hint->hint)))
2721           {
2722              if (!strncmp(hint->val, "1", 1))
2723                {
2724                   ELOGF("POL_VIS", "Set ignore_geometry.. value(%s)", ec, hint->val);
2725                   ec->visibility.ignore_geometry = EINA_TRUE;
2726                }
2727              else
2728                {
2729                   ELOGF("POL_VIS", "UNSet ignore_geometry.. value(%s)", ec, hint->val);
2730                   ec->visibility.ignore_geometry = EINA_FALSE;
2731                }
2732           }
2733         else if (!strncmp(hint->hint, hint_names[E_POLICY_HINT_RESIZE_PPU], strlen(hint->hint)))
2734           {
2735              int ppu = atoi(hint->val);
2736              if (ppu < 1) ppu = 1;
2737
2738              ELOGF("RESIZE", "Set resize unit. size:%d", ec, ppu);
2739              e_client_resize_unit_size_set(ec, ppu);
2740           }
2741         else if (!strncmp(hint->hint, hint_names[E_POLICY_HINT_DECORATION_SIZE_SHADOW_TOP], strlen(hint->hint)))
2742           {
2743              int size = atoi(hint->val);
2744              if (size > 0)
2745                {
2746                   ELOGF("CSD", "Set decoration SHADOW top.. size(%d)", ec, size);
2747                   ec->manage_resize.shadow.t = size;
2748                }
2749              else
2750                {
2751                   ELOGF("CSD", "Unset decoration SHADOW top", ec);
2752                   ec->manage_resize.shadow.t = 0;
2753                }
2754           }
2755         else if (!strncmp(hint->hint, hint_names[E_POLICY_HINT_DECORATION_SIZE_SHADOW_BOTTOM], strlen(hint->hint)))
2756           {
2757              int size = atoi(hint->val);
2758              if (size > 0)
2759                {
2760                   ELOGF("CSD", "Set decoration SHADOW bottom.. size(%d)", ec, size);
2761                   ec->manage_resize.shadow.b = size;
2762                }
2763              else
2764                {
2765                   ELOGF("CSD", "Unset decoration SHADOW bottom", ec);
2766                   ec->manage_resize.shadow.b = 0;
2767                }
2768           }
2769         else if (!strncmp(hint->hint, hint_names[E_POLICY_HINT_DECORATION_SIZE_SHADOW_LEFT], strlen(hint->hint)))
2770           {
2771              int size = atoi(hint->val);
2772              if (size > 0)
2773                {
2774                   ELOGF("CSD", "Set decoration SHADOW left.. size(%d)", ec, size);
2775                   ec->manage_resize.shadow.l = size;
2776                }
2777              else
2778                {
2779                   ELOGF("CSD", "Unset decoration SHADOW left", ec);
2780                   ec->manage_resize.shadow.l = 0;
2781                }
2782           }
2783         else if (!strncmp(hint->hint, hint_names[E_POLICY_HINT_DECORATION_SIZE_SHADOW_RIGHT], strlen(hint->hint)))
2784           {
2785              int size = atoi(hint->val);
2786              if (size > 0)
2787                {
2788                   ELOGF("CSD", "Set decoration SHADOW right.. size(%d)", ec, size);
2789                   ec->manage_resize.shadow.r = size;
2790                }
2791              else
2792                {
2793                   ELOGF("CSD", "Unset decoration SHADOW right", ec);
2794                   ec->manage_resize.shadow.r = 0;
2795                }
2796           }
2797      }
2798
2799    e_policy_hook_call(E_POLICY_HOOK_CLIENT_AUX_HINT_CHANGED, ec);
2800 }
2801
2802 static void
2803 _tzpol_iface_cb_aux_hint_add(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol, struct wl_resource *surf, int32_t id, const char *name, const char *value)
2804 {
2805    E_Client *ec;
2806    Eina_Bool res = EINA_FALSE;
2807
2808    ec = e_client_from_surface_resource(surf);
2809    EINA_SAFETY_ON_NULL_RETURN(ec);
2810
2811    res = e_hints_aux_hint_add(ec, id, name, value);
2812
2813    ELOGF("TZPOL", "HINT_ADD |res_tzpol:%8p|id:%d, name:%s, val:%s, res:%d", ec, res_tzpol, id, name, value, res);
2814
2815    if (res)
2816      {
2817         _e_policy_wl_aux_hint_apply(ec);
2818         _e_policy_wl_allowed_aux_hint_send(res_tzpol, surf, id);
2819      }
2820 }
2821
2822 static void
2823 _tzpol_iface_cb_aux_hint_change(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol, struct wl_resource *surf, int32_t id, const char *value)
2824 {
2825    E_Client *ec;
2826    Eina_Bool res = EINA_FALSE;
2827
2828    ec = e_client_from_surface_resource(surf);
2829    EINA_SAFETY_ON_NULL_RETURN(ec);
2830
2831    res = e_hints_aux_hint_change(ec, id, value);
2832
2833    ELOGF("TZPOL", "HINT_CHD |res_tzpol:%8p|id:%d, val:%s, result:%d", ec, res_tzpol, id, value, res);
2834
2835    if (res)
2836      {
2837         _e_policy_wl_aux_hint_apply(ec);
2838         _e_policy_wl_allowed_aux_hint_send(res_tzpol, surf, id);
2839      }
2840 }
2841
2842 static void
2843 _tzpol_iface_cb_aux_hint_del(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol, struct wl_resource *surf, int32_t id)
2844 {
2845    E_Client *ec;
2846    unsigned int res = -1;
2847
2848    ec = e_client_from_surface_resource(surf);
2849    EINA_SAFETY_ON_NULL_RETURN(ec);
2850
2851    res = e_hints_aux_hint_del(ec, id);
2852    ELOGF("TZPOL", "HINT_DEL |res_tzpol:%8p|id:%d, result:%d", ec, res_tzpol, id, res);
2853
2854    if (res)
2855      _e_policy_wl_aux_hint_apply(ec);
2856 }
2857
2858 static void
2859 _tzpol_iface_cb_supported_aux_hints_get(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol, struct wl_resource *surf)
2860 {
2861    E_Client *ec;
2862    const Eina_List *hints_list;
2863    const Eina_List *l;
2864    struct wl_array hints;
2865    const char *hint_name;
2866    int len;
2867    char *p;
2868
2869    ec = e_client_from_surface_resource(surf);
2870    EINA_SAFETY_ON_NULL_RETURN(ec);
2871
2872    hints_list = e_hints_aux_hint_supported_get();
2873
2874    wl_array_init(&hints);
2875    EINA_LIST_FOREACH(hints_list, l, hint_name)
2876      {
2877         len = strlen(hint_name) + 1;
2878         p = wl_array_add(&hints, len);
2879
2880         if (p == NULL)
2881           break;
2882         strncpy(p, hint_name, len);
2883      }
2884
2885    tizen_policy_send_supported_aux_hints(res_tzpol, surf, &hints, eina_list_count(hints_list));
2886    ELOGF("TZPOL",
2887          "SEND     |res_tzpol:%8p|supported_hints size:%d",
2888          ec,
2889          res_tzpol,
2890          eina_list_count(hints_list));
2891    wl_array_release(&hints);
2892 }
2893
2894 static void
2895 _e_policy_wl_background_state_apply(E_Client *ec, Eina_Bool state)
2896 {
2897    if (!ec) return;
2898
2899    ELOGF("TZPOL",
2900          "BACKGROUND STATE %s for PID(%u), iconic:%d",
2901          ec,
2902          state?"SET":"UNSET", ec->netwm.pid, ec->iconic);
2903
2904    if (state)
2905      {
2906         ec->bg_state = EINA_TRUE;
2907         evas_object_hide(ec->frame);
2908         e_pixmap_image_clear(ec->pixmap, 1);
2909      }
2910    else
2911      {
2912         ec->bg_state = EINA_FALSE;
2913         if (!ec->iconic)
2914           {
2915              E_Comp_Wl_Client_Data *cdata;
2916              cdata = e_client_cdata_get(ec);
2917              if (cdata && cdata->mapped)
2918                {
2919                   evas_object_show(ec->frame);
2920                   e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
2921                }
2922           }
2923      }
2924
2925    EC_CHANGED(ec);
2926    e_comp_visibility_calculation_set(EINA_TRUE);
2927 }
2928
2929 static void
2930 _e_policy_wl_background_state_set(E_Policy_Wl_Surface *psurf, Eina_Bool state)
2931 {
2932    psurf->is_background = state;
2933    ELOGF("TZPOL", "Set psurf(%p)'s background_state to %d", NULL, psurf, state);
2934
2935    if (state)
2936      {
2937         if (psurf->ec)
2938           _e_policy_wl_background_state_apply(psurf->ec, EINA_TRUE);
2939      }
2940    else
2941      {
2942         if (psurf->ec)
2943           _e_policy_wl_background_state_apply(psurf->ec, EINA_FALSE);
2944      }
2945 }
2946
2947 static void
2948 _e_policy_wl_tzlaunch_effect_type_sync(E_Client *ec)
2949 {
2950    Eina_List *l;
2951    E_Policy_Wl_Tzlaunch_Effect_Info *effect_info;
2952
2953    EINA_SAFETY_ON_NULL_RETURN(ec);
2954
2955    EINA_LIST_FOREACH(polwl->tzlaunch_effect_info, l, effect_info)
2956      {
2957         if (effect_info->pid == ec->netwm.pid)
2958           {
2959              ELOGF("TZPOL",
2960                    "Launchscreen effect type sync | pid (%d) effect_type (%d)",
2961                    ec, ec->netwm.pid, effect_info->effect_type);
2962              ec->effect_type = effect_info->effect_type;
2963              _e_policy_wl_tzlaunch_effect_type_unset(ec->netwm.pid);
2964              break;
2965           }
2966      }
2967 }
2968
2969 static int
2970 _e_policy_wl_tzlaunch_effect_type_get(const char * effect_type)
2971 {
2972    Tzlaunch_Effect_Type type = TZLAUNCH_EFFECT_TYPE_LAUNCH;
2973
2974    if      (!e_util_strcmp(effect_type, "launch"    )) type = TZLAUNCH_EFFECT_TYPE_LAUNCH;
2975    else if (!e_util_strcmp(effect_type, "depth-in" )) type = TZLAUNCH_EFFECT_TYPE_DEPTH_IN;
2976
2977    return type;
2978 }
2979
2980 static void
2981 _e_policy_wl_tzlaunch_effect_type_unset(uint32_t pid)
2982 {
2983    Eina_List *l;
2984    E_Policy_Wl_Tzlaunch_Effect_Info *effect_info;
2985
2986    EINA_LIST_FOREACH(polwl->tzlaunch_effect_info, l, effect_info)
2987      {
2988         if (effect_info->pid == pid)
2989           {
2990              ELOGF("TZPOL",
2991                    "Launchscreen effect type unset | pid (%d)",
2992                    NULL, pid);
2993              polwl->tzlaunch_effect_info = eina_list_remove(polwl->tzlaunch_effect_info, effect_info);
2994              memset(effect_info, 0x0, sizeof(E_Policy_Wl_Tzlaunch_Effect_Info));
2995              E_FREE(effect_info);
2996              break;
2997           }
2998      }
2999 }
3000
3001 static void
3002 _e_policy_wl_tzpol_background_state_set(E_Policy_Wl_Tzpol *tzpol, Eina_Bool bg_state, pid_t pid)
3003 {
3004    Eina_List *l;
3005    E_Policy_Wl_Surface *psurf;
3006
3007    if (!tzpol) return;
3008
3009    tzpol->bg_state = bg_state;
3010    ELOGF("TZPOL", "Set tzpol(%p)'s background_state to %d", NULL, tzpol, bg_state);
3011
3012    EINA_LIST_FOREACH(tzpol->psurfs, l, psurf)
3013      {
3014         if (psurf->pid == pid)
3015           {
3016              if (psurf->is_background == bg_state)
3017                continue;
3018
3019              _e_policy_wl_background_state_set(psurf, bg_state);
3020           }
3021      }
3022 }
3023
3024 static void
3025 _e_policy_wl_tzpols_background_state_set(Eina_Bool bg_state, pid_t pid)
3026 {
3027    E_Policy_Wl_Tzpol *tzpol;
3028    Eina_Iterator *it;
3029
3030    it = eina_hash_iterator_data_new(polwl->tzpols);
3031    EINA_ITERATOR_FOREACH(it, tzpol)
3032      {
3033         if (tzpol->pid == pid)
3034           {
3035              _e_policy_wl_tzpol_background_state_set(tzpol, bg_state, pid);
3036           }
3037      }
3038    eina_iterator_free(it);
3039 }
3040
3041 static void
3042 _tzpol_iface_cb_background_state_set(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol, uint32_t pid)
3043 {
3044    E_Policy_Wl_Tzpol *tzpol;
3045
3046    tzpol = _e_policy_wl_tzpol_get(res_tzpol);
3047    EINA_SAFETY_ON_NULL_RETURN(tzpol);
3048
3049    ELOGF("TZPOL", "Register PID(%u) for BACKGROUND STATE res_tzpol:%p tzpol:%p", NULL, pid, res_tzpol, tzpol);
3050
3051    _e_policy_wl_tzpols_background_state_set(EINA_TRUE, pid);
3052 }
3053
3054 static void
3055 _tzpol_iface_cb_background_state_unset(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol, uint32_t pid)
3056 {
3057    E_Policy_Wl_Tzpol *tzpol;
3058
3059    tzpol = _e_policy_wl_tzpol_get(res_tzpol);
3060    EINA_SAFETY_ON_NULL_RETURN(tzpol);
3061
3062    ELOGF("TZPOL", "Unregister PID(%u) for BACKGROUND STATE res_tzpol:%p tzpol:%p", NULL, pid, res_tzpol, tzpol);
3063
3064    _e_policy_wl_tzpols_background_state_set(EINA_FALSE, pid);
3065 }
3066
3067 static void
3068 _e_policy_wl_floating_mode_apply(E_Client *ec, Eina_Bool floating)
3069 {
3070    if (ec->floating == floating) return;
3071
3072    ec->floating = floating;
3073    ec->lock_client_location = EINA_FALSE;
3074
3075    if (ec->frame)
3076      {
3077         if (floating)
3078           {
3079              ec->floating_saved_layer = ec->layer;
3080              e_client_layer_set(ec, E_LAYER_CLIENT_ABOVE);
3081           }
3082         else
3083           {
3084              e_client_layer_set(ec, ec->floating_saved_layer);
3085           }
3086      }
3087
3088    EC_CHANGED(ec);
3089 }
3090
3091 static void
3092 _tzpol_iface_cb_floating_mode_set(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol, struct wl_resource *surf)
3093 {
3094    E_Client *ec;
3095
3096    ec = e_client_from_surface_resource(surf);
3097    EINA_SAFETY_ON_NULL_RETURN(ec);
3098
3099    ELOGF("TZPOL", "FLOATING Set", ec);
3100
3101    _e_policy_wl_floating_mode_apply(ec, EINA_TRUE);
3102 }
3103
3104 static void
3105 _tzpol_iface_cb_floating_mode_unset(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol, struct wl_resource *surf)
3106 {
3107    E_Client *ec;
3108
3109    ec = e_client_from_surface_resource(surf);
3110    EINA_SAFETY_ON_NULL_RETURN(ec);
3111
3112    ELOGF("TZPOL", "FLOATING Unset", ec);
3113
3114    e_client_pending_geometry_flush(ec);
3115
3116    _e_policy_wl_floating_mode_apply(ec, EINA_FALSE);
3117 }
3118
3119 static void
3120 _tzpol_iface_cb_stack_mode_set(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol, struct wl_resource *surf, uint32_t mode)
3121 {
3122    E_Client *ec;
3123
3124    ec = e_client_from_surface_resource(surf);
3125    EINA_SAFETY_ON_NULL_RETURN(ec);
3126
3127    ELOGF("TZPOL", "STACK Mode Set. mode:%d", ec, mode);
3128
3129    if (ec->frame)
3130      {
3131         if (mode == TIZEN_POLICY_STACK_MODE_ABOVE)
3132           {
3133              e_client_layer_set(ec, E_LAYER_CLIENT_ABOVE);
3134           }
3135         else if (mode == TIZEN_POLICY_STACK_MODE_BELOW)
3136           {
3137              e_client_layer_set(ec, E_LAYER_CLIENT_BELOW);
3138           }
3139         else
3140           {
3141              e_client_layer_set(ec, E_LAYER_CLIENT_NORMAL);
3142           }
3143         EC_CHANGED(ec);
3144
3145         e_policy_hook_call(E_POLICY_HOOK_CLIENT_STACK_MODE_SET, ec);
3146      }
3147 }
3148
3149 // --------------------------------------------------------
3150 // E_Policy_Wl_Tz_Dpy_Pol
3151 // --------------------------------------------------------
3152 static E_Policy_Wl_Tz_Dpy_Pol *
3153 _e_policy_wl_tz_dpy_pol_add(struct wl_resource *res_tz_dpy_pol)
3154 {
3155    E_Policy_Wl_Tz_Dpy_Pol *tz_dpy_pol;
3156
3157    tz_dpy_pol = E_NEW(E_Policy_Wl_Tz_Dpy_Pol, 1);
3158    EINA_SAFETY_ON_NULL_RETURN_VAL(tz_dpy_pol, NULL);
3159
3160    tz_dpy_pol->res_tz_dpy_pol = res_tz_dpy_pol;
3161
3162    polwl->tz_dpy_pols = eina_list_append(polwl->tz_dpy_pols, tz_dpy_pol);
3163
3164    return tz_dpy_pol;
3165 }
3166
3167 static void
3168 _e_policy_wl_tz_dpy_pol_del(E_Policy_Wl_Tz_Dpy_Pol *tz_dpy_pol)
3169 {
3170    E_Policy_Wl_Dpy_Surface *dpy_surf;
3171
3172    EINA_SAFETY_ON_NULL_RETURN(tz_dpy_pol);
3173
3174    polwl->tz_dpy_pols = eina_list_remove(polwl->tz_dpy_pols, tz_dpy_pol);
3175
3176    EINA_LIST_FREE(tz_dpy_pol->dpy_surfs, dpy_surf)
3177      {
3178         E_FREE(dpy_surf);
3179      }
3180
3181    E_FREE(tz_dpy_pol);
3182 }
3183
3184 static E_Policy_Wl_Tz_Dpy_Pol *
3185 _e_policy_wl_tz_dpy_pol_get(struct wl_resource *res_tz_dpy_pol)
3186 {
3187    Eina_List *l;
3188    E_Policy_Wl_Tz_Dpy_Pol *tz_dpy_pol;
3189
3190    EINA_LIST_FOREACH(polwl->tz_dpy_pols, l, tz_dpy_pol)
3191      {
3192         if (tz_dpy_pol->res_tz_dpy_pol == res_tz_dpy_pol)
3193           return tz_dpy_pol;
3194      }
3195
3196    return NULL;
3197 }
3198
3199 // --------------------------------------------------------
3200 // E_Policy_Wl_Dpy_Surface
3201 // --------------------------------------------------------
3202 static E_Policy_Wl_Dpy_Surface *
3203 _e_policy_wl_dpy_surf_find(E_Policy_Wl_Tz_Dpy_Pol *tz_dpy_pol, E_Client *ec)
3204 {
3205    Eina_List *l;
3206    E_Policy_Wl_Dpy_Surface *dpy_surf;
3207
3208    EINA_LIST_FOREACH(tz_dpy_pol->dpy_surfs, l, dpy_surf)
3209      {
3210         if (dpy_surf->ec == ec)
3211           return dpy_surf;
3212      }
3213
3214    return NULL;
3215 }
3216
3217 static E_Policy_Wl_Dpy_Surface *
3218 _e_policy_wl_dpy_surf_add(E_Client *ec, struct wl_resource *res_tz_dpy_pol)
3219 {
3220    E_Policy_Wl_Tz_Dpy_Pol  *tz_dpy_pol = NULL;
3221    E_Policy_Wl_Dpy_Surface *dpy_surf   = NULL;
3222    E_Comp_Wl_Client_Data *cdata;
3223
3224    tz_dpy_pol = _e_policy_wl_tz_dpy_pol_get(res_tz_dpy_pol);
3225    EINA_SAFETY_ON_NULL_RETURN_VAL(tz_dpy_pol, NULL);
3226
3227    dpy_surf = _e_policy_wl_dpy_surf_find(tz_dpy_pol, ec);
3228    if (dpy_surf)
3229      return dpy_surf;
3230
3231    dpy_surf = E_NEW(E_Policy_Wl_Dpy_Surface, 1);
3232    EINA_SAFETY_ON_NULL_RETURN_VAL(dpy_surf, NULL);
3233
3234    cdata = e_client_cdata_get(ec);
3235    dpy_surf->surf = cdata->surface;
3236    dpy_surf->tz_dpy_pol = tz_dpy_pol;
3237    dpy_surf->ec = ec;
3238    dpy_surf->brightness = -1;
3239
3240    tz_dpy_pol->dpy_surfs = eina_list_append(tz_dpy_pol->dpy_surfs, dpy_surf);
3241    return dpy_surf;
3242 }
3243
3244 static void
3245 _e_policy_wl_dpy_surf_del(E_Client *ec)
3246 {
3247    Eina_List *l;
3248    E_Policy_Wl_Tz_Dpy_Pol *tz_dpy_pol;
3249    E_Policy_Wl_Dpy_Surface *dpy_surf;
3250
3251    EINA_SAFETY_ON_NULL_RETURN(ec);
3252
3253    EINA_LIST_FOREACH(polwl->tz_dpy_pols, l, tz_dpy_pol)
3254      {
3255         dpy_surf = _e_policy_wl_dpy_surf_find(tz_dpy_pol, ec);
3256         if (dpy_surf)
3257           {
3258              tz_dpy_pol->dpy_surfs = eina_list_remove(tz_dpy_pol->dpy_surfs, dpy_surf);
3259              E_FREE(dpy_surf);
3260           }
3261      }
3262 }
3263
3264 // --------------------------------------------------------
3265 // brightness
3266 // --------------------------------------------------------
3267 static Eina_Bool
3268 _e_policy_system_brightness_get(int *brightness)
3269 {
3270    int error;
3271    int sys_brightness = -1;
3272
3273    if (!brightness) return EINA_FALSE;
3274
3275    error = device_display_get_brightness(0, &sys_brightness);
3276    if (error != DEVICE_ERROR_NONE)
3277      {
3278         // error
3279         return EINA_FALSE;
3280      }
3281
3282    *brightness = sys_brightness;
3283
3284    return EINA_TRUE;
3285 }
3286
3287 static Eina_Bool
3288 _e_policy_system_brightness_set(int brightness)
3289 {
3290    Eina_Bool ret;
3291    int error;
3292    int num_of_dpy;
3293    int id;
3294
3295    ret = EINA_TRUE;
3296
3297    error = device_display_get_numbers(&num_of_dpy);
3298    if (error != DEVICE_ERROR_NONE)
3299      {
3300         // error
3301         return EINA_FALSE;
3302      }
3303
3304    for (id = 0; id < num_of_dpy; id++)
3305      {
3306         error = device_display_set_brightness(id, brightness);
3307         if (error != DEVICE_ERROR_NONE)
3308           {
3309              // error
3310              ret = EINA_FALSE;
3311              break;
3312           }
3313      }
3314
3315    return ret;
3316 }
3317
3318 static Eina_Bool
3319 _e_policy_change_system_brightness(int new_brightness)
3320 {
3321    Eina_Bool ret;
3322    int sys_brightness;
3323
3324    if (!e_policy_system_info.brightness.use_client)
3325      {
3326         // save system brightness
3327         ret = _e_policy_system_brightness_get(&sys_brightness);
3328         if (!ret)
3329           {
3330              return EINA_FALSE;
3331           }
3332         e_policy_system_info.brightness.system = sys_brightness;
3333      }
3334
3335    ret = _e_policy_system_brightness_set(new_brightness);
3336    if (!ret)
3337      {
3338         return EINA_FALSE;
3339      }
3340    e_policy_system_info.brightness.client = new_brightness;
3341    e_policy_system_info.brightness.use_client = EINA_TRUE;
3342
3343    return EINA_TRUE;
3344 }
3345
3346 static Eina_Bool
3347 _e_policy_restore_system_brightness(void)
3348 {
3349    Eina_Bool ret;
3350
3351    if (!e_policy_system_info.brightness.use_client) return EINA_TRUE;
3352
3353    // restore system brightness
3354    ret = _e_policy_system_brightness_set(e_policy_system_info.brightness.system);
3355    if (!ret)
3356      {
3357         return EINA_FALSE;
3358      }
3359    e_policy_system_info.brightness.use_client = EINA_FALSE;
3360
3361    // Todo:
3362    // if there are another window which set brighteness, then we change brighteness of it
3363    // if no, then we rollback system brightness
3364
3365    return EINA_TRUE;
3366 }
3367
3368 EINTERN Eina_Bool
3369 e_policy_wl_win_brightness_apply(E_Client *ec)
3370 {
3371    Eina_Bool ret;
3372    Eina_List *l;
3373    E_Policy_Wl_Tz_Dpy_Pol *tz_dpy_pol;
3374    E_Policy_Wl_Dpy_Surface *dpy_surf = NULL;
3375    int ec_visibility;
3376
3377    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
3378    if (e_object_is_del(E_OBJECT(ec)))
3379      ec_visibility = E_VISIBILITY_FULLY_OBSCURED;
3380    else
3381      ec_visibility = e_client_visibility_get(ec);
3382
3383    EINA_LIST_FOREACH(polwl->tz_dpy_pols, l, tz_dpy_pol)
3384      {
3385         dpy_surf = _e_policy_wl_dpy_surf_find(tz_dpy_pol, ec);
3386         if (dpy_surf)
3387           break;
3388      }
3389
3390    if (!dpy_surf) return EINA_FALSE;
3391    if (!dpy_surf->set) return EINA_FALSE;
3392
3393    // use system brightness
3394    if (dpy_surf->brightness < 0)
3395      {
3396         ELOGF("TZ_DPY_POL", "Restore system brightness. Win(0x%08zx)'s brightness:%d", ec, e_client_util_win_get(ec), dpy_surf->brightness);
3397         ret = _e_policy_restore_system_brightness();
3398         return ret;
3399      }
3400
3401    if (ec_visibility == E_VISIBILITY_UNOBSCURED)
3402      {
3403         ELOGF("TZ_DPY_POL", "Change system brightness(%d). Win(0x%08zx) is un-obscured", ec, dpy_surf->brightness, e_client_util_win_get(ec));
3404         ret = _e_policy_change_system_brightness(dpy_surf->brightness);
3405         if (!ret) return EINA_FALSE;
3406      }
3407    else
3408      {
3409         ELOGF("TZ_DPY_POL", "Restore system brightness. Win(0x%08zx) is obscured", ec, e_client_util_win_get(ec));
3410         ret = _e_policy_restore_system_brightness();
3411         if (!ret) return EINA_FALSE;
3412      }
3413
3414    return EINA_TRUE;
3415 }
3416
3417 static void
3418 _tz_dpy_pol_iface_cb_brightness_set(struct wl_client *client, struct wl_resource *res_tz_dpy_pol, struct wl_resource *surf, int32_t brightness)
3419 {
3420    E_Client *ec;
3421    E_Policy_Wl_Dpy_Surface *dpy_surf;
3422    pid_t pid = 0;
3423    uid_t uid = 0;
3424    Eina_Bool res;
3425
3426    ec = e_client_from_surface_resource(surf);
3427    EINA_SAFETY_ON_NULL_RETURN(ec);
3428
3429    dpy_surf = _e_policy_wl_dpy_surf_add(ec, res_tz_dpy_pol);
3430    EINA_SAFETY_ON_NULL_RETURN(dpy_surf);
3431
3432    wl_client_get_credentials(client, &pid, &uid, NULL);
3433    res = e_security_privilege_check(pid, uid,
3434                                     E_PRIVILEGE_BRIGHTNESS_SET);
3435    if (!res)
3436      {
3437         ELOGF("TZ_DPY_POL",
3438               "Privilege Check Failed! DENY set_brightness",
3439               ec);
3440
3441         tizen_display_policy_send_window_brightness_done
3442            (res_tz_dpy_pol,
3443             surf,
3444             -1,
3445             TIZEN_DISPLAY_POLICY_ERROR_STATE_PERMISSION_DENIED);
3446         return;
3447      }
3448    ELOGF("TZ_DPY_POL", "Set Win(0x%08zx)'s brightness:%d", ec, e_client_util_win_get(ec), brightness);
3449    dpy_surf->set = EINA_TRUE;
3450    dpy_surf->brightness = brightness;
3451
3452    e_policy_wl_win_brightness_apply(ec);
3453
3454    tizen_display_policy_send_window_brightness_done
3455       (res_tz_dpy_pol, surf, brightness, TIZEN_DISPLAY_POLICY_ERROR_STATE_NONE);
3456 }
3457
3458 static void
3459 _tz_dpy_pol_iface_cb_destroy(struct wl_client *client, struct wl_resource *resource)
3460 {
3461    wl_resource_destroy(resource);
3462 }
3463
3464 static void
3465 _tzpol_iface_cb_subsurf_watcher_get(struct wl_client *client, struct wl_resource *res_tzpol, uint32_t id, struct wl_resource *surface)
3466 {
3467    E_Client *ec;
3468
3469    if (!(ec = e_client_from_surface_resource(surface))) return;
3470    if (e_object_is_del(E_OBJECT(ec))) return;
3471
3472    e_subsurface_watcher_add(client, id, surface);
3473 }
3474
3475 static void
3476 _tzpol_iface_cb_parent_set(struct wl_client *client, struct wl_resource *res_tzpol, struct wl_resource *child, struct wl_resource *parent)
3477 {
3478    E_Client *ec, *parent_ec;
3479
3480    ELOGF("TZPOL",
3481          "PARENT_SET   |res_tzpol:%8p|parent_surf:%8p|child_surf:%8p",
3482          NULL, res_tzpol, parent, child);
3483
3484    ec = e_client_from_surface_resource(child);
3485    EINA_SAFETY_ON_NULL_RETURN(ec);
3486
3487    parent_ec = e_client_from_surface_resource(parent);
3488    e_policy_stack_parent_set(ec, parent_ec);
3489 }
3490
3491 static void
3492 _tzpol_iface_cb_ack_conformant_region(struct wl_client *client, struct wl_resource *res_tzpol, struct wl_resource *surface, uint32_t serial)
3493 {
3494    E_Client *ec;
3495
3496    if (!(ec = e_client_from_surface_resource(surface))) return;
3497
3498    e_policy_conformant_client_ack(ec, res_tzpol, serial);
3499 }
3500
3501 static void
3502 _tzpol_iface_cb_destroy(struct wl_client *client, struct wl_resource *res_tzpol)
3503 {
3504    wl_resource_destroy(res_tzpol);
3505 }
3506
3507 static void
3508 _tzpol_iface_cb_has_video(struct wl_client *client, struct wl_resource *res_tzpol, struct wl_resource *surface, uint32_t has)
3509 {
3510    E_Client *ec;
3511    E_Comp_Wl_Client_Data *cdata;
3512
3513    if (!(ec = e_client_from_surface_resource(surface))) return;
3514    if (e_object_is_del(E_OBJECT(ec))) return;
3515    cdata = e_client_cdata_get(ec);
3516    if (!cdata) return;
3517    if (cdata->has_video_client == has) return;
3518
3519    ELOGF("TZPOL", "video client has(%d)", ec, has);
3520
3521    cdata->has_video_client = has;
3522 }
3523
3524 static void
3525 _tzpol_iface_cb_set_appid(struct wl_client *client, struct wl_resource *res_tzpol, int32_t pid, const char *appid)
3526 {
3527    E_Policy_Wl_Tzpol *tzpol;
3528    E_Appinfo *eai;
3529
3530    tzpol = _e_policy_wl_tzpol_get(res_tzpol);
3531    EINA_SAFETY_ON_NULL_RETURN(tzpol);
3532
3533    ELOGF("TZPOL", "Set appid(%s) pid(%d)", NULL, appid, pid);
3534
3535    if (!(eai = e_appinfo_find_with_appid(appid)))
3536      {
3537         eai = e_appinfo_new();
3538         e_appinfo_appid_set(eai, appid);
3539         e_appinfo_owner_set(eai, E_APPINFO_OWNER_CLIENT);
3540      }
3541    EINA_SAFETY_ON_NULL_RETURN(eai);
3542
3543    e_appinfo_pid_set(eai, pid);
3544 }
3545
3546 static void
3547 _tzpol_iface_cb_show(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol EINA_UNUSED, struct wl_resource *surf)
3548 {
3549    E_Client *ec;
3550    E_Comp_Wl_Client_Data *cdata;
3551
3552    ec = e_client_from_surface_resource(surf);
3553    EINA_SAFETY_ON_NULL_RETURN(ec);
3554    EINA_SAFETY_ON_NULL_RETURN(ec->frame);
3555
3556    ELOGF("TZPOL", "Prepare SHOW (wait for buffer attach)", ec);
3557    e_client_hide_by_request_set(ec, EINA_FALSE);
3558
3559    cdata = e_client_cdata_get(ec);
3560    if (cdata && !cdata->mapped)
3561      {
3562         if (e_config->raise_before_show)
3563           {
3564              e_client_raise(ec);
3565              ec->post_raise = EINA_FALSE;
3566           }
3567      }
3568 }
3569
3570 static void
3571 _tzpol_iface_cb_hide(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol EINA_UNUSED, struct wl_resource *surf)
3572 {
3573    E_Client *ec;
3574
3575    ec = e_client_from_surface_resource(surf);
3576    EINA_SAFETY_ON_NULL_RETURN(ec);
3577    EINA_SAFETY_ON_NULL_RETURN(ec->frame);
3578
3579    ELOGF("TZPOL", "Prepare HIDE (wait for NULL buffer attach)", ec);
3580    e_client_hide_by_request_set(ec, EINA_TRUE);
3581 }
3582
3583 static void
3584 _tzpol_iface_cb_set_transient_for_below(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol, uint32_t child_id, uint32_t parent_id)
3585 {
3586    E_Client *ec, *parent_ec;
3587    E_Comp_Wl_Client_Data *cdata, *p_cdata;
3588
3589    ELOGF("TZPOL",
3590          "TF_SET(B) |res_tzpol:%8p|parent_id:%8d  |child_id:%8d",
3591          NULL, res_tzpol, parent_id, child_id);
3592
3593    ec = e_pixmap_find_client_by_res_id(child_id);
3594    EINA_SAFETY_ON_NULL_RETURN(ec);
3595    parent_ec = e_pixmap_find_client_by_res_id(parent_id);
3596
3597    cdata = e_client_cdata_get(ec);
3598    p_cdata = e_client_cdata_get(parent_ec);
3599    ELOGF("TZPOL",
3600          "          |res_tzpol:%8p|parent_surf:%8p|child_surf:%8p",
3601          NULL, res_tzpol, (p_cdata ? p_cdata->surface : NULL), (cdata ? cdata->surface : NULL));
3602
3603    e_policy_stack_transient_for_below_set(ec, parent_ec, EINA_TRUE);
3604 }
3605
3606 static void
3607 _tzpol_iface_cb_set_parent_with_below(struct wl_client *client, struct wl_resource *res_tzpol, struct wl_resource *child, struct wl_resource *parent)
3608 {
3609    E_Client *ec, *parent_ec;
3610
3611    ELOGF("TZPOL",
3612          "PARENT_SET(B)|res_tzpol:%8p|parent_surf:%8p|child_surf:%8p",
3613          NULL, res_tzpol, parent, child);
3614
3615    ec = e_client_from_surface_resource(child);
3616    EINA_SAFETY_ON_NULL_RETURN(ec);
3617
3618    if (parent)
3619      parent_ec = e_client_from_surface_resource(parent);
3620    else
3621      parent_ec = NULL;
3622
3623    e_policy_stack_transient_for_below_set(ec, parent_ec, EINA_FALSE);
3624 }
3625
3626 static void
3627 _tzpol_iface_cb_set_maximize_direction(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol EINA_UNUSED, struct wl_resource *surf, uint32_t direction)
3628 {
3629    E_Client *ec;
3630
3631    ec = e_client_from_surface_resource(surf);
3632    EINA_SAFETY_ON_NULL_RETURN(ec);
3633    EINA_SAFETY_ON_NULL_RETURN(ec->frame);
3634
3635    ELOGF("TZPOL", "Set Maximize_direction. direction:%d", ec, direction);
3636
3637    if (direction == TIZEN_POLICY_MAXIMIZE_DIRECTION_NONE)
3638      {
3639         ec->maximize_dir = E_MAXIMIZE_DIRECTION_NONE;
3640         e_client_unmaximize(ec, E_MAXIMIZE_BOTH);
3641         return;
3642      }
3643
3644    if (direction == TIZEN_POLICY_MAXIMIZE_DIRECTION_ALL)
3645      {
3646         ec->maximize_dir = E_MAXIMIZE_DIRECTION_ALL;
3647      }
3648    else if (direction == TIZEN_POLICY_MAXIMIZE_DIRECTION_LEFT)
3649      {
3650         ec->maximize_dir = E_MAXIMIZE_DIRECTION_LEFT;
3651      }
3652    else if (direction == TIZEN_POLICY_MAXIMIZE_DIRECTION_RIGHT)
3653      {
3654         ec->maximize_dir = E_MAXIMIZE_DIRECTION_RIGHT;
3655      }
3656    else
3657      {
3658         ELOGF("TZPOL", "Not supported direction:%d", ec, direction);
3659         return;
3660      }
3661
3662    e_client_maximize(ec, ec->maximize_type | ec->maximize_dir);
3663 }
3664
3665 static void
3666 _e_policy_set_pin_mode(E_Client *ec, Eina_Bool pinned)
3667 {
3668    EINA_SAFETY_ON_NULL_RETURN(ec);
3669    EINA_SAFETY_ON_NULL_RETURN(ec->frame);
3670
3671    ELOGF("TZPOL", "Set Pin mode to %d", ec, pinned);
3672    e_client_pinned_set(ec, pinned);
3673 }
3674
3675 static void
3676 _tzpol_iface_cb_set_pin_mode(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol EINA_UNUSED, struct wl_resource *surf)
3677 {
3678    E_Client *ec;
3679
3680    ec = e_client_from_surface_resource(surf);
3681    _e_policy_set_pin_mode(ec, EINA_TRUE);
3682 }
3683
3684 static void
3685 _tzpol_iface_cb_unset_pin_mode(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol EINA_UNUSED, struct wl_resource *surf)
3686 {
3687    E_Client *ec;
3688
3689    ec = e_client_from_surface_resource(surf);
3690    _e_policy_set_pin_mode(ec, EINA_FALSE);
3691 }
3692
3693 static void
3694 _tzpol_iface_cb_set_layout(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol EINA_UNUSED, struct wl_resource *surf, uint32_t num_cols, uint32_t num_rows, uint32_t column, uint32_t row, uint32_t col_span, uint32_t row_span)
3695 {
3696    E_Client *ec;
3697    E_Desk *desk;
3698
3699    int unit_w, unit_h;
3700    int x, y, w, h;
3701    ec = e_client_from_surface_resource(surf);
3702    if (!ec) return;
3703
3704    desk = e_comp_desk_find_by_ec(ec);
3705    EINA_SAFETY_ON_NULL_RETURN(desk);
3706
3707    unit_w = desk->geom.w / num_cols;
3708    unit_h = desk->geom.h / num_rows;
3709
3710    x = unit_w * column;
3711    y = unit_h * row;
3712    w = unit_w * col_span;
3713    h = unit_h * row_span;
3714
3715    // TODO: We may need to adjust the last size if the unit size is not devided exactly
3716
3717    ELOGF("TZPOL", "TIZEN_POLICY_SET_LAYOUT... total_layout(%d,%d) -> unit_size(%dx%d). request(%d,%d,%d,%d) -> geo(%d,%d,%dx%d)",
3718          ec, num_cols, num_rows, unit_w, unit_h, column, row, col_span, row_span, x, y, w, h);
3719
3720    // Apply shadow size (left, right, top, bottom)
3721    x -= ec->manage_resize.shadow.l;
3722    y -= ec->manage_resize.shadow.t;
3723    w = w + ec->manage_resize.shadow.l + ec->manage_resize.shadow.r;
3724    h = h + ec->manage_resize.shadow.t + ec->manage_resize.shadow.b;
3725
3726    ELOGF("TZPOL", "Consider Shadow size(l:%d,r:%d,t:%d,b:%d). new (%d,%d,%dx%d)",
3727          ec, ec->manage_resize.shadow.l, ec->manage_resize.shadow.r, ec->manage_resize.shadow.t, ec->manage_resize.shadow.b, x, y, w, h);
3728
3729    e_client_layout_apply(ec, EINA_TRUE);
3730    e_client_frame_geometry_set(ec, x, y, w, h);
3731
3732    if (!ec->visible)
3733      e_client_shell_configure_send(ec, 0, w, h);
3734 }
3735
3736 static void
3737 _e_policy_set_modal(E_Client *ec, Eina_Bool modal)
3738 {
3739    EINA_SAFETY_ON_NULL_RETURN(ec);
3740    EINA_SAFETY_ON_NULL_RETURN(ec->frame);
3741
3742    ELOGF("TZPOL", "Set modal to %d", ec, modal);
3743    e_client_modal_state_set(ec, modal);
3744 }
3745
3746 static void
3747 _tzpol_iface_cb_set_modal(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol EINA_UNUSED, struct wl_resource *surf)
3748 {
3749    E_Client *ec;
3750
3751    ec = e_client_from_surface_resource(surf);
3752    _e_policy_set_modal(ec, EINA_TRUE);
3753 }
3754
3755 static void
3756 _tzpol_iface_cb_unset_modal(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol EINA_UNUSED, struct wl_resource *surf)
3757 {
3758    E_Client *ec;
3759
3760    ec = e_client_from_surface_resource(surf);
3761    _e_policy_set_modal(ec, EINA_FALSE);
3762 }
3763
3764 // --------------------------------------------------------
3765 // tizen_policy_interface
3766 // --------------------------------------------------------
3767 static const struct tizen_policy_interface _tzpol_iface =
3768 {
3769    _tzpol_iface_cb_vis_get,
3770    _tzpol_iface_cb_pos_get,
3771    _tzpol_iface_cb_activate,
3772    _tzpol_iface_cb_activate_below_by_res_id,
3773    _tzpol_iface_cb_raise,
3774    _tzpol_iface_cb_lower,
3775    _tzpol_iface_cb_lower_by_res_id,
3776    _tzpol_iface_cb_focus_skip_set,
3777    _tzpol_iface_cb_focus_skip_unset,
3778    _tzpol_iface_cb_role_set,
3779    _tzpol_iface_cb_type_set,
3780    _tzpol_iface_cb_conformant_set,
3781    _tzpol_iface_cb_conformant_unset,
3782    _tzpol_iface_cb_conformant_get,
3783    _tzpol_iface_cb_notilv_set,
3784    _tzpol_iface_cb_transient_for_set,
3785    _tzpol_iface_cb_transient_for_unset,
3786    _tzpol_iface_cb_win_scrmode_set,
3787    _tzpol_iface_cb_subsurf_place_below_parent,
3788    _tzpol_iface_cb_subsurf_stand_alone_set,
3789    _tzpol_iface_cb_subsurface_get,
3790    _tzpol_iface_cb_opaque_state_set,
3791    _tzpol_iface_cb_iconify,
3792    _tzpol_iface_cb_uniconify,
3793    _tzpol_iface_cb_aux_hint_add,
3794    _tzpol_iface_cb_aux_hint_change,
3795    _tzpol_iface_cb_aux_hint_del,
3796    _tzpol_iface_cb_supported_aux_hints_get,
3797    _tzpol_iface_cb_background_state_set,
3798    _tzpol_iface_cb_background_state_unset,
3799    _tzpol_iface_cb_floating_mode_set,
3800    _tzpol_iface_cb_floating_mode_unset,
3801    _tzpol_iface_cb_stack_mode_set,
3802    _tzpol_iface_cb_activate_above_by_res_id,
3803    _tzpol_iface_cb_subsurf_watcher_get,
3804    _tzpol_iface_cb_parent_set,
3805    _tzpol_iface_cb_ack_conformant_region,
3806    _tzpol_iface_cb_destroy,
3807    _tzpol_iface_cb_has_video,
3808    _tzpol_iface_cb_set_appid,
3809    _tzpol_iface_cb_show,
3810    _tzpol_iface_cb_hide,
3811    _tzpol_iface_cb_set_transient_for_below,
3812    _tzpol_iface_cb_set_parent_with_below,
3813    _tzpol_iface_cb_set_maximize_direction,
3814    _tzpol_iface_cb_set_pin_mode,
3815    _tzpol_iface_cb_unset_pin_mode,
3816    _tzpol_iface_cb_set_layout,
3817    _tzpol_iface_cb_set_modal,
3818    _tzpol_iface_cb_unset_modal,
3819 };
3820
3821 static void
3822 _tzpol_cb_unbind(struct wl_resource *res_tzpol)
3823 {
3824    E_Policy_Wl_Tzpol *tzpol;
3825
3826    tzpol = _e_policy_wl_tzpol_get(res_tzpol);
3827    EINA_SAFETY_ON_NULL_RETURN(tzpol);
3828
3829    eina_hash_del_by_key(polwl->tzpols, &res_tzpol);
3830 }
3831
3832 static void
3833 _tzpol_cb_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t ver, uint32_t id)
3834 {
3835    E_Policy_Wl_Tzpol *tzpol;
3836    struct wl_resource *res_tzpol;
3837
3838    EINA_SAFETY_ON_NULL_GOTO(polwl, err);
3839
3840    res_tzpol = wl_resource_create(client,
3841                                   &tizen_policy_interface,
3842                                   ver,
3843                                   id);
3844    EINA_SAFETY_ON_NULL_GOTO(res_tzpol, err);
3845
3846    tzpol = _e_policy_wl_tzpol_add(client, res_tzpol);
3847    EINA_SAFETY_ON_NULL_GOTO(tzpol, err);
3848
3849    wl_resource_set_implementation(res_tzpol,
3850                                   &_tzpol_iface,
3851                                   NULL,
3852                                   _tzpol_cb_unbind);
3853    return;
3854
3855 err:
3856    ERR("Could not create tizen_policy_interface res: %m");
3857    wl_client_post_no_memory(client);
3858 }
3859
3860 // --------------------------------------------------------
3861 // tizen_display_policy_interface
3862 // --------------------------------------------------------
3863 static const struct tizen_display_policy_interface _tz_dpy_pol_iface =
3864 {
3865    _tz_dpy_pol_iface_cb_brightness_set,
3866    _tz_dpy_pol_iface_cb_destroy,
3867 };
3868
3869 static void
3870 _tz_dpy_pol_cb_unbind(struct wl_resource *res_tz_dpy_pol)
3871 {
3872    E_Policy_Wl_Tz_Dpy_Pol *tz_dpy_pol;
3873
3874    tz_dpy_pol = _e_policy_wl_tz_dpy_pol_get(res_tz_dpy_pol);
3875    EINA_SAFETY_ON_NULL_RETURN(tz_dpy_pol);
3876
3877    _e_policy_wl_tz_dpy_pol_del(tz_dpy_pol);
3878 }
3879
3880 static void
3881 _tz_dpy_pol_cb_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t ver, uint32_t id)
3882 {
3883    E_Policy_Wl_Tz_Dpy_Pol *tz_dpy_pol;
3884    struct wl_resource *res_tz_dpy_pol;
3885
3886    EINA_SAFETY_ON_NULL_GOTO(polwl, err);
3887
3888    res_tz_dpy_pol = wl_resource_create(client,
3889                                        &tizen_display_policy_interface,
3890                                        ver,
3891                                        id);
3892    EINA_SAFETY_ON_NULL_GOTO(res_tz_dpy_pol, err);
3893
3894    tz_dpy_pol = _e_policy_wl_tz_dpy_pol_add(res_tz_dpy_pol);
3895    EINA_SAFETY_ON_NULL_GOTO(tz_dpy_pol, err);
3896
3897    wl_resource_set_implementation(res_tz_dpy_pol,
3898                                   &_tz_dpy_pol_iface,
3899                                   NULL,
3900                                   _tz_dpy_pol_cb_unbind);
3901    return;
3902
3903 err:
3904    ERR("Could not create tizen_display_policy_interface res: %m");
3905    wl_client_post_no_memory(client);
3906 }
3907
3908 // --------------------------------------------------------
3909 // tizen_ws_shell_interface::service
3910 // --------------------------------------------------------
3911 static void
3912 _tzsh_srv_iface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzsh_srv)
3913 {
3914    wl_resource_destroy(res_tzsh_srv);
3915 }
3916
3917 static void
3918 _tzsh_srv_iface_cb_region_set(struct wl_client *client, struct wl_resource *res_tzsh_srv, int32_t type, int32_t angle, struct wl_resource *res_reg)
3919 {
3920    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
3921    E_Policy_Wl_Tzsh_Region *tzsh_reg;
3922
3923    tzsh_srv = wl_resource_get_user_data(res_tzsh_srv);
3924    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
3925
3926    if (!eina_list_data_find(polwl->tzsh_srvs, tzsh_srv))
3927      return;
3928
3929    tzsh_reg = wl_resource_get_user_data(res_reg);
3930    EINA_SAFETY_ON_NULL_RETURN(tzsh_reg);
3931
3932    if ((tzsh_srv->role == TZSH_SRV_ROLE_QUICKPANEL_SYSTEM_DEFAULT) ||
3933        (tzsh_srv->role == TZSH_SRV_ROLE_QUICKPANEL_CONTEXT_MENU) ||
3934        (tzsh_srv->role == TZSH_SRV_ROLE_QUICKPANEL_APPS_MENU))
3935      {
3936         EINA_SAFETY_ON_NULL_RETURN(tzsh_srv->tzsh);
3937         EINA_SAFETY_ON_NULL_RETURN(tzsh_srv->ec);
3938
3939         e_service_quickpanel_region_set(tzsh_srv->ec,
3940                                         type,
3941                                         angle,
3942                                         tzsh_reg->tiler);
3943      }
3944    else if (tzsh_srv->role == TZSH_SRV_ROLE_VOLUME)
3945      e_service_volume_region_set(type, angle, tzsh_reg->tiler);
3946    else if (tzsh_srv->role == TZSH_SRV_ROLE_SOFTKEY)
3947      {
3948         if (e_config->use_softkey_service)
3949           {
3950              EINA_SAFETY_ON_NULL_RETURN(tzsh_srv->tzsh);
3951              EINA_SAFETY_ON_NULL_RETURN(tzsh_srv->ec);
3952
3953              e_service_softkey_handler_region_set(tzsh_srv->ec, angle, tzsh_reg->tiler);
3954           }
3955      }
3956 }
3957
3958 static void
3959 _tzsh_srv_indicator_cb_resource_destroy(struct wl_resource *resource)
3960 {
3961    if (_indicator_srv_res == resource)
3962      _indicator_srv_res = NULL;
3963 }
3964
3965 static void
3966 _tzsh_srv_indicator_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
3967 {
3968    _indicator_srv_res = NULL;
3969    wl_resource_destroy(resource);
3970 }
3971
3972 static const struct tws_service_indicator_interface _tzsh_srv_indicator_iface =
3973 {
3974    _tzsh_srv_indicator_cb_destroy,
3975 };
3976
3977 static void
3978 _tzsh_srv_iface_cb_indicator_get(struct wl_client *client, struct wl_resource *res_tzsh_srv, uint32_t id)
3979 {
3980    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
3981    struct wl_resource *res;
3982
3983    tzsh_srv = wl_resource_get_user_data(res_tzsh_srv);
3984    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
3985
3986    if (!eina_list_data_find(polwl->tzsh_srvs, tzsh_srv))
3987      return;
3988
3989    res = wl_resource_create(client, &tws_service_indicator_interface, 1, id);
3990    if (!res)
3991      {
3992         wl_client_post_no_memory(client);
3993         return;
3994      }
3995    _indicator_srv_res = res;
3996
3997    wl_resource_set_implementation(res, &_tzsh_srv_indicator_iface, tzsh_srv,
3998                                   _tzsh_srv_indicator_cb_resource_destroy);
3999 }
4000
4001 static void
4002 _tzsh_srv_qp_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
4003 {
4004    wl_resource_destroy(resource);
4005 }
4006
4007 static void
4008 _tzsh_srv_qp_cb_msg(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t msg)
4009 {
4010    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4011
4012    tzsh_srv = wl_resource_get_user_data(resource);
4013
4014    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
4015    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv->tzsh);
4016
4017 #define EC  tzsh_srv->ec
4018    EINA_SAFETY_ON_NULL_RETURN(EC);
4019
4020    switch (msg)
4021      {
4022       case TWS_SERVICE_QUICKPANEL_MSG_SHOW:
4023          e_service_quickpanel_show(EC);
4024          break;
4025       case TWS_SERVICE_QUICKPANEL_MSG_HIDE:
4026          e_service_quickpanel_hide(EC);
4027          break;
4028       default:
4029          ERR("Unknown message!! msg %d", msg);
4030          break;
4031      }
4032 #undef EC
4033 }
4034
4035 static void
4036 _tzsh_srv_qp_cb_effect_type_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t type)
4037 {
4038    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4039
4040    tzsh_srv = wl_resource_get_user_data(resource);
4041
4042    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
4043    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv->tzsh);
4044
4045 #define EC  tzsh_srv->ec
4046    EINA_SAFETY_ON_NULL_RETURN(EC);
4047    e_service_quickpanel_effect_type_set(EC, type);
4048 #undef EC
4049 }
4050
4051 static void
4052 _tzsh_srv_qp_cb_scroll_lock_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t lock)
4053 {
4054    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4055
4056    tzsh_srv = wl_resource_get_user_data(resource);
4057
4058    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
4059    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv->tzsh);
4060
4061 #define EC  tzsh_srv->ec
4062    EINA_SAFETY_ON_NULL_RETURN(EC);
4063    e_service_quickpanel_scroll_lock_set(EC, lock);
4064 #undef EC
4065 }
4066
4067 static const struct tws_service_quickpanel_interface _tzsh_srv_qp_iface =
4068 {
4069    _tzsh_srv_qp_cb_destroy,
4070    _tzsh_srv_qp_cb_msg,
4071    _tzsh_srv_qp_cb_effect_type_set,
4072    _tzsh_srv_qp_cb_scroll_lock_set,
4073 };
4074
4075 static void
4076 _tzsh_srv_iface_cb_quickpanel_get(struct wl_client *client, struct wl_resource *res_tzsh_srv, uint32_t id)
4077 {
4078    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4079    struct wl_resource *res;
4080
4081    tzsh_srv = wl_resource_get_user_data(res_tzsh_srv);
4082    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
4083
4084    if (!eina_list_data_find(polwl->tzsh_srvs, tzsh_srv))
4085      return;
4086
4087    res = wl_resource_create(client,
4088                             &tws_service_quickpanel_interface,
4089                             wl_resource_get_version(res_tzsh_srv),
4090                             id);
4091    if (!res)
4092      {
4093         wl_client_post_no_memory(client);
4094         return;
4095      }
4096
4097    wl_resource_set_implementation(res, &_tzsh_srv_qp_iface, tzsh_srv, NULL);
4098 }
4099
4100
4101
4102 static void
4103 _tzsh_srv_softkey_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
4104 {
4105    wl_resource_destroy(resource);
4106 }
4107
4108 static void
4109 _tzsh_srv_softkey_cb_msg_send(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t msg)
4110 {
4111    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4112    E_Service_Softkey *softkey_service;
4113    E_Zone *zone;
4114
4115    tzsh_srv = wl_resource_get_user_data(resource);
4116
4117    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
4118    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv->tzsh);
4119
4120    zone = tzsh_srv->zone;
4121    EINA_SAFETY_ON_NULL_RETURN(zone);
4122
4123    softkey_service = e_service_softkey_get(zone);
4124    EINA_SAFETY_ON_NULL_RETURN(softkey_service);
4125
4126    switch (msg)
4127      {
4128       case TWS_SERVICE_SOFTKEY_MSG_SHOW:
4129          e_service_softkey_show(softkey_service);
4130          break;
4131       case TWS_SERVICE_SOFTKEY_MSG_HIDE:
4132          e_service_softkey_hide(softkey_service);
4133          break;
4134       default:
4135          ERR("Unknown message!! msg %d", msg);
4136          break;
4137      }
4138 }
4139
4140 static const struct tws_service_softkey_interface _tzsh_srv_softkey_iface =
4141 {
4142    _tzsh_srv_softkey_cb_destroy,
4143    _tzsh_srv_softkey_cb_msg_send,
4144 };
4145
4146 static void
4147 _tzsh_srv_iface_cb_softkey_get(struct wl_client *client, struct wl_resource *res_tzsh_srv, uint32_t id)
4148 {
4149    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4150    E_Service_Softkey *softkey_service = NULL;
4151    struct wl_resource *res;
4152
4153    tzsh_srv = wl_resource_get_user_data(res_tzsh_srv);
4154    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
4155
4156    if (!eina_list_data_find(polwl->tzsh_srvs, tzsh_srv))
4157      return;
4158
4159    res = wl_resource_create(client, &tws_service_softkey_interface, 1, id);
4160    if (!res)
4161      {
4162         wl_client_post_no_memory(client);
4163         return;
4164      }
4165
4166    ELOGF("TZSH", "[SOFTKEY SERVICE] resource created. res:%p, res_tzsh_srv:%p, id:%d", NULL, res, res_tzsh_srv, id);
4167
4168    if (tzsh_srv->tzsh)
4169      {
4170         E_Zone *zone = tzsh_srv->zone;
4171         if (zone)
4172           softkey_service = e_service_softkey_get(zone);
4173         ELOGF("TZSH", "[SOFTKEY SERVICE] resource set. res:%p, softkey_service:%p, softkey_ec:%p", NULL, res, softkey_service, tzsh_srv->ec);
4174         if (softkey_service)
4175           {
4176              e_service_softkey_wl_resource_set(softkey_service, res);
4177              e_service_softkey_restore_visible_request(softkey_service);
4178           }
4179      }
4180
4181    wl_resource_set_implementation(res, &_tzsh_srv_softkey_iface, tzsh_srv, NULL);
4182 }
4183
4184 static void
4185 _tzsh_srv_magnifier_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
4186 {
4187    wl_resource_destroy(resource);
4188 }
4189
4190 static void
4191 _tzsh_srv_magnifier_cb_zoom_geometry_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t angle, int32_t x, int32_t y, uint32_t w, uint32_t h)
4192 {
4193    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4194    E_Client *ec;
4195
4196    tzsh_srv = wl_resource_get_user_data(resource);
4197
4198    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
4199    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv->tzsh);
4200    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv->ec);
4201
4202    ELOGF("TZSH", "[MAGNIFIER] Set Geometry. angle:%d, geo:%d,%d,%dx%d", tzsh_srv->ec, angle, x, y, w, h);
4203
4204    ec = tzsh_srv->ec;
4205    // angle: 0, 90, 180, 270
4206    e_magnifier_zoom_obj_geometry_set(ec, angle, x, y, w, h);
4207 }
4208
4209 static void
4210 _tzsh_srv_magnifier_cb_ratio_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t ratio)
4211 {
4212    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4213    E_Client *ec;
4214
4215    tzsh_srv = wl_resource_get_user_data(resource);
4216
4217    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
4218    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv->tzsh);
4219    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv->ec);
4220
4221    ELOGF("TZSH", "[MAGNIFIER] Set Ratio. ratio:%d", tzsh_srv->ec, ratio);
4222
4223    ec = tzsh_srv->ec;
4224    // ratio : 100 ~ 200 (each 10)
4225    e_magnifier_zoom_obj_ratio_set(ec, ratio);
4226 }
4227
4228 static void
4229 _tzsh_srv_magnifier_cb_enable_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t enable)
4230 {
4231    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4232    E_Client *ec;
4233
4234    tzsh_srv = wl_resource_get_user_data(resource);
4235
4236    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
4237    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv->tzsh);
4238    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv->ec);
4239
4240    ELOGF("TZSH", "[MAGNIFIER] Set Enable. enable:%d", tzsh_srv->ec, enable);
4241
4242    ec = tzsh_srv->ec;
4243
4244    if (enable)
4245      e_magnifier_show(ec);
4246    else
4247      e_magnifier_hide(ec);
4248 }
4249
4250 static const struct tws_service_magnifier_interface _tzsh_srv_magnifier_iface =
4251 {
4252    _tzsh_srv_magnifier_cb_destroy,
4253    _tzsh_srv_magnifier_cb_zoom_geometry_set,
4254    _tzsh_srv_magnifier_cb_ratio_set,
4255    _tzsh_srv_magnifier_cb_enable_set,
4256 };
4257
4258 static void
4259 _tzsh_srv_iface_cb_magnifier_get(struct wl_client *client, struct wl_resource *res_tzsh_srv, uint32_t id)
4260 {
4261    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4262    struct wl_resource *res;
4263
4264    tzsh_srv = wl_resource_get_user_data(res_tzsh_srv);
4265    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
4266
4267    if (!eina_list_data_find(polwl->tzsh_srvs, tzsh_srv))
4268      return;
4269
4270    res = wl_resource_create(client, &tws_service_magnifier_interface, 1, id);
4271    if (!res)
4272      {
4273         wl_client_post_no_memory(client);
4274         return;
4275      }
4276
4277    ELOGF("TZSH", "[MAGNIFIER] resource created. res:%p, res_tzsh_srv:%p, id:%d", NULL, res, res_tzsh_srv, id);
4278    wl_resource_set_implementation(res, &_tzsh_srv_magnifier_iface, tzsh_srv, NULL);
4279 }
4280
4281 //////////////////////////////////////////////////////////////////////////////////////////////////////
4282 static void
4283 _tzsh_srv_scrsaver_cb_release(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
4284 {
4285    wl_resource_destroy(resource);
4286 }
4287
4288 static const struct tws_service_screensaver_interface _tzsh_srv_scrsaver_iface =
4289 {
4290    _tzsh_srv_scrsaver_cb_release
4291 };
4292
4293 static void
4294 _tzsh_srv_iface_cb_scrsaver_get(struct wl_client *client, struct wl_resource *res_tzsh_srv, uint32_t id)
4295 {
4296    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4297    struct wl_resource *res;
4298
4299    tzsh_srv = wl_resource_get_user_data(res_tzsh_srv);
4300    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
4301
4302    if (!eina_list_data_find(polwl->tzsh_srvs, tzsh_srv))
4303      return;
4304
4305    res = wl_resource_create(client, &tws_service_screensaver_interface, 1, id);
4306    if (!res)
4307      {
4308         wl_client_post_no_memory(client);
4309         return;
4310      }
4311
4312    wl_resource_set_implementation(res, &_tzsh_srv_scrsaver_iface, tzsh_srv, NULL);
4313 }
4314
4315 static void
4316 _tzsh_srv_scrsaver_mng_cb_resource_destroy(struct wl_resource *resource)
4317 {
4318    if (_scrsaver_mng_res == resource)
4319      {
4320         _scrsaver_mng_res = NULL;
4321         e_screensaver_disable();
4322      }
4323 }
4324
4325 static void
4326 _tzsh_srv_scrsaver_mng_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
4327 {
4328    _scrsaver_mng_res = NULL;
4329    wl_resource_destroy(resource);
4330    e_screensaver_disable();
4331 }
4332
4333 static void
4334 _tzsh_srv_scrsaver_mng_cb_enable(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
4335 {
4336    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4337
4338    tzsh_srv = wl_resource_get_user_data(resource);
4339
4340    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
4341    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv->tzsh);
4342
4343    e_screensaver_enable();
4344 }
4345
4346 static void
4347 _tzsh_srv_scrsaver_mng_cb_disable(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
4348 {
4349    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4350
4351    tzsh_srv = wl_resource_get_user_data(resource);
4352
4353    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
4354    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv->tzsh);
4355
4356    e_screensaver_disable();
4357 }
4358
4359 static void
4360 _tzsh_srv_scrsaver_mng_cb_idle_time_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t time)
4361 {
4362    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4363    double timeout;
4364
4365    tzsh_srv = wl_resource_get_user_data(resource);
4366
4367    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
4368    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv->tzsh);
4369
4370    /* convert time to seconds (double) from milliseconds (unsigned int) */
4371    timeout = (double)time * 0.001f;
4372
4373    e_screensaver_timeout_set(timeout);
4374 }
4375
4376 static void
4377 _tzsh_srv_scrsaver_mng_cb_state_get(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t type)
4378 {
4379    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4380    uint32_t val = 0;
4381    double timeout;
4382
4383    tzsh_srv = wl_resource_get_user_data(resource);
4384
4385    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
4386    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv->tzsh);
4387
4388    switch (type)
4389      {
4390       case TWS_SERVICE_SCREENSAVER_MANAGER_STATE_TYPE_IDLE_TIMEOUT:
4391         /* convert time to milliseconds (unsigned int) from seconds (double) */
4392         timeout = e_screensaver_timeout_get();
4393         val = (uint32_t)(timeout * 1000);
4394         break;
4395       default:
4396         break;
4397      }
4398
4399    tws_service_screensaver_manager_send_state_get_done(resource, type, val, 0);
4400 }
4401
4402 static const struct tws_service_screensaver_manager_interface _tzsh_srv_scrsaver_mng_iface =
4403 {
4404    _tzsh_srv_scrsaver_mng_cb_destroy,
4405    _tzsh_srv_scrsaver_mng_cb_enable,
4406    _tzsh_srv_scrsaver_mng_cb_disable,
4407    _tzsh_srv_scrsaver_mng_cb_idle_time_set,
4408    _tzsh_srv_scrsaver_mng_cb_state_get
4409 };
4410
4411 static void
4412 _tzsh_srv_iface_cb_scrsaver_mng_get(struct wl_client *client, struct wl_resource *res_tzsh_srv, uint32_t id)
4413 {
4414    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4415    struct wl_resource *res;
4416
4417    tzsh_srv = wl_resource_get_user_data(res_tzsh_srv);
4418    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
4419
4420    if (!eina_list_data_find(polwl->tzsh_srvs, tzsh_srv))
4421      return;
4422
4423    res = wl_resource_create(client, &tws_service_screensaver_manager_interface, 1, id);
4424    if (!res)
4425      {
4426         wl_client_post_no_memory(client);
4427         return;
4428      }
4429
4430    _scrsaver_mng_res = res;
4431
4432    wl_resource_set_implementation(res, &_tzsh_srv_scrsaver_mng_iface, tzsh_srv,
4433                                   _tzsh_srv_scrsaver_mng_cb_resource_destroy);
4434 }
4435
4436 static void
4437 _tzsh_srv_cbhm_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
4438 {
4439    wl_resource_destroy(resource);
4440 }
4441
4442 static void
4443 _tzsh_srv_cbhm_cb_msg(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t msg)
4444 {
4445    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4446
4447    tzsh_srv = wl_resource_get_user_data(resource);
4448
4449    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
4450    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv->tzsh);
4451
4452 #define EC  tzsh_srv->ec
4453    EINA_SAFETY_ON_NULL_RETURN(EC);
4454
4455    switch (msg)
4456      {
4457       case TWS_SERVICE_CBHM_MSG_SHOW:
4458          e_service_cbhm_show();
4459          break;
4460       case TWS_SERVICE_CBHM_MSG_HIDE:
4461          e_service_cbhm_hide();
4462          break;
4463       case TWS_SERVICE_CBHM_MSG_DATA_SELECTED:
4464          e_service_cbhm_data_selected();
4465          break;
4466       default:
4467          ERR("Unknown message!! msg %d", msg);
4468          break;
4469      }
4470 #undef EC
4471 }
4472
4473 static const struct tws_service_cbhm_interface _tzsh_srv_cbhm_iface =
4474 {
4475    _tzsh_srv_cbhm_cb_destroy,
4476    _tzsh_srv_cbhm_cb_msg
4477 };
4478
4479 static void
4480 _tzsh_srv_iface_cb_cbhm_get(struct wl_client *client, struct wl_resource *res_tzsh_srv, uint32_t id)
4481 {
4482    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4483    struct wl_resource *res;
4484
4485    tzsh_srv = wl_resource_get_user_data(res_tzsh_srv);
4486    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
4487
4488    if (!eina_list_data_find(polwl->tzsh_srvs, tzsh_srv))
4489      return;
4490
4491    res = wl_resource_create(client, &tws_service_cbhm_interface, 1, id);
4492    if (!res)
4493      {
4494         wl_client_post_no_memory(client);
4495         return;
4496      }
4497
4498    wl_resource_set_implementation(res, &_tzsh_srv_cbhm_iface, tzsh_srv, NULL);
4499 }
4500
4501
4502 static void
4503 _tzsh_srv_iface_cb_launcher_get(struct wl_client *client, struct wl_resource *res_tzsh_srv, uint32_t id)
4504 {
4505    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4506    struct wl_resource *res;
4507
4508    tzsh_srv = wl_resource_get_user_data(res_tzsh_srv);
4509    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
4510    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv->tzsh);
4511
4512    if (!eina_list_data_find(polwl->tzsh_srvs, tzsh_srv))
4513      return;
4514
4515    res = wl_resource_create(client, &tws_service_launcher_interface, 1, id);
4516    if (!res)
4517      {
4518         wl_client_post_no_memory(client);
4519         return;
4520      }
4521
4522    if (tzsh_srv->ec)
4523      e_service_launcher_resource_set(tzsh_srv->ec, res);
4524 }
4525
4526 static void
4527 _tzsh_srv_taskbar_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
4528 {
4529    wl_resource_destroy(resource);
4530 }
4531
4532 static void
4533 _tzsh_srv_taskbar_cb_place_type_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t place_type)
4534 {
4535    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4536    E_Client *ec;
4537
4538    tzsh_srv = wl_resource_get_user_data(resource);
4539    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
4540    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv->tzsh);
4541
4542    ec = tzsh_srv->ec;
4543    EINA_SAFETY_ON_NULL_RETURN(ec);
4544
4545    e_service_taskbar_place_type_set(ec, place_type);
4546 }
4547
4548 static void
4549 _tzsh_srv_taskbar_cb_size_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t width, uint32_t height)
4550 {
4551    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4552    E_Client *ec;
4553
4554    tzsh_srv = wl_resource_get_user_data(resource);
4555    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
4556    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv->tzsh);
4557
4558    ec = tzsh_srv->ec;
4559    EINA_SAFETY_ON_NULL_RETURN(ec);
4560
4561    e_service_taskbar_size_set(ec, width, height);
4562 }
4563
4564 static void
4565 _tzsh_srv_taskbar_cb_auto_placement_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t auto_placement)
4566 {
4567    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4568    E_Client *ec;
4569
4570    tzsh_srv = wl_resource_get_user_data(resource);
4571    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
4572    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv->tzsh);
4573
4574    ec = tzsh_srv->ec;
4575    EINA_SAFETY_ON_NULL_RETURN(ec);
4576
4577    e_service_taskbar_auto_placement_set(ec, auto_placement);
4578 }
4579
4580 static const struct tws_service_taskbar_interface _tzsh_srv_taskbar_iface =
4581 {
4582    _tzsh_srv_taskbar_cb_destroy,
4583    _tzsh_srv_taskbar_cb_place_type_set,
4584    _tzsh_srv_taskbar_cb_size_set,
4585    _tzsh_srv_taskbar_cb_auto_placement_set,
4586 };
4587
4588 static void
4589 _tzsh_srv_iface_cb_taskbar_get(struct wl_client *client, struct wl_resource *res_tzsh_srv, uint32_t id)
4590 {
4591    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4592    struct wl_resource *res;
4593
4594    tzsh_srv = wl_resource_get_user_data(res_tzsh_srv);
4595    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
4596    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv->tzsh);
4597
4598    if (!eina_list_data_find(polwl->tzsh_srvs, tzsh_srv))
4599      return;
4600
4601    res = wl_resource_create(client,
4602                             &tws_service_taskbar_interface,
4603                             1,
4604                             id);
4605    if (!res)
4606      {
4607         wl_client_post_no_memory(client);
4608         return;
4609      }
4610
4611    wl_resource_set_implementation(res, &_tzsh_srv_taskbar_iface, tzsh_srv, NULL);
4612 }
4613
4614 static void
4615 _tzsh_srv_kvm_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
4616 {
4617    wl_resource_destroy(resource);
4618 }
4619
4620 static void
4621 _tzsh_srv_kvm_cb_perform_drop(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
4622 {
4623    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4624    E_Client *ec;
4625
4626    tzsh_srv = wl_resource_get_user_data(resource);
4627    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
4628
4629    ec = tzsh_srv->ec;
4630    EINA_SAFETY_ON_NULL_RETURN(ec);
4631
4632    if (!e_comp_wl->drag) return;
4633
4634    e_service_kvm_drop_perform(ec);
4635 }
4636
4637 static void
4638 _tzsh_srv_kvm_cb_cancel_drag(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
4639 {
4640    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4641    E_Client *ec;
4642
4643    tzsh_srv = wl_resource_get_user_data(resource);
4644    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
4645
4646    ec = tzsh_srv->ec;
4647    EINA_SAFETY_ON_NULL_RETURN(ec);
4648
4649    if (!e_comp_wl->drag) return;
4650
4651    e_service_kvm_drag_cancel(ec);
4652 }
4653
4654 static void
4655 _tzsh_srv_kvm_cb_perform_drag_enter(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
4656 {
4657    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4658    E_Client *ec;
4659
4660    tzsh_srv = wl_resource_get_user_data(resource);
4661    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
4662
4663    ec = tzsh_srv->ec;
4664    EINA_SAFETY_ON_NULL_RETURN(ec);
4665
4666    if (!e_comp_wl->drag) return;
4667
4668    e_service_kvm_perform_drag_enter(ec);
4669 }
4670
4671 static void
4672 _tzsh_srv_kvm_cb_perform_drag_leave(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
4673 {
4674    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4675    E_Client *ec;
4676
4677    tzsh_srv = wl_resource_get_user_data(resource);
4678    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
4679
4680    ec = tzsh_srv->ec;
4681    EINA_SAFETY_ON_NULL_RETURN(ec);
4682
4683    if (!e_comp_wl->drag) return;
4684
4685    e_service_kvm_perform_drag_leave(ec);
4686 }
4687
4688 static void
4689 _tzsh_srv_kvm_cb_secondary_selection_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
4690 {
4691    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4692    E_Client *ec;
4693
4694    tzsh_srv = wl_resource_get_user_data(resource);
4695    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
4696
4697    ec = tzsh_srv->ec;
4698    EINA_SAFETY_ON_NULL_RETURN(ec);
4699
4700    e_service_kvm_secondary_selection_set(ec, EINA_TRUE);
4701 }
4702
4703 static void
4704 _tzsh_srv_kvm_cb_secondary_selection_unset(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
4705 {
4706    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4707    E_Client *ec;
4708
4709    tzsh_srv = wl_resource_get_user_data(resource);
4710    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
4711
4712    ec = tzsh_srv->ec;
4713    EINA_SAFETY_ON_NULL_RETURN(ec);
4714
4715    e_service_kvm_secondary_selection_set(ec, EINA_FALSE);
4716 }
4717
4718 static const struct tws_service_kvm_interface _tzsh_srv_kvm_iface =
4719 {
4720    _tzsh_srv_kvm_cb_destroy,
4721    _tzsh_srv_kvm_cb_perform_drop,
4722    _tzsh_srv_kvm_cb_cancel_drag,
4723    _tzsh_srv_kvm_cb_perform_drag_enter,
4724    _tzsh_srv_kvm_cb_perform_drag_leave,
4725    _tzsh_srv_kvm_cb_secondary_selection_set,
4726    _tzsh_srv_kvm_cb_secondary_selection_unset,
4727 };
4728
4729 static void
4730 _tzsh_srv_iface_cb_kvm_get(struct wl_client *client, struct wl_resource *res_tzsh_srv, uint32_t id)
4731 {
4732    E_Service_Kvm *esk = NULL;
4733    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4734    struct wl_resource *res;
4735    E_Client *ec;
4736
4737    tzsh_srv = wl_resource_get_user_data(res_tzsh_srv);
4738    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
4739    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv->tzsh);
4740
4741    if (!eina_list_data_find(polwl->tzsh_srvs, tzsh_srv))
4742      return;
4743
4744    res = wl_resource_create(client,
4745                             &tws_service_kvm_interface,
4746                             1,
4747                             id);
4748    if (!res)
4749      {
4750         wl_client_post_no_memory(client);
4751         return;
4752      }
4753
4754    ELOGF("KVM", "multi control resource created, res:%p, tzsh_srv:%p, res_tzsh_srv:%p", NULL, res, tzsh_srv, res_tzsh_srv);
4755
4756    ec = tzsh_srv->ec;
4757    if (ec)
4758      esk = e_service_kvm_service_get(ec);
4759
4760    if (esk)
4761      {
4762         ELOGF("KVM", "multi control resource set. res:%p, service:%p, ec:%p", NULL, res, esk, ec);
4763         e_service_kvm_wl_resource_set(esk, res);
4764      }
4765
4766    wl_resource_set_implementation(res, &_tzsh_srv_kvm_iface, tzsh_srv, NULL);
4767 }
4768
4769 static const struct tws_service_interface _tzsh_srv_iface =
4770 {
4771    _tzsh_srv_iface_cb_destroy,
4772    _tzsh_srv_iface_cb_region_set,
4773    _tzsh_srv_iface_cb_indicator_get,
4774    _tzsh_srv_iface_cb_quickpanel_get,
4775    _tzsh_srv_iface_cb_scrsaver_mng_get,
4776    _tzsh_srv_iface_cb_scrsaver_get,
4777    _tzsh_srv_iface_cb_cbhm_get,
4778    _tzsh_srv_iface_cb_softkey_get,
4779    _tzsh_srv_iface_cb_magnifier_get,
4780    _tzsh_srv_iface_cb_launcher_get,
4781    _tzsh_srv_iface_cb_taskbar_get,
4782    _tzsh_srv_iface_cb_kvm_get,
4783 };
4784
4785 static Eina_Bool
4786 _e_policy_wl_tzsh_service_check_privilege(struct wl_client *client, int role)
4787 {
4788    const char *privilege;
4789    pid_t pid;
4790    uid_t uid;
4791    Eina_Bool res;
4792
4793    switch (role)
4794      {
4795       case TZSH_SRV_ROLE_QUICKPANEL_SYSTEM_DEFAULT:
4796       case TZSH_SRV_ROLE_QUICKPANEL_CONTEXT_MENU:
4797       case TZSH_SRV_ROLE_QUICKPANEL_APPS_MENU:
4798          privilege = E_PRIVILEGE_QUICKPANEL_SERVICE;
4799          break;
4800       case TZSH_SRV_ROLE_VOLUME:
4801          privilege = E_PRIVILEGE_VOLUME_SERVICE;
4802          break;
4803       case TZSH_SRV_ROLE_LOCKSCREEN:
4804          privilege = E_PRIVILEGE_LOCKSCREEN_SERVICE;
4805          break;
4806       case TZSH_SRV_ROLE_INDICATOR:
4807          privilege = E_PRIVILEGE_INDICATOR_SERVICE;
4808          break;
4809       case TZSH_SRV_ROLE_SCREENSAVER_MNG:
4810       case TZSH_SRV_ROLE_SCREENSAVER:
4811          privilege = E_PRIVILEGE_SCREENSAVER_SERVICE;
4812          break;
4813       case TZSH_SRV_ROLE_CBHM:
4814          privilege = E_PRIVILEGE_CBHM_SERVICE;
4815          break;
4816       case TZSH_SRV_ROLE_SOFTKEY:
4817          privilege = E_PRIVILEGE_SOFTKEY_SERVICE;
4818          break;
4819       case TZSH_SRV_ROLE_MAGNIFIER:
4820          privilege = E_PRIVILEGE_MAGNIFIER_SERVICE;
4821          break;
4822       case TZSH_SRV_ROLE_LAUNCHER:
4823          privilege = E_PRIVILEGE_LAUNCHER_SERVICE;
4824          break;
4825       case TZSH_SRV_ROLE_TASKBAR:
4826          privilege = E_PRIVILEGE_TASKBAR_SERVICE;
4827          break;
4828          /* TODO: need to check privilege
4829       case TZSH_SRV_ROLE_KVM:
4830          privilege = E_PRIVILEGE_KVM_SERVICE;
4831          break;
4832          */
4833       default:
4834          return EINA_TRUE;
4835      }
4836
4837    wl_client_get_credentials(client, &pid, &uid, NULL);
4838    res = e_security_privilege_check(pid,
4839                                     uid,
4840                                     privilege);
4841    return res;
4842 }
4843
4844 static void
4845 _tzsh_cb_srv_destroy(struct wl_resource *res_tzsh_srv)
4846 {
4847    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4848
4849    tzsh_srv = wl_resource_get_user_data(res_tzsh_srv);
4850    EINA_SAFETY_ON_NULL_RETURN(tzsh_srv);
4851
4852    if (!eina_list_data_find(polwl->tzsh_srvs, tzsh_srv))
4853      return;
4854
4855    _e_policy_wl_tzsh_srv_del(tzsh_srv);
4856 }
4857
4858 static void
4859 _tzsh_iface_cb_srv_create(struct wl_client *client, struct wl_resource *res_tzsh, uint32_t id, uint32_t surf_id, const char *name)
4860 {
4861    E_Policy_Wl_Tzsh *tzsh;
4862    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
4863    struct wl_resource *res_tzsh_srv;
4864    E_Client *ec;
4865    E_Pixmap *cp;
4866    int role;
4867    Eina_Bool res;
4868
4869    role = _e_policy_wl_tzsh_srv_role_get(name);
4870    if (role == TZSH_SRV_ROLE_UNKNOWN)
4871      {
4872         wl_resource_post_error
4873           (res_tzsh,
4874            WL_DISPLAY_ERROR_INVALID_OBJECT,
4875            "Invalid res_tzsh");
4876         return;
4877      }
4878
4879    /* check whether client has a privilege */
4880    res = _e_policy_wl_tzsh_service_check_privilege(client, role);
4881    if (!res)
4882      {
4883         ERR("Could not get privilege of resource: %m");
4884         tizen_ws_shell_send_error(res_tzsh,
4885                                   TIZEN_WS_SHELL_ERROR_PERMISSION_DENIED);
4886         return;
4887      }
4888
4889    /* to avoid sending a wayland error after tzsh ERROR_NONE for every cases
4890     * such as invalid object or no memory error, tzsh ERROR_NONE should be sent
4891     * first to clients without privilege problem.
4892     */
4893    tizen_ws_shell_send_error(res_tzsh, TIZEN_WS_SHELL_ERROR_NONE);
4894
4895    tzsh = wl_resource_get_user_data(res_tzsh);
4896    if (!tzsh)
4897      {
4898         wl_resource_post_error
4899           (res_tzsh,
4900            WL_DISPLAY_ERROR_INVALID_OBJECT,
4901            "Invalid res_tzsh's user data");
4902         return;
4903      }
4904
4905    cp = _e_policy_wl_e_pixmap_get_from_id(client, surf_id);
4906    if (!cp)
4907      {
4908         if (role == TZSH_SRV_ROLE_INDICATOR)
4909           cp = e_pixmap_new(E_PIXMAP_TYPE_NONE, 0);
4910
4911         if (!cp)
4912           {
4913              wl_resource_post_error
4914                (res_tzsh,
4915                 WL_DISPLAY_ERROR_INVALID_OBJECT,
4916                 "Invalid surface id");
4917              return;
4918           }
4919      }
4920
4921    ec = e_pixmap_client_get(cp);
4922    if (!ec)
4923      {
4924         if (role == TZSH_SRV_ROLE_INDICATOR)
4925           {
4926              ec = e_client_new(cp, 0, 1);
4927              if (ec) ec->ignored = 1;
4928           }
4929      }
4930
4931    if (ec)
4932      {
4933         if (!_e_policy_wl_e_client_is_valid(ec))
4934           {
4935              wl_resource_post_error
4936                (res_tzsh,
4937                 WL_DISPLAY_ERROR_INVALID_OBJECT,
4938                 "Invalid surface id");
4939              return;
4940           }
4941      }
4942
4943    res_tzsh_srv = wl_resource_create(client,
4944                                      &tws_service_interface,
4945                                      wl_resource_get_version(res_tzsh),
4946                                      id);
4947    if (!res_tzsh_srv)
4948      {
4949         ERR("Could not create tws_service resource: %m");
4950         wl_client_post_no_memory(client);
4951         return;
4952      }
4953
4954    tzsh_srv = _e_policy_wl_tzsh_srv_add(tzsh,
4955                                         role,
4956                                         res_tzsh_srv,
4957                                         name,
4958                                         cp,
4959                                         ec);
4960    if (!tzsh_srv)
4961      {
4962         ERR("Could not create WS_Shell_Service");
4963         wl_client_post_no_memory(client);
4964         wl_resource_destroy(res_tzsh_srv);
4965         return;
4966      }
4967
4968    wl_resource_set_implementation(res_tzsh_srv,
4969                                   &_tzsh_srv_iface,
4970                                   tzsh_srv,
4971                                   _tzsh_cb_srv_destroy);
4972
4973    if (tzsh_srv->ec && tzsh_srv->ec->maximized)
4974      {
4975         tzsh_srv->ec->maximize_type = E_MAXIMIZE_TYPE_FULLSCREEN;
4976         e_client_maximize(tzsh_srv->ec, tzsh_srv->ec->maximize_type | E_MAXIMIZE_BOTH);
4977      }
4978
4979    if (role == TZSH_SRV_ROLE_QUICKPANEL_SYSTEM_DEFAULT)
4980      e_service_quickpanel_client_add(tzsh_srv->ec, E_SERVICE_QUICKPANEL_TYPE_SYSTEM_DEFAULT);
4981    else if (role == TZSH_SRV_ROLE_QUICKPANEL_CONTEXT_MENU)
4982      e_service_quickpanel_client_add(tzsh_srv->ec, E_SERVICE_QUICKPANEL_TYPE_CONTEXT_MENU);
4983    else if (role == TZSH_SRV_ROLE_QUICKPANEL_APPS_MENU)
4984      e_service_quickpanel_client_add(tzsh_srv->ec, E_SERVICE_QUICKPANEL_TYPE_APPS_MENU);
4985    else if (role == TZSH_SRV_ROLE_VOLUME)
4986      e_service_volume_client_set(tzsh_srv->ec);
4987    else if (role == TZSH_SRV_ROLE_LOCKSCREEN)
4988      e_service_lockscreen_client_set(tzsh_srv->ec);
4989    else if (role == TZSH_SRV_ROLE_SCREENSAVER_MNG)
4990      e_service_scrsaver_client_set(tzsh_srv->ec);
4991    else if (role == TZSH_SRV_ROLE_SCREENSAVER)
4992      e_service_scrsaver_client_set(tzsh_srv->ec);
4993    else if (role == TZSH_SRV_ROLE_INDICATOR)
4994      e_mod_indicator_client_set(tzsh_srv->ec);
4995    else if (role == TZSH_SRV_ROLE_CBHM)
4996      e_service_cbhm_client_set(tzsh_srv->ec);
4997    else if (role == TZSH_SRV_ROLE_SOFTKEY)
4998      e_service_softkey_client_set(tzsh_srv->ec);
4999    else if (role == TZSH_SRV_ROLE_MAGNIFIER)
5000      {
5001         e_magnifier_new();
5002         e_magnifier_owner_set(tzsh_srv->ec);
5003      }
5004    else if (role == TZSH_SRV_ROLE_LAUNCHER)
5005      e_service_launcher_client_set(tzsh_srv->ec);
5006    else if (role == TZSH_SRV_ROLE_TASKBAR)
5007      e_service_taskbar_client_set(tzsh_srv->ec);
5008    else if (role == TZSH_SRV_ROLE_KVM)
5009      e_service_kvm_client_set(tzsh_srv->ec);
5010
5011    e_client_desk_iconify_skip_set(tzsh_srv->ec, EINA_TRUE);
5012 }
5013
5014 // --------------------------------------------------------
5015 // tizen_ws_shell common
5016 // --------------------------------------------------------
5017 EINTERN Eina_Bool
5018 e_tzsh_extension_add(const char *name, E_Policy_Wl_Tzsh_Ext_Hook_Cb cb)
5019 {
5020    E_Policy_Wl_Tzsh_Extension *tzsh_ext;
5021
5022    if (_e_policy_wl_tzsh_extension_get(name))
5023      {
5024         ERR("Already exists the %s extension\n", name);
5025         return EINA_FALSE;
5026      }
5027
5028    tzsh_ext = E_NEW(E_Policy_Wl_Tzsh_Extension, 1);
5029    EINA_SAFETY_ON_NULL_RETURN_VAL(tzsh_ext, EINA_FALSE);
5030
5031    tzsh_ext->name = strndup(name, 512);
5032    tzsh_ext->cb = cb;
5033
5034    polwl->tzsh_extensions = eina_list_append(polwl->tzsh_extensions, tzsh_ext);
5035    ELOGF("TZSH",
5036          "EXTENSION_ADD | name:%s | cb:%p",
5037          NULL,
5038          name, cb);
5039
5040    return EINA_TRUE;
5041 }
5042
5043 EINTERN void
5044 e_tzsh_extension_del(const char *name)
5045 {
5046    E_Policy_Wl_Tzsh_Extension *tzsh_ext;
5047
5048    tzsh_ext = _e_policy_wl_tzsh_extension_get(name);
5049    if (!tzsh_ext)
5050      {
5051         ERR("Cannot find the %s extension\n", name);
5052         return;
5053      }
5054
5055    polwl->tzsh_extensions = eina_list_remove(polwl->tzsh_extensions, tzsh_ext);
5056    memset(tzsh_ext, 0x0, sizeof(E_Policy_Wl_Tzsh_Extension));
5057    E_FREE(tzsh_ext);
5058
5059    ELOGF("TZSH",
5060          "EXTENSION_DEL | name:%s",
5061          NULL,
5062          name);
5063 }
5064
5065 // --------------------------------------------------------
5066 // tizen_ws_shell_interface::region
5067 // --------------------------------------------------------
5068 static void
5069 _tzsh_reg_cb_shell_destroy(struct wl_listener *listener, void *data)
5070 {
5071    E_Policy_Wl_Tzsh_Region *tzsh_reg;
5072
5073    tzsh_reg = container_of(listener, E_Policy_Wl_Tzsh_Region, destroy_listener);
5074    if (tzsh_reg->destroy_listener.notify)
5075      {
5076         wl_list_remove(&tzsh_reg->destroy_listener.link);
5077         tzsh_reg->destroy_listener.notify = NULL;
5078      }
5079
5080    if (tzsh_reg->res_tzsh_reg)
5081      {
5082         wl_resource_destroy(tzsh_reg->res_tzsh_reg);
5083         tzsh_reg->res_tzsh_reg = NULL;
5084      }
5085 }
5086
5087 static void
5088 _tzsh_reg_iface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzsh_reg)
5089 {
5090    wl_resource_destroy(res_tzsh_reg);
5091 }
5092
5093 static void
5094 _tzsh_reg_iface_cb_add(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzsh_reg, int32_t x, int32_t y, int32_t w, int32_t h)
5095 {
5096    E_Policy_Wl_Tzsh_Region *tzsh_reg;
5097    Eina_Tiler *src;
5098    int area_w = 0, area_h = 0;
5099
5100    tzsh_reg = wl_resource_get_user_data(res_tzsh_reg);
5101    EINA_SAFETY_ON_NULL_RETURN(tzsh_reg);
5102    EINA_SAFETY_ON_NULL_RETURN(tzsh_reg->tiler);
5103
5104    eina_tiler_area_size_get(tzsh_reg->tiler, &area_w, &area_h);
5105    src = eina_tiler_new(area_w, area_h);
5106    eina_tiler_tile_size_set(src, 1, 1);
5107    eina_tiler_rect_add(src, &(Eina_Rectangle){x, y, w, h});
5108    eina_tiler_union(tzsh_reg->tiler, src);
5109    eina_tiler_free(src);
5110 }
5111
5112 static void
5113 _tzsh_reg_iface_cb_subtract(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzsh_reg, int32_t x, int32_t y, int32_t w, int32_t h)
5114 {
5115    E_Policy_Wl_Tzsh_Region *tzsh_reg;
5116    Eina_Tiler *src;
5117    int area_w = 0, area_h = 0;
5118
5119    tzsh_reg = wl_resource_get_user_data(res_tzsh_reg);
5120    EINA_SAFETY_ON_NULL_RETURN(tzsh_reg);
5121    EINA_SAFETY_ON_NULL_RETURN(tzsh_reg->tiler);
5122
5123    eina_tiler_area_size_get(tzsh_reg->tiler, &area_w, &area_h);
5124    src = eina_tiler_new(area_w, area_h);
5125    eina_tiler_tile_size_set(src, 1, 1);
5126    eina_tiler_rect_add(src, &(Eina_Rectangle){x, y, w, h});
5127    eina_tiler_subtract(tzsh_reg->tiler, src);
5128    eina_tiler_free(src);
5129 }
5130
5131 static const struct tws_region_interface _tzsh_reg_iface =
5132 {
5133    _tzsh_reg_iface_cb_destroy,
5134    _tzsh_reg_iface_cb_add,
5135    _tzsh_reg_iface_cb_subtract
5136 };
5137
5138 static void
5139 _tzsh_reg_cb_destroy(struct wl_resource *res_tzsh_reg)
5140 {
5141    E_Policy_Wl_Tzsh_Region *tzsh_reg;
5142
5143    tzsh_reg = wl_resource_get_user_data(res_tzsh_reg);
5144    EINA_SAFETY_ON_NULL_RETURN(tzsh_reg);
5145
5146    if (tzsh_reg->destroy_listener.notify)
5147      {
5148         wl_list_remove(&tzsh_reg->destroy_listener.link);
5149         tzsh_reg->destroy_listener.notify = NULL;
5150      }
5151    eina_tiler_free(tzsh_reg->tiler);
5152
5153    E_FREE(tzsh_reg);
5154 }
5155
5156 static void
5157 _tzsh_iface_cb_reg_create(struct wl_client *client, struct wl_resource *res_tzsh, uint32_t id)
5158 {
5159    E_Policy_Wl_Tzsh *tzsh;
5160    E_Policy_Wl_Tzsh_Region *tzsh_reg = NULL;
5161    Eina_Tiler *tz = NULL;
5162    struct wl_resource *res_tzsh_reg;
5163    int zw = 0, zh = 0;
5164
5165    tzsh = wl_resource_get_user_data(res_tzsh);
5166    if (!tzsh)
5167      {
5168         wl_resource_post_error
5169           (res_tzsh,
5170            WL_DISPLAY_ERROR_INVALID_OBJECT,
5171            "Invalid res_tzsh's user data");
5172         return;
5173      }
5174
5175    tzsh_reg = E_NEW(E_Policy_Wl_Tzsh_Region, 1);
5176    EINA_SAFETY_ON_NULL_RETURN(tzsh_reg);
5177
5178    e_zone_useful_geometry_get(e_zone_current_get(),
5179                               NULL, NULL, &zw, &zh);
5180
5181    tz = eina_tiler_new(zw, zh);
5182    EINA_SAFETY_ON_NULL_GOTO(tz, err);
5183    tzsh_reg->tiler = tz;
5184
5185    eina_tiler_tile_size_set(tzsh_reg->tiler, 1, 1);
5186
5187    if (!(res_tzsh_reg = wl_resource_create(client,
5188                                            &tws_region_interface,
5189                                            wl_resource_get_version(res_tzsh),
5190                                            id)))
5191      {
5192         ERR("Could not create tws_service resource: %m");
5193         wl_client_post_no_memory(client);
5194         goto err;
5195      }
5196
5197    wl_resource_set_implementation(res_tzsh_reg,
5198                                   &_tzsh_reg_iface,
5199                                   tzsh_reg,
5200                                   _tzsh_reg_cb_destroy);
5201
5202    tzsh_reg->tzsh = tzsh;
5203    tzsh_reg->res_tzsh_reg = res_tzsh_reg;
5204    tzsh_reg->destroy_listener.notify = _tzsh_reg_cb_shell_destroy;
5205
5206    wl_resource_add_destroy_listener(res_tzsh,
5207                                     &tzsh_reg->destroy_listener);
5208    return;
5209
5210 err:
5211    if (tzsh_reg->tiler) eina_tiler_free(tzsh_reg->tiler);
5212    E_FREE(tzsh_reg);
5213 }
5214
5215 // --------------------------------------------------------
5216 // tizen_ws_shell_interface::indicator
5217 // --------------------------------------------------------
5218 static E_Client *
5219 _e_tzsh_indicator_find_topvisible_client(E_Zone *zone)
5220 {
5221    E_Client *ec;
5222    Evas_Object *o;
5223    int ex, ey, ew, eh;
5224
5225    o = evas_object_top_get(e_comp->evas);
5226    for (; o; o = evas_object_below_get(o))
5227      {
5228         ec = evas_object_data_get(o, "E_Client");
5229
5230         /* check e_client and skip e_clients not intersects with zone */
5231         if (!ec) continue;
5232         if (e_object_is_del(E_OBJECT(ec))) continue;
5233         if (e_client_util_ignored_get(ec)) continue;
5234         if (!e_zone_has_ec(zone, ec)) continue;
5235         if (!ec->frame) continue;
5236
5237         if (!ec->visible) continue;
5238         if (ec->visibility.skip) continue;
5239         if ((e_client_visibility_get(ec) != E_VISIBILITY_UNOBSCURED) &&
5240             (e_client_visibility_get(ec) != E_VISIBILITY_PARTIALLY_OBSCURED) &&
5241             (!eina_list_data_find(e_comp->launchscrns, ec)))
5242           continue;
5243
5244         if (e_comp_wl_subsurface_check(ec)) continue;
5245
5246         e_client_geometry_get(ec, &ex, &ey, &ew, &eh);
5247         if (!E_CONTAINS(ex, ey, ew, eh, zone->x, zone->y, zone->w, zone->h))
5248           continue;
5249
5250         return ec;
5251
5252      }
5253
5254    return NULL;
5255 }
5256
5257 EINTERN void
5258 e_tzsh_indicator_srv_property_change_send(E_Client *ec, int angle)
5259 {
5260    int opacity;
5261
5262    if (!ec) return;
5263    if (!_indicator_srv_res)
5264      {
5265         ELOGF("TZ_IND", "NO indicator service", NULL);
5266         return;
5267      }
5268
5269    opacity = ec->indicator.opacity_mode;
5270
5271    ELOGF("TZ_IND", "SEND indicator info. angle:%d, opacity:%d", ec, angle, opacity);
5272    tws_service_indicator_send_property_change(_indicator_srv_res, angle, opacity);
5273 }
5274
5275 EINTERN void
5276 e_tzsh_indicator_srv_property_update(E_Client *ec)
5277 {
5278    E_Client *ec_ind_owner;
5279    if (!_indicator_srv_res) return;
5280
5281    ec_ind_owner = e_mod_indicator_owner_get();
5282    if (ec != ec_ind_owner) return;
5283
5284    if (ec->e.state.rot.ang.next != -1)
5285      e_tzsh_indicator_srv_property_change_send(ec, ec->e.state.rot.ang.next);
5286    else
5287      e_tzsh_indicator_srv_property_change_send(ec, ec->e.state.rot.ang.curr);
5288 }
5289
5290 EINTERN void
5291 e_tzsh_indicator_srv_ower_win_update(E_Zone *zone)
5292 {
5293    E_Client *ec = NULL;
5294    E_Client *ec_cur_owner = NULL;
5295
5296    if (!zone) return;
5297    if (!_indicator_srv_res) return;
5298
5299    ec_cur_owner = e_mod_indicator_owner_get();
5300    ec = _e_tzsh_indicator_find_topvisible_client(zone);
5301
5302    if (ec != ec_cur_owner)
5303      {
5304         ELOGF("TZ_IND", "Changed OWNER. win:%zx, state:%d, opacity:%d, vtype:%d", NULL, e_client_util_win_get(ec),
5305               ec ? ec->indicator.state:-1, ec ? ec->indicator.opacity_mode:-1, ec ? ec->indicator.visible_type:-1);
5306         e_mod_indicator_owner_set(ec);
5307
5308         if (ec && !ec->e.state.rot.pending_show)
5309           {
5310              ELOGF("TZ_IND", "Property Update. name:%s curr:%d, next:%d", NULL, ec->icccm.name?:"NULL",
5311                    ec->e.state.rot.ang.curr, ec->e.state.rot.ang.next);
5312              e_tzsh_indicator_srv_property_update(ec);
5313           }
5314      }
5315 }
5316
5317 // --------------------------------------------------------
5318 // tizen_ws_shell_interface::quickpanel
5319 // --------------------------------------------------------
5320 static void
5321 _tzsh_client_data_quickpanel_type_set(E_Policy_Wl_Tzsh_Client_Data_Quickpanel *quickpanel_client, E_Quickpanel_Type type)
5322 {
5323    if (quickpanel_client)
5324      quickpanel_client->type = type;
5325 }
5326
5327 static E_Quickpanel_Type
5328 _tzsh_client_data_quickpanel_type_get(E_Policy_Wl_Tzsh_Client_Data_Quickpanel *quickpanel_client)
5329 {
5330    if (!quickpanel_client)
5331      return E_QUICKPANEL_TYPE_UNKNOWN;
5332    else
5333      return quickpanel_client->type;
5334 }
5335
5336 static void
5337 _e_tzsh_qp_state_change_send(struct wl_resource *res_tzsh_client, int type, int value)
5338 {
5339    struct wl_array states;
5340    E_Tzsh_QP_Event *ev;
5341
5342    if (!res_tzsh_client) return;
5343
5344    wl_array_init(&states);
5345    ev = wl_array_add(&states, sizeof(E_Tzsh_QP_Event));
5346    if (!ev) return;
5347
5348    ev->type = type;
5349    ev->val = value;
5350
5351    tws_quickpanel_send_state_changed(res_tzsh_client, &states);
5352
5353    wl_array_release(&states);
5354 }
5355
5356 static Eina_Bool
5357 _e_tzsh_qp_client_data_type_check(E_Policy_Wl_Tzsh_Client *tzsh_client, E_Quickpanel_Type type)
5358 {
5359    E_Policy_Wl_Tzsh_Client_Data_Quickpanel *tzsh_client_quickpanel;
5360
5361    if (!tzsh_client)
5362      return EINA_FALSE;
5363
5364    if (tzsh_client->handle_type != TZSH_CLIENT_HANDLE_TYPE_QUICKPANEL)
5365      return EINA_FALSE;
5366
5367    tzsh_client_quickpanel = (E_Policy_Wl_Tzsh_Client_Data_Quickpanel*)tzsh_client->client_data;
5368    if (!tzsh_client_quickpanel)
5369      return EINA_FALSE;
5370
5371    if (_tzsh_client_data_quickpanel_type_get(tzsh_client_quickpanel) != type)
5372      return EINA_FALSE;
5373
5374    return EINA_TRUE;
5375 }
5376
5377 E_API void
5378 e_tzsh_qp_state_visible_update(E_Client *ec, Eina_Bool vis, E_Quickpanel_Type type)
5379 {
5380    E_Policy_Wl_Tzsh_Client *tzsh_client;
5381    Eina_List *l;
5382    int val;
5383
5384    if (!ec) return;
5385    if (e_object_is_del(E_OBJECT(ec))) return;
5386
5387    EINA_LIST_FOREACH(polwl->tzsh_clients, l, tzsh_client)
5388      {
5389         /* check for type of qp */
5390         if (!_e_tzsh_qp_client_data_type_check(tzsh_client, type))
5391           continue;
5392         if (!tzsh_client->tzsh) continue;
5393         if (!tzsh_client->ec) continue;
5394
5395         if (tzsh_client->ep == ec->pixmap)
5396           {
5397              if (tzsh_client->ec != ec)
5398                {
5399                   ELOGF("TZSH",
5400                         "CRI ERR!!|tzsh_client_ep:%8p|tzsh_client_ec:%8p|tzsh_client:%8p|tzsh:%8p",
5401                         ec,
5402                         tzsh_client->ep,
5403                         tzsh_client->ec,
5404                         tzsh_client,
5405                         tzsh_client->tzsh);
5406                   continue;
5407                }
5408
5409              val = vis ? TWS_QUICKPANEL_STATE_VALUE_VISIBLE_SHOW : TWS_QUICKPANEL_STATE_VALUE_VISIBLE_HIDE;
5410              _e_tzsh_qp_state_change_send(tzsh_client->res_tzsh_client,
5411                                           TWS_QUICKPANEL_STATE_TYPE_VISIBILITY,
5412                                           val);
5413           }
5414      }
5415 }
5416
5417 EINTERN void
5418 e_tzsh_qp_state_scrollable_update(E_Client *ec, Eina_Bool scrollable, E_Quickpanel_Type type)
5419 {
5420    E_Policy_Wl_Tzsh_Client *tzsh_client;
5421    Eina_List *l;
5422    int val;
5423
5424    if (!ec) return;
5425    if (e_object_is_del(E_OBJECT(ec))) return;
5426
5427    EINA_LIST_FOREACH(polwl->tzsh_clients, l, tzsh_client)
5428      {
5429         /* check for type of qp */
5430         if (!_e_tzsh_qp_client_data_type_check(tzsh_client, type))
5431           continue;
5432         if (!tzsh_client->tzsh) continue;
5433         if (!tzsh_client->ec) continue;
5434
5435         if (tzsh_client->ep == ec->pixmap)
5436           {
5437              if (tzsh_client->ec != ec)
5438                {
5439                   ELOGF("TZSH",
5440                         "CRI ERR!!|tzsh_client_ep:%8p|tzsh_client_ec:%8p|tzsh_client:%8p|tzsh:%8p",
5441                         ec,
5442                         tzsh_client->ep,
5443                         tzsh_client->ec,
5444                         tzsh_client,
5445                         tzsh_client->tzsh);
5446                   continue;
5447                }
5448
5449              val = scrollable ? TWS_QUICKPANEL_STATE_VALUE_SCROLLABLE_SET : TWS_QUICKPANEL_STATE_VALUE_SCROLLABLE_UNSET;
5450              _e_tzsh_qp_state_change_send(tzsh_client->res_tzsh_client,
5451                                           TWS_QUICKPANEL_STATE_TYPE_SCROLLABLE,
5452                                           val);
5453           }
5454      }
5455 }
5456
5457 E_API void
5458 e_tzsh_qp_state_orientation_update(E_Client *ec, int ridx, E_Quickpanel_Type type)
5459 {
5460    E_Policy_Wl_Tzsh_Client *tzsh_client;
5461    Eina_List *l;
5462    int val;
5463
5464    if (!ec) return;
5465    if (e_object_is_del(E_OBJECT(ec))) return;
5466
5467    EINA_LIST_FOREACH(polwl->tzsh_clients, l, tzsh_client)
5468      {
5469         /* check for type of qp */
5470         if (!_e_tzsh_qp_client_data_type_check(tzsh_client, type))
5471           continue;
5472         if (!tzsh_client->tzsh) continue;
5473         if (!tzsh_client->ec) continue;
5474
5475         if (tzsh_client->ep == ec->pixmap)
5476           {
5477              if (tzsh_client->ec != ec)
5478                {
5479                   ELOGF("TZSH",
5480                         "CRI ERR!!|tzsh_client_ep:%8p|tzsh_client_ec:%8p|tzsh_client:%8p|tzsh:%8p",
5481                         ec,
5482                         tzsh_client->ep,
5483                         tzsh_client->ec,
5484                         tzsh_client,
5485                         tzsh_client->tzsh);
5486                   continue;
5487                }
5488
5489              val = TWS_QUICKPANEL_STATE_VALUE_ORIENTATION_0 + ridx;
5490              _e_tzsh_qp_state_change_send(tzsh_client->res_tzsh_client,
5491                                           TWS_QUICKPANEL_STATE_TYPE_ORIENTATION,
5492                                           val);
5493           }
5494      }
5495 }
5496
5497 static void
5498 _tzsh_qp_iface_cb_release(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzsh_qp)
5499 {
5500    wl_resource_destroy(res_tzsh_qp);
5501 }
5502
5503 static E_Quickpanel_Type
5504 _e_tzsh_qp_type_get(E_Policy_Wl_Tzsh_Client *tzsh_client)
5505 {
5506    E_Policy_Wl_Tzsh_Client_Data_Quickpanel *tzsh_client_quickpanel;
5507    tzsh_client_quickpanel = (E_Policy_Wl_Tzsh_Client_Data_Quickpanel*)tzsh_client->client_data;
5508    if (!tzsh_client_quickpanel)
5509      return E_QUICKPANEL_TYPE_UNKNOWN;
5510    else
5511      return _tzsh_client_data_quickpanel_type_get(tzsh_client_quickpanel);
5512 }
5513
5514
5515 static void
5516 _tzsh_qp_iface_cb_show(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzsh_qp)
5517 {
5518    E_Policy_Wl_Tzsh_Client *tzsh_client;
5519    E_Client *ec;
5520
5521    ELOGF("TZ_QUICKPANEL", "Request to Show Quickpanel", NULL);
5522
5523    tzsh_client = wl_resource_get_user_data(res_tzsh_qp);
5524    EINA_SAFETY_ON_NULL_RETURN(tzsh_client);
5525    EINA_SAFETY_ON_NULL_RETURN(tzsh_client->tzsh);
5526    EINA_SAFETY_ON_NULL_RETURN(tzsh_client->ec);
5527    EINA_SAFETY_ON_TRUE_RETURN(tzsh_client->handle_type != TZSH_CLIENT_HANDLE_TYPE_QUICKPANEL);
5528
5529    E_Quickpanel_Type qp_type = _e_tzsh_qp_type_get(tzsh_client);
5530    EINA_SAFETY_ON_TRUE_RETURN(qp_type == E_QUICKPANEL_TYPE_UNKNOWN);
5531
5532    ec = tzsh_client->ec;
5533
5534    if (!eina_list_data_find(polwl->tzsh_clients, tzsh_client))
5535      return;
5536
5537    e_qp_client_show(ec, qp_type);
5538 }
5539
5540 static void
5541 _tzsh_qp_iface_cb_hide(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzsh_qp)
5542 {
5543    E_Policy_Wl_Tzsh_Client *tzsh_client;
5544    E_Client *ec;
5545
5546    ELOGF("TZ_QUICKPANEL", "Request to Hide Quickpanel", NULL);
5547
5548    tzsh_client = wl_resource_get_user_data(res_tzsh_qp);
5549    EINA_SAFETY_ON_NULL_RETURN(tzsh_client);
5550    EINA_SAFETY_ON_NULL_RETURN(tzsh_client->tzsh);
5551    EINA_SAFETY_ON_NULL_RETURN(tzsh_client->ec);
5552    EINA_SAFETY_ON_TRUE_RETURN(tzsh_client->handle_type != TZSH_CLIENT_HANDLE_TYPE_QUICKPANEL);
5553
5554    E_Quickpanel_Type qp_type = _e_tzsh_qp_type_get(tzsh_client);
5555    EINA_SAFETY_ON_TRUE_RETURN(qp_type == E_QUICKPANEL_TYPE_UNKNOWN);
5556
5557    ec = tzsh_client->ec;
5558
5559    if (!eina_list_data_find(polwl->tzsh_clients, tzsh_client))
5560      return;
5561
5562    e_qp_client_hide(ec, qp_type);
5563 }
5564
5565 static void
5566 _tzsh_qp_iface_cb_enable(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzsh_qp)
5567 {
5568    E_Policy_Wl_Tzsh_Client *tzsh_client;
5569    E_Client *ec;
5570
5571    ELOGF("TZ_QUICKPANEL", "Request to Set scrollable state of Quickpanel to 1", NULL);
5572
5573    tzsh_client = wl_resource_get_user_data(res_tzsh_qp);
5574    EINA_SAFETY_ON_NULL_RETURN(tzsh_client);
5575    EINA_SAFETY_ON_NULL_RETURN(tzsh_client->tzsh);
5576    EINA_SAFETY_ON_NULL_RETURN(tzsh_client->ec);
5577    EINA_SAFETY_ON_TRUE_RETURN(tzsh_client->handle_type != TZSH_CLIENT_HANDLE_TYPE_QUICKPANEL);
5578
5579    E_Quickpanel_Type qp_type = _e_tzsh_qp_type_get(tzsh_client);
5580    EINA_SAFETY_ON_TRUE_RETURN(qp_type == E_QUICKPANEL_TYPE_UNKNOWN);
5581
5582    ec = tzsh_client->ec;
5583
5584    if (!eina_list_data_find(polwl->tzsh_clients, tzsh_client))
5585      return;
5586
5587    e_qp_client_scrollable_state_set(ec, qp_type, E_QUICKPANEL_CLIENT_SCROLL_STATE_SET);
5588 }
5589
5590 static void
5591 _tzsh_qp_iface_cb_disable(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzsh_qp)
5592 {
5593    E_Policy_Wl_Tzsh_Client *tzsh_client;
5594    E_Client *ec;
5595
5596    ELOGF("TZ_QUICKPANEL", "Request to Set scrollable state of Quickpanel to 0", NULL);
5597
5598    tzsh_client = wl_resource_get_user_data(res_tzsh_qp);
5599    EINA_SAFETY_ON_NULL_RETURN(tzsh_client);
5600    EINA_SAFETY_ON_NULL_RETURN(tzsh_client->tzsh);
5601    EINA_SAFETY_ON_NULL_RETURN(tzsh_client->ec);
5602    EINA_SAFETY_ON_TRUE_RETURN(tzsh_client->handle_type != TZSH_CLIENT_HANDLE_TYPE_QUICKPANEL);
5603
5604    E_Quickpanel_Type qp_type = _e_tzsh_qp_type_get(tzsh_client);
5605    EINA_SAFETY_ON_TRUE_RETURN(qp_type == E_QUICKPANEL_TYPE_UNKNOWN);
5606
5607    ec = tzsh_client->ec;
5608
5609    if (!eina_list_data_find(polwl->tzsh_clients, tzsh_client))
5610      return;
5611
5612    e_qp_client_scrollable_state_set(ec, qp_type, E_QUICKPANEL_CLIENT_SCROLL_STATE_UNSET);
5613 }
5614
5615 static void
5616 _tzsh_qp_iface_cb_state_get(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzsh_qp, int32_t type)
5617 {
5618    E_Policy_Wl_Tzsh_Client *tzsh_client;
5619    E_Client *ec;
5620    Eina_Bool vis;
5621    E_Quickpanel_Client_Scroll_State scrollable;
5622    int ridx;
5623    int val = TWS_QUICKPANEL_STATE_VALUE_UNKNOWN;
5624
5625    tzsh_client = wl_resource_get_user_data(res_tzsh_qp);
5626    EINA_SAFETY_ON_NULL_RETURN(tzsh_client);
5627    EINA_SAFETY_ON_NULL_RETURN(tzsh_client->tzsh);
5628    EINA_SAFETY_ON_NULL_RETURN(tzsh_client->ec);
5629    EINA_SAFETY_ON_TRUE_RETURN(tzsh_client->handle_type != TZSH_CLIENT_HANDLE_TYPE_QUICKPANEL);
5630
5631    E_Quickpanel_Type qp_type = _e_tzsh_qp_type_get(tzsh_client);
5632    EINA_SAFETY_ON_TRUE_RETURN(qp_type == E_QUICKPANEL_TYPE_UNKNOWN);
5633
5634    ec = tzsh_client->ec;
5635
5636    if (!eina_list_data_find(polwl->tzsh_clients, tzsh_client))
5637      return;
5638
5639    switch (type)
5640      {
5641       case TWS_QUICKPANEL_STATE_TYPE_VISIBILITY:
5642         val = TWS_QUICKPANEL_STATE_VALUE_VISIBLE_HIDE;
5643         vis = e_qp_visible_get(ec, qp_type);
5644         if (vis) val = TWS_QUICKPANEL_STATE_VALUE_VISIBLE_SHOW;
5645         break;
5646       case TWS_QUICKPANEL_STATE_TYPE_SCROLLABLE:
5647         scrollable = e_qp_client_scrollable_state_get(ec, qp_type);
5648         if (scrollable == E_QUICKPANEL_CLIENT_SCROLL_STATE_UNSET)
5649           val = TWS_QUICKPANEL_STATE_VALUE_SCROLLABLE_UNSET;
5650         else if (scrollable == E_QUICKPANEL_CLIENT_SCROLL_STATE_SET)
5651           val = TWS_QUICKPANEL_STATE_VALUE_SCROLLABLE_SET;
5652         else if (scrollable == E_QUICKPANEL_CLIENT_SCROLL_STATE_RETAIN)
5653           val = TWS_QUICKPANEL_STATE_VALUE_SCROLLABLE_RETAIN;
5654         else
5655           val = TWS_QUICKPANEL_STATE_VALUE_SCROLLABLE_SET;
5656         break;
5657       case TWS_QUICKPANEL_STATE_TYPE_ORIENTATION:
5658         ridx = e_qp_orientation_get(ec, qp_type);
5659         val = TWS_QUICKPANEL_STATE_VALUE_ORIENTATION_0 + ridx;
5660         break;
5661       default:
5662         break;
5663      }
5664
5665    tws_quickpanel_send_state_get_done(res_tzsh_qp, type, val, 0);
5666 }
5667
5668 static void
5669 _tzsh_qp_iface_cb_type_set(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzsh_qp, uint32_t type)
5670 {
5671    E_Policy_Wl_Tzsh_Client *tzsh_client;
5672    E_Client *ec;
5673
5674    ELOGF("TZ_QUICKPANEL", "Request to Set type of Quickpanel to %d", NULL, type);
5675
5676    tzsh_client = wl_resource_get_user_data(res_tzsh_qp);
5677    EINA_SAFETY_ON_NULL_RETURN(tzsh_client);
5678    EINA_SAFETY_ON_NULL_RETURN(tzsh_client->tzsh);
5679    EINA_SAFETY_ON_NULL_RETURN(tzsh_client->ec);
5680    EINA_SAFETY_ON_TRUE_RETURN(tzsh_client->handle_type != TZSH_CLIENT_HANDLE_TYPE_QUICKPANEL);
5681
5682    E_Policy_Wl_Tzsh_Client_Data_Quickpanel *tzsh_client_quickpanel;
5683    tzsh_client_quickpanel = (E_Policy_Wl_Tzsh_Client_Data_Quickpanel*)tzsh_client->client_data;
5684    EINA_SAFETY_ON_NULL_RETURN(tzsh_client_quickpanel);
5685
5686    E_Quickpanel_Type qp_type = _tzsh_client_data_quickpanel_type_get(tzsh_client_quickpanel);
5687    EINA_SAFETY_ON_TRUE_RETURN(qp_type != E_QUICKPANEL_TYPE_UNKNOWN);
5688
5689    _tzsh_client_data_quickpanel_type_set(tzsh_client_quickpanel, type);
5690
5691    ec = tzsh_client->ec;
5692
5693    if (!eina_list_data_find(polwl->tzsh_clients, tzsh_client))
5694      return;
5695
5696    /* Since various types of qp are supported, one ec can be used for handler for
5697     * two or more qp types. So e_qp_client_add function is called at the callback
5698     * of qp_type_set, because it is easy to add the E_QP_Client instance after setting
5699     * of qp type is completed.
5700     */
5701    e_qp_client_add(ec, type);
5702 }
5703
5704 static void
5705 _tzsh_qp_iface_cb_scrollable_state_set(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzsh_qp, int32_t state)
5706 {
5707    E_Policy_Wl_Tzsh_Client *tzsh_client;
5708    E_Client *ec;
5709
5710    ELOGF("TZ_QUICKPANEL", "Request to Set scrollable state to %d", NULL, state);
5711
5712    tzsh_client = wl_resource_get_user_data(res_tzsh_qp);
5713    EINA_SAFETY_ON_NULL_RETURN(tzsh_client);
5714    EINA_SAFETY_ON_NULL_RETURN(tzsh_client->tzsh);
5715    EINA_SAFETY_ON_NULL_RETURN(tzsh_client->ec);
5716    EINA_SAFETY_ON_TRUE_RETURN(tzsh_client->handle_type != TZSH_CLIENT_HANDLE_TYPE_QUICKPANEL);
5717
5718    E_Quickpanel_Type qp_type = _e_tzsh_qp_type_get(tzsh_client);
5719    EINA_SAFETY_ON_TRUE_RETURN(qp_type == E_QUICKPANEL_TYPE_UNKNOWN);
5720
5721    ec = tzsh_client->ec;
5722    if (!eina_list_data_find(polwl->tzsh_clients, tzsh_client))
5723      return;
5724
5725    if (state == TWS_QUICKPANEL_STATE_VALUE_SCROLLABLE_UNSET)
5726      e_qp_client_scrollable_state_set(ec, qp_type, E_QUICKPANEL_CLIENT_SCROLL_STATE_UNSET);
5727    else if (state == TWS_QUICKPANEL_STATE_VALUE_SCROLLABLE_SET)
5728      e_qp_client_scrollable_state_set(ec, qp_type, E_QUICKPANEL_CLIENT_SCROLL_STATE_SET);
5729    else if (state == TWS_QUICKPANEL_STATE_VALUE_SCROLLABLE_RETAIN)
5730      e_qp_client_scrollable_state_set(ec, qp_type, E_QUICKPANEL_CLIENT_SCROLL_STATE_RETAIN);
5731 }
5732
5733 static const struct tws_quickpanel_interface _tzsh_qp_iface =
5734 {
5735    _tzsh_qp_iface_cb_release,
5736    _tzsh_qp_iface_cb_show,
5737    _tzsh_qp_iface_cb_hide,
5738    _tzsh_qp_iface_cb_enable,
5739    _tzsh_qp_iface_cb_disable,
5740    _tzsh_qp_iface_cb_state_get,
5741    _tzsh_qp_iface_cb_type_set,
5742    _tzsh_qp_iface_cb_scrollable_state_set
5743 };
5744
5745 static void
5746 _tzsh_cb_qp_destroy(struct wl_resource *res_tzsh_qp)
5747 {
5748    E_Policy_Wl_Tzsh_Client *tzsh_client;
5749
5750    tzsh_client = wl_resource_get_user_data(res_tzsh_qp);
5751    EINA_SAFETY_ON_NULL_RETURN(tzsh_client);
5752
5753    E_Quickpanel_Type qp_type =
5754      _tzsh_client_data_quickpanel_type_get((E_Policy_Wl_Tzsh_Client_Data_Quickpanel*)tzsh_client->client_data);
5755    e_qp_client_del(tzsh_client->ec, qp_type);
5756
5757    E_FREE(tzsh_client->client_data);
5758
5759    tzsh_client->res_tzsh_client = NULL;
5760    _e_policy_wl_tzsh_client_del(tzsh_client);
5761 }
5762
5763 static E_Policy_Wl_Tzsh_Client_Data_Quickpanel *
5764 _tzsh_client_data_quickpanel_new(void)
5765 {
5766    E_Policy_Wl_Tzsh_Client_Data_Quickpanel *tzsh_client_quickpanel;
5767
5768    tzsh_client_quickpanel = E_NEW(E_Policy_Wl_Tzsh_Client_Data_Quickpanel, 1);
5769    EINA_SAFETY_ON_NULL_RETURN_VAL(tzsh_client_quickpanel, NULL);
5770
5771    tzsh_client_quickpanel->type = E_QUICKPANEL_TYPE_UNKNOWN;
5772    return tzsh_client_quickpanel;
5773 }
5774
5775 static void
5776 _tzsh_iface_cb_qp_get(struct wl_client *client, struct wl_resource *res_tzsh, uint32_t id, uint32_t surf_id)
5777 {
5778    E_Policy_Wl_Tzsh *tzsh;
5779    E_Policy_Wl_Tzsh_Client *tzsh_client;
5780    struct wl_resource *res_tzsh_qp;
5781    E_Client *ec;
5782    E_Pixmap *cp;
5783
5784    tzsh = wl_resource_get_user_data(res_tzsh);
5785    if (!tzsh)
5786      {
5787         wl_resource_post_error
5788           (res_tzsh,
5789            WL_DISPLAY_ERROR_INVALID_OBJECT,
5790            "Invalid res_tzsh's user data");
5791         return;
5792      }
5793
5794    cp = _e_policy_wl_e_pixmap_get_from_id(client, surf_id);
5795    if (!cp)
5796      {
5797         wl_resource_post_error
5798           (res_tzsh,
5799            WL_DISPLAY_ERROR_INVALID_OBJECT,
5800            "Invalid surface id");
5801         return;
5802      }
5803
5804    ec = e_pixmap_client_get(cp);
5805    if (ec)
5806      {
5807         if (!_e_policy_wl_e_client_is_valid(ec))
5808           {
5809              wl_resource_post_error
5810                (res_tzsh,
5811                 WL_DISPLAY_ERROR_INVALID_OBJECT,
5812                 "Invalid surface id");
5813              return;
5814           }
5815      }
5816
5817    res_tzsh_qp = wl_resource_create(client,
5818                                     &tws_quickpanel_interface,
5819                                     wl_resource_get_version(res_tzsh),
5820                                     id);
5821    if (!res_tzsh_qp)
5822      {
5823         ERR("Could not create tws_quickpanel resource: %m");
5824         wl_client_post_no_memory(client);
5825         return;
5826      }
5827
5828    tzsh_client = _e_policy_wl_tzsh_client_add(tzsh, res_tzsh_qp, cp, ec);
5829    if (!tzsh_client)
5830      {
5831         ERR("Could not create tzsh_client");
5832         wl_client_post_no_memory(client);
5833         return;
5834      }
5835
5836    tzsh_client->handle_type = TZSH_CLIENT_HANDLE_TYPE_QUICKPANEL;
5837    tzsh_client->client_data = _tzsh_client_data_quickpanel_new();
5838    if (!tzsh_client->client_data)
5839      {
5840         ERR("Could not create tzsh_client");
5841         wl_client_post_no_memory(client);
5842         return;
5843      }
5844
5845    /* Since various types of qp are supported, one ec can be used for handler for
5846     * two or more qp types. So e_qp_client_add function is called at the callback
5847     * of qp_type_set, because it is easy to add the E_QP_Client instance after setting
5848     * of qp type is completed.
5849     */
5850    //e_qp_client_add(tzsh->ec);
5851
5852    wl_resource_set_implementation(res_tzsh_qp,
5853                                   &_tzsh_qp_iface,
5854                                   tzsh_client,
5855                                   _tzsh_cb_qp_destroy);
5856 }
5857
5858 static void _tzsh_iface_cb_extension_get(struct wl_client *client, struct wl_resource *res_tzsh, uint32_t id, const char *name)
5859 {
5860    E_Policy_Wl_Tzsh *tzsh;
5861    E_Policy_Wl_Tzsh_Extension *tzsh_ext;
5862    struct wl_resource *res_ext;
5863
5864    tzsh = wl_resource_get_user_data(res_tzsh);
5865    if (!tzsh)
5866      {
5867         wl_resource_post_error
5868           (res_tzsh,
5869            WL_DISPLAY_ERROR_INVALID_OBJECT,
5870            "Invalid res_tzsh's user data");
5871         return;
5872      }
5873
5874    tzsh_ext = _e_policy_wl_tzsh_extension_get(name);
5875    if (!tzsh_ext)
5876       {
5877          ERR("Could not find tzsh_extension(%s)", name);
5878          wl_resource_post_error
5879            (res_tzsh,
5880             WL_DISPLAY_ERROR_INVALID_OBJECT,
5881             "unregistered ext:%s", name);
5882       }
5883    else
5884       {
5885          res_ext = tzsh_ext->cb(client, res_tzsh, id);
5886          if (!res_ext)
5887             {
5888                ERR("Could not create extension(%s) resource", name);
5889                wl_resource_post_error
5890                  (res_tzsh,
5891                   WL_DISPLAY_ERROR_INVALID_OBJECT,
5892                   "Unknown error:%s", name);
5893             }
5894       }
5895 }
5896
5897 // --------------------------------------------------------
5898 // tizen_ws_shell_interface::softkey
5899 // --------------------------------------------------------
5900 static void
5901 _tzsh_softkey_iface_cb_release(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzsh_softkey)
5902 {
5903    wl_resource_destroy(res_tzsh_softkey);
5904 }
5905
5906 static void
5907 _tzsh_softkey_iface_cb_support_check(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzsh_softkey)
5908 {
5909    E_Policy_Wl_Tzsh_Client *tzsh_client;
5910    int support;
5911
5912    ELOGF("TZ_SOFTKEY", "Request to Check supporting softkey", NULL);
5913
5914    tzsh_client = wl_resource_get_user_data(res_tzsh_softkey);
5915    EINA_SAFETY_ON_NULL_RETURN(tzsh_client);
5916    EINA_SAFETY_ON_NULL_RETURN(tzsh_client->tzsh);
5917    EINA_SAFETY_ON_NULL_RETURN(tzsh_client->ec);
5918
5919    if (!eina_list_data_find(polwl->tzsh_clients, tzsh_client))
5920      return;
5921
5922    if (e_config->use_softkey || e_config->use_softkey_service)
5923      support = 1;
5924    else
5925      support = 0;
5926
5927    ELOGF("TZ_SOFTKEY", "Send SUPPORT_CHECK_DONE. support:%d", NULL, support);
5928    tws_softkey_send_support_check_done(res_tzsh_softkey, support);
5929 }
5930
5931 static void
5932 _tzsh_softkey_show(E_Policy_Wl_Tzsh_Client *tzsh_client)
5933 {
5934    E_Zone *zone;
5935    E_Client *ec;
5936
5937    zone = tzsh_client->zone;
5938    if (!zone) return;
5939    ec = tzsh_client->ec;
5940    if (!ec) return;
5941
5942    if (e_config->use_softkey)
5943      {
5944         E_Policy_Softkey *softkey;
5945         softkey = e_policy_softkey_get(zone);
5946         if (softkey)
5947           {
5948              ELOGF("TZ_SOFTKEY", "SHOW softkey", ec);
5949              e_policy_softkey_show(softkey);
5950           }
5951      }
5952
5953    if (e_config->use_softkey_service)
5954      {
5955         E_Service_Softkey *softkey_service;
5956         softkey_service = e_service_softkey_get(zone);
5957         if (softkey_service)
5958           {
5959              ELOGF("TZ_SOFTKEY", "Request to SHOW softkey service. (service:%p)", ec, softkey_service);
5960              e_service_softkey_visible_set(softkey_service, 1);
5961           }
5962         else
5963           {
5964              ELOGF("TZ_SOFTKEY", "There is no softkey service. store show request", ec);
5965              e_service_softkey_store_visible_request(ec, 1);
5966           }
5967      }
5968 }
5969
5970 static void
5971 _tzsh_softkey_iface_cb_show(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzsh_softkey)
5972 {
5973    E_Policy_Wl_Tzsh_Client *tzsh_client;
5974
5975    ELOGF("TZ_SOFTKEY", "Request to Show softkey", NULL);
5976
5977    if (!e_config->use_softkey && !e_config->use_softkey_service)
5978      return;
5979
5980    tzsh_client = wl_resource_get_user_data(res_tzsh_softkey);
5981    EINA_SAFETY_ON_NULL_RETURN(tzsh_client);
5982    EINA_SAFETY_ON_NULL_RETURN(tzsh_client->tzsh);
5983    EINA_SAFETY_ON_NULL_RETURN(tzsh_client->ec);
5984
5985    if (!eina_list_data_find(polwl->tzsh_clients, tzsh_client))
5986      return;
5987
5988    E_Policy_Wl_Tzsh_Client_Data_Softkey *tzsh_client_data_softkey;
5989    tzsh_client_data_softkey = (E_Policy_Wl_Tzsh_Client_Data_Softkey*)tzsh_client->client_data;
5990    EINA_SAFETY_ON_NULL_RETURN(tzsh_client_data_softkey);
5991
5992    if (tzsh_client_data_softkey->show_state == 1)
5993      return;
5994
5995    tzsh_client_data_softkey->show_state = 1;
5996    _tzsh_softkey_show(tzsh_client);
5997 }
5998
5999 static void
6000 _tzsh_softkey_hide(E_Policy_Wl_Tzsh_Client *tzsh_client)
6001 {
6002    E_Zone *zone;
6003    E_Client *ec;
6004
6005    zone = tzsh_client->zone;
6006    if (!zone) return;
6007    ec = tzsh_client->ec;
6008    if (!ec) return;
6009
6010    if (e_config->use_softkey)
6011      {
6012         E_Policy_Softkey *softkey;
6013         softkey = e_policy_softkey_get(zone);
6014         if (softkey)
6015           {
6016              ELOGF("TZ_SOFTKEY", "HIDE softkey", NULL);
6017              e_policy_softkey_hide(softkey);
6018           }
6019      }
6020
6021    if (e_config->use_softkey_service)
6022      {
6023         E_Service_Softkey *softkey_service;
6024         softkey_service = e_service_softkey_get(zone);
6025         if (softkey_service)
6026           {
6027              ELOGF("TZ_SOFTKEY", "Request to HIDE softkey service. (service:%p)", ec, softkey_service);
6028              e_service_softkey_visible_set(softkey_service, 0);
6029           }
6030         else
6031           {
6032              ELOGF("TZ_SOFTKEY", "There is no softkey service. store hide request", ec);
6033              e_service_softkey_store_visible_request(ec, 0);
6034           }
6035      }
6036 }
6037
6038 static void
6039 _tzsh_softkey_iface_cb_hide(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzsh_softkey)
6040 {
6041    E_Policy_Wl_Tzsh_Client *tzsh_client;
6042
6043    ELOGF("TZ_SOFTKEY", "Request to Hide softkey", NULL);
6044
6045    if (!e_config->use_softkey && !e_config->use_softkey_service)
6046      return;
6047
6048    tzsh_client = wl_resource_get_user_data(res_tzsh_softkey);
6049    EINA_SAFETY_ON_NULL_RETURN(tzsh_client);
6050    EINA_SAFETY_ON_NULL_RETURN(tzsh_client->tzsh);
6051    EINA_SAFETY_ON_NULL_RETURN(tzsh_client->ec);
6052
6053    if (!eina_list_data_find(polwl->tzsh_clients, tzsh_client))
6054      return;
6055
6056    E_Policy_Wl_Tzsh_Client_Data_Softkey *tzsh_client_data_softkey;
6057    tzsh_client_data_softkey = (E_Policy_Wl_Tzsh_Client_Data_Softkey*)tzsh_client->client_data;
6058    EINA_SAFETY_ON_NULL_RETURN(tzsh_client_data_softkey);
6059
6060    if (tzsh_client_data_softkey->show_state == 0)
6061      return;
6062
6063    tzsh_client_data_softkey->show_state = 0;
6064    _tzsh_softkey_hide(tzsh_client);
6065 }
6066
6067 static void
6068 _tzsh_softkey_iface_cb_state_set(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzsh_softkey, int32_t type, int32_t val)
6069 {
6070    E_Policy_Wl_Tzsh_Client *tzsh_client;
6071    E_Policy_Softkey_Expand expand;
6072    E_Policy_Softkey_Opacity opacity;
6073
6074    ELOGF("TZ_SOFTKEY", "Request to Set state (tz_type:%d, tz_val:%d)", NULL, type, val);
6075
6076    if (!e_config->use_softkey && !e_config->use_softkey_service)
6077      return;
6078
6079    tzsh_client = wl_resource_get_user_data(res_tzsh_softkey);
6080    EINA_SAFETY_ON_NULL_RETURN(tzsh_client);
6081    EINA_SAFETY_ON_NULL_RETURN(tzsh_client->tzsh);
6082    EINA_SAFETY_ON_NULL_RETURN(tzsh_client->ec);
6083
6084    if (!eina_list_data_find(polwl->tzsh_clients, tzsh_client))
6085      return;
6086
6087    if (e_config->use_softkey)
6088      {
6089         E_Policy_Softkey *softkey;
6090         softkey = e_policy_softkey_get(tzsh_client->zone);
6091         if (!softkey) return;
6092
6093         switch (type)
6094           {
6095            case TWS_SOFTKEY_STATE_EXPAND:
6096               if (val == TWS_SOFTKEY_STATE_EXPAND_ON)
6097                 expand = E_POLICY_SOFTKEY_EXPAND_ON;
6098               else
6099                 expand = E_POLICY_SOFTKEY_EXPAND_OFF;
6100
6101               ELOGF("TZ_SOFTKEY", "Set EXPAND state to %d", NULL, expand);
6102               e_policy_softkey_expand_set(softkey, expand);
6103               break;
6104
6105            case TWS_SOFTKEY_STATE_OPACITY:
6106               if (val == TWS_SOFTKEY_STATE_OPACITY_TRANSPARENT)
6107                 opacity = E_POLICY_SOFTKEY_OPACITY_TRANSPARENT;
6108               else
6109                 opacity = E_POLICY_SOFTKEY_OPACITY_OPAQUE;
6110
6111               ELOGF("TZ_SOFTKEY", "Set OPACITY state to %d", NULL, opacity);
6112               e_policy_softkey_opacity_set(softkey, opacity);
6113               break;
6114
6115            default:
6116               break;
6117           }
6118      }
6119
6120    if (e_config->use_softkey_service)
6121      {
6122         E_Service_Softkey *softkey_service;
6123
6124         softkey_service = e_service_softkey_get(tzsh_client->zone);
6125         if (!softkey_service) return;
6126
6127         switch (type)
6128           {
6129            case TWS_SOFTKEY_STATE_EXPAND:
6130               if (val == TWS_SOFTKEY_STATE_EXPAND_ON)
6131                 expand = E_POLICY_SOFTKEY_EXPAND_ON;
6132               else
6133                 expand = E_POLICY_SOFTKEY_EXPAND_OFF;
6134
6135               ELOGF("TZ_SOFTKEY", "Request to Change EXPAND state to %d. (service:%p)", NULL, expand, softkey_service);
6136               e_service_softkey_expand_set(softkey_service, expand);
6137               break;
6138
6139            case TWS_SOFTKEY_STATE_OPACITY:
6140               if (val == TWS_SOFTKEY_STATE_OPACITY_TRANSPARENT)
6141                 opacity = E_POLICY_SOFTKEY_OPACITY_TRANSPARENT;
6142               else
6143                 opacity = E_POLICY_SOFTKEY_OPACITY_OPAQUE;
6144
6145               ELOGF("TZ_SOFTKEY", "Request to Change OPACITY state to %d. (service:%p)", NULL, opacity, softkey_service);
6146               e_service_softkey_opacity_set(softkey_service, opacity);
6147               break;
6148
6149            default:
6150               break;
6151           }
6152      }
6153 }
6154
6155 static void
6156 _tzsh_softkey_iface_cb_state_get(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzsh_softkey, int32_t type)
6157 {
6158    E_Policy_Wl_Tzsh_Client *tzsh_client;
6159    E_Policy_Softkey_Expand expand;
6160    E_Policy_Softkey_Opacity opacity;
6161    E_Zone *zone;
6162    int visible;
6163    int val;
6164
6165    ELOGF("TZ_SOFTKEY", "Request to Get state (tz_type:%d)", NULL, type);
6166
6167    if (!e_config->use_softkey && !e_config->use_softkey_service)
6168      return;
6169
6170    tzsh_client = wl_resource_get_user_data(res_tzsh_softkey);
6171    EINA_SAFETY_ON_NULL_RETURN(tzsh_client);
6172    EINA_SAFETY_ON_NULL_RETURN(tzsh_client->tzsh);
6173    EINA_SAFETY_ON_NULL_RETURN(tzsh_client->ec);
6174    zone = tzsh_client->zone;
6175    EINA_SAFETY_ON_NULL_RETURN(zone);
6176
6177    if (!eina_list_data_find(polwl->tzsh_clients, tzsh_client))
6178      return;
6179
6180    if (e_config->use_softkey)
6181      {
6182         E_Policy_Softkey *softkey;
6183         softkey = e_policy_softkey_get(zone);
6184         if (!softkey) return;
6185
6186         switch (type)
6187           {
6188            case TWS_SOFTKEY_STATE_VISIBLE:
6189               visible = e_policy_softkey_visible_get(softkey);
6190               if (visible)
6191                 val = TWS_SOFTKEY_STATE_VISIBLE_SHOW;
6192               else
6193                 val = TWS_SOFTKEY_STATE_VISIBLE_HIDE;
6194
6195               ELOGF("TZ_SOFTKEY", "Send current VISIBLE state: %d (tz_val:%d)", NULL, visible, val);
6196               tws_softkey_send_state_get_done(res_tzsh_softkey, type, val, 0);
6197               break;
6198
6199            case TWS_SOFTKEY_STATE_EXPAND:
6200               e_policy_softkey_expand_get(softkey, &expand);
6201               if (expand == E_POLICY_SOFTKEY_EXPAND_ON)
6202                 val = TWS_SOFTKEY_STATE_EXPAND_ON;
6203               else
6204                 val = TWS_SOFTKEY_STATE_EXPAND_OFF;
6205
6206               ELOGF("TZ_SOFTKEY", "Send current EXPAND state: %d (tz_val:%d)", NULL, expand, val);
6207               tws_softkey_send_state_get_done(res_tzsh_softkey, type, val, 0);
6208               break;
6209
6210            case TWS_SOFTKEY_STATE_OPACITY:
6211               e_policy_softkey_opacity_get(softkey, &opacity);
6212               if (opacity == E_POLICY_SOFTKEY_OPACITY_TRANSPARENT)
6213                 val = TWS_SOFTKEY_STATE_OPACITY_TRANSPARENT;
6214               else
6215                 val = TWS_SOFTKEY_STATE_OPACITY_OPAQUE;
6216
6217               ELOGF("TZ_SOFTKEY", "Send current OPACITY state: %d (tz_val:%d)", NULL, opacity, val);
6218               tws_softkey_send_state_get_done(res_tzsh_softkey, type, val, 0);
6219               break;
6220
6221            default:
6222               break;
6223           }
6224      }
6225
6226    if (e_config->use_softkey_service)
6227      {
6228         E_Service_Softkey *softkey_service;
6229         softkey_service = e_service_softkey_get(zone);
6230         if (!softkey_service) return;
6231
6232         switch (type)
6233           {
6234            case TWS_SOFTKEY_STATE_VISIBLE:
6235               visible = e_service_softkey_visible_get(softkey_service);
6236               if (visible)
6237                 val = TWS_SOFTKEY_STATE_VISIBLE_SHOW;
6238               else
6239                 val = TWS_SOFTKEY_STATE_VISIBLE_HIDE;
6240
6241               ELOGF("TZ_SOFTKEY", "Send service's current VISIBLE state: %d (tz_val:%d)", NULL, visible, val);
6242               tws_softkey_send_state_get_done(res_tzsh_softkey, type, val, 0);
6243               break;
6244
6245            case TWS_SOFTKEY_STATE_EXPAND:
6246               e_service_softkey_expand_get(softkey_service, &expand);
6247               if (expand == E_POLICY_SOFTKEY_EXPAND_ON)
6248                 val = TWS_SOFTKEY_STATE_EXPAND_ON;
6249               else
6250                 val = TWS_SOFTKEY_STATE_EXPAND_OFF;
6251
6252               ELOGF("TZ_SOFTKEY", "Send service's current EXPAND state: %d (tz_val:%d)", NULL, expand, val);
6253               tws_softkey_send_state_get_done(res_tzsh_softkey, type, val, 0);
6254               break;
6255
6256            case TWS_SOFTKEY_STATE_OPACITY:
6257               e_service_softkey_opacity_get(softkey_service, &opacity);
6258               if (opacity == E_POLICY_SOFTKEY_OPACITY_TRANSPARENT)
6259                 val = TWS_SOFTKEY_STATE_OPACITY_TRANSPARENT;
6260               else
6261                 val = TWS_SOFTKEY_STATE_OPACITY_OPAQUE;
6262
6263               ELOGF("TZ_SOFTKEY", "Send service's current OPACITY state: %d (tz_val:%d)", NULL, opacity, val);
6264               tws_softkey_send_state_get_done(res_tzsh_softkey, type, val, 0);
6265               break;
6266
6267            default:
6268               break;
6269           }
6270      }
6271 }
6272
6273 static const struct tws_softkey_interface _tzsh_softkey_iface =
6274 {
6275    _tzsh_softkey_iface_cb_release,
6276    _tzsh_softkey_iface_cb_support_check,
6277    _tzsh_softkey_iface_cb_show,
6278    _tzsh_softkey_iface_cb_hide,
6279    _tzsh_softkey_iface_cb_state_set,
6280    _tzsh_softkey_iface_cb_state_get
6281 };
6282
6283 static E_Policy_Wl_Tzsh_Client_Data_Softkey *
6284 _tzsh_client_data_softkey_new(void)
6285 {
6286    E_Policy_Wl_Tzsh_Client_Data_Softkey *tzsh_client_data_softkey;
6287
6288    tzsh_client_data_softkey = E_NEW(E_Policy_Wl_Tzsh_Client_Data_Softkey, 1);
6289    EINA_SAFETY_ON_NULL_RETURN_VAL(tzsh_client_data_softkey, NULL);
6290
6291    tzsh_client_data_softkey->show_state = 1;
6292    return tzsh_client_data_softkey;
6293 }
6294
6295 static void
6296 _tzsh_cb_softkey_destroy(struct wl_resource *res_tzsh_softkey)
6297 {
6298    E_Policy_Wl_Tzsh_Client *tzsh_client;
6299
6300    tzsh_client = wl_resource_get_user_data(res_tzsh_softkey);
6301    EINA_SAFETY_ON_NULL_RETURN(tzsh_client);
6302
6303    E_Policy_Wl_Tzsh_Client_Data_Softkey *tzsh_client_data_softkey;
6304    tzsh_client_data_softkey = (E_Policy_Wl_Tzsh_Client_Data_Softkey*)tzsh_client->client_data;
6305    if (tzsh_client_data_softkey)
6306      {
6307         if (tzsh_client_data_softkey->show_state == 0)
6308           {
6309              ELOGF("TZ_SOFTKEY", "Request to Show softkey by destroying client", NULL);
6310              _tzsh_softkey_show(tzsh_client);
6311           }
6312      }
6313    E_FREE(tzsh_client->client_data);
6314
6315    tzsh_client->res_tzsh_client = NULL;
6316    _e_policy_wl_tzsh_client_del(tzsh_client);
6317 }
6318
6319
6320 static void
6321 _tzsh_iface_cb_softkey_get(struct wl_client *client, struct wl_resource *res_tzsh, uint32_t id, uint32_t surf_id)
6322 {
6323    E_Policy_Wl_Tzsh *tzsh;
6324    E_Policy_Wl_Tzsh_Client *tzsh_client;
6325    struct wl_resource *res_tzsh_softkey;
6326    E_Client *ec;
6327    E_Pixmap *cp;
6328    pid_t pid;
6329    uid_t uid;
6330
6331    tzsh = wl_resource_get_user_data(res_tzsh);
6332    if (!tzsh)
6333      {
6334         wl_resource_post_error
6335            (res_tzsh,
6336             WL_DISPLAY_ERROR_INVALID_OBJECT,
6337             "Invalid res_tzsh's user data");
6338         return;
6339      }
6340
6341    wl_client_get_credentials(client, &pid, &uid, NULL);
6342    if (!e_security_privilege_check(pid, uid, E_PRIVILEGE_SOFTKEY))
6343      {
6344         ERR("Could not get privilege of resource: %m");
6345         tizen_ws_shell_send_error(tzsh->res_tzsh, TIZEN_WS_SHELL_ERROR_PERMISSION_DENIED);
6346         return;
6347      }
6348    else
6349      tizen_ws_shell_send_error(tzsh->res_tzsh, TIZEN_WS_SHELL_ERROR_NONE);
6350
6351    cp = _e_policy_wl_e_pixmap_get_from_id(client, surf_id);
6352    if (!cp)
6353      {
6354         wl_resource_post_error
6355            (res_tzsh,
6356             WL_DISPLAY_ERROR_INVALID_OBJECT,
6357             "Invalid surface id");
6358         return;
6359      }
6360
6361    ec = e_pixmap_client_get(cp);
6362    if (ec)
6363      {
6364         if (!_e_policy_wl_e_client_is_valid(ec))
6365           {
6366              wl_resource_post_error
6367                 (res_tzsh,
6368                  WL_DISPLAY_ERROR_INVALID_OBJECT,
6369                  "Invalid surface id");
6370              return;
6371           }
6372      }
6373
6374    res_tzsh_softkey = wl_resource_create(client,
6375                                          &tws_softkey_interface,
6376                                          wl_resource_get_version(res_tzsh),
6377                                          id);
6378    if (!res_tzsh_softkey)
6379      {
6380         ERR("Could not create tws_softkey resource: %m");
6381         wl_client_post_no_memory(client);
6382         return;
6383      }
6384
6385    tzsh_client = _e_policy_wl_tzsh_client_add(tzsh, res_tzsh_softkey, cp, ec);
6386    if (!tzsh_client)
6387      {
6388         ERR("Could not create tzsh_client");
6389         wl_client_post_no_memory(client);
6390         return;
6391      }
6392
6393    tzsh_client->handle_type = TZSH_CLIENT_HANDLE_TYPE_SOFTKEY;
6394    tzsh_client->client_data = _tzsh_client_data_softkey_new();
6395    if (!tzsh_client->client_data)
6396      {
6397         ERR("Could not create tzsh_client");
6398         _e_policy_wl_tzsh_client_del(tzsh_client);
6399         wl_resource_destroy(res_tzsh_softkey);
6400         wl_client_post_no_memory(client);
6401         return;
6402      }
6403
6404    wl_resource_set_implementation(res_tzsh_softkey,
6405                                   &_tzsh_softkey_iface,
6406                                   tzsh_client,
6407                                   _tzsh_cb_softkey_destroy);
6408 }
6409
6410 // --------------------------------------------------------
6411 // tizen_ws_shell_interface::shared_widget_launch
6412 // --------------------------------------------------------
6413 EINTERN Eina_Bool
6414 e_tzsh_shared_widget_launch_prepare_send(E_Client *callee_ec,
6415                                          uint32_t state,
6416                                          uint32_t serial)
6417 {
6418    E_Policy_Wl_Tzsh_Client *tzsh_client;
6419    Eina_List *l;
6420    Eina_Bool res = EINA_FALSE;
6421
6422    EINA_SAFETY_ON_NULL_RETURN_VAL(callee_ec, EINA_FALSE);
6423    EINA_SAFETY_ON_TRUE_RETURN_VAL(e_object_is_del(E_OBJECT(callee_ec)), EINA_FALSE);
6424
6425    EINA_LIST_FOREACH(polwl->tzsh_clients, l, tzsh_client)
6426      {
6427         if (!tzsh_client->tzsh) continue;
6428         if (!tzsh_client->ec) continue;
6429         if (tzsh_client->ec != callee_ec) continue;
6430
6431         tws_shared_widget_launch_send_prepare_shared_widget(tzsh_client->res_tzsh_client,
6432                                                             state,
6433                                                             serial);
6434
6435         res = EINA_TRUE;
6436         break;
6437      }
6438
6439    return res;
6440 }
6441
6442 static void
6443 _tzsh_swl_iface_cb_release(struct wl_client *client,
6444                            struct wl_resource *res_tzsh_swl)
6445 {
6446    ELOGF("TZSH_SWL", "Release", NULL);
6447
6448    wl_resource_destroy(res_tzsh_swl);
6449 }
6450
6451 static void
6452 _tzsh_swl_iface_cb_prepare_shared_widget_done(struct wl_client *client,
6453                                               struct wl_resource *res_tzsh_swl,
6454                                               const char *shared_widget_info,
6455                                               uint32_t state,
6456                                               uint32_t serial)
6457 {
6458    E_Policy_Wl_Tzsh_Client *tzsh_client;
6459
6460    ELOGF("TZSH_SWL", "Done", NULL);
6461
6462    tzsh_client = wl_resource_get_user_data(res_tzsh_swl);
6463    EINA_SAFETY_ON_NULL_RETURN(tzsh_client);
6464    EINA_SAFETY_ON_NULL_RETURN(tzsh_client->tzsh);
6465    EINA_SAFETY_ON_NULL_RETURN(tzsh_client->ec);
6466    EINA_SAFETY_ON_NULL_RETURN(eina_list_data_find(polwl->tzsh_clients, tzsh_client));
6467
6468    // send prepare event to caller
6469    e_service_launcher_prepare_send_with_shared_widget_info(tzsh_client->ec,
6470                                                            shared_widget_info,
6471                                                            state,
6472                                                            serial);
6473 }
6474
6475 static const struct tws_shared_widget_launch_interface _tzsh_swl_iface =
6476 {
6477    _tzsh_swl_iface_cb_release,
6478    _tzsh_swl_iface_cb_prepare_shared_widget_done,
6479 };
6480
6481 static void
6482 _tzsh_cb_swl_destroy(struct wl_resource *res_tzsh_swl)
6483 {
6484    E_Policy_Wl_Tzsh_Client *tzsh_client;
6485
6486    ELOGF("TZSH_SWL", "Destroy", NULL);
6487
6488    tzsh_client = wl_resource_get_user_data(res_tzsh_swl);
6489    EINA_SAFETY_ON_NULL_RETURN(tzsh_client);
6490
6491    e_service_launcher_release_shared_widget_launch(tzsh_client->ec);
6492
6493    tzsh_client->res_tzsh_client = NULL;
6494    _e_policy_wl_tzsh_client_del(tzsh_client);
6495 }
6496
6497 static void
6498 _tzsh_iface_cb_shared_widget_launch_get(struct wl_client *client,
6499                                         struct wl_resource *res_tzsh,
6500                                         uint32_t id,
6501                                         uint32_t surf_id)
6502 {
6503    E_Policy_Wl_Tzsh *tzsh;
6504    E_Policy_Wl_Tzsh_Client *tzsh_client;
6505    struct wl_resource *res_tzsh_swl;
6506    E_Client *ec;
6507    E_Pixmap *cp;
6508
6509    tzsh = wl_resource_get_user_data(res_tzsh);
6510    if (!tzsh)
6511      {
6512         wl_resource_post_error
6513            (res_tzsh,
6514             WL_DISPLAY_ERROR_INVALID_OBJECT,
6515             "Invalid res_tzsh's user data");
6516         return;
6517      }
6518
6519    cp = _e_policy_wl_e_pixmap_get_from_id(client, surf_id);
6520    if (!cp)
6521      {
6522         wl_resource_post_error
6523            (res_tzsh,
6524             WL_DISPLAY_ERROR_INVALID_OBJECT,
6525             "Invalid surface id");
6526         return;
6527      }
6528
6529    ec = e_pixmap_client_get(cp);
6530    if (ec)
6531      {
6532         if (!_e_policy_wl_e_client_is_valid(ec))
6533           {
6534              wl_resource_post_error
6535                 (res_tzsh,
6536                  WL_DISPLAY_ERROR_INVALID_OBJECT,
6537                  "Invalid surface id");
6538              return;
6539           }
6540      }
6541
6542    res_tzsh_swl = wl_resource_create(client,
6543                                      &tws_shared_widget_launch_interface,
6544                                      wl_resource_get_version(res_tzsh),
6545                                      id);
6546    if (!res_tzsh_swl)
6547      {
6548         ERR("Could not create tws_shared_widget_launch resource: %m");
6549         wl_client_post_no_memory(client);
6550         return;
6551      }
6552
6553    tzsh_client = _e_policy_wl_tzsh_client_add(tzsh, res_tzsh_swl, cp, ec);
6554    if (!tzsh_client)
6555      {
6556         ERR("Could not create tzsh_client");
6557         wl_client_post_no_memory(client);
6558         return;
6559      }
6560
6561    tzsh_client->handle_type = TZSH_CLIENT_HANDLE_TYPE_SHARED_WIDGET_LAUNCH;
6562
6563    wl_resource_set_implementation(res_tzsh_swl,
6564                                   &_tzsh_swl_iface,
6565                                   tzsh_client,
6566                                   _tzsh_cb_swl_destroy);
6567 }
6568
6569 // --------------------------------------------------------
6570 // tizen_ws_shell_interface
6571 // --------------------------------------------------------
6572 static void
6573 _tzsh_iface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzsh)
6574 {
6575    wl_resource_destroy(res_tzsh);
6576 }
6577
6578 static const struct tizen_ws_shell_interface _tzsh_iface =
6579 {
6580    _tzsh_iface_cb_destroy,
6581    _tzsh_iface_cb_srv_create,
6582    _tzsh_iface_cb_reg_create,
6583    _tzsh_iface_cb_qp_get,
6584    _tzsh_iface_cb_extension_get,
6585    _tzsh_iface_cb_softkey_get,
6586    _tzsh_iface_cb_shared_widget_launch_get,
6587 };
6588
6589 static void
6590 _tzsh_cb_unbind(struct wl_resource *res_tzsh)
6591 {
6592    E_Policy_Wl_Tzsh *tzsh;
6593
6594    tzsh = wl_resource_get_user_data(res_tzsh);
6595    EINA_SAFETY_ON_NULL_RETURN(tzsh);
6596
6597    _e_policy_wl_tzsh_del(tzsh);
6598 }
6599
6600 static void
6601 _tzsh_cb_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t ver, uint32_t id)
6602 {
6603    E_Policy_Wl_Tzsh *tzsh;
6604    struct wl_resource *res_tzsh;
6605
6606    EINA_SAFETY_ON_NULL_GOTO(polwl, err);
6607
6608    res_tzsh = wl_resource_create(client,
6609                                  &tizen_ws_shell_interface,
6610                                  ver,
6611                                  id);
6612    EINA_SAFETY_ON_NULL_GOTO(res_tzsh, err);
6613
6614    tzsh = _e_policy_wl_tzsh_add(res_tzsh);
6615    EINA_SAFETY_ON_NULL_GOTO(tzsh, err);
6616
6617    wl_resource_set_implementation(res_tzsh,
6618                                   &_tzsh_iface,
6619                                   tzsh,
6620                                   _tzsh_cb_unbind);
6621
6622    _e_policy_wl_tzsh_registered_srv_send(tzsh);
6623    return;
6624
6625 err:
6626    ERR("Could not create tizen_ws_shell_interface res: %m");
6627    wl_client_post_no_memory(client);
6628 }
6629
6630 // --------------------------------------------------------
6631 // tizen_launch_effect_interface
6632 // --------------------------------------------------------
6633 #define SPLASH_GROUP_NAME "effect"
6634 #define SPLASH_CONFIG_CUSTOM_EFFECT_CALLEE "_CUSTOM_EFFECT_CALLEE_"
6635
6636 static void
6637 _launch_effect_hide(uint32_t pid)
6638 {
6639    Eina_List *l, *ll;
6640    E_Policy_Wl_Tzlaunch_Effect *tzlaunch_effect;
6641    E_Policy_Wl_Tzlaunch_Splash *tzlaunch_splash;
6642
6643    if(pid <= 0) return;
6644
6645    EINA_LIST_FOREACH(polwl->tzlaunch_effect, l, tzlaunch_effect)
6646      {
6647         EINA_LIST_FOREACH(tzlaunch_effect->splash_list, ll, tzlaunch_splash)
6648            if (tzlaunch_splash->pid == pid)
6649              {
6650                 _launch_splash_off(tzlaunch_splash);
6651              }
6652      }
6653 }
6654
6655 static void
6656 _launch_effect_client_del(E_Client *ec)
6657 {
6658    Eina_List *l, *ll;
6659    E_Policy_Wl_Tzlaunch_Effect *tzlaunch_effect;
6660    E_Policy_Wl_Tzlaunch_Splash *tzlaunch_splash;
6661
6662    EINA_LIST_FOREACH(polwl->tzlaunch_effect, l, tzlaunch_effect)
6663      {
6664         EINA_LIST_FOREACH(tzlaunch_effect->splash_list, ll, tzlaunch_splash)
6665            if (tzlaunch_splash->ec == ec)
6666              {
6667                 _launch_splash_off(tzlaunch_splash);
6668              }
6669      }
6670 }
6671
6672 static void
6673 _launchscreen_splash_cb_indicator_resized(Ecore_Evas *ee)
6674 {
6675    Evas_Coord_Size size = {0, 0};
6676    Evas_Object *indicator_obj;
6677    E_Policy_Wl_Tzlaunch_Splash *tzlaunch_splash;
6678
6679    tzlaunch_splash = ecore_evas_data_get(ee, "tzlaunch_splash");
6680    if (!tzlaunch_splash) return;
6681
6682    indicator_obj = tzlaunch_splash->indicator_obj;
6683
6684    ecore_evas_geometry_get(ee, NULL, NULL, &(size.w), &(size.h));
6685    ELOGF("TZPOL", "Launchscreen indicator_obj resized(%d x %d)",
6686          NULL,
6687          size.w, size.h);
6688    evas_object_size_hint_min_set(indicator_obj, size.w, size.h);
6689    evas_object_size_hint_max_set(indicator_obj, size.w, size.h);
6690    e_comp_object_indicator_size_set(tzlaunch_splash->ec->frame, size.w, size.h);
6691 }
6692
6693 static void
6694 _launchscreen_splash_cb_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
6695 {
6696    E_Policy_Wl_Tzlaunch_Splash *tzlaunch_splash = data;
6697
6698    if ((tzlaunch_splash) && (tzlaunch_splash->obj == obj))
6699      tzlaunch_splash->obj = NULL;
6700 }
6701
6702 static void
6703 _launchscreen_splash_cb_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
6704 {
6705    E_Policy_Wl_Tzlaunch_Splash *tzlaunch_splash = data;
6706
6707    if ((tzlaunch_splash) && (tzlaunch_splash->obj == obj))
6708      _launch_splash_off(tzlaunch_splash);
6709 }
6710
6711 static void
6712 _launch_splash_off(E_Policy_Wl_Tzlaunch_Splash *tzlaunch_splash)
6713 {
6714    E_Client *ec = NULL;
6715    Evas_Object *obj = NULL;
6716
6717    if (!tzlaunch_splash->valid) return;
6718    if (!tzlaunch_splash->ec) return;
6719
6720    ec = tzlaunch_splash->ec;
6721    obj = tzlaunch_splash->obj;
6722
6723    tzlaunch_splash->obj = NULL;
6724    tzlaunch_splash->ec = NULL;
6725    tzlaunch_splash->valid = EINA_FALSE;
6726    if (tzlaunch_splash->timeout) ecore_timer_del(tzlaunch_splash->timeout);
6727    tzlaunch_splash->timeout = NULL;
6728
6729    eina_stringshare_del(tzlaunch_splash->appid);
6730    tzlaunch_splash->appid = NULL;
6731    eina_stringshare_del(tzlaunch_splash->path);
6732    tzlaunch_splash->path = NULL;
6733
6734
6735    ELOGF("TZPOL",
6736          "Launchscreen hide | pid %d, replaced:%d, tzlaunch_pixmap:%p, ec_pixmap:%p",
6737          ec, tzlaunch_splash->pid, tzlaunch_splash->replaced, tzlaunch_splash->ep, ec->pixmap);
6738
6739    if (tzlaunch_splash->indicator_obj)
6740      {
6741         e_comp_object_indicator_unswallow(ec->frame, tzlaunch_splash->indicator_obj);
6742         evas_object_del(tzlaunch_splash->indicator_obj);
6743         evas_object_unref(tzlaunch_splash->indicator_obj);
6744         tzlaunch_splash->indicator_obj = NULL;
6745      }
6746
6747    if ((ec->pixmap) &&
6748        (ec->pixmap == tzlaunch_splash->ep))
6749      {
6750         /* case 1: Surface for this pid is not created until timeout or
6751          * launchscreen resource is destroied.
6752          */
6753         if (ec->visible)
6754           {
6755              ec->visible = EINA_FALSE;
6756              evas_object_hide(ec->frame);
6757              ec->ignored = EINA_TRUE;
6758           }
6759
6760         e_comp->launchscrns = eina_list_remove(e_comp->launchscrns, ec);
6761
6762         e_pixmap_win_id_del(tzlaunch_splash->ep);
6763         e_object_del(E_OBJECT(ec));
6764         ec = NULL;
6765      }
6766
6767    if (ec)
6768      {
6769         if (!e_util_strcmp("wl_pointer-cursor", ec->icccm.window_role))
6770           {
6771              // if Launchscreen is replaced to cursor, than hide
6772              e_comp_object_content_unset(ec->frame);
6773              ec->visible = EINA_FALSE;
6774              evas_object_hide(ec->frame);
6775              ec->ignored = EINA_TRUE;
6776           }
6777         else if (!tzlaunch_splash->replaced)
6778           {
6779              if (ec->focused)
6780                e_comp_wl_feed_focus_in(ec);
6781
6782              /* to send launch,done event to launchscreen client */
6783              if (!e_object_is_del(E_OBJECT(ec)))
6784                {
6785                   if (ec->first_mapped)
6786                     {
6787                        ELOGF("LAUNCH", "SHOW real win by replaced splash ec", ec);
6788                        e_comp_object_signal_emit(ec->frame, "e,action,launch_real,done", "e");
6789                     }
6790                   e_comp_object_signal_emit(ec->frame, "e,action,launch,done", "e");
6791                }
6792           }
6793
6794         e_comp->launchscrns = eina_list_remove(e_comp->launchscrns, ec);
6795      }
6796
6797    if (obj)
6798      evas_object_unref(obj);
6799
6800    tzlaunch_splash->ep = NULL;
6801    tzlaunch_splash->replaced = EINA_FALSE;
6802 }
6803
6804 static Eina_Bool
6805 _launchscreen_splash_timeout(void *data)
6806 {
6807    E_Policy_Wl_Tzlaunch_Splash *tzlaunch_splash;
6808    tzlaunch_splash = (E_Policy_Wl_Tzlaunch_Splash *)data;
6809
6810    EINA_SAFETY_ON_NULL_RETURN_VAL(tzlaunch_splash, 0);
6811
6812    _launch_splash_off(tzlaunch_splash);
6813
6814    return ECORE_CALLBACK_CANCEL;
6815 }
6816
6817 static Eina_Bool
6818 _launchscreen_splash_setup(E_Policy_Wl_Tzlaunch_Splash *splash,
6819                            const char *pfname, uint32_t ftype,
6820                            uint32_t depth, uint32_t angle,
6821                            uint32_t indicator, const char *effect_type,
6822                            const char *theme_type, struct wl_array *options,
6823                            struct wl_array *extra_config)
6824 {
6825    E_Client *ec = NULL;
6826    E_Comp_Object_Content_Type content_type = 0;
6827    Eina_Bool intercepted = EINA_FALSE;
6828
6829    EINA_SAFETY_ON_NULL_RETURN_VAL(splash->ec, EINA_FALSE);
6830    EINA_SAFETY_ON_NULL_RETURN_VAL(splash->ec->frame, EINA_FALSE);
6831
6832    ec = splash->ec;
6833    ec->effect_type = _e_policy_wl_tzlaunch_effect_type_get(effect_type);
6834
6835    ELOGF("TZPOL",
6836          "Launchscreen setup START| path %s(%d), indicator(%d), angle(%d), effect_type(%s), theme_type(%s)",
6837          ec, pfname, ftype, indicator, angle, effect_type, theme_type);
6838    ELOGF("TZPOL",
6839          "Launchscreen setup | options %p extra_config:%p",
6840          ec, options, extra_config);
6841
6842    splash->path = eina_stringshare_add(pfname);
6843    splash->type = ftype;
6844    splash->indicator = indicator;
6845    splash->angle = angle;
6846
6847    if (indicator)
6848      {
6849         /* To configure indicator options */
6850         ec->indicator.state = TIZEN_INDICATOR_STATE_ON;
6851         ec->indicator.visible_type = TIZEN_INDICATOR_VISIBLE_TYPE_SHOWN;
6852         ec->indicator.opacity_mode = TIZEN_INDICATOR_OPACITY_MODE_BG_TRANSPARENT;
6853      }
6854
6855    intercepted = e_policy_interceptor_call(E_POLICY_INTERCEPT_LAUNCHSCREEN_OBJECT_SETUP,
6856                                            ec,
6857                                            pfname, ftype, depth,
6858                                            angle, indicator, options);
6859    if (intercepted)
6860      {
6861         splash->obj = e_comp_object_content_get(ec->frame);
6862
6863         ELOGF("TZPOL",
6864               "Launchscreen setup | was INTERCEPTED : content(%p)",
6865               ec, splash->obj);
6866      }
6867    else //Do original setup process
6868      {
6869         if (splash->type == LAUNCH_IMG_FILE_TYPE_IMAGE)
6870           {
6871              Evas_Load_Error err;
6872
6873              content_type = E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE;
6874              splash->obj = evas_object_image_add(e_comp->evas);
6875              EINA_SAFETY_ON_NULL_RETURN_VAL(splash->obj, EINA_FALSE);
6876
6877              evas_object_image_file_set(splash->obj, splash->path, NULL);
6878
6879              err = evas_object_image_load_error_get(splash->obj);
6880              if (err != EVAS_LOAD_ERROR_NONE)
6881                {
6882                   ELOGF("TZPOL",
6883                         "Launchscreen setup | fail to load image %s : %s",
6884                         ec, splash->path, evas_load_error_str(err));
6885                   evas_object_del(splash->obj);
6886                   splash->obj = NULL;
6887                   return EINA_FALSE;
6888                }
6889
6890              evas_object_image_fill_set(splash->obj, 0, 0, e_comp->w, e_comp->h);
6891              evas_object_image_filled_set(splash->obj, EINA_TRUE);
6892           }
6893         else
6894           {
6895              content_type = E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE;
6896              splash->obj = edje_object_add(e_comp->evas);
6897              EINA_SAFETY_ON_NULL_RETURN_VAL(splash->obj, EINA_FALSE);
6898
6899              if (!edje_object_file_set(splash->obj, splash->path, SPLASH_GROUP_NAME))
6900                {
6901                   Edje_Load_Error err;
6902
6903                   err = edje_object_load_error_get(splash->obj);
6904                   ELOGF("TZPOL",
6905                         "Launchscreen setup | fail to load edje %s : %s",
6906                         ec, splash->path, edje_load_error_str(err));
6907                   evas_object_del(splash->obj);
6908                   splash->obj = NULL;
6909                   return EINA_FALSE;
6910
6911                }
6912
6913              evas_object_move(splash->obj, 0, 0);
6914              evas_object_resize(splash->obj, e_comp->w, e_comp->h);
6915           }
6916
6917         if (depth == 32) ec->argb = EINA_TRUE;
6918         else ec->argb = EINA_FALSE;
6919         ELOGF("COMP", "Set argb:%d", ec, ec->argb);
6920
6921         //set splash->obj to a content of ec->frame
6922         if (!e_comp_object_content_set(ec->frame, splash->obj, content_type))
6923           {
6924              ERR("Launchscreen setup | setting comp object content failed ec(%p) obj(%p)",
6925                  ec, splash->obj);
6926              return EINA_FALSE;
6927           }
6928      }
6929
6930
6931    /* Post job of setup content_type */
6932
6933    //Parse extra config
6934    if ((extra_config) && (extra_config->size))
6935      {
6936         char *p_char;
6937         int len = 0;
6938         int size = extra_config->size;
6939
6940         while (size > 0)
6941           {
6942              p_char = extra_config->data + len;
6943              len = strlen(p_char) + 1;
6944              size -= len;
6945
6946              if (!e_util_strcmp(p_char, SPLASH_CONFIG_CUSTOM_EFFECT_CALLEE))
6947                {
6948                   //parse next data(appid) from array
6949                   if (size > 0)
6950                     {
6951                        p_char = p_char + len;
6952                        len = strlen(p_char) + 1;
6953                        size -= len;
6954
6955                        splash->appid = eina_stringshare_add(p_char);
6956                        splash->custom_effect_callee = EINA_TRUE;
6957
6958                        ELOGF("TZPOL",
6959                              "Launchscreen setup | custom effect callee set appid(%s)",
6960                              ec, splash->appid);
6961                     }
6962                   else break;
6963                }
6964           }
6965      }
6966
6967    //Setup indicator
6968    if (indicator)
6969      {
6970         Evas_Object *indicator_obj = NULL;
6971         Eina_Bool ret = EINA_FALSE;
6972
6973         e_mod_indicator_owner_set(ec);
6974         e_tzsh_indicator_srv_property_update(ec);
6975
6976         indicator_obj = ecore_evas_extn_plug_new(e_comp->ee);
6977         if (!indicator_obj)
6978           {
6979              ELOGF("TZPOL",
6980                    "Launchscreen setup | Failed to create ecore_evas_plug for indicator",
6981                    ec);
6982           }
6983         else
6984           {
6985              if (e_config->indicator_plug_name)
6986                {
6987                   ret = ecore_evas_extn_plug_connect(indicator_obj, e_config->indicator_plug_name, 0, EINA_FALSE);
6988                   if (ret)
6989                     {
6990                        Ecore_Evas *ee;
6991
6992                        ee = ecore_evas_object_ecore_evas_get(indicator_obj);
6993                        ecore_evas_data_set(ee, "tzlaunch_splash", splash);
6994                        ecore_evas_callback_resize_set(ee,
6995                                                       _launchscreen_splash_cb_indicator_resized);
6996                        e_comp_object_indicator_swallow(ec->frame, indicator_obj);
6997                        evas_object_ref(indicator_obj);
6998                        ELOGF("TZPOL",
6999                              "Launchscreen launch | Succeeded to add indicator object plug_name(%s) indicator_obj(%p)",
7000                              ec, e_config->indicator_plug_name, indicator_obj);
7001                     }
7002                   else
7003                     {
7004                        evas_object_del(indicator_obj);
7005                        indicator_obj = NULL;
7006                     }
7007                }
7008
7009              if (!indicator_obj)
7010                {
7011                   ELOGF("TZPOL",
7012                         "Launchscreen launch | Failed to add indicator object plug_name(%s)",
7013                         ec, e_config->indicator_plug_name?:"NO PLUG NAME");
7014                }
7015           }
7016
7017         splash->indicator_obj = indicator_obj;
7018      }
7019
7020    //ref splash object
7021    if (splash->obj)
7022      {
7023         evas_object_ref(splash->obj);
7024
7025         evas_object_event_callback_add(splash->obj,
7026                                        EVAS_CALLBACK_DEL,
7027                                        _launchscreen_splash_cb_del, splash);
7028         evas_object_event_callback_add(splash->obj,
7029                                        EVAS_CALLBACK_HIDE,
7030                                        _launchscreen_splash_cb_hide, splash);
7031      }
7032
7033    splash->valid = EINA_TRUE;
7034    splash->content_type = e_comp_object_content_type_get(ec->frame);
7035
7036    return EINA_TRUE;
7037 }
7038
7039 static void
7040 _tzlaunch_splash_iface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzlaunch_splash)
7041 {
7042    wl_resource_destroy(res_tzlaunch_splash);
7043 }
7044
7045 static void
7046 _tzlaunch_splash_iface_cb_launch(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzlaunch_splash,
7047                                  const char *pfname, uint32_t ftype,
7048                                  uint32_t depth, uint32_t angle,
7049                                  uint32_t indicator, const char *effect_type,
7050                                  const char *theme_type, struct wl_array *options)
7051 {
7052    E_Policy_Wl_Tzlaunch_Splash *tzlaunch_splash;
7053    Eina_Bool res = EINA_FALSE;
7054
7055    tzlaunch_splash = wl_resource_get_user_data(res_tzlaunch_splash);
7056    EINA_SAFETY_ON_NULL_RETURN(tzlaunch_splash);
7057
7058    ELOGF("TZPOL","Launchscreen launch | START", NULL);
7059
7060
7061    res = _launchscreen_splash_setup(tzlaunch_splash,
7062                                     pfname, ftype,
7063                                     depth, angle,
7064                                     indicator, effect_type,
7065                                     theme_type, options, NULL);
7066
7067    ELOGF("TZPOL","Launchscreen launch | END res:%d ", NULL, res);
7068
7069    if (!res)
7070      {
7071         ERR("Launchscreen launch | Could not complete %s", __FUNCTION__);
7072         if (tzlaunch_splash->obj)
7073           {
7074              evas_object_del(tzlaunch_splash->obj);
7075              tzlaunch_splash->obj = NULL;
7076           }
7077      }
7078 }
7079
7080 static void
7081 _tzlaunch_splash_iface_cb_owner(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzlaunch_splash, uint32_t pid)
7082 {
7083    E_Policy_Wl_Tzlaunch_Splash *tzlaunch_splash;
7084    E_Client *pre_ec = NULL, *new_ec = NULL, *old_ec;
7085    Eina_List *clients, *l;
7086    int tw, th;
7087
7088    tzlaunch_splash = wl_resource_get_user_data(res_tzlaunch_splash);
7089    EINA_SAFETY_ON_NULL_RETURN(tzlaunch_splash);
7090    EINA_SAFETY_ON_FALSE_RETURN(tzlaunch_splash->valid);
7091
7092    /* use ec was already created */
7093    clients = _e_policy_wl_e_clients_find_by_pid(pid);
7094    EINA_LIST_FOREACH(clients, l, pre_ec)
7095      {
7096         if (pre_ec == tzlaunch_splash->ec) continue;
7097         if (!pre_ec->ignored) continue;
7098         if (pre_ec->is_cursor) continue;
7099         new_ec = pre_ec;
7100         e_client_geometry_get(new_ec, NULL, NULL, &tw, &th);
7101         if (tw <= 1 || th <= 1)
7102           evas_object_resize(new_ec->frame, e_comp->w, e_comp->h);
7103         break;
7104      }
7105    eina_list_free(clients);
7106
7107    old_ec = tzlaunch_splash->ec;
7108    if (new_ec)
7109      {
7110         if (e_comp_object_content_set(new_ec->frame,
7111                                       tzlaunch_splash->obj,
7112                                       tzlaunch_splash->content_type))
7113           {
7114              e_client_unignore(new_ec);
7115              new_ec->visible = EINA_TRUE;
7116              if (new_ec->new_client)
7117                e_comp->new_clients--;
7118              new_ec->new_client = EINA_FALSE;
7119              new_ec->argb = old_ec->argb;
7120              ELOGF("COMP", "Set argb:%d", new_ec, new_ec->argb);
7121              new_ec->effect_type = old_ec->effect_type;
7122              new_ec->use_splash = EINA_TRUE;
7123              e_client_icccm_title_set(new_ec, "launchscreen");
7124
7125              e_comp->launchscrns = eina_list_append(e_comp->launchscrns, new_ec);
7126
7127              if (tzlaunch_splash->custom_effect_callee)
7128                {
7129                   e_service_launcher_callee_register(new_ec, tzlaunch_splash->appid, tzlaunch_splash->path, SPLASH_GROUP_NAME);
7130                }
7131
7132              evas_object_show(new_ec->frame);
7133              e_client_raise(new_ec);
7134
7135              tzlaunch_splash->ec = new_ec;
7136              tzlaunch_splash->replaced = EINA_TRUE;
7137
7138              ELOGF("TZPOL",
7139                    "Launchscreen client changed | old(%p) new(%p) using obj(%p)",
7140                    new_ec,
7141                    old_ec, new_ec, tzlaunch_splash->obj);
7142
7143              if (tzlaunch_splash->indicator_obj)
7144                {
7145                   e_mod_indicator_owner_set(new_ec);
7146                   e_tzsh_indicator_srv_property_update(new_ec);
7147                   e_comp_object_indicator_unswallow(old_ec->frame, tzlaunch_splash->indicator_obj);
7148                   e_comp_object_indicator_swallow(new_ec->frame, tzlaunch_splash->indicator_obj);
7149                }
7150
7151              /* delete ec was created for launchscreen */
7152              e_comp->launchscrns = eina_list_remove(e_comp->launchscrns, old_ec);
7153
7154              e_pixmap_win_id_del(tzlaunch_splash->ep);
7155              e_object_del(E_OBJECT(old_ec));
7156              tzlaunch_splash->ep = NULL;
7157           }
7158         else
7159           ERR("Can't set external content for new_ec(%p)", new_ec);
7160      }
7161    else
7162      {
7163         old_ec->ignored = EINA_FALSE;
7164         old_ec->visible = EINA_TRUE;
7165         if (old_ec->new_client)
7166           e_comp->new_clients--;
7167         old_ec->new_client = EINA_FALSE;
7168         old_ec->icccm.accepts_focus = EINA_TRUE;
7169
7170         if (tzlaunch_splash->custom_effect_callee)
7171           {
7172              e_service_launcher_callee_register(old_ec, tzlaunch_splash->appid, tzlaunch_splash->path, SPLASH_GROUP_NAME);
7173           }
7174
7175         evas_object_show(old_ec->frame);
7176         e_client_raise(old_ec);
7177      }
7178
7179    EC_CHANGED(tzlaunch_splash->ec);
7180    e_comp_visibility_calculation_set(EINA_TRUE);
7181
7182    if (tzlaunch_splash->timeout)
7183      {
7184         ecore_timer_del(tzlaunch_splash->timeout);
7185         tzlaunch_splash->timeout = NULL;
7186      }
7187    if (!e_config->launchscreen_without_timer)
7188      tzlaunch_splash->timeout = ecore_timer_add(e_config->launchscreen_timeout, _launchscreen_splash_timeout, tzlaunch_splash);
7189
7190    ELOGF("TZPOL", "Launchscreen img(%d) set owner pid: %d",
7191          tzlaunch_splash->ec,
7192          wl_resource_get_id(res_tzlaunch_splash), pid);
7193
7194    tzlaunch_splash->pid = pid;
7195    tzlaunch_splash->ec->netwm.pid = pid;
7196    tzlaunch_splash->ec->use_splash = EINA_TRUE;
7197 }
7198
7199 static void
7200 _tzlaunch_splash_iface_cb_launch_v2(struct wl_client *client EINA_UNUSED,
7201                                     struct wl_resource *res_tzlaunch_splash,
7202                                     const char *pfname, uint32_t ftype,
7203                                     uint32_t depth, uint32_t angle,
7204                                     uint32_t indicator, const char *effect_type,
7205                                     const char *theme_type, struct wl_array *options,
7206                                     struct wl_array *extra_config)
7207 {
7208    E_Policy_Wl_Tzlaunch_Splash *tzlaunch_splash;
7209    Eina_Bool res = EINA_FALSE;
7210
7211    tzlaunch_splash = wl_resource_get_user_data(res_tzlaunch_splash);
7212    EINA_SAFETY_ON_NULL_RETURN(tzlaunch_splash);
7213
7214    ELOGF("TZPOL","Launchscreen launch_v2 | START", NULL);
7215
7216    res = _launchscreen_splash_setup(tzlaunch_splash,
7217                                     pfname, ftype,
7218                                     depth, angle,
7219                                     indicator, effect_type,
7220                                     theme_type, options, extra_config);
7221
7222    ELOGF("TZPOL","Launchscreen launch_v2 | END res:%d ", NULL, res);
7223
7224    if (!res)
7225      {
7226         ERR("Launchscreen launch_v2 | Could not complete %s", __FUNCTION__);
7227         if (tzlaunch_splash->obj)
7228           {
7229              evas_object_del(tzlaunch_splash->obj);
7230              tzlaunch_splash->obj = NULL;
7231           }
7232      }
7233
7234 }
7235
7236 static const struct tizen_launch_splash_interface _tzlaunch_splash_iface =
7237 {
7238    _tzlaunch_splash_iface_cb_destroy,
7239    _tzlaunch_splash_iface_cb_launch,
7240    _tzlaunch_splash_iface_cb_owner,
7241    _tzlaunch_splash_iface_cb_launch_v2,
7242 };
7243
7244 static E_Policy_Wl_Tzlaunch_Splash *
7245 _tzlaunch_splash_add(struct wl_resource *res_tzlaunch_effect, struct wl_resource *res_tzlaunch_splash)
7246 {
7247    E_Policy_Wl_Tzlaunch_Effect *tzlaunch_effect;
7248    E_Policy_Wl_Tzlaunch_Splash *tzlaunch_splash;
7249
7250    tzlaunch_splash = E_NEW(E_Policy_Wl_Tzlaunch_Splash, 1);
7251    EINA_SAFETY_ON_NULL_GOTO(tzlaunch_splash, error);
7252
7253    tzlaunch_effect = wl_resource_get_user_data(res_tzlaunch_effect);
7254    EINA_SAFETY_ON_NULL_GOTO(tzlaunch_effect, error);
7255
7256    tzlaunch_effect->splash_list = eina_list_append(tzlaunch_effect->splash_list, tzlaunch_splash);
7257
7258    tzlaunch_splash->tzlaunch_effect  = tzlaunch_effect;
7259    tzlaunch_splash->res_tzlaunch_splash = res_tzlaunch_splash;
7260
7261    tzlaunch_splash->replaced = EINA_FALSE;
7262    tzlaunch_splash->ep = e_pixmap_new(E_PIXMAP_TYPE_EXT_OBJECT, 0);
7263    EINA_SAFETY_ON_NULL_GOTO(tzlaunch_splash->ep, error);
7264    tzlaunch_splash->ec = e_client_new(tzlaunch_splash->ep, 0, 1);
7265    EINA_SAFETY_ON_NULL_GOTO(tzlaunch_splash->ec, error);
7266
7267    e_client_icccm_title_set(tzlaunch_splash->ec, "Launchscreen");
7268    e_client_icccm_name_set(tzlaunch_splash->ec, "Launchscreen");
7269    tzlaunch_splash->ec->ignored = EINA_TRUE;
7270
7271    e_comp->launchscrns = eina_list_append(e_comp->launchscrns, tzlaunch_splash->ec);
7272
7273    return tzlaunch_splash;
7274 error:
7275    if (tzlaunch_splash)
7276      {
7277         ERR("Could not initialize launchscreen client");
7278         if (tzlaunch_splash->ep)
7279           e_pixmap_win_id_del(tzlaunch_splash->ep);
7280         if (tzlaunch_splash->ec)
7281           e_object_del(E_OBJECT(tzlaunch_splash->ec));
7282         E_FREE(tzlaunch_splash);
7283      }
7284    return NULL;
7285 }
7286
7287
7288 static void
7289 _tzlaunch_splash_destroy(struct wl_resource *res_tzlaunch_splash)
7290 {
7291    E_Policy_Wl_Tzlaunch_Splash *tzlaunch_splash;
7292    E_Policy_Wl_Tzlaunch_Effect *tzlaunch_effect;
7293
7294    EINA_SAFETY_ON_NULL_RETURN(res_tzlaunch_splash);
7295
7296    tzlaunch_splash = wl_resource_get_user_data(res_tzlaunch_splash);
7297    EINA_SAFETY_ON_NULL_RETURN(tzlaunch_splash);
7298
7299    if (tzlaunch_splash->obj)
7300      {
7301         evas_object_event_callback_del_full(tzlaunch_splash->obj, EVAS_CALLBACK_DEL, _launchscreen_splash_cb_del, tzlaunch_splash);
7302         evas_object_event_callback_del_full(tzlaunch_splash->obj, EVAS_CALLBACK_HIDE, _launchscreen_splash_cb_hide, tzlaunch_splash);
7303      }
7304
7305    _launch_splash_off(tzlaunch_splash);
7306
7307    tzlaunch_effect = tzlaunch_splash->tzlaunch_effect;
7308    tzlaunch_effect->splash_list = eina_list_remove(tzlaunch_effect->splash_list, tzlaunch_splash);
7309
7310    eina_stringshare_del(tzlaunch_splash->appid);
7311    eina_stringshare_del(tzlaunch_splash->path);
7312    memset(tzlaunch_splash, 0x0, sizeof(E_Policy_Wl_Tzlaunch_Splash));
7313    E_FREE(tzlaunch_splash);
7314 }
7315
7316 static void
7317 _tzlaunch_effect_iface_cb_create_splash_img(struct wl_client *client, struct wl_resource *res_tzlaunch_effect, uint32_t id)
7318 {
7319
7320    E_Policy_Wl_Tzlaunch_Splash *plaunch_splash;
7321    struct wl_resource *res_tzlaunch_splash;
7322
7323    res_tzlaunch_splash = wl_resource_create(client,
7324                                          &tizen_launch_splash_interface,
7325                                          wl_resource_get_version(res_tzlaunch_effect),
7326                                          id);
7327    if (!res_tzlaunch_splash)
7328      {
7329         wl_resource_post_error
7330            (res_tzlaunch_effect,
7331             WL_DISPLAY_ERROR_INVALID_OBJECT,
7332             "Invalid res_tzlaunch effect's user data");
7333         return;
7334      }
7335
7336    plaunch_splash = _tzlaunch_splash_add(res_tzlaunch_effect, res_tzlaunch_splash);
7337    EINA_SAFETY_ON_NULL_GOTO(plaunch_splash, err);
7338
7339    ELOGF("TZPOL", "Launchscreen effect create splash img. res_tzlaunch_effect:%p, res_tzlaunch_splash:%p", plaunch_splash->ec, res_tzlaunch_effect, res_tzlaunch_splash);
7340
7341    wl_resource_set_implementation(res_tzlaunch_splash,
7342                                   &_tzlaunch_splash_iface,
7343                                   plaunch_splash,
7344                                   _tzlaunch_splash_destroy);
7345
7346    return;
7347
7348 err:
7349    ERR("Could not create tizen_launch_splash_interface res: %m");
7350    wl_client_post_no_memory(client);
7351 }
7352
7353 static void
7354 _tzlaunch_effect_iface_cb_type_set(struct wl_client *client, struct wl_resource *res_tzlaunch_effect,
7355                                                const char *effect_type, uint32_t pid, struct wl_array *options)
7356 {
7357    Eina_List *clients, *l;
7358    E_Client *_ec = NULL;
7359    int effect_set = 0;
7360    int tzlaunch_effect_type = _e_policy_wl_tzlaunch_effect_type_get(effect_type);
7361
7362    clients = _e_policy_wl_e_clients_find_by_pid(pid);
7363    EINA_LIST_FOREACH(clients, l, _ec)
7364      {
7365         if (_ec)
7366           {
7367              _ec->effect_type = tzlaunch_effect_type;
7368              effect_set = 1;
7369              ELOGF("TZPOL",
7370                     "Launchscreen effect type set | exist ec | effect (%d) pid (%d)",
7371                     _ec, tzlaunch_effect_type, pid);
7372           }
7373      }
7374    eina_list_free(clients);
7375
7376    if (effect_set)
7377      _e_policy_wl_tzlaunch_effect_type_unset(pid);
7378    else
7379      {
7380         E_Policy_Wl_Tzlaunch_Effect_Info *tzlaunch_effect_info;
7381
7382         tzlaunch_effect_info = E_NEW(E_Policy_Wl_Tzlaunch_Effect_Info, 1);
7383         EINA_SAFETY_ON_NULL_RETURN(tzlaunch_effect_info);
7384         tzlaunch_effect_info->pid = pid;
7385         tzlaunch_effect_info->effect_type = tzlaunch_effect_type;
7386         polwl->tzlaunch_effect_info = eina_list_append(polwl->tzlaunch_effect_info, tzlaunch_effect_info);
7387
7388         ELOGF("TZPOL",
7389               "Launchscreen effect type set | no match ec | effect (%d) pid (%d)",
7390               NULL, tzlaunch_effect_type, pid);
7391      }
7392 }
7393
7394 static void
7395 _tzlaunch_effect_iface_cb_type_unset(struct wl_client *client, struct wl_resource *res_tzlaunch_effect,
7396                                                  uint32_t pid)
7397 {
7398    _e_policy_wl_tzlaunch_effect_type_unset(pid);
7399 }
7400
7401 static void
7402 _tzlaunch_effect_iface_cb_destroy(struct wl_client *client, struct wl_resource *resource)
7403 {
7404    wl_resource_destroy(resource);
7405 }
7406
7407 static const struct tizen_launch_effect_interface _tzlaunch_effect_iface =
7408 {
7409    _tzlaunch_effect_iface_cb_create_splash_img,
7410    _tzlaunch_effect_iface_cb_type_set,
7411    _tzlaunch_effect_iface_cb_type_unset,
7412    _tzlaunch_effect_iface_cb_destroy,
7413 };
7414
7415 static void
7416 _tzlaunch_effect_del(E_Policy_Wl_Tzlaunch_Effect *tzlaunch_effect)
7417 {
7418    E_Policy_Wl_Tzlaunch_Splash *plaunch_splash;
7419    Eina_List *l, *ll;
7420
7421    EINA_SAFETY_ON_NULL_RETURN(tzlaunch_effect);
7422
7423    // remove tzlaunch created splash list
7424    EINA_LIST_FOREACH_SAFE(tzlaunch_effect->splash_list, l, ll, plaunch_splash)
7425      {
7426         if (plaunch_splash->tzlaunch_effect != tzlaunch_effect) continue;
7427         wl_resource_destroy(plaunch_splash->res_tzlaunch_splash);
7428         break;
7429      }
7430
7431    polwl->tzlaunch_effect = eina_list_remove(polwl->tzlaunch_effect, tzlaunch_effect);
7432
7433    memset(tzlaunch_effect, 0x0, sizeof(E_Policy_Wl_Tzlaunch_Effect));
7434    E_FREE(tzlaunch_effect);
7435 }
7436
7437 static E_Policy_Wl_Tzlaunch_Effect *
7438 _tzlaunch_effect_add(struct wl_resource *res_tzlaunch_effect)
7439 {
7440    E_Policy_Wl_Tzlaunch_Effect *tzlaunch_effect;
7441
7442    tzlaunch_effect = E_NEW(E_Policy_Wl_Tzlaunch_Effect, 1);
7443    EINA_SAFETY_ON_NULL_RETURN_VAL(tzlaunch_effect, NULL);
7444
7445    tzlaunch_effect->res_tzlaunch_effect = res_tzlaunch_effect;
7446
7447    polwl->tzlaunch_effect = eina_list_append(polwl->tzlaunch_effect, tzlaunch_effect);
7448
7449    return tzlaunch_effect;
7450 }
7451
7452 static void
7453 _tzlaunch_effect_cb_unbind(struct wl_resource *res_tzlaunch_effect)
7454 {
7455    E_Policy_Wl_Tzlaunch_Effect *tzlaunch_effect = NULL;
7456    Eina_List *l, *ll;
7457
7458    EINA_LIST_FOREACH_SAFE(polwl->tzlaunch_effect, l, ll, tzlaunch_effect)
7459      {
7460         if (tzlaunch_effect->res_tzlaunch_effect != res_tzlaunch_effect) continue;
7461         _tzlaunch_effect_del(tzlaunch_effect);
7462         break;
7463      }
7464 }
7465
7466 static void
7467 _tzlaunch_effect_cb_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t ver, uint32_t id)
7468 {
7469    E_Policy_Wl_Tzlaunch_Effect *tzlaunch_effect = NULL;
7470    struct wl_resource *res_tzlaunch_effect;
7471
7472    EINA_SAFETY_ON_NULL_GOTO(polwl, err);
7473
7474    res_tzlaunch_effect = wl_resource_create(client,
7475                                      &tizen_launch_effect_interface,
7476                                      ver,
7477                                      id);
7478    EINA_SAFETY_ON_NULL_GOTO(res_tzlaunch_effect, err);
7479
7480    tzlaunch_effect = _tzlaunch_effect_add(res_tzlaunch_effect);
7481    EINA_SAFETY_ON_NULL_GOTO(tzlaunch_effect, err);
7482
7483    wl_resource_set_implementation(res_tzlaunch_effect,
7484                                   &_tzlaunch_effect_iface,
7485                                   tzlaunch_effect,
7486                                   _tzlaunch_effect_cb_unbind);
7487
7488    return;
7489
7490 err:
7491    ERR("Could not create tizen_launch_effect_interface res: %m");
7492    wl_client_post_no_memory(client);
7493 }
7494
7495 // --------------------------------------------------------
7496 // tizen_launch_appinfo_interface
7497 // --------------------------------------------------------
7498 static void
7499 _tzlaunch_appinfo_iface_cb_register_pid(struct wl_client *client, struct wl_resource *res_tzlaunch_appinfo,
7500                                             uint32_t pid)
7501 {
7502    E_Policy_Wl_Tzlaunch_Appinfo *tzlaunch_appinfo = NULL;
7503    E_Appinfo *eai = NULL;
7504
7505    tzlaunch_appinfo = wl_resource_get_user_data(res_tzlaunch_appinfo);
7506    if (!tzlaunch_appinfo)
7507      {
7508         wl_resource_post_error(res_tzlaunch_appinfo,
7509                                WL_DISPLAY_ERROR_INVALID_OBJECT,
7510                                "Invalid tzlaunch_appinfo's user data");
7511         return;
7512      }
7513
7514    if (pid <= 0)
7515      {
7516         ELOGF("TZ_APPINFO", "registered pid is invalid. pid:%u", NULL, pid);
7517         return;
7518      }
7519
7520    eai = e_appinfo_find_with_pid(pid);
7521    if (!eai)
7522      {
7523         eai = e_appinfo_new();
7524         EINA_SAFETY_ON_NULL_RETURN(eai);
7525
7526         if (!e_appinfo_pid_set(eai, pid))
7527           {
7528              ELOGF("TZ_APPINFO", "failed to set pid is invalid. pid:%u", NULL, pid);
7529              e_appinfo_del(eai);
7530              return;
7531           }
7532      }
7533
7534    e_appinfo_owner_set(eai, E_APPINFO_OWNER_CLIENT);
7535 }
7536
7537 static void
7538 _tzlaunch_appinfo_iface_cb_deregister_pid(struct wl_client *client, struct wl_resource *res_tzlaunch_appinfo,
7539                                             uint32_t pid)
7540 {
7541    E_Policy_Wl_Tzlaunch_Appinfo *tzlaunch_appinfo = NULL;
7542    E_Appinfo *eai = NULL;
7543
7544    tzlaunch_appinfo = wl_resource_get_user_data(res_tzlaunch_appinfo);
7545    if (!tzlaunch_appinfo)
7546      {
7547         wl_resource_post_error(res_tzlaunch_appinfo,
7548                                WL_DISPLAY_ERROR_INVALID_OBJECT,
7549                                "Invalid tzlaunch_appinfo's user data");
7550         return;
7551      }
7552
7553    eai = e_appinfo_find_with_pid(pid);
7554    EINA_SAFETY_ON_NULL_RETURN(eai);
7555
7556    e_appinfo_del(eai);
7557 }
7558
7559 static void
7560 _tzlaunch_appinfo_iface_cb_set_appid(struct wl_client *client, struct wl_resource *res_tzlaunch_appinfo,
7561                                       uint32_t pid, const char *appid)
7562 {
7563    E_Policy_Wl_Tzlaunch_Appinfo *tzlaunch_appinfo = NULL;
7564    E_Appinfo *eai = NULL;
7565    int width = 0;
7566    int height = 0;
7567
7568    tzlaunch_appinfo = wl_resource_get_user_data(res_tzlaunch_appinfo);
7569    if (!tzlaunch_appinfo)
7570      {
7571         wl_resource_post_error(res_tzlaunch_appinfo,
7572                                WL_DISPLAY_ERROR_INVALID_OBJECT,
7573                                "Invalid tzlaunch_appinfo's user data");
7574         return;
7575      }
7576
7577    if (pid <= 0)
7578      {
7579         ELOGF("TZ_APPINFO", "set pid is invalid. pid:%u", NULL, pid);
7580         return;
7581      }
7582
7583    eai = e_appinfo_find_with_pid(pid);
7584    EINA_SAFETY_ON_NULL_RETURN(eai);
7585
7586    if (!e_appinfo_appid_set(eai, appid))
7587      {
7588         ELOGF("TZ_APPINFO", "failed to set appid, appid:%s", NULL, appid);
7589         return;
7590      }
7591
7592    /* about base  output resolution */
7593    if (e_config->configured_output_resolution.use)
7594      {
7595
7596         // 1. send HOOK with pid
7597         e_policy_wl_base_output_resolution_info_update(pid);
7598         // 2. module must set the base_output_resolution.
7599         if (!e_appinfo_base_output_resolution_get(eai, &width, &height))
7600           {
7601              ELOGF("TZ_APPINFO", "failed to set base_output_resolution in module, pid:%u, appid:%s", NULL, pid, appid);
7602              return;
7603           }
7604         // 3. server has to get the base_screern_resolution via e_appinfo_base_output_resolution_get.
7605         //    3-1. if success, use the base_rescreen_resolution
7606         //    3-2. if fail, get the base_output_resolution from the E_Comp_Wl_Output.
7607
7608         // 4. send output.
7609         if (!e_comp_wl_pid_output_configured_resolution_send(pid, width, height))
7610           {
7611              ELOGF("TZ_APPINFO", "failed to send output_configured_resolution, pid:%u, appid:%s", NULL, pid, appid);
7612              return;
7613           }
7614      }
7615
7616    return;
7617 }
7618
7619 static void
7620 _tzlaunch_appinfo_iface_cb_destroy(struct wl_client *client, struct wl_resource *res_tzlaunch_appinfo)
7621 {
7622    wl_resource_destroy(res_tzlaunch_appinfo);
7623 }
7624
7625 static void
7626 _tzlaunch_appinfo_iface_cb_get_base_output_resolution(struct wl_client *client, struct wl_resource *res_tzlaunch_appinfo,
7627                                     uint32_t pid)
7628 {
7629    E_Appinfo *eai = NULL;
7630    int width = 0, height = 0;
7631
7632    if (pid <= 0)
7633      {
7634         ELOGF("TZ_APPINFO", "requested pid is invalid. pid:%u", NULL, pid);
7635         goto err;
7636      }
7637
7638    eai = e_appinfo_find_with_pid(pid);
7639    if (!eai)
7640      {
7641         ELOGF("TZ_APPINFO", "cannot find pid. pid:%u", NULL, pid);
7642         goto err;
7643      }
7644
7645    if (!e_appinfo_base_output_resolution_get(eai, &width, &height))
7646      {
7647         ELOGF("TZ_APPINFO", "cannot read size. pid:%u", NULL, pid);
7648         goto err;
7649      }
7650
7651    tizen_launch_appinfo_send_base_output_resolution_done(res_tzlaunch_appinfo, pid, width, height);
7652    ELOGF("TZ_APPINFO", "send Output base_output_resolution size(%d, %d) : pid(%u)", NULL, width, height, pid);
7653
7654    return;
7655
7656 err:
7657    width = e_config->configured_output_resolution.w;
7658    height = e_config->configured_output_resolution.h;
7659    ELOGF("TZ_APPINFO", "send Output base_output_resolution size(%d, %d) : pid(%u)", NULL, width, height, pid);
7660    tizen_launch_appinfo_send_base_output_resolution_done(res_tzlaunch_appinfo, pid, width, height);
7661
7662    return;
7663 }
7664
7665 static void
7666 _tzlaunch_appinfo_iface_cb_register_appid(struct wl_client *client, struct wl_resource *res_tzlaunch_appinfo,
7667                                           const char *appid)
7668 {
7669    E_Policy_Wl_Tzlaunch_Appinfo *tzlaunch_appinfo = NULL;
7670    E_Appinfo *eai = NULL;
7671
7672    tzlaunch_appinfo = wl_resource_get_user_data(res_tzlaunch_appinfo);
7673    if (!tzlaunch_appinfo)
7674      {
7675         wl_resource_post_error(res_tzlaunch_appinfo,
7676                                WL_DISPLAY_ERROR_INVALID_OBJECT,
7677                                "Invalid tzlaunch_appinfo's user data");
7678         return;
7679      }
7680
7681    if ((eai = e_appinfo_find_with_appid(appid)))
7682      {
7683         ELOGF("TZ_APPINFO", "appid:%s is already registered!", NULL, appid);
7684         return;
7685      }
7686
7687    eai = e_appinfo_new();
7688    EINA_SAFETY_ON_NULL_RETURN(eai);
7689
7690    if (!e_appinfo_appid_set(eai, appid))
7691      {
7692         ELOGF("TZ_APPINFO", "Failed to register appid:%s", NULL, appid);
7693         e_appinfo_del(eai);
7694         return;
7695      }
7696
7697    e_appinfo_owner_set(eai, E_APPINFO_OWNER_CLIENT);
7698 }
7699
7700 static void
7701 _tzlaunch_appinfo_iface_cb_deregister_appid(struct wl_client *client, struct wl_resource *res_tzlaunch_appinfo,
7702                                             const char *appid)
7703 {
7704    E_Policy_Wl_Tzlaunch_Appinfo *tzlaunch_appinfo = NULL;
7705    E_Appinfo *eai = NULL;
7706
7707    tzlaunch_appinfo = wl_resource_get_user_data(res_tzlaunch_appinfo);
7708    if (!tzlaunch_appinfo)
7709      {
7710         wl_resource_post_error(res_tzlaunch_appinfo,
7711                                WL_DISPLAY_ERROR_INVALID_OBJECT,
7712                                "Invalid tzlaunch_appinfo's user data");
7713         return;
7714      }
7715
7716    eai = e_appinfo_find_with_appid(appid);
7717    EINA_SAFETY_ON_NULL_RETURN(eai);
7718
7719    e_appinfo_del(eai);
7720 }
7721
7722 static void
7723 _tzlaunch_appinfo_iface_cb_set_pid(struct wl_client *client, struct wl_resource *res_tzlaunch_appinfo,
7724                                    const char *appid, uint32_t pid)
7725 {
7726    E_Policy_Wl_Tzlaunch_Appinfo *tzlaunch_appinfo = NULL;
7727    E_Appinfo *eai = NULL;
7728
7729    tzlaunch_appinfo = wl_resource_get_user_data(res_tzlaunch_appinfo);
7730    if (!tzlaunch_appinfo)
7731      {
7732         wl_resource_post_error(res_tzlaunch_appinfo,
7733                                WL_DISPLAY_ERROR_INVALID_OBJECT,
7734                                "Invalid tzlaunch_appinfo's user data");
7735         return;
7736      }
7737
7738    eai = e_appinfo_find_with_appid(appid);
7739    EINA_SAFETY_ON_NULL_RETURN(eai);
7740
7741    if (!e_appinfo_pid_set(eai, pid))
7742      {
7743         ELOGF("TZ_APPINFO", "Failed to set pid:%u for appid:%s", NULL, pid, appid);
7744         return;
7745      }
7746 }
7747
7748 static void
7749 _tzlaunch_appinfo_iface_cb_ready_metadata(struct wl_client *client, struct wl_resource *res_tzlaunch_appinfo,
7750                                           const char *appid, uint32_t pid)
7751 {
7752    E_Policy_Wl_Tzlaunch_Appinfo *tzlaunch_appinfo = NULL;
7753    E_Appinfo *eai = NULL;
7754    int width = 0, height = 0;
7755
7756    tzlaunch_appinfo = wl_resource_get_user_data(res_tzlaunch_appinfo);
7757    if (!tzlaunch_appinfo)
7758      {
7759         wl_resource_post_error(res_tzlaunch_appinfo,
7760                                WL_DISPLAY_ERROR_INVALID_OBJECT,
7761                                "Invalid tzlaunch_appinfo's user data");
7762         return;
7763      }
7764
7765    eai = e_appinfo_find_with_appid(appid);
7766    EINA_SAFETY_ON_NULL_RETURN(eai);
7767
7768    e_appinfo_ready_metadata(eai, pid);
7769
7770    /* about base  output resolution */
7771    if (e_config->configured_output_resolution.use)
7772      {
7773         // 1. send HOOK with pid
7774         e_policy_wl_base_output_resolution_info_update(pid);
7775         // 2. module must set the base_output_resolution.
7776         if (!e_appinfo_base_output_resolution_get(eai, &width, &height))
7777           {
7778              ELOGF("TZ_APPINFO", "failed to set base_output_resolution in module, pid:%u, appid:%s", NULL, pid, appid);
7779              return;
7780           }
7781         // 3. server has to get the base_screern_resolution via e_appinfo_base_output_resolution_get.
7782         //    3-1. if success, use the base_rescreen_resolution
7783         //    3-2. if fail, get the base_output_resolution from the E_Comp_Wl_Output.
7784
7785         // 4. send output.
7786         if (!e_comp_wl_pid_output_configured_resolution_send(pid, width, height))
7787           {
7788              ELOGF("TZ_APPINFO", "failed to send output_configured_resolution, pid:%u, appid:%s", NULL, pid, appid);
7789              return;
7790           }
7791      }
7792 }
7793
7794 static void
7795 _tzlaunch_appinfo_iface_cb_set_auto_placement(struct wl_client *client, struct wl_resource *res_tzlaunch_appinfo,
7796                                               uint32_t pid)
7797 {
7798    E_Policy_Wl_Tzlaunch_Appinfo *tzlaunch_appinfo = NULL;
7799    E_Appinfo *eai = NULL;
7800
7801    tzlaunch_appinfo = wl_resource_get_user_data(res_tzlaunch_appinfo);
7802    if (!tzlaunch_appinfo)
7803      {
7804         wl_resource_post_error(res_tzlaunch_appinfo,
7805                                WL_DISPLAY_ERROR_INVALID_OBJECT,
7806                                "Invalid tzlaunch_appinfo's user data");
7807         return;
7808      }
7809
7810    eai = e_appinfo_find_with_pid(pid);
7811    EINA_SAFETY_ON_NULL_RETURN(eai);
7812
7813    ELOGF("TZ_APPINFO", "Set auto placement. pid(%d)", NULL, pid);
7814    e_appinfo_auto_placement_set(eai, EINA_TRUE);
7815 }
7816
7817 static const struct tizen_launch_appinfo_interface _tzlaunch_appinfo_iface =
7818 {
7819    _tzlaunch_appinfo_iface_cb_destroy,
7820    _tzlaunch_appinfo_iface_cb_register_pid,
7821    _tzlaunch_appinfo_iface_cb_deregister_pid,
7822    _tzlaunch_appinfo_iface_cb_set_appid,
7823    _tzlaunch_appinfo_iface_cb_get_base_output_resolution,
7824    _tzlaunch_appinfo_iface_cb_register_appid,
7825    _tzlaunch_appinfo_iface_cb_deregister_appid,
7826    _tzlaunch_appinfo_iface_cb_set_pid,
7827    _tzlaunch_appinfo_iface_cb_ready_metadata,
7828    _tzlaunch_appinfo_iface_cb_set_auto_placement,
7829 };
7830
7831 static void
7832 _tzlaunch_appinfo_del(E_Policy_Wl_Tzlaunch_Appinfo *tzlaunch_appinfo)
7833 {
7834    EINA_SAFETY_ON_NULL_RETURN(tzlaunch_appinfo);
7835
7836    polwl->tzlaunch_appinfo = eina_list_remove(polwl->tzlaunch_appinfo, tzlaunch_appinfo);
7837
7838    memset(tzlaunch_appinfo, 0x0, sizeof(E_Policy_Wl_Tzlaunch_Appinfo));
7839    E_FREE(tzlaunch_appinfo);
7840 }
7841
7842 static E_Policy_Wl_Tzlaunch_Appinfo *
7843 _tzlaunch_appinfo_add(struct wl_resource *res_tzlaunch_appinfo)
7844 {
7845    E_Policy_Wl_Tzlaunch_Appinfo *tzlaunch_appinfo;
7846
7847    tzlaunch_appinfo = E_NEW(E_Policy_Wl_Tzlaunch_Appinfo, 1);
7848    EINA_SAFETY_ON_NULL_RETURN_VAL(tzlaunch_appinfo, NULL);
7849
7850    tzlaunch_appinfo->res_tzlaunch_appinfo = res_tzlaunch_appinfo;
7851
7852    polwl->tzlaunch_appinfo = eina_list_append(polwl->tzlaunch_appinfo, tzlaunch_appinfo);
7853
7854    return tzlaunch_appinfo;
7855 }
7856
7857 static void
7858 _tzlaunch_appinfo_cb_unbind(struct wl_resource *res_tzlaunch_appinfo)
7859 {
7860    E_Policy_Wl_Tzlaunch_Appinfo *tzlaunch_appinfo = NULL;
7861    Eina_List *l, *ll;
7862
7863    EINA_LIST_FOREACH_SAFE(polwl->tzlaunch_appinfo, l, ll, tzlaunch_appinfo)
7864      {
7865         if (tzlaunch_appinfo->res_tzlaunch_appinfo != res_tzlaunch_appinfo) continue;
7866         _tzlaunch_appinfo_del(tzlaunch_appinfo);
7867         break;
7868      }
7869 }
7870
7871 static void
7872 _tzlaunch_appinfo_cb_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t ver, uint32_t id)
7873 {
7874    E_Policy_Wl_Tzlaunch_Appinfo *tzlaunch_appinfo = NULL;
7875    struct wl_resource *res_tzlaunch_appinfo;
7876
7877    EINA_SAFETY_ON_NULL_GOTO(polwl, err);
7878
7879    res_tzlaunch_appinfo = wl_resource_create(client,
7880                                      &tizen_launch_appinfo_interface,
7881                                      ver,
7882                                      id);
7883    EINA_SAFETY_ON_NULL_GOTO(res_tzlaunch_appinfo, err);
7884
7885    tzlaunch_appinfo = _tzlaunch_appinfo_add(res_tzlaunch_appinfo);
7886    EINA_SAFETY_ON_NULL_GOTO(tzlaunch_appinfo, err);
7887
7888    wl_resource_set_implementation(res_tzlaunch_appinfo,
7889                                   &_tzlaunch_appinfo_iface,
7890                                   tzlaunch_appinfo,
7891                                   _tzlaunch_appinfo_cb_unbind);
7892
7893    return;
7894
7895 err:
7896    ERR("Could not create tizen_launch_appinfo_interface res: %m");
7897    wl_client_post_no_memory(client);
7898 }
7899
7900 EINTERN void
7901 e_policy_wl_base_output_resolution_info_update(pid_t pid)
7902 {
7903    _e_policy_wl_hook_call(E_POLICY_WL_HOOK_BASE_OUTPUT_RESOLUTION_GET, pid);
7904 }
7905
7906 static Eina_Bool
7907 _e_policy_wl_cb_hook_intercept_show_helper(void *data, E_Client *ec)
7908 {
7909    E_Policy_Wl_Tzpol *tzpol;
7910    E_Policy_Wl_Surface *psurf;
7911    Eina_Iterator *it;
7912    Eina_Bool ret = EINA_TRUE;
7913
7914    it = eina_hash_iterator_data_new(polwl->tzpols);
7915    EINA_ITERATOR_FOREACH(it, tzpol)
7916      {
7917         psurf = _e_policy_wl_tzpol_surf_find(tzpol, ec);
7918         if (psurf)
7919           {
7920              if (psurf->is_background)
7921                {
7922                   ELOGF("TZPOL",
7923                         "BACKGROUND State is On, Deny Show",
7924                         ec);
7925                   ret = EINA_FALSE;
7926                   break;
7927                }
7928           }
7929      }
7930    eina_iterator_free(it);
7931
7932    return ret;
7933 }
7934
7935 static Eina_Bool
7936 _e_policy_wl_cb_scrsaver_on(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
7937 {
7938    if (_scrsaver_mng_res)
7939      tws_service_screensaver_manager_send_idle(_scrsaver_mng_res);
7940    return ECORE_CALLBACK_PASS_ON;
7941 }
7942
7943 static Eina_Bool
7944 _e_policy_wl_cb_scrsaver_off(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
7945 {
7946    if (_scrsaver_mng_res)
7947      tws_service_screensaver_manager_send_active(_scrsaver_mng_res);
7948    return ECORE_CALLBACK_PASS_ON;
7949 }
7950
7951 // --------------------------------------------------------
7952 // E_Policy_Wl_Tz_Indicator
7953 // --------------------------------------------------------
7954 static E_Policy_Wl_Tz_Indicator *
7955 _e_policy_wl_tz_indicator_add(struct wl_resource *res_tz_indicator)
7956 {
7957    E_Policy_Wl_Tz_Indicator *tz_indicator;
7958
7959    tz_indicator = E_NEW(E_Policy_Wl_Tz_Indicator, 1);
7960    EINA_SAFETY_ON_NULL_RETURN_VAL(tz_indicator, NULL);
7961
7962    tz_indicator->res_tz_indicator = res_tz_indicator;
7963
7964    polwl->tz_indicators = eina_list_append(polwl->tz_indicators, tz_indicator);
7965
7966    return tz_indicator;
7967 }
7968
7969 static void
7970 _e_policy_wl_tz_indicator_del(E_Policy_Wl_Tz_Indicator *tz_indicator)
7971 {
7972    EINA_SAFETY_ON_NULL_RETURN(tz_indicator);
7973
7974    polwl->tz_indicators = eina_list_remove(polwl->tz_indicators, tz_indicator);
7975    E_FREE(tz_indicator);
7976 }
7977
7978 static E_Policy_Wl_Tz_Indicator *
7979 _e_policy_wl_tz_indicator_get(struct wl_resource *res_tz_indicator)
7980 {
7981    Eina_List *l;
7982    E_Policy_Wl_Tz_Indicator *tz_indicator;
7983
7984    EINA_LIST_FOREACH(polwl->tz_indicators, l, tz_indicator)
7985      {
7986         if (tz_indicator->res_tz_indicator == res_tz_indicator)
7987           return tz_indicator;
7988      }
7989    return NULL;
7990 }
7991
7992 static E_Policy_Wl_Tz_Indicator *
7993 _e_policy_wl_tz_indicator_get_from_client(E_Client *ec)
7994 {
7995    Eina_List *l;
7996    E_Policy_Wl_Tz_Indicator *tz_indicator;
7997
7998    EINA_LIST_FOREACH(polwl->tz_indicators, l, tz_indicator)
7999      {
8000         if (eina_list_data_find(tz_indicator->ec_list, ec))
8001           return tz_indicator;
8002      }
8003
8004    return NULL;
8005 }
8006
8007 static Eina_Bool
8008 _e_policy_wl_tz_indicator_set_client(struct wl_resource *res_tz_indicator, E_Client *ec)
8009 {
8010    E_Policy_Wl_Tz_Indicator *tz_indicator = NULL;
8011
8012    tz_indicator = _e_policy_wl_tz_indicator_get(res_tz_indicator);
8013    EINA_SAFETY_ON_NULL_RETURN_VAL(tz_indicator, EINA_FALSE);
8014
8015    if (!eina_list_data_find(tz_indicator->ec_list, ec))
8016      tz_indicator->ec_list = eina_list_append(tz_indicator->ec_list, ec);
8017
8018    return EINA_TRUE;
8019 }
8020
8021 static void
8022 _e_policy_wl_tz_indicator_unset_client(E_Client *ec)
8023 {
8024    Eina_List *l;
8025    E_Policy_Wl_Tz_Indicator *tz_indicator;
8026
8027    EINA_SAFETY_ON_NULL_RETURN(ec);
8028
8029    EINA_LIST_FOREACH(polwl->tz_indicators, l, tz_indicator)
8030      {
8031         if (eina_list_data_find(tz_indicator->ec_list, ec))
8032           tz_indicator->ec_list = eina_list_remove(tz_indicator->ec_list, ec);
8033      }
8034 }
8035
8036 static void
8037 _tz_indicator_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tz_indicator)
8038 {
8039    wl_resource_destroy(res_tz_indicator);
8040 }
8041
8042 static void
8043 _tz_indicator_cb_state_set(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tz_indicator, struct wl_resource *surf, int32_t state)
8044 {
8045    E_Client *ec;
8046    E_Indicator_State ind_state;
8047
8048    ec = e_client_from_surface_resource(surf);
8049    EINA_SAFETY_ON_NULL_RETURN(ec);
8050    EINA_SAFETY_ON_NULL_RETURN(ec->frame);
8051
8052    if (state == TIZEN_INDICATOR_STATE_ON)
8053      ind_state = E_INDICATOR_STATE_ON;
8054    else if (state == TIZEN_INDICATOR_STATE_OFF)
8055      ind_state = E_INDICATOR_STATE_OFF;
8056    else
8057      ind_state = E_INDICATOR_STATE_UNKNOWN;
8058
8059    ELOGF("TZ_IND", "TZ_STATE:%d, E_STATE:%d", ec, state, ind_state);
8060    _e_policy_wl_tz_indicator_set_client(res_tz_indicator, ec);
8061    ec->indicator.state = ind_state;
8062
8063    e_policy_event_simple(ec, E_EVENT_POLICY_INDICATOR_STATE_CHANGE);
8064 }
8065
8066 static void
8067 _tz_indicator_cb_opacity_mode_set(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tz_indicator, struct wl_resource *surf, int32_t mode)
8068 {
8069    E_Client *ec;
8070    E_Indicator_Opacity_Mode op_mode;
8071
8072    ec = e_client_from_surface_resource(surf);
8073    EINA_SAFETY_ON_NULL_RETURN(ec);
8074    EINA_SAFETY_ON_NULL_RETURN(ec->frame);
8075
8076    switch (mode)
8077      {
8078       case TIZEN_INDICATOR_OPACITY_MODE_OPAQUE:
8079         op_mode = E_INDICATOR_OPACITY_MODE_OPAQUE;
8080         break;
8081
8082       case TIZEN_INDICATOR_OPACITY_MODE_TRANSLUCENT:
8083         op_mode = E_INDICATOR_OPACITY_MODE_TRANSLUCENT;
8084         break;
8085
8086       case TIZEN_INDICATOR_OPACITY_MODE_TRANSPARENT:
8087         op_mode = E_INDICATOR_OPACITY_MODE_TRANSPARENT;
8088         break;
8089
8090       case TIZEN_INDICATOR_OPACITY_MODE_BG_TRANSPARENT:
8091         op_mode = E_INDICATOR_OPACITY_MODE_BG_TRANSPARENT;
8092         break;
8093
8094       default:
8095         op_mode = E_INDICATOR_OPACITY_MODE_OPAQUE;
8096         break;
8097      }
8098
8099    ELOGF("TZ_IND", "TZ_OP_MODE:%d, E_OP_MODE:%d", ec, mode, op_mode);
8100    _e_policy_wl_tz_indicator_set_client(res_tz_indicator, ec);
8101
8102    if (ec->indicator.opacity_mode == op_mode) return;
8103
8104    ec->indicator.opacity_mode = op_mode;
8105    e_tzsh_indicator_srv_property_change_send(ec, ec->e.state.rot.ang.curr);
8106
8107    e_policy_event_simple(ec, E_EVENT_POLICY_INDICATOR_OPACITY_MODE_CHANGE);
8108 }
8109
8110 static void
8111 _tz_indicator_cb_visible_type_set(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tz_indicator, struct wl_resource *surf, int32_t vtype)
8112 {
8113    E_Client *ec;
8114    E_Indicator_Visible_Type vis_type;
8115
8116    ec = e_client_from_surface_resource(surf);
8117    EINA_SAFETY_ON_NULL_RETURN(ec);
8118    EINA_SAFETY_ON_NULL_RETURN(ec->frame);
8119
8120    if (vtype == TIZEN_INDICATOR_VISIBLE_TYPE_SHOWN)
8121      vis_type = E_INDICATOR_VISIBLE_TYPE_SHOWN;
8122    else
8123      vis_type = E_INDICATOR_VISIBLE_TYPE_HIDDEN;
8124
8125    ELOGF("TZ_IND", "TZ_VIS_TYPE:%d, E_VIS_TYPE:%d", ec, vtype, vis_type);
8126    _e_policy_wl_tz_indicator_set_client(res_tz_indicator, ec);
8127    ec->indicator.visible_type = vis_type;
8128
8129    e_policy_event_simple(ec, E_EVENT_POLICY_INDICATOR_VISIBLE_STATE_CHANGE);
8130 }
8131
8132 // --------------------------------------------------------
8133 // tizen_indicator_interface
8134 // --------------------------------------------------------
8135 static const struct tizen_indicator_interface _tz_indicator_iface =
8136 {
8137    _tz_indicator_cb_destroy,
8138    _tz_indicator_cb_state_set,
8139    _tz_indicator_cb_opacity_mode_set,
8140    _tz_indicator_cb_visible_type_set,
8141 };
8142
8143 static void
8144 _tz_indicator_cb_unbind(struct wl_resource *res_tz_indicator)
8145 {
8146    E_Policy_Wl_Tz_Indicator *tz_indicator;
8147
8148    tz_indicator = _e_policy_wl_tz_indicator_get(res_tz_indicator);
8149    EINA_SAFETY_ON_NULL_RETURN(tz_indicator);
8150
8151    _e_policy_wl_tz_indicator_del(tz_indicator);
8152 }
8153
8154 static void
8155 _tz_indicator_cb_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t ver, uint32_t id)
8156 {
8157    E_Policy_Wl_Tz_Indicator *tz_indicator_pol;
8158    struct wl_resource *res_tz_indicator;
8159
8160    EINA_SAFETY_ON_NULL_GOTO(polwl, err);
8161
8162    res_tz_indicator = wl_resource_create(client,
8163                                          &tizen_indicator_interface,
8164                                          ver,
8165                                          id);
8166    EINA_SAFETY_ON_NULL_GOTO(res_tz_indicator, err);
8167
8168    tz_indicator_pol = _e_policy_wl_tz_indicator_add(res_tz_indicator);
8169    EINA_SAFETY_ON_NULL_GOTO(tz_indicator_pol, err);
8170
8171    wl_resource_set_implementation(res_tz_indicator,
8172                                   &_tz_indicator_iface,
8173                                   NULL,
8174                                   _tz_indicator_cb_unbind);
8175    return;
8176
8177 err:
8178    ERR("Could not create tizen_indicator_interface res: %m");
8179    wl_client_post_no_memory(client);
8180 }
8181
8182 EINTERN void
8183 e_policy_wl_indicator_flick_send(E_Client *ec)
8184 {
8185    E_Comp_Wl_Client_Data *cdata;
8186    E_Policy_Wl_Tz_Indicator *tz_indicator;
8187    struct wl_resource *surf;
8188
8189    tz_indicator = _e_policy_wl_tz_indicator_get_from_client(ec);
8190    EINA_SAFETY_ON_NULL_RETURN(tz_indicator);
8191
8192    cdata = e_client_cdata_get(ec);
8193    if (cdata)
8194      surf = cdata->surface;
8195    else
8196      surf = NULL;
8197
8198    ELOGF("TZ_IND", "SEND FLICK EVENT", ec);
8199    tizen_indicator_send_flick(tz_indicator->res_tz_indicator, surf, 0);
8200 }
8201
8202
8203 // --------------------------------------------------------
8204 // E_Policy_Wl_Tz_Clipboard
8205 // --------------------------------------------------------
8206 static E_Policy_Wl_Tz_Clipboard *
8207 _e_policy_wl_tz_clipboard_add(struct wl_resource *res_tz_clipboard)
8208 {
8209    E_Policy_Wl_Tz_Clipboard *tz_clipboard;
8210
8211    tz_clipboard = E_NEW(E_Policy_Wl_Tz_Clipboard, 1);
8212    EINA_SAFETY_ON_NULL_RETURN_VAL(tz_clipboard, NULL);
8213
8214    tz_clipboard->res_tz_clipboard = res_tz_clipboard;
8215    polwl->tz_clipboards = eina_list_append(polwl->tz_clipboards, tz_clipboard);
8216
8217    return tz_clipboard;
8218 }
8219
8220 static void
8221 _e_policy_wl_tz_clipboard_del(E_Policy_Wl_Tz_Clipboard *tz_clipboard)
8222 {
8223    EINA_SAFETY_ON_NULL_RETURN(tz_clipboard);
8224
8225    polwl->tz_clipboards = eina_list_remove(polwl->tz_clipboards, tz_clipboard);
8226    E_FREE(tz_clipboard);
8227 }
8228
8229 static E_Policy_Wl_Tz_Clipboard *
8230 _e_policy_wl_tz_clipboard_get_from_client(E_Client *ec)
8231 {
8232    Eina_List *l;
8233    E_Policy_Wl_Tz_Clipboard *tz_clipboard;
8234
8235    EINA_LIST_FOREACH(polwl->tz_clipboards, l, tz_clipboard)
8236      {
8237         if (eina_list_data_find(tz_clipboard->ec_list, ec))
8238           return tz_clipboard;
8239      }
8240
8241    return NULL;
8242 }
8243
8244 static Eina_Bool
8245 _e_policy_wl_tz_clipboard_set_client(struct wl_resource *res_tz_clipboard, E_Client *ec)
8246 {
8247    E_Policy_Wl_Tz_Clipboard *tz_clipboard = NULL;
8248
8249    tz_clipboard = wl_resource_get_user_data(res_tz_clipboard);
8250    EINA_SAFETY_ON_NULL_RETURN_VAL(tz_clipboard, EINA_FALSE);
8251
8252    if (!eina_list_data_find(tz_clipboard->ec_list, ec))
8253      {
8254         tz_clipboard->ec_list = eina_list_append(tz_clipboard->ec_list, ec);
8255      }
8256    return EINA_TRUE;
8257 }
8258
8259 static void
8260 _e_policy_wl_tz_clipboard_unset_client(E_Client *ec)
8261 {
8262    Eina_List *l;
8263    E_Policy_Wl_Tz_Clipboard *tz_clipboard = NULL;
8264
8265    EINA_SAFETY_ON_NULL_RETURN(ec);
8266
8267    EINA_LIST_FOREACH(polwl->tz_clipboards, l, tz_clipboard)
8268      {
8269         if (eina_list_data_find(tz_clipboard->ec_list, ec))
8270           {
8271              tz_clipboard->ec_list = eina_list_remove(tz_clipboard->ec_list, ec);
8272           }
8273      }
8274 }
8275
8276 // --------------------------------------------------------
8277 // tizen_clipboard_interface
8278 // --------------------------------------------------------
8279 static void
8280 _tz_clipboard_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tz_clipboard)
8281 {
8282    wl_resource_destroy(res_tz_clipboard);
8283 }
8284
8285 static void
8286 _tz_clipboard_cb_show(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tz_clipboard, struct wl_resource *surf)
8287 {
8288    E_Client *ec;
8289
8290    ec = e_client_from_surface_resource(surf);
8291    EINA_SAFETY_ON_NULL_RETURN(ec);
8292    EINA_SAFETY_ON_NULL_RETURN(ec->frame);
8293
8294    _e_policy_wl_tz_clipboard_set_client(res_tz_clipboard, ec);
8295    e_service_cbhm_parent_set(ec, EINA_TRUE);
8296    e_service_cbhm_show();
8297 }
8298
8299 static void
8300 _tz_clipboard_cb_hide(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tz_clipboard, struct wl_resource *surf)
8301 {
8302    E_Client *ec;
8303
8304    ec = e_client_from_surface_resource(surf);
8305    EINA_SAFETY_ON_NULL_RETURN(ec);
8306    EINA_SAFETY_ON_NULL_RETURN(ec->frame);
8307
8308    e_service_cbhm_parent_set(ec, EINA_FALSE);
8309    e_service_cbhm_hide();
8310 }
8311
8312 static void
8313 _tz_clipboard_cb_data_only_set(struct wl_client *client, struct wl_resource *res_tz_clipboard, uint32_t set)
8314 {
8315    E_Policy_Wl_Tz_Clipboard *tz_clipboard = NULL;
8316    struct wl_client *_wc;
8317    struct wl_resource *data_res;
8318    pid_t pid = 0;
8319    uid_t uid = 0;
8320    Eina_Bool res;
8321    Eina_List *clients;
8322    E_Client *ec, *found = NULL;
8323    E_Comp_Wl_Client_Data *cdata;
8324
8325    tz_clipboard = wl_resource_get_user_data(res_tz_clipboard);
8326    EINA_SAFETY_ON_NULL_RETURN(tz_clipboard);
8327
8328    if (tz_clipboard->ec_list)
8329      {
8330         ELOGF("TZPOL",
8331               "Unable to set data only mode for wl_client(%p) : "
8332               "ec_list exists",
8333               NULL, client);
8334         goto send_deny;
8335      }
8336
8337    if (!(data_res = e_comp_wl_data_find_for_client(client)))
8338      {
8339         ELOGF("TZPOL",
8340               "Unable to set data only mode for wl_client(%p) : "
8341               "no wl_data_device resource",
8342               NULL, client);
8343         goto send_deny;
8344      }
8345
8346    clients = _e_policy_wl_e_clients_find_by_pid(pid);
8347    if (clients)
8348      {
8349         EINA_LIST_FREE(clients, ec)
8350           {
8351              if (found) continue;
8352              cdata = e_client_cdata_get(ec);
8353              if (cdata && cdata->surface)
8354                {
8355                   _wc = wl_resource_get_client(cdata->surface);
8356                   if (_wc == client)
8357                     found = ec;
8358                }
8359           }
8360      }
8361
8362    if (found)
8363      {
8364         ELOGF("TZPOL",
8365               "Unable to set data only mode for wl_client(%p) : "
8366               "have ec(%p)",
8367               NULL, client, ec);
8368         goto send_deny;
8369      }
8370
8371    /* Privilege Check */
8372    wl_client_get_credentials(client, &pid, &uid, NULL);
8373    res = e_security_privilege_check(pid, uid,
8374                                     E_PRIVILEGE_DATA_ONLY_SET);
8375    if (!res)
8376      {
8377         ELOGF("TZPOL",
8378               "Privilege Check Failed! DENY data_only_set",
8379               NULL);
8380         goto send_deny;
8381      }
8382
8383    ELOGF("TZPOL",
8384          "Set data only mode :%d for wl_client(%p)",
8385          NULL, set, client);
8386    e_comp_wl_data_device_only_set(data_res, !(set == 0));
8387    tizen_clipboard_send_allowed_data_only(res_tz_clipboard, (uint32_t)1);
8388    return;
8389
8390 send_deny:
8391    tizen_clipboard_send_allowed_data_only(res_tz_clipboard, (uint32_t)0);
8392 }
8393
8394 static const struct tizen_clipboard_interface _tz_clipboard_iface =
8395 {
8396    _tz_clipboard_cb_destroy,
8397    _tz_clipboard_cb_show,
8398    _tz_clipboard_cb_hide,
8399    _tz_clipboard_cb_data_only_set,
8400 };
8401
8402 static void
8403 _tz_clipboard_cb_unbind(struct wl_resource *res_tz_clipboard)
8404 {
8405    E_Policy_Wl_Tz_Clipboard *tz_clipboard;
8406
8407    tz_clipboard = wl_resource_get_user_data(res_tz_clipboard);
8408    EINA_SAFETY_ON_NULL_RETURN(tz_clipboard);
8409
8410    _e_policy_wl_tz_clipboard_del(tz_clipboard);
8411 }
8412
8413 static void
8414 _tz_clipboard_cb_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t ver, uint32_t id)
8415 {
8416    E_Policy_Wl_Tz_Clipboard *tz_clipboard_pol;
8417    struct wl_resource *res_tz_clipboard;
8418
8419    EINA_SAFETY_ON_NULL_GOTO(polwl, err);
8420
8421    res_tz_clipboard = wl_resource_create(client,
8422                                          &tizen_clipboard_interface,
8423                                          ver,
8424                                          id);
8425    EINA_SAFETY_ON_NULL_GOTO(res_tz_clipboard, err);
8426
8427    tz_clipboard_pol = _e_policy_wl_tz_clipboard_add(res_tz_clipboard);
8428    EINA_SAFETY_ON_NULL_GOTO(tz_clipboard_pol, err);
8429
8430    wl_resource_set_implementation(res_tz_clipboard,
8431                                   &_tz_clipboard_iface,
8432                                   tz_clipboard_pol,
8433                                   _tz_clipboard_cb_unbind);
8434    return;
8435
8436 err:
8437    ERR("Could not create tizen_clipboard_interface res: %m");
8438    wl_client_post_no_memory(client);
8439 }
8440
8441 EINTERN void
8442 e_policy_wl_clipboard_data_selected_send(E_Client *ec)
8443 {
8444    E_Comp_Wl_Client_Data *cdata;
8445    E_Policy_Wl_Tz_Clipboard *tz_clipboard;
8446
8447    EINA_SAFETY_ON_NULL_RETURN(ec);
8448
8449    tz_clipboard = _e_policy_wl_tz_clipboard_get_from_client(ec);
8450    EINA_SAFETY_ON_NULL_RETURN(tz_clipboard);
8451
8452    cdata = e_client_cdata_get(ec);
8453    tizen_clipboard_send_data_selected(tz_clipboard->res_tz_clipboard,
8454                                       cdata ? cdata->surface : NULL);
8455 }
8456
8457 static void
8458 _e_policy_wl_cb_hook_shell_surface_ready(void *d, E_Client *ec)
8459 {
8460    int w = 0, h = 0;
8461
8462    if (EINA_UNLIKELY(!ec))
8463      return;
8464
8465    e_client_base_output_resolution_update(ec);
8466
8467    e_policy_client_maximize(ec);
8468
8469    e_client_base_output_resolution_transform_adjust(ec);
8470
8471    if (ec->lock_client_size)
8472      {
8473         w = ec->w;
8474         h = ec->h;
8475      }
8476    e_client_shell_configure_send(ec, 0, w, h);
8477 }
8478
8479 static void
8480 _e_policy_wl_cb_hook_alpha_change(void *data, E_Client *ec)
8481 {
8482    if (!ec) return;
8483    if (!ec->argb) return;
8484    if (!ec->transients) return;
8485    if (!e_policy_visibility_client_is_uniconify_render_running(ec)) return;
8486
8487    E_Client *child;
8488    Eina_List *list = eina_list_clone(ec->transients);
8489
8490    EINA_LIST_FREE(list, child)
8491      {
8492         if (e_client_transient_policy_get(child) == E_TRANSIENT_BELOW)
8493           {
8494              ELOGF("POL_VIS", "Uniconify below child(win:%zx, ec:%p) by changing alpha", ec, e_client_util_win_get(child), child);
8495              e_policy_client_uniconify_by_visibility(child);
8496           }
8497      }
8498 }
8499
8500 static void
8501 _e_policy_wl_client_cb_resize_end(void *data EINA_UNUSED, E_Client *ec)
8502 {
8503    int x, y, w, h;
8504
8505    if (e_object_is_del(E_OBJECT(ec))) return;
8506    if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
8507
8508    if (ec->manage_resize.resize_obj)
8509      {
8510         x = ec->manage_resize.x;
8511         y = ec->manage_resize.y;
8512         w = ec->manage_resize.w;
8513         h = ec->manage_resize.h;
8514      }
8515    else
8516      {
8517         x = ec->x;
8518         y = ec->y;
8519         w = ec->w;
8520         h = ec->h;
8521         e_client_geometry_get(ec, &x, &y, &w, &h);
8522      }
8523
8524    E_Policy_Wl_Tzpol *tzpol;
8525    E_Policy_Wl_Surface *psurf;
8526    Eina_List *l;
8527    Eina_Iterator *it;
8528    int ver = -1;
8529
8530    it = eina_hash_iterator_data_new(polwl->tzpols);
8531    EINA_ITERATOR_FOREACH(it, tzpol)
8532      {
8533         EINA_LIST_FOREACH(tzpol->psurfs, l, psurf)
8534           {
8535              if (e_pixmap_client_get(psurf->cp) != ec) continue;
8536              if (!psurf->surf) continue;
8537
8538              ver = wl_resource_get_version(tzpol->res_tzpol);
8539              if (ver < 10)
8540                {
8541                   // interactive_resize_done event is supported since ver 10
8542                   continue;
8543                }
8544
8545              tizen_policy_send_interactive_resize_done(tzpol->res_tzpol,
8546                                                        psurf->surf, x, y, w, h,
8547                                                        ec->e.state.rot.ang.curr);
8548           }
8549      }
8550    eina_iterator_free(it);
8551 }
8552
8553 static void
8554 _e_policy_wl_client_cb_move_end(void *data EINA_UNUSED, E_Client *ec)
8555 {
8556    if (e_object_is_del(E_OBJECT(ec))) return;
8557    if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
8558
8559    int x, y, w, h;
8560    x = ec->x;
8561    y = ec->y;
8562    w = ec->w;
8563    h = ec->h;
8564    e_client_geometry_get(ec, &x, &y, &w, &h);
8565
8566    E_Policy_Wl_Tzpol *tzpol;
8567    E_Policy_Wl_Surface *psurf;
8568    Eina_List *l;
8569    Eina_Iterator *it;
8570    int ver = -1;
8571
8572    it = eina_hash_iterator_data_new(polwl->tzpols);
8573    EINA_ITERATOR_FOREACH(it, tzpol)
8574      {
8575         EINA_LIST_FOREACH(tzpol->psurfs, l, psurf)
8576           {
8577              if (e_pixmap_client_get(psurf->cp) != ec) continue;
8578              if (!psurf->surf) continue;
8579
8580              ver = wl_resource_get_version(tzpol->res_tzpol);
8581              if (ver < 10)
8582                {
8583                   // interactive_move_done event is supported since ver 10
8584                   continue;
8585                }
8586
8587              tizen_policy_send_interactive_move_done(tzpol->res_tzpol,
8588                                                      psurf->surf,
8589                                                      x, y, w, h,
8590                                                      ec->e.state.rot.ang.curr);
8591           }
8592      }
8593    eina_iterator_free(it);
8594 }
8595
8596 void
8597 e_policy_wl_generate_request(E_Client *ec, E_Policy_Wl_Gen_Request type)
8598 {
8599    E_Comp_Wl_Client_Data *cdata = NULL;
8600    if (!ec) return;
8601
8602    cdata = e_client_cdata_get(ec);
8603    if (!cdata) return;
8604    if (!cdata->wl_surface) return;
8605
8606    ELOGF("POL", "Generate operation (type:%d)", ec, type);
8607    switch (type)
8608      {
8609       case E_POLICY_WL_GENERATE_REQUEST_LOWER:
8610          _tzpol_iface_cb_lower(NULL, NULL, cdata->wl_surface);
8611          break;
8612       case E_POLICY_WL_GENERATE_REQUEST_ACTIVATE:
8613          _tzpol_iface_cb_activate(NULL, NULL, cdata->wl_surface);
8614          break;
8615       case E_POLICY_WL_GENERATE_REQUEST_ICONIFY:
8616          _tzpol_iface_cb_iconify(NULL, NULL, cdata->wl_surface);
8617          break;
8618       case E_POLICY_WL_GENERATE_REQUEST_UNICONIFY:
8619          _tzpol_iface_cb_uniconify(NULL, NULL, cdata->wl_surface);
8620          break;
8621       default:
8622          break;
8623      }
8624 }
8625
8626 EINTERN void
8627 e_policy_wl_aux_hint_apply(E_Client *ec)
8628 {
8629    _e_policy_wl_aux_hint_apply(ec);
8630 }
8631
8632 // --------------------------------------------------------
8633 // public functions
8634 // --------------------------------------------------------
8635 EINTERN void
8636 e_policy_wl_client_add(E_Client *ec)
8637 {
8638    EINA_SAFETY_ON_NULL_RETURN(ec);
8639    if (!ec->pixmap) return;
8640
8641    _e_policy_wl_surf_client_set(ec);
8642    _e_policy_wl_tzlaunch_effect_type_sync(ec);
8643 }
8644
8645 EINTERN void
8646 e_policy_wl_client_del(E_Client *ec)
8647 {
8648    EINA_SAFETY_ON_NULL_RETURN(ec);
8649    if (!ec->pixmap) return;
8650
8651    e_policy_wl_pixmap_del(ec->pixmap);
8652    _e_policy_wl_dpy_surf_del(ec);
8653    _e_policy_wl_tz_indicator_unset_client(ec);
8654    _e_policy_wl_tz_clipboard_unset_client(ec);
8655    _launch_effect_client_del(ec);
8656
8657    polwl->pending_vis = eina_list_remove(polwl->pending_vis, ec);
8658 }
8659
8660 EINTERN void
8661 e_policy_wl_pixmap_del(E_Pixmap *cp)
8662 {
8663    E_Policy_Wl_Tzpol *tzpol;
8664    E_Policy_Wl_Surface *psurf;
8665    Eina_List *l, *ll;
8666    Eina_Iterator *it;
8667
8668    it = eina_hash_iterator_data_new(polwl->tzpols);
8669    EINA_ITERATOR_FOREACH(it, tzpol)
8670      EINA_LIST_FOREACH_SAFE(tzpol->psurfs, l, ll, psurf)
8671        {
8672           if (psurf->cp != cp) continue;
8673           tzpol->psurfs = eina_list_remove_list(tzpol->psurfs, l);
8674           _e_policy_wl_surf_del(psurf);
8675        }
8676    eina_iterator_free(it);
8677 }
8678
8679 EINTERN void
8680 e_policy_wl_aux_message_send(E_Client *ec,
8681                              const char *key,
8682                              const char *val,
8683                              Eina_List *options)
8684 {
8685    E_Comp_Wl_Client_Data *cdata;
8686    E_Policy_Wl_Tzpol *tzpol;
8687    E_Policy_Wl_Surface *psurf;
8688    Eina_List *l;
8689    Eina_Iterator *it;
8690    struct wl_array opt_array;
8691    const char *option;
8692    int len;
8693    char *p;
8694
8695    if (e_object_is_del(E_OBJECT(ec))) return;
8696    cdata = e_client_cdata_get(ec);
8697    if (!cdata) return;
8698    if (!cdata->aux_hint.use_msg) return;
8699
8700    wl_array_init(&opt_array);
8701    EINA_LIST_FOREACH(options, l, option)
8702      {
8703         len = strlen(option) + 1;
8704         p = wl_array_add(&opt_array, len);
8705
8706         if (p == NULL)
8707           break;
8708         strncpy(p, option, len);
8709      }
8710
8711    it = eina_hash_iterator_data_new(polwl->tzpols);
8712    EINA_ITERATOR_FOREACH(it, tzpol)
8713       EINA_LIST_FOREACH(tzpol->psurfs, l, psurf)
8714         {
8715            if (e_pixmap_client_get(psurf->cp) != ec) continue;
8716            if (!psurf->surf) continue;
8717
8718            tizen_policy_send_aux_message(tzpol->res_tzpol,
8719                                          psurf->surf,
8720                                          key, val, &opt_array);
8721           ELOGF("TZPOL",
8722                 "SEND     |res_tzpol:%8p|aux message key:%s val:%s opt_count:%d",
8723                 ec,
8724                 tzpol->res_tzpol,
8725                 key, val, eina_list_count(options));
8726         }
8727    eina_iterator_free(it);
8728    wl_array_release(&opt_array);
8729 }
8730
8731 EINTERN void
8732 e_policy_wl_aux_hint_init(void)
8733 {
8734    int i, n;
8735    E_Config_Aux_Hint_Supported *auxhint;
8736    Eina_List *l;
8737
8738    n = (sizeof(hint_names) / sizeof(char *));
8739
8740    for (i = 0; i < n; i++)
8741      {
8742         e_hints_aux_hint_supported_add(hint_names[i]);
8743      }
8744
8745    EINA_LIST_FOREACH(e_config->aux_hint_supported, l, auxhint)
8746      {
8747         if (!auxhint->name) continue;
8748         e_hints_aux_hint_supported_add(auxhint->name);
8749      }
8750
8751    return;
8752 }
8753
8754 EINTERN Eina_Bool
8755 e_policy_wl_defer_job(void)
8756 {
8757    struct wl_global *global = NULL;
8758    EINA_SAFETY_ON_NULL_GOTO(polwl, err);
8759
8760    if (!e_config->global_object_not_provide.launch_effect)
8761      {
8762         global = wl_global_create(e_comp_wl->wl.disp,
8763                                   &tizen_launch_effect_interface,
8764                                   1,
8765                                   NULL,
8766                                   _tzlaunch_effect_cb_bind);
8767         EINA_SAFETY_ON_NULL_GOTO(global, err);
8768
8769         polwl->globals = eina_list_append(polwl->globals, global);
8770      }
8771
8772    global = wl_global_create(e_comp_wl->wl.disp,
8773                              &tizen_launch_appinfo_interface,
8774                              2,
8775                              NULL,
8776                              _tzlaunch_appinfo_cb_bind);
8777    EINA_SAFETY_ON_NULL_GOTO(global, err);
8778
8779    polwl->globals = eina_list_append(polwl->globals, global);
8780
8781    return EINA_TRUE;
8782
8783 err:
8784    return EINA_FALSE;
8785 }
8786
8787 EINTERN Eina_Bool
8788 e_policy_wl_init(void)
8789 {
8790    struct wl_global *global;
8791
8792    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, EINA_FALSE);
8793    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl->wl.disp, EINA_FALSE);
8794
8795    polwl = E_NEW(E_Policy_Wl, 1);
8796    EINA_SAFETY_ON_NULL_RETURN_VAL(polwl, EINA_FALSE);
8797
8798    /* create globals */
8799    global = wl_global_create(e_comp_wl->wl.disp,
8800                              &tizen_policy_interface,
8801                              13,
8802                              NULL,
8803                              _tzpol_cb_bind);
8804    EINA_SAFETY_ON_NULL_GOTO(global, err);
8805    polwl->globals = eina_list_append(polwl->globals, global);
8806
8807    global = wl_global_create(e_comp_wl->wl.disp,
8808                              &tizen_display_policy_interface,
8809                              1,
8810                              NULL,
8811                              _tz_dpy_pol_cb_bind);
8812    EINA_SAFETY_ON_NULL_GOTO(global, err);
8813    polwl->globals = eina_list_append(polwl->globals, global);
8814
8815    global = wl_global_create(e_comp_wl->wl.disp,
8816                              &tizen_ws_shell_interface,
8817                              4,
8818                              NULL,
8819                              _tzsh_cb_bind);
8820
8821    EINA_SAFETY_ON_NULL_GOTO(global, err);
8822    polwl->globals = eina_list_append(polwl->globals, global);
8823
8824    global = wl_global_create(e_comp_wl->wl.disp,
8825                              &tizen_indicator_interface,
8826                              1,
8827                              NULL,
8828                              _tz_indicator_cb_bind);
8829    EINA_SAFETY_ON_NULL_GOTO(global, err);
8830    polwl->globals = eina_list_append(polwl->globals, global);
8831
8832    global = wl_global_create(e_comp_wl->wl.disp,
8833                              &tizen_clipboard_interface,
8834                              2,
8835                              NULL,
8836                              _tz_clipboard_cb_bind);
8837    EINA_SAFETY_ON_NULL_GOTO(global, err);
8838    polwl->globals = eina_list_append(polwl->globals, global);
8839
8840    polwl->tzpols = eina_hash_pointer_new(_e_policy_wl_tzpol_del);
8841
8842    E_COMP_OBJECT_INTERCEPT_HOOK_APPEND(hooks_co, E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, _e_policy_wl_cb_hook_intercept_show_helper, NULL);
8843
8844    E_LIST_HANDLER_APPEND(handlers, E_EVENT_SCREENSAVER_ON,  _e_policy_wl_cb_scrsaver_on,  NULL);
8845    E_LIST_HANDLER_APPEND(handlers, E_EVENT_SCREENSAVER_OFF, _e_policy_wl_cb_scrsaver_off, NULL);
8846
8847    E_COMP_WL_HOOK_APPEND(hooks_cw, E_COMP_WL_HOOK_SHELL_SURFACE_READY, _e_policy_wl_cb_hook_shell_surface_ready, NULL);
8848    E_COMP_WL_HOOK_APPEND(hooks_cw, E_COMP_WL_HOOK_CLIENT_ALPHA_CHANGE, _e_policy_wl_cb_hook_alpha_change, NULL);
8849
8850    E_LIST_HOOK_APPEND(polwl_hooks_ec, E_CLIENT_HOOK_RESIZE_END, _e_policy_wl_client_cb_resize_end, NULL);
8851    E_LIST_HOOK_APPEND(polwl_hooks_ec, E_CLIENT_HOOK_MOVE_END, _e_policy_wl_client_cb_move_end, NULL);
8852
8853    E_EVENT_POLICY_INDICATOR_STATE_CHANGE = ecore_event_type_new();
8854    E_EVENT_POLICY_INDICATOR_OPACITY_MODE_CHANGE = ecore_event_type_new();
8855    E_EVENT_POLICY_INDICATOR_VISIBLE_STATE_CHANGE = ecore_event_type_new();
8856
8857    e_service_softkey_client_remove_handler_add();
8858
8859    e_policy_display_init();
8860
8861    return EINA_TRUE;
8862
8863 err:
8864    if (polwl)
8865      {
8866         EINA_LIST_FREE(polwl->globals, global)
8867           wl_global_destroy(global);
8868
8869         E_FREE(polwl);
8870      }
8871    return EINA_FALSE;
8872 }
8873
8874 EINTERN void
8875 e_policy_wl_shutdown(void)
8876 {
8877    E_Policy_Wl_Tzsh *tzsh;
8878    E_Policy_Wl_Tzsh_Srv *tzsh_srv;
8879    E_Policy_Wl_Tzsh_Extension *tzsh_extension;
8880    E_Policy_Wl_Tzlaunch_Effect_Info *effect_info;
8881    E_Policy_Wl_Tz_Dpy_Pol *tz_dpy_pol;
8882    E_Policy_Wl_Tz_Indicator *tz_indicator;
8883    struct wl_global *global;
8884    int i;
8885
8886    e_policy_display_shutdown();
8887
8888    EINA_SAFETY_ON_NULL_RETURN(polwl);
8889
8890    E_FREE_LIST(polwl_hooks_ec, e_client_hook_del);
8891    E_FREE_LIST(hooks_cw, e_comp_wl_hook_del);
8892    E_FREE_LIST(hooks_co, e_comp_object_intercept_hook_del);
8893    E_FREE_LIST(handlers, ecore_event_handler_del);
8894
8895    e_service_softkey_client_remove_handler_del();
8896
8897    polwl->pending_vis = eina_list_free(polwl->pending_vis);
8898
8899    for (i = 0; i < TZSH_SRV_ROLE_MAX; i++)
8900      {
8901         tzsh_srv = polwl->srvs[i];
8902         if (!tzsh_srv) continue;
8903
8904         wl_resource_destroy(tzsh_srv->res_tzsh_srv);
8905      }
8906
8907    EINA_LIST_FREE(polwl->tzshs, tzsh)
8908      wl_resource_destroy(tzsh->res_tzsh);
8909
8910    EINA_LIST_FREE(polwl->tz_dpy_pols, tz_dpy_pol)
8911      {
8912         E_Policy_Wl_Dpy_Surface *dpy_surf;
8913         EINA_LIST_FREE(tz_dpy_pol->dpy_surfs, dpy_surf)
8914           {
8915              E_FREE(dpy_surf);
8916           }
8917         wl_resource_destroy(tz_dpy_pol->res_tz_dpy_pol);
8918      }
8919
8920    EINA_LIST_FREE(polwl->tzlaunch_effect_info, effect_info)
8921      {
8922         E_FREE(effect_info);
8923      }
8924
8925    EINA_LIST_FREE(polwl->tz_indicators, tz_indicator)
8926      {
8927         eina_list_free(tz_indicator->ec_list);
8928         wl_resource_destroy(tz_indicator->res_tz_indicator);
8929      }
8930
8931    EINA_LIST_FREE(polwl->tzsh_extensions, tzsh_extension)
8932      {
8933         free(tzsh_extension->name);
8934      }
8935
8936    EINA_LIST_FREE(polwl->globals, global)
8937      wl_global_destroy(global);
8938
8939    E_FREE_FUNC(polwl->tzpols, eina_hash_free);
8940
8941    E_FREE(polwl);
8942 }