e_client: use e_client_visibility_set/get funtions
[platform/upstream/enlightenment.git] / src / bin / e_info_server.c
1 #include "e_info_server_intern.h"
2 #include "e_utils_intern.h"
3 #include "e_comp_object.h"
4 #include "e_info_protocol_intern.h"
5 #include "e_info_server_input_intern.h"
6 #include "services/e_service_quickpanel_intern.h"
7 #include "services/e_service_kvm_intern.h"
8 #include "e_process_intern.h"
9 #include "e_comp_screen_intern.h"
10 #include "e_comp_wl_rsm_intern.h"
11 #include "e_explicit_sync_intern.h"
12 #include "e_comp_wl_subsurface_intern.h"
13 #include "e_comp_wl_tbm_intern.h"
14 #include "e_comp_intern.h"
15 #include "e_config_intern.h"
16 #include "e_input_intern.h"
17 #include "e_presentation_time_intern.h"
18 #include "e_policy_intern.h"
19 #include "e_policy_wl_intern.h"
20 #include "e_output_intern.h"
21 #include "e_module_intern.h"
22 #include "e_magnifier_intern.h"
23 #include "e_hwc_window_intern.h"
24 #include "e_hwc_windows_intern.h"
25 #include "e_hwc_intern.h"
26 #include "e_focus_intern.h"
27 #include "e_client_video_intern.h"
28 #include "e_video_debug_intern.h"
29 #include "e_client_intern.h"
30 #include "e_comp_object_intern.h"
31 #include "e_desk_area_intern.h"
32 #include "e_desk_intern.h"
33 #include "e_zone_intern.h"
34 #include "e_screensaver_intern.h"
35 #include "e_comp_wl_input_intern.h"
36 #include "e_main_intern.h"
37 #include "e_dbus_conn_intern.h"
38 #include "e_hints_intern.h"
39 #include "e_comp_input_intern.h"
40
41 #include <tbm_bufmgr.h>
42 #include <tbm_surface.h>
43 #include <tbm_surface_internal.h>
44 #include <tdm_helper.h>
45 #include <wayland-tbm-server.h>
46 #include <dlfcn.h>
47 #include <mcheck.h>
48
49 #define EDJE_EDIT_IS_UNSTABLE_AND_I_KNOW_ABOUT_IT
50 #include <Edje_Edit.h>
51
52 #define USE_WAYLAND_LOG_TRACE
53
54 void wl_map_for_each(struct wl_map *map, void *func, void *data);
55
56 #define BUS "org.enlightenment.wm"
57 #define PATH "/org/enlightenment/wm"
58 #define IFACE "org.enlightenment.wm.info"
59
60 #define ERR_BASE "org.enlightenment.wm.Error."
61 #define INVALID_ARGS         ERR_BASE"InvalidArguments"
62 #define GET_CALL_MSG_ARG_ERR ERR_BASE"GetCallMsgArgFailed"
63 #define WIN_NOT_EXIST        ERR_BASE"WindowNotExist"
64 #define INVALID_PROPERTY_NAME        ERR_BASE"InvalidPropertyName"
65 #define FAIL_TO_SET_PROPERTY         ERR_BASE"FailedToSetProperty"
66 #define FAIL_TO_GET_PROPERTY         ERR_BASE"FailedToGetProperty"
67
68 E_API int E_EVENT_INFO_ROTATION_MESSAGE = -1;
69
70 typedef struct _E_Info_Server
71 {
72    Eldbus_Connection *edbus_conn;
73    Eldbus_Connection_Type edbus_conn_type;
74    Eldbus_Service_Interface *iface;
75    Ecore_Event_Handler *dbus_init_done_handler;
76 } E_Info_Server;
77
78 typedef struct _E_Info_Transform
79 {
80    E_Client         *ec;
81    E_Util_Transform *transform;
82    int               id;
83    int               enable;
84    int               background;
85 } E_Info_Transform;
86
87 static E_Info_Server e_info_server;
88 static Eina_List    *e_info_transform_list = NULL;
89
90 static Eina_List    *e_info_dump_hdlrs;
91 static char         *e_info_dump_path;
92 static int           e_info_dump_running;
93 static int           e_info_dump_count;
94 static int           e_info_dump_mark;
95 static int           e_info_dump_mark_count;
96 static int           e_info_dump_remote_surface = 0;
97 static int           e_info_dump_server_or_client = 0; // 1: server 2: client
98 static uint64_t      e_info_dump_win_id = 0;
99
100 //FILE pointer for protocol_trace
101 static FILE *log_fp_ptrace = NULL;
102
103 //wayland protocol logger
104 static struct wl_protocol_logger *e_info_protocol_logger;
105
106 // Module list for module info
107 static Eina_List *module_hook = NULL;
108
109 #define BUF_SNPRINTF(fmt, ARG...) do { \
110    str_l = snprintf(str_buff, str_r, fmt, ##ARG); \
111    str_buff += str_l; \
112    str_r -= str_l; \
113 } while(0)
114
115 #define VALUE_TYPE_FOR_ZONE "iiiiiibii"
116 #define VALUE_TYPE_FOR_TOPVWINS "uuisiiiiibbbiibibbiiiusbbiib"
117 #define VALUE_TYPE_REQUEST_RESLIST "ui"
118 #define VALUE_TYPE_REPLY_RESLIST "ssu"
119 #define VALUE_TYPE_FOR_INPUTDEV "ssiss"
120 #define VALUE_TYPE_FOR_PENDING_COMMIT "uiuu"
121 #define VALUE_TYPE_FOR_FPS "usiud"
122 #define VALUE_TYPE_REQUEST_FOR_KILL "uts"
123 #define VALUE_TYPE_REPLY_KILL "s"
124 #define VALUE_TYPE_REQUEST_FOR_WININFO "t"
125 #define VALUE_TYPE_REPLY_WININFO "uiiiiiibbiibbbiitsiiib"
126 #define VALUE_TYPE_REQUEST_FOR_WININFO_TREE "ti"
127 #define VALUE_TYPE_REPLY_WININFO_TREE "tsia(tsiiiiiiii)"
128
129 enum
130 {
131    E_INFO_SERVER_SIGNAL_WIN_UNDER_TOUCH = 0
132 };
133
134 static E_Info_Transform *_e_info_transform_new(E_Client *ec, int id, int enable, int x, int y, int sx, int sy, int degree, int background, const char *role);
135 static E_Info_Transform *_e_info_transform_find(E_Client *ec, int id);
136 static void              _e_info_transform_set(E_Info_Transform *transform, int enable, int x, int y, int sx, int sy, int degree);
137 static void              _e_info_transform_del(E_Info_Transform *transform);
138 static void              _e_info_transform_del_with_id(E_Client *ec, int id);
139
140 static int _e_info_server_hooks_delete = 0;
141 static int _e_info_server_hooks_walking = 0;
142
143 static Eina_Inlist *_e_info_server_hooks[] =
144 {
145     [E_INFO_SERVER_HOOK_BUFFER_DUMP_BEGIN] = NULL,
146     [E_INFO_SERVER_HOOK_BUFFER_DUMP_END] = NULL
147 };
148
149 static void
150 _e_info_server_hooks_clean(void)
151 {
152    Eina_Inlist *l;
153    E_Info_Server_Hook *iswh;
154    unsigned int x;
155
156    for (x = 0; x < E_INFO_SERVER_HOOK_LAST; x++)
157      EINA_INLIST_FOREACH_SAFE(_e_info_server_hooks[x], l, iswh)
158        {
159           if (!iswh->delete_me) continue;
160           _e_info_server_hooks[x] = eina_inlist_remove(_e_info_server_hooks[x],
161                                                 EINA_INLIST_GET(iswh));
162           free(iswh);
163        }
164 }
165
166 static void
167 _e_info_server_hook_call(E_Info_Server_Hook_Point hookpoint, void *data EINA_UNUSED)
168 {
169    E_Info_Server_Hook *iswh;
170
171    _e_info_server_hooks_walking++;
172    EINA_INLIST_FOREACH(_e_info_server_hooks[hookpoint], iswh)
173      {
174         if (iswh->delete_me) continue;
175         iswh->func(iswh->data);
176      }
177    _e_info_server_hooks_walking--;
178    if ((_e_info_server_hooks_walking == 0) && (_e_info_server_hooks_delete > 0))
179      _e_info_server_hooks_clean();
180 }
181
182 E_API E_Info_Server_Hook *
183 e_info_server_hook_add(E_Info_Server_Hook_Point hookpoint, E_Info_Server_Hook_Cb func, const void *data)
184 {
185    E_Info_Server_Hook *iswh;
186
187    EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_INFO_SERVER_HOOK_LAST, NULL);
188    iswh = E_NEW(E_Info_Server_Hook, 1);
189    EINA_SAFETY_ON_NULL_RETURN_VAL(iswh, NULL);
190    iswh->hookpoint = hookpoint;
191    iswh->func = func;
192    iswh->data = (void*)data;
193    _e_info_server_hooks[hookpoint] = eina_inlist_append(_e_info_server_hooks[hookpoint],
194                                                  EINA_INLIST_GET(iswh));
195    return iswh;
196 }
197
198 E_API void
199 e_info_server_hook_del(E_Info_Server_Hook *iswh)
200 {
201    iswh->delete_me = 1;
202    if (_e_info_server_hooks_walking == 0)
203      {
204         _e_info_server_hooks[iswh->hookpoint] = eina_inlist_remove(_e_info_server_hooks[iswh->hookpoint],
205                                                           EINA_INLIST_GET(iswh));
206         free(iswh);
207      }
208    else
209      _e_info_server_hooks_delete++;
210 }
211
212 EINTERN void
213 e_info_server_hook_call(E_Info_Server_Hook_Point hookpoint)
214 {
215    if (hookpoint >= E_INFO_SERVER_HOOK_LAST) return;
216
217    _e_info_server_hook_call(hookpoint, NULL);
218 }
219
220 static void
221 _e_info_server_ec_hwc_info_get(E_Client *ec, int *hwc, int *hwc_policy, int *pl_zpos)
222 {
223    Eina_List *l;
224    E_Output *eout;
225    E_Zone *zone;
226    E_Plane *ep;
227    E_Hwc_Window *hwc_window = NULL;
228
229    *hwc = -1;
230    *pl_zpos = -999;
231
232    if ((!e_comp->hwc) || e_comp_hwc_deactive_get())
233      return;
234
235    *hwc = 0;
236
237    zone = e_comp_zone_find_by_ec(ec);
238    if (!zone) return;
239    eout = e_output_find(zone->output_id);
240    if (!eout) return;
241
242    *hwc_policy = e_hwc_policy_get(eout->hwc);
243
244    if (*hwc_policy == E_HWC_POLICY_PLANES)
245      {
246         EINA_LIST_FOREACH(eout->planes, l, ep)
247           {
248              if (e_plane_is_fb_target(ep))
249                *pl_zpos = ep->zpos;
250
251              if (ep->ec == ec)
252                {
253                   *hwc = 1;
254                   *pl_zpos = ep->zpos;
255                   break;
256                }
257           }
258      }
259    else
260      {
261         if (!ec->hwc_window) return;
262         hwc_window = ec->hwc_window;
263         if (e_hwc_window_is_on_hw_overlay(hwc_window))
264           *hwc = 1;
265
266         *pl_zpos = e_hwc_window_accepted_state_get(hwc_window);
267      }
268 }
269
270 static Eldbus_Message *
271 _e_info_server_cb_zone_info_get(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
272 {
273    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
274    Eldbus_Message_Iter *iter = eldbus_message_iter_get(reply);
275
276    Eldbus_Message_Iter *array_of_zone;
277    Eina_List *l;
278    E_Zone *zone = NULL;
279    E_Zone *current_zone = NULL;
280    int zone_id = -1;
281    int disp_state = -1;
282    Eina_Bool is_current_zone = EINA_FALSE;
283    int angle_cur = 0;
284    int angle_active = 0;
285
286    eldbus_message_iter_arguments_append(iter, "("VALUE_TYPE_FOR_ZONE")", &array_of_zone);
287
288    current_zone = e_zone_current_get();
289    EINA_LIST_FOREACH(e_comp->zones, l, zone)
290      {
291         Eldbus_Message_Iter *struct_of_zone;
292         zone_id = zone->id;
293         disp_state = e_zone_display_state_get(zone);
294         if (current_zone == zone)
295           is_current_zone = EINA_TRUE;
296         else
297           is_current_zone = EINA_FALSE;
298
299         angle_cur = zone->rot.curr;
300         angle_active = zone->rot.act;
301
302         eldbus_message_iter_arguments_append(array_of_zone, "("VALUE_TYPE_FOR_ZONE")", &struct_of_zone);
303         eldbus_message_iter_arguments_append(struct_of_zone, VALUE_TYPE_FOR_ZONE, zone_id, disp_state, zone->x, zone->y, zone->w, zone->h, is_current_zone, angle_cur, angle_active);
304
305         eldbus_message_iter_container_close(array_of_zone, struct_of_zone);
306      }
307
308    eldbus_message_iter_container_close(iter, array_of_zone);
309
310    return reply;
311 }
312
313 static void
314 _msg_ecs_append(Eldbus_Message_Iter *iter, Eina_Bool is_visible)
315 {
316    Eldbus_Message_Iter *array_of_ec;
317    E_Client *ec;
318
319    eldbus_message_iter_arguments_append(iter, "a("VALUE_TYPE_FOR_TOPVWINS")", &array_of_ec);
320
321    // append clients.
322    E_CLIENT_REVERSE_FOREACH(ec)
323      {
324         Eldbus_Message_Iter* struct_of_ec;
325         Ecore_Window win;
326         Ecore_Window pwin;
327         uint32_t res_id = 0;
328         pid_t pid = -1;
329         char layer_name[128] = {0,};
330         int hwc = -1, hwc_policy = E_HWC_POLICY_NONE, pl_zpos = -999;
331         int iconified = 0;
332         Eina_Bool has_input_region = EINA_FALSE;
333         Eina_List *list_input_region = NULL;
334         Eina_Bool mapped = EINA_FALSE;
335         Eina_Bool transformed = EINA_FALSE;
336         int x = 0, y = 0, w = 0, h = 0;
337         int zone_id = -1;
338         E_Iconified_Type iconified_type;
339         E_Zone *zone;
340
341         if (is_visible && e_client_util_ignored_get(ec)) continue;
342
343         win = e_client_util_win_get(ec);
344         e_comp_layer_name_get(ec->layer, layer_name, sizeof(layer_name));
345
346         pwin = e_client_util_win_get(ec->parent);
347
348         if (ec->pixmap)
349           res_id = e_pixmap_res_id_get(ec->pixmap);
350
351         pid = ec->netwm.pid;
352         if (pid <= 0)
353           {
354              if (ec->comp_data)
355                {
356                   E_Comp_Wl_Client_Data *cdata = (E_Comp_Wl_Client_Data*)ec->comp_data;
357                   if (cdata->surface)
358                     wl_client_get_credentials(wl_resource_get_client(cdata->surface), &pid, NULL, NULL);
359                }
360           }
361
362         if (ec->iconic)
363           {
364              iconified_type = e_client_iconified_type_get(ec);
365              if (iconified_type == 0)
366                {
367                   // if iconified_type is 0, then there is code not to set iconify_type
368                   // before calling e_client_iconify. We have to find and fix it.
369                   iconified = -1;
370                }
371              else
372                iconified = iconified_type;
373           }
374         else
375           iconified = 0;
376
377         if (ec->comp_data)
378           mapped = ec->comp_data->mapped;
379
380         _e_info_server_ec_hwc_info_get(ec, &hwc, &hwc_policy, &pl_zpos);
381
382         e_comp_object_input_rect_get(ec->frame, &list_input_region);
383         if (list_input_region)
384           {
385              has_input_region = EINA_TRUE;
386              list_input_region = eina_list_free(list_input_region);
387           }
388         e_client_geometry_get(ec, &x, &y, &w, &h);
389
390         transformed = e_client_transform_core_enable_get(ec);
391
392         zone = e_comp_zone_find_by_ec(ec);
393         if (zone)
394           zone_id = zone->id;
395
396         eldbus_message_iter_arguments_append(array_of_ec, "("VALUE_TYPE_FOR_TOPVWINS")", &struct_of_ec);
397
398         eldbus_message_iter_arguments_append
399            (struct_of_ec, VALUE_TYPE_FOR_TOPVWINS,
400             win,
401             res_id,
402             pid,
403             e_client_util_name_get(ec) ?: "NO NAME",
404             x, y, w, h, ec->layer,
405             ec->visible, mapped, ec->argb, ec->visibility.opaque, e_client_visibility_get(ec), ec->visibility.force_obscured, iconified,
406             evas_object_visible_get(ec->frame), ec->focused, hwc, hwc_policy, pl_zpos, pwin, layer_name, has_input_region, transformed, ec->transient_policy,
407             zone_id, ec->apply_layout);
408
409         eldbus_message_iter_container_close(array_of_ec, struct_of_ec);
410      }
411
412    eldbus_message_iter_container_close(iter, array_of_ec);
413 }
414
415 static void
416 _msg_clients_append(Eldbus_Message_Iter *iter, Eina_Bool is_visible)
417 {
418    Eldbus_Message_Iter *array_of_ec;
419    E_Client *ec;
420    Evas_Object *o;
421
422    eldbus_message_iter_arguments_append(iter, "a("VALUE_TYPE_FOR_TOPVWINS")", &array_of_ec);
423
424    // append clients.
425    for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
426      {
427         Eldbus_Message_Iter* struct_of_ec;
428         Ecore_Window win;
429         Ecore_Window pwin;
430         uint32_t res_id = 0;
431         pid_t pid = -1;
432         char layer_name[128] = {0,};
433         int hwc = -1, hwc_policy = E_HWC_POLICY_NONE, pl_zpos = -999;
434         int iconified = 0;
435         Eina_Bool has_input_region = EINA_FALSE;
436         Eina_List *list_input_region = NULL;
437         Eina_Bool mapped = EINA_FALSE;
438         Eina_Bool transformed = EINA_FALSE;
439         int zone_id = -1;
440         E_Iconified_Type iconified_type;
441         E_Zone *zone;
442
443         ec = evas_object_data_get(o, "E_Client");
444         if (!ec) continue;
445         if (is_visible && e_client_util_ignored_get(ec)) continue;
446
447         win = e_client_util_win_get(ec);
448         e_comp_layer_name_get(ec->layer, layer_name, sizeof(layer_name));
449
450         pwin = e_client_util_win_get(ec->parent);
451
452         if (ec->pixmap)
453           res_id = e_pixmap_res_id_get(ec->pixmap);
454
455         pid = ec->netwm.pid;
456         if (pid <= 0)
457           {
458              if (ec->comp_data)
459                {
460                   E_Comp_Wl_Client_Data *cdata = (E_Comp_Wl_Client_Data*)ec->comp_data;
461                   if (cdata->surface)
462                     wl_client_get_credentials(wl_resource_get_client(cdata->surface), &pid, NULL, NULL);
463                }
464           }
465
466         if (ec->iconic)
467           {
468              iconified_type = e_client_iconified_type_get(ec);
469              if (iconified_type == 0)
470                {
471                   // if iconified_type is 0, then there is code not to set iconify_type
472                   // before calling e_client_iconify. We have to find and fix it.
473                   iconified = -1;
474                }
475              else
476                iconified = iconified_type;
477           }
478         else
479           iconified = 0;
480
481         if (ec->comp_data)
482           mapped = ec->comp_data->mapped;
483
484         _e_info_server_ec_hwc_info_get(ec, &hwc, &hwc_policy, &pl_zpos);
485
486         e_comp_object_input_rect_get(o, &list_input_region);
487         if (list_input_region)
488           {
489              has_input_region = EINA_TRUE;
490              list_input_region = eina_list_free(list_input_region);
491           }
492
493         transformed = e_client_transform_core_enable_get(ec);
494
495         zone = e_comp_zone_find_by_ec(ec);
496         if (zone)
497           zone_id = zone->id;
498
499         eldbus_message_iter_arguments_append(array_of_ec, "("VALUE_TYPE_FOR_TOPVWINS")", &struct_of_ec);
500
501         eldbus_message_iter_arguments_append
502            (struct_of_ec, VALUE_TYPE_FOR_TOPVWINS,
503             win,
504             res_id,
505             pid,
506             e_client_util_name_get(ec) ?: "NO NAME",
507             ec->x, ec->y, ec->w, ec->h, ec->layer,
508             ec->visible, mapped, ec->argb, ec->visibility.opaque, e_client_visibility_get(ec), ec->visibility.force_obscured, iconified,
509             evas_object_visible_get(ec->frame), ec->focused, hwc, hwc_policy, pl_zpos, pwin, layer_name, has_input_region, transformed, ec->transient_policy,
510             zone_id, ec->apply_layout);
511
512         eldbus_message_iter_container_close(array_of_ec, struct_of_ec);
513      }
514
515    eldbus_message_iter_container_close(iter, array_of_ec);
516 }
517
518 static int
519 _e_info_server_is_hwc_windows()
520 {
521    E_Output *primary_output;
522
523    primary_output = e_comp_screen_primary_output_get(e_comp->e_comp_screen);
524    if (!primary_output)
525       return 0;
526
527    if (e_hwc_policy_get(primary_output->hwc) == E_HWC_POLICY_WINDOWS)
528      return 1;
529
530    return 0;
531 }
532
533 /* Method Handlers */
534 static Eldbus_Message *
535 _e_info_server_cb_window_info_get(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
536 {
537    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
538    Eldbus_Message_Iter *iter = eldbus_message_iter_get(reply);
539
540    eldbus_message_iter_basic_append(iter, 'i', e_comp_gl_get());
541    eldbus_message_iter_basic_append(iter, 'i', e_comp_config_get()->hwc);
542    eldbus_message_iter_basic_append(iter, 'i', e_comp_config_get()->hwc_use_multi_plane);
543    eldbus_message_iter_basic_append(iter, 'i', e_comp->hwc);
544    eldbus_message_iter_basic_append(iter, 'i', _e_info_server_is_hwc_windows());
545    eldbus_message_iter_basic_append(iter, 's', ecore_evas_engine_name_get(e_comp->ee));
546    eldbus_message_iter_basic_append(iter, 'i', e_comp_config_get()->engine);
547    eldbus_message_iter_basic_append(iter, 'i', e_config->use_buffer_flush);
548    eldbus_message_iter_basic_append(iter, 'i', e_config->deiconify_approve);
549
550    _msg_clients_append(iter, EINA_TRUE);
551
552    return reply;
553 }
554
555 /* Method Handlers */
556 static Eldbus_Message *
557 _e_info_server_cb_ec_info_get(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
558 {
559    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
560    Eldbus_Message_Iter *iter = eldbus_message_iter_get(reply);
561
562    eldbus_message_iter_basic_append(iter, 'i', e_comp->hwc);
563    eldbus_message_iter_basic_append(iter, 'i', _e_info_server_is_hwc_windows());
564
565    _msg_ecs_append(iter, EINA_TRUE);
566
567    return reply;
568 }
569 static Eldbus_Message *
570 _e_info_server_cb_all_ec_info_get(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
571 {
572    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
573    Eldbus_Message_Iter *iter = eldbus_message_iter_get(reply);
574
575    eldbus_message_iter_basic_append(iter, 'i', e_comp->hwc);
576    eldbus_message_iter_basic_append(iter, 'i', _e_info_server_is_hwc_windows());
577
578    _msg_ecs_append(iter, EINA_FALSE);
579
580    return reply;
581 }
582
583 /* Method Handlers */
584 static Eldbus_Message *
585 _e_info_server_cb_all_window_info_get(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
586 {
587    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
588    Eldbus_Message_Iter *iter = eldbus_message_iter_get(reply);
589
590    eldbus_message_iter_basic_append(iter, 'i', e_comp->hwc);
591    eldbus_message_iter_basic_append(iter, 'i', _e_info_server_is_hwc_windows());
592
593    _msg_clients_append(iter, EINA_FALSE);
594
595    return reply;
596 }
597
598 typedef struct _Obj_Info
599 {
600    Evas_Object *po; /* parent object */
601    Evas_Object *o;
602    int          depth;
603 } Obj_Info;
604
605 static Obj_Info *
606 _obj_info_get(Evas_Object *po, Evas_Object *o, int depth)
607 {
608    Obj_Info *info = E_NEW(Obj_Info, 1);
609    EINA_SAFETY_ON_NULL_RETURN_VAL(info, NULL);
610
611    info->po = po;
612    info->o = o;
613    info->depth = depth;
614    return info;
615 }
616
617 static E_Info_Comp_Obj *
618 _compobj_info_get(Evas_Object *po, Evas_Object *o, int depth)
619 {
620    E_Info_Comp_Obj *cobj;
621    const char *name = NULL, *type = NULL;
622    const char *file = NULL, *group = NULL, *part = NULL, *key = NULL;
623    E_Client *ec;
624    char buf[PATH_MAX];
625    double val = 0.0f;
626    Evas_Object *edit_obj = NULL, *c = NULL;
627    Eina_List *parts = NULL, *ll;
628    Evas_Native_Surface *ns;
629
630    cobj = E_NEW(E_Info_Comp_Obj, 1);
631    EINA_SAFETY_ON_NULL_RETURN_VAL(cobj, NULL);
632
633    cobj->obj = (uintptr_t)o;
634    cobj->depth = depth;
635
636    type = evas_object_type_get(o);
637    if      (!e_util_strcmp(type, "rectangle"    )) cobj->type = eina_stringshare_add("r");
638    else if (!e_util_strcmp(type, "edje"         )) cobj->type = eina_stringshare_add("EDJ");
639    else if (!e_util_strcmp(type, "image"        )) cobj->type = eina_stringshare_add("IMG");
640    else if (!e_util_strcmp(type, "e_comp_object")) cobj->type = eina_stringshare_add("EC");
641    else                                            cobj->type = eina_stringshare_add(type);
642
643    cobj->name = eina_stringshare_add("no_use");
644    name = evas_object_name_get(o);
645    if (name)
646      {
647         eina_stringshare_del(cobj->name);
648         cobj->name = eina_stringshare_add(name);
649      }
650
651    evas_object_geometry_get(o, &cobj->x, &cobj->y, &cobj->w, &cobj->h);
652    evas_object_color_get(o, &cobj->r, &cobj->g, &cobj->b, &cobj->a);
653    cobj->pass_events = evas_object_pass_events_get(o);
654    cobj->freeze_events = evas_object_freeze_events_get(o);
655    cobj->focus = evas_object_focus_get(o);
656    cobj->vis = evas_object_visible_get(o);
657    cobj->ly = evas_object_layer_get(o);
658
659 #define _CLAMP(x) if ((x >= 0) && (x > 9999)) x = 9999; else if (x < -999) x = -999;
660    _CLAMP(cobj->ly);
661    _CLAMP(cobj->x);
662    _CLAMP(cobj->y);
663    _CLAMP(cobj->w);
664    _CLAMP(cobj->h);
665 #undef _CLAMP
666
667    switch (evas_object_render_op_get(o))
668      {
669       case EVAS_RENDER_BLEND:    cobj->opmode = eina_stringshare_add("BL" ); break;
670       case EVAS_RENDER_COPY:     cobj->opmode = eina_stringshare_add("CP" ); break;
671       default:                   cobj->opmode = eina_stringshare_add("NO" ); break;
672      }
673
674    if ((!e_util_strcmp(cobj->name, "no_use")) &&
675        (!e_util_strcmp(cobj->type, "EC")))
676      {
677         ec = evas_object_data_get(o, "E_Client");
678         if (ec)
679           {
680              /* append window id, client pid and window title */
681              eina_stringshare_del(cobj->name);
682
683              snprintf(buf, sizeof(buf), "%zx %d %s",
684                       e_client_util_win_get(ec),
685                       ec->netwm.pid,
686                       e_client_util_name_get(ec));
687
688              cobj->name = eina_stringshare_add(buf);
689           }
690      }
691
692    /* get edje file path and group name if it is a edje object */
693    cobj->edje.file = eina_stringshare_add("no_use");
694    cobj->edje.group = eina_stringshare_add("no_use");
695    if (!e_util_strcmp(cobj->type, "EDJ"))
696      {
697         edje_object_file_get(o, &file, &group);
698
699         if (file)
700           {
701              eina_stringshare_del(cobj->edje.file);
702              cobj->edje.file = eina_stringshare_add(file);
703           }
704
705         if (group)
706           {
707              eina_stringshare_del(cobj->edje.group);
708              cobj->edje.group = eina_stringshare_add(group);
709           }
710      }
711
712    /* get part name and part value if it is a member of parent edje object */
713    cobj->edje.part = eina_stringshare_add("no_use");
714    if (po)
715      {
716         type = evas_object_type_get(po);
717         if (!e_util_strcmp(type, "edje"))
718           {
719              edje_object_file_get(po, &file, &group);
720              edit_obj = edje_edit_object_add(e_comp->evas);
721              if (edje_object_file_set(edit_obj, file, group))
722                {
723                   parts = edje_edit_parts_list_get(edit_obj);
724                   EINA_LIST_FOREACH(parts, ll, part)
725                     {
726                        c = (Evas_Object *)edje_object_part_object_get(po, part);
727                        if (c == o)
728                          {
729                             edje_object_part_state_get(po, part, &val);
730
731                             eina_stringshare_del(cobj->edje.part);
732                             cobj->edje.part = eina_stringshare_add(part);
733                             cobj->edje.val = val;
734                             break;
735                          }
736                     }
737                   edje_edit_string_list_free(parts);
738                }
739              evas_object_del(edit_obj);
740           }
741      }
742
743    /* get image object information */
744    cobj->img.native_type = eina_stringshare_add("no_use");
745    cobj->img.file = eina_stringshare_add("no_use");
746    cobj->img.key = eina_stringshare_add("no_use");
747
748    if (!e_util_strcmp(cobj->type, "IMG"))
749      {
750         ns = evas_object_image_native_surface_get(o);
751         if (ns)
752           {
753              cobj->img.native = EINA_TRUE;
754              eina_stringshare_del(cobj->img.native_type);
755              switch (ns->type)
756                {
757                 case EVAS_NATIVE_SURFACE_WL:
758                    cobj->img.native_type = eina_stringshare_add("WL");
759                    cobj->img.data = (uintptr_t)ns->data.wl.legacy_buffer;
760                    break;
761                 case EVAS_NATIVE_SURFACE_TBM:
762                    cobj->img.native_type = eina_stringshare_add("TBM");
763                    cobj->img.data = (uintptr_t)ns->data.tbm.buffer;
764                    break;
765                 default:
766                    cobj->img.native_type = eina_stringshare_add("?");
767                    cobj->img.data = 0;
768                    break;
769                }
770           }
771         else
772           {
773              evas_object_image_file_get(o, &file, &key);
774
775              if (file)
776                {
777                   eina_stringshare_del(cobj->img.file);
778                   cobj->img.file = eina_stringshare_add(file);
779                }
780
781              if (key)
782                {
783                   eina_stringshare_del(cobj->img.key);
784                   cobj->img.key = eina_stringshare_add(key);
785                }
786
787              cobj->img.data = (uintptr_t)evas_object_image_data_get(o, 0);
788           }
789
790         evas_object_image_size_get(o, &cobj->img.w, &cobj->img.h);
791         evas_object_image_load_size_get(o, &cobj->img.lw, &cobj->img.lh);
792         evas_object_image_fill_get(o, &cobj->img.fx, &cobj->img.fy, &cobj->img.fw, &cobj->img.fh);
793         cobj->img.alpha = evas_object_image_alpha_get(o);
794         cobj->img.dirty = evas_object_image_pixels_dirty_get(o);
795      }
796
797    if (evas_object_map_enable_get(o))
798      {
799         E_Map *m = e_comp_object_map_get(o);
800         if (m)
801           {
802              int i;
803              cobj->map.enable = EINA_TRUE;
804              cobj->map.alpha = e_map_alpha_get(m);
805              for (i = 0; i < 4; i++)
806                {
807                   Evas_Coord x, y, z;
808                   e_map_point_image_uv_get(m, i, &cobj->map.u[i], &cobj->map.v[i]);
809                   e_map_point_coord_get(m, i, &x, &y, &z);
810                   cobj->map.x[i] = x;
811                   cobj->map.y[i] = y;
812                   cobj->map.z[i] = z;
813                }
814           }
815         e_map_free(m);
816      }
817
818    return cobj;
819 }
820
821 static Eldbus_Message *
822 _e_info_server_cb_compobjs(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
823 {
824    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
825    Eldbus_Message_Iter *iter = eldbus_message_iter_get(reply);
826    Eldbus_Message_Iter *cobjs;
827    Evas_Object *o, *c;
828    Obj_Info *info, *info2;
829    E_Info_Comp_Obj *cobj;
830    Eina_List *stack = NULL; /* stack for DFS */
831    Eina_List *queue = NULL; /* result queue */
832    Eina_List *ll = NULL;
833
834    eldbus_message_iter_arguments_append(iter,
835                                         "a("SIGNATURE_COMPOBJS_CLIENT")",
836                                         &cobjs);
837
838    /* 1. push: top-level evas objects */
839    for (o = evas_object_bottom_get(e_comp->evas); o; o = evas_object_above_get(o))
840      {
841         info = _obj_info_get(NULL, o, 0);
842         if (!info) continue;
843         stack = eina_list_append(stack, info);
844      }
845
846    while (1)
847      {
848         /* 2. pop */
849         info = eina_list_last_data_get(stack);
850         if (!info) break;
851
852         /* store data */
853         cobj = _compobj_info_get(info->po, info->o, info->depth);
854         if (!cobj) continue;
855         queue = eina_list_append(queue, cobj);
856
857         /* 3. push : child objects */
858         if ((evas_object_smart_smart_get(info->o)) || (!e_util_strcmp(cobj->type, "EDJ")))
859           {
860              if (evas_object_smart_data_get(info->o))
861                {
862                   EINA_LIST_FOREACH(evas_object_smart_members_get(info->o), ll, c)
863                     {
864                        info2 = _obj_info_get(info->o, c, info->depth + 1);
865                        stack = eina_list_append(stack, info2);
866                     }
867                }
868           }
869
870         stack = eina_list_remove(stack, info);
871         E_FREE(info);
872      }
873
874    /* send result */
875    EINA_LIST_FREE(queue, cobj)
876      {
877         Eldbus_Message_Iter *struct_of_cobj;
878         eldbus_message_iter_arguments_append(cobjs,
879                                              "("SIGNATURE_COMPOBJS_CLIENT")",
880                                              &struct_of_cobj);
881
882         eldbus_message_iter_arguments_append(struct_of_cobj,
883                                              SIGNATURE_COMPOBJS_CLIENT,
884                                              cobj->obj,
885                                              cobj->depth,
886                                              cobj->type,
887                                              cobj->name,
888                                              cobj->ly,
889                                              cobj->opmode,
890                                              cobj->x, cobj->y, cobj->w, cobj->h,
891                                              cobj->r, cobj->g, cobj->b, cobj->a,
892                                              cobj->pass_events,
893                                              cobj->freeze_events,
894                                              cobj->focus,
895                                              cobj->vis,
896                                              cobj->edje.file,
897                                              cobj->edje.group,
898                                              cobj->edje.part,
899                                              cobj->edje.val,
900                                              cobj->img.native,
901                                              cobj->img.native_type,
902                                              cobj->img.file,
903                                              cobj->img.key,
904                                              cobj->img.data,
905                                              cobj->img.w, cobj->img.h,
906                                              cobj->img.lw, cobj->img.lh,
907                                              cobj->img.fx, cobj->img.fy, cobj->img.fw, cobj->img.fh,
908                                              cobj->img.alpha,
909                                              cobj->img.dirty,
910                                              cobj->map.enable,
911                                              cobj->map.alpha,
912                                              cobj->map.u[0], cobj->map.u[1], cobj->map.u[2], cobj->map.u[3],
913                                              cobj->map.v[0], cobj->map.v[1], cobj->map.v[2], cobj->map.v[3],
914                                              cobj->map.x[0], cobj->map.x[1], cobj->map.x[2], cobj->map.x[3],
915                                              cobj->map.y[0], cobj->map.y[1], cobj->map.y[2], cobj->map.y[3],
916                                              cobj->map.z[0], cobj->map.z[1], cobj->map.z[2], cobj->map.z[3]);
917
918         eldbus_message_iter_container_close(cobjs, struct_of_cobj);
919
920         eina_stringshare_del(cobj->type);
921         eina_stringshare_del(cobj->name);
922         eina_stringshare_del(cobj->opmode);
923         eina_stringshare_del(cobj->edje.file);
924         eina_stringshare_del(cobj->edje.group);
925         eina_stringshare_del(cobj->edje.part);
926         eina_stringshare_del(cobj->img.native_type);
927         eina_stringshare_del(cobj->img.file);
928         eina_stringshare_del(cobj->img.key);
929         E_FREE(cobj);
930      }
931
932    eldbus_message_iter_container_close(iter, cobjs);
933    return reply;
934 }
935
936 static void
937 _input_msg_clients_append(Eldbus_Message_Iter *iter)
938 {
939    Eldbus_Message_Iter *array_of_input;
940    Eina_List *l;
941    E_Devicemgr_Input_Device *dev;
942    const char *output_name = NULL;
943
944    eldbus_message_iter_arguments_append(iter, "a("VALUE_TYPE_FOR_INPUTDEV")", &array_of_input);
945
946    g_rec_mutex_lock(&e_devicemgr->device_list_mutex);
947    EINA_LIST_FOREACH(e_devicemgr->device_list, l, dev)
948      {
949         Eldbus_Message_Iter *struct_of_input;
950
951         eldbus_message_iter_arguments_append(array_of_input, "("VALUE_TYPE_FOR_INPUTDEV")", &struct_of_input);
952
953         output_name = e_input_device_output_name_get(NULL, dev->identifier);
954         if (!output_name) output_name = "None";
955         eldbus_message_iter_arguments_append
956                      (struct_of_input, VALUE_TYPE_FOR_INPUTDEV,
957                       dev->name, dev->identifier, dev->clas, dev->seat_name, output_name);
958
959         eldbus_message_iter_container_close(array_of_input, struct_of_input);
960      }
961    g_rec_mutex_unlock(&e_devicemgr->device_list_mutex);
962    eldbus_message_iter_container_close(iter, array_of_input);
963 }
964
965
966 static Eldbus_Message *
967 _e_info_server_cb_input_device_info_get(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
968 {
969    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
970
971    _input_msg_clients_append(eldbus_message_iter_get(reply));
972
973    return reply;
974 }
975
976 static void
977 _msg_connected_clients_append(Eldbus_Message_Iter *iter)
978 {
979    Eldbus_Message_Iter *array_of_ec;
980    E_Client *ec;
981    Evas_Object *o;
982
983    eldbus_message_iter_arguments_append(iter, "a(ss)", &array_of_ec);
984
985    Eina_List *l;
986    E_Comp_Connected_Client_Info *cinfo;
987
988
989    Eldbus_Message_Iter* struct_of_ec;
990
991 #define __CONNECTED_CLIENTS_ARG_APPEND_TYPE(title, str, x...) ({                           \
992                                                                char __temp[128] = {0,};                                                     \
993                                                                snprintf(__temp, sizeof(__temp), str, ##x);                                  \
994                                                                eldbus_message_iter_arguments_append(array_of_ec, "(ss)", &struct_of_ec);    \
995                                                                eldbus_message_iter_arguments_append(struct_of_ec, "ss", (title), (__temp)); \
996                                                                eldbus_message_iter_container_close(array_of_ec, struct_of_ec);})
997
998    EINA_LIST_FOREACH(e_comp->connected_clients, l, cinfo)
999      {
1000         __CONNECTED_CLIENTS_ARG_APPEND_TYPE("[Connected Clients]", "name:%20s pid:%3d uid:%3d gid:%3d", cinfo->name ?: "NO_NAME", cinfo->pid, cinfo->uid, cinfo->gid);
1001         for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
1002           {
1003              Ecore_Window win;
1004              uint32_t res_id = 0;
1005              pid_t pid = -1;
1006
1007              ec = evas_object_data_get(o, "E_Client");
1008              if (!ec) continue;
1009              if (e_client_util_ignored_get(ec)) continue;
1010
1011              win = e_client_util_win_get(ec);
1012
1013              if (ec->pixmap)
1014                res_id = e_pixmap_res_id_get(ec->pixmap);
1015              if (ec->comp_data)
1016                {
1017                   E_Comp_Wl_Client_Data *cdata = (E_Comp_Wl_Client_Data*)ec->comp_data;
1018                   if (cdata->surface)
1019                     wl_client_get_credentials(wl_resource_get_client(cdata->surface), &pid, NULL, NULL);
1020                }
1021              if (cinfo->pid == pid)
1022                {
1023                   __CONNECTED_CLIENTS_ARG_APPEND_TYPE("[E_Client Info]", "win:0x%08zx res_id:%5d, name:%20s, geo:(%4d, %4d, %4dx%4d), layer:%5d, visible:%d, argb:%d",
1024                                                       win, res_id, e_client_util_name_get(ec) ?: "NO_NAME", ec->x, ec->y, ec->w, ec->h, ec->layer, ec->visible, ec->argb);
1025                }
1026           }
1027      }
1028
1029    eldbus_message_iter_container_close(iter, array_of_ec);
1030 }
1031
1032 static Eldbus_Message *
1033 _e_info_server_cb_connected_clients_get(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
1034 {
1035    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
1036
1037    _msg_connected_clients_append(eldbus_message_iter_get(reply));
1038
1039    return reply;
1040 }
1041
1042 #ifndef wl_client_for_each
1043 #define wl_client_for_each(client, list)     \
1044    for (client = 0, client = wl_client_from_link((list)->next);   \
1045         wl_client_get_link(client) != (list);                     \
1046         client = wl_client_from_link(wl_client_get_link(client)->next))
1047 #endif
1048
1049 static int resurceCnt = 0;
1050
1051 static enum wl_iterator_result
1052 _e_info_server_get_resource(struct wl_resource *resource, void *data)
1053 {
1054    Eldbus_Message_Iter* array_of_res= data;
1055    Eldbus_Message_Iter* struct_of_res;
1056
1057    eldbus_message_iter_arguments_append(array_of_res, "("VALUE_TYPE_REPLY_RESLIST")", &struct_of_res);
1058    eldbus_message_iter_arguments_append(struct_of_res, VALUE_TYPE_REPLY_RESLIST, "[resource]", wl_resource_get_class(resource), wl_resource_get_id(resource));
1059    eldbus_message_iter_container_close(array_of_res, struct_of_res);
1060    resurceCnt++;
1061
1062    return WL_ITERATOR_CONTINUE;
1063 }
1064
1065 static void
1066 _msg_clients_res_list_append(Eldbus_Message_Iter *iter, uint32_t mode, int id)
1067 {
1068    Eldbus_Message_Iter *array_of_res;
1069
1070    struct wl_list * client_list;
1071    struct wl_client *client;
1072    E_Comp_Wl_Data *wl_cdata;
1073    int pid = -1;
1074
1075    enum {
1076    DEFAULT_SUMMARY,
1077    TREE,
1078    PID} type = mode;
1079
1080    eldbus_message_iter_arguments_append(iter, "a("VALUE_TYPE_REPLY_RESLIST")", &array_of_res);
1081
1082    if (!e_comp) return;
1083    if (!(wl_cdata = e_comp->wl_comp_data)) return;
1084    if (!wl_cdata->wl.disp) return;
1085
1086    client_list = wl_display_get_client_list(wl_cdata->wl.disp);
1087
1088    wl_client_for_each(client, client_list)
1089      {
1090         Eldbus_Message_Iter* struct_of_res;
1091
1092         wl_client_get_credentials(client, &pid, NULL, NULL);
1093
1094         if ((type == PID) && (pid != id)) continue;
1095
1096         eldbus_message_iter_arguments_append(array_of_res, "("VALUE_TYPE_REPLY_RESLIST")", &struct_of_res);
1097
1098         eldbus_message_iter_arguments_append(struct_of_res, VALUE_TYPE_REPLY_RESLIST, "[client]", "pid", (uint32_t)pid);
1099         eldbus_message_iter_container_close(array_of_res, struct_of_res);
1100
1101         resurceCnt = 0;
1102         wl_client_for_each_resource(client, _e_info_server_get_resource, array_of_res);
1103
1104         eldbus_message_iter_arguments_append(array_of_res, "("VALUE_TYPE_REPLY_RESLIST")", &struct_of_res);
1105         eldbus_message_iter_arguments_append(struct_of_res, VALUE_TYPE_REPLY_RESLIST, "[count]", "resurceCnt", (uint32_t)resurceCnt);
1106         eldbus_message_iter_container_close(array_of_res, struct_of_res);
1107      }
1108    eldbus_message_iter_container_close(iter, array_of_res);
1109 }
1110
1111 static Eldbus_Message *
1112 _e_info_server_cb_res_lists_get(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
1113 {
1114    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
1115    uint32_t mode = 0;
1116    int pid = -1;
1117
1118    if (!eldbus_message_arguments_get(msg, VALUE_TYPE_REQUEST_RESLIST, &mode, &pid))
1119      {
1120         ERR("Error getting arguments.");
1121         return reply;
1122      }
1123
1124    _msg_clients_res_list_append(eldbus_message_iter_get(reply), mode, pid);
1125
1126    return reply;
1127 }
1128
1129 /*
1130  * behaves like strcat but also dynamically extends buffer when it's needed
1131  *
1132  * dst - the pointer to result string (dynamically allocated) will be stored to memory 'dst' points to
1133  *       '*dst' MUST either point nothing (nullptr) or point a !_dynamically allocated_! null-terminated string
1134  *       (e.g. returned by the previous call)
1135  * src - null-terminated string to concatenate (can be either statically or dynamically allocated string)
1136  *
1137  * *dst got to be freed by free() when it's no longer needed
1138  *
1139  * return -1 in case of an error, 0 otherwise
1140  */
1141 static int
1142 _astrcat(char **dst, const char *src)
1143 {
1144    int new_size;
1145    char *res;
1146
1147    if (!dst || !src)
1148      return -1;
1149
1150    if (*dst)
1151      new_size = strlen(*dst) + strlen(src) + 1; /* + '/0' */
1152    else
1153      new_size = strlen(src) + 1; /* + '/0' */
1154
1155    /* if *dst is nullptr realloc behaves like malloc */
1156    res = realloc(*dst, new_size);
1157    if (!res)
1158      return -1;
1159
1160    /* if we were asked to concatenate to null string */
1161    if (!*dst)
1162      res[0] = '\0'; /* strncat looks for null-terminated string */
1163
1164    *dst = res;
1165    strncat(*dst, src, new_size - strlen(*dst) - 1);
1166
1167    return 0;
1168 }
1169
1170 #define astrcat_(str, mod, x...) ({                                  \
1171                                   char *temp = NULL;                 \
1172                                   if (asprintf(&temp, mod, ##x) < 0) \
1173                                     goto fail;                      \
1174                                   if (_astrcat(str, temp) < 0)       \
1175                                     {                                \
1176                                        free(temp);                   \
1177                                        goto fail;                    \
1178                                     }                                \
1179                                   free(temp); })
1180
1181
1182 static const char *
1183 _get_win_prop_Input_region(const Evas_Object *evas_obj)
1184 {
1185    Eina_List *list = NULL, *l;
1186    Eina_Rectangle *data;
1187    char *str = NULL;
1188
1189    e_comp_object_input_rect_get((Evas_Object *)evas_obj, &list);
1190    if (!list)
1191      {
1192         astrcat_(&str, "No Input Region\n");
1193         return str;
1194      }
1195
1196    EINA_LIST_FOREACH(list, l, data)
1197      {
1198         astrcat_(&str, "[(%d, %d) %dx%d]\n", data->x, data->y, data->w, data->h);
1199      }
1200    list = eina_list_free(list);
1201
1202    return str;
1203 fail:
1204    if (str) free(str);
1205    if (list) list = eina_list_free(list);
1206    return NULL;
1207 }
1208
1209
1210
1211 static const char*
1212 _get_win_prop_Rotation(const Evas_Object *evas_obj)
1213 {
1214    const E_Client *ec;
1215    char *str = NULL;
1216
1217    int i, count;
1218
1219    ec = evas_object_data_get(evas_obj, "E_Client");
1220    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1221    count = ec->e.state.rot.count;
1222
1223    astrcat_(&str, "Support(%d) Type(%s)\n", ec->e.state.rot.support,
1224            ec->e.state.rot.type == E_CLIENT_ROTATION_TYPE_NORMAL ? "normal" : "dependent");
1225
1226    if (ec->e.state.rot.available_rots && count)
1227      {
1228         astrcat_(&str, "Availables[%d] ", count);
1229
1230         for (i = 0; i < count; i++)
1231           astrcat_(&str, "%d ", ec->e.state.rot.available_rots[i]);
1232      }
1233    else
1234      astrcat_(&str, "Availables[%d] N/A", count);
1235
1236
1237    astrcat_(&str, "\nAngle prev(%d) curr(%d) next(%d) reserve(%d) preferred(%d)\n",
1238            ec->e.state.rot.ang.prev,
1239            ec->e.state.rot.ang.curr,
1240            ec->e.state.rot.ang.next,
1241            ec->e.state.rot.ang.reserve,
1242            ec->e.state.rot.preferred_rot);
1243
1244    astrcat_(&str, "pending_change_request(%d) pending_show(%d) nopending_render(%d) wait_for_done(%d)\n",
1245            ec->e.state.rot.pending_change_request,
1246            ec->e.state.rot.pending_show,
1247            ec->e.state.rot.nopending_render,
1248            ec->e.state.rot.wait_for_done);
1249
1250    if (ec->e.state.rot.geom_hint)
1251      for (i = 0; i < 4; i++)
1252        astrcat_(&str, "Geometry hint[%d] %d,%d   %dx%d\n",
1253                i,
1254                ec->e.state.rot.geom[i].x,
1255                ec->e.state.rot.geom[i].y,
1256                ec->e.state.rot.geom[i].w,
1257                ec->e.state.rot.geom[i].h);
1258
1259    return str;
1260
1261 fail:
1262    free(str);
1263    return NULL;
1264 }
1265
1266 static const char*
1267 _get_win_prop_Transform(const Evas_Object *evas_obj)
1268 {
1269    const E_Client *ec;
1270    char *str = NULL;
1271
1272    int i, count;
1273
1274    ec = evas_object_data_get(evas_obj, "E_Client");
1275    count = e_client_transform_core_transform_count_get((E_Client *)ec);
1276
1277    astrcat_(&str, "transform count: %d\n", count);
1278
1279    if (count <= 0)
1280      return str;
1281
1282    astrcat_(&str, "               [id] [role                   ] [move]       [scale]        [rot] [viewport]\n");
1283
1284    for (i = 0; i < count; ++i)
1285      {
1286         double dsx, dsy;
1287         int x = 0, y = 0, rz = 0;
1288         int view_port = 0;
1289         int vx = 0, vy = 0, vw = 0, vh = 0;
1290         E_Util_Transform *transform = NULL;
1291         const char *tmp_str = NULL;
1292         char role[24] = {0,};
1293
1294         transform = e_client_transform_core_transform_get((E_Client *)ec, i);
1295         if (!transform) continue;
1296
1297         e_util_transform_move_round_get(transform, &x, &y, NULL);
1298         e_util_transform_scale_get(transform, &dsx, &dsy, NULL);
1299         e_util_transform_rotation_round_get(transform, NULL, NULL, &rz);
1300         view_port = e_util_transform_viewport_flag_get(transform);
1301
1302         if (view_port)
1303           e_util_transform_viewport_get(transform, &vx, &vy, &vw, &vh);
1304
1305         tmp_str = e_util_transform_role_get(transform);
1306         strncpy(role, (tmp_str ? tmp_str:"unknown"), sizeof(role)-1);
1307
1308         astrcat_(&str, "transform    : [%2d] [%-23s] [%4d, %4d] [%2.3f, %2.3f] [%3d] [%d :%d, %d, %d, %d]\n",
1309                 i, role, x, y, dsx, dsy, rz, view_port, vx, vy, vw, vh);
1310
1311         if (e_util_transform_bg_transform_flag_get(transform))
1312           {
1313              e_util_transform_bg_move_round_get(transform, &x, &y, NULL);
1314              e_util_transform_bg_scale_get(transform, &dsx, &dsy, NULL);
1315              e_util_transform_bg_rotation_round_get(transform, NULL, NULL, &rz);
1316
1317              astrcat_(&str, "transform_bg : [%2d] [%4d, %4d] [%2.3f, %2.3f] [%3d]\n",
1318                      i, x, y, dsx, dsy, rz);
1319           }
1320      }
1321
1322    return str;
1323
1324 fail:
1325    free(str);
1326    return NULL;
1327 }
1328
1329 static const char*
1330 _get_win_prop_Subsurface_Below_Child_List(const Evas_Object *evas_obj)
1331 {
1332    const E_Comp_Wl_Client_Data *cdata;
1333    const E_Client *ec;
1334    char *str = NULL;
1335
1336    const Eina_List *list;
1337    const Eina_List *l;
1338    const E_Client *child;
1339
1340    ec = evas_object_data_get(evas_obj, "E_Client");
1341    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1342
1343    if (!ec->comp_data)
1344      return strdup("None");
1345
1346    cdata = (E_Comp_Wl_Client_Data*)ec->comp_data;
1347    list = cdata->sub.below_list;
1348
1349    if (!list)
1350      return strdup("None");
1351
1352    EINA_LIST_FOREACH(list, l, child)
1353      astrcat_(&str, "0x%zx, ", e_client_util_win_get(child));
1354
1355    return str;
1356
1357 fail:
1358    free(str);
1359    return NULL;
1360 }
1361
1362 static const char*
1363 _get_win_prop_Subsurface_Child_List(const Evas_Object *evas_obj)
1364 {
1365    const E_Comp_Wl_Client_Data *cdata;
1366    const E_Client *ec;
1367    char *str = NULL;
1368
1369    const Eina_List *list;
1370    const Eina_List *l;
1371    const E_Client *child;
1372
1373    ec = evas_object_data_get(evas_obj, "E_Client");
1374    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1375
1376    if (!ec->comp_data)
1377      return strdup("None");
1378
1379    cdata = (E_Comp_Wl_Client_Data*)ec->comp_data;
1380    list = cdata->sub.list;
1381
1382    if (!list)
1383      return strdup("None");
1384
1385    EINA_LIST_FOREACH(list, l, child)
1386      astrcat_(&str, "0x%zx, ", e_client_util_win_get(child));
1387
1388    return str;
1389
1390 fail:
1391    free(str);
1392    return NULL;
1393 }
1394
1395 static const char*
1396 _get_win_prop_Subsurface_Parent(const Evas_Object *evas_obj)
1397 {
1398    const E_Client *ec, *parent = NULL;
1399    char *str = NULL;
1400
1401    ec = evas_object_data_get(evas_obj, "E_Client");
1402    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1403
1404    if (!ec->comp_data)
1405      return strdup("None");
1406
1407    if (e_comp_wl_subsurface_check((E_Client *)ec))
1408      parent = e_comp_wl_subsurface_parent_get((E_Client *)ec);
1409
1410    if (asprintf(&str, "0x%zx", parent ? e_client_util_win_get(parent) : 0) < 0)
1411      return NULL;
1412
1413    return str;
1414 }
1415
1416 static const char*
1417 _get_win_prop_Aux_Hint(const Evas_Object *evas_obj)
1418 {
1419    const E_Comp_Wl_Client_Data *cdata;
1420    const E_Comp_Wl_Aux_Hint *hint;
1421    const Eina_List *l;
1422
1423    const E_Client *ec;
1424    char *str = NULL;
1425
1426    ec = evas_object_data_get(evas_obj, "E_Client");
1427    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1428
1429    if (!ec->comp_data)
1430      return strdup("None");
1431
1432    cdata = (E_Comp_Wl_Client_Data*)ec->comp_data;
1433
1434    if (!cdata->aux_hint.hints)
1435      return strdup("None");
1436
1437    EINA_LIST_FOREACH(cdata->aux_hint.hints, l, hint)
1438      astrcat_(&str, "[%d][%s][%s]\n", hint->id, hint->hint, hint->val);
1439
1440    return str;
1441
1442 fail:
1443    free(str);
1444    return NULL;
1445 }
1446
1447 static const char*
1448 _get_win_prop_Video_Client(const Evas_Object *evas_obj)
1449 {
1450    const E_Client *ec;
1451    char *str = NULL;
1452
1453    ec = evas_object_data_get(evas_obj, "E_Client");
1454    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1455
1456    if (asprintf(&str, "%d", ec->comp_data ? (ec->comp_data->video_client || e_client_video_hw_composition_check((E_Client *)ec)) : 0) < 0)
1457      return NULL;
1458
1459    return str;
1460 }
1461
1462 static const char*
1463 _get_win_prop_Transformed(const Evas_Object *evas_obj)
1464 {
1465    const E_Client *ec = evas_object_data_get(evas_obj, "E_Client");
1466    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1467
1468    return ec->transformed ? strdup("TRUE") : strdup("FALSE");
1469 }
1470
1471 static const char*
1472 _get_win_prop_Maximize_override(const Evas_Object *evas_obj)
1473 {
1474    const E_Client *ec = evas_object_data_get(evas_obj, "E_Client");
1475    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1476
1477    return ec->maximize_override ? strdup("TRUE") : strdup("FALSE");
1478 }
1479
1480 static const char*
1481 _set_win_prop_Ignored(Evas_Object *evas_obj, const char *prop_value)
1482 {
1483    E_Client *ec = evas_object_data_get(evas_obj, "E_Client");
1484
1485    if (!ec)
1486      {
1487         ERR("No ec available !Return NULL !");
1488         return NULL;
1489      }
1490
1491    if(strstr(prop_value, "TRUE"))
1492      ec->ignored = 1; /* TODO: is't right? */
1493    else if(strstr(prop_value, "FALSE"))
1494      e_client_unignore(ec);
1495    else
1496      return strdup("invalid property value");
1497
1498    return NULL;
1499 }
1500
1501 static const char*
1502 _get_win_prop_Ignored(const Evas_Object *evas_obj)
1503 {
1504    const E_Client *ec = evas_object_data_get(evas_obj, "E_Client");
1505    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1506
1507    return ec->ignored ? strdup("TRUE") : strdup("FALSE");
1508 }
1509
1510 static const char*
1511 _get_win_prop_Layer_block(const Evas_Object *evas_obj)
1512 {
1513    const E_Client *ec = evas_object_data_get(evas_obj, "E_Client");
1514    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1515
1516    return ec->layer_block ? strdup("TRUE") : strdup("FALSE");
1517 }
1518
1519 static const char*
1520 _set_win_prop_Redirected(Evas_Object *evas_obj, const char *prop_value)
1521 {
1522    E_Client *ec = evas_object_data_get(evas_obj, "E_Client");
1523
1524    if(strstr(prop_value, "TRUE"))
1525      e_client_redirected_set(ec, EINA_TRUE);
1526    else if(strstr(prop_value, "FALSE"))
1527      e_client_redirected_set(ec, EINA_FALSE);
1528    else
1529      return strdup("invalid property value");
1530
1531    return NULL;
1532 }
1533
1534 static const char*
1535 _get_win_prop_Redirected(const Evas_Object *evas_obj)
1536 {
1537    const E_Client *ec = evas_object_data_get(evas_obj, "E_Client");
1538    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1539
1540    return ec->redirected ? strdup("TRUE") : strdup("FALSE");
1541 }
1542
1543 static const char*
1544 _get_win_prop_Dialog(const Evas_Object *evas_obj)
1545 {
1546    const E_Client *ec = evas_object_data_get(evas_obj, "E_Client");
1547    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1548
1549    return ec->dialog ? strdup("TRUE") : strdup("FALSE");
1550 }
1551
1552 static const char*
1553 _get_win_prop_Input_only(const Evas_Object *evas_obj)
1554 {
1555    const E_Client *ec = evas_object_data_get(evas_obj, "E_Client");
1556    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1557
1558    return ec->input_only ? strdup("TRUE") : strdup("FALSE");
1559 }
1560
1561 static const char*
1562 _get_win_prop_Override(const Evas_Object *evas_obj)
1563 {
1564    const E_Client *ec = evas_object_data_get(evas_obj, "E_Client");
1565    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1566
1567    return ec->override ? strdup("TRUE") : strdup("FALSE");
1568 }
1569
1570 static const char*
1571 _get_win_prop_E_Transient_Policy(const Evas_Object *evas_obj)
1572 {
1573    const E_Client *ec;
1574    char *str = NULL;
1575
1576    ec = evas_object_data_get(evas_obj, "E_Client");
1577    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1578
1579    if (asprintf(&str, "%d", ec->transient_policy) < 0)
1580      return NULL;
1581
1582    return str;
1583 }
1584
1585 static const char*
1586 _get_win_prop_E_FullScreen_Policy(const Evas_Object *evas_obj)
1587 {
1588    const E_Client *ec;
1589    char *str = NULL;
1590
1591    ec = evas_object_data_get(evas_obj, "E_Client");
1592    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1593
1594    if (asprintf(&str, "%d", ec->fullscreen_policy) < 0)
1595      return NULL;
1596
1597    return str;
1598 }
1599
1600 static const char*
1601 _get_win_prop_E_Maximize_Policy(const Evas_Object *evas_obj)
1602 {
1603    const E_Client *ec;
1604    char *str = NULL;
1605
1606    ec = evas_object_data_get(evas_obj, "E_Client");
1607    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1608
1609    if (asprintf(&str, "0x%x", ec->maximized) < 0)
1610      return NULL;
1611
1612    return str;
1613 }
1614
1615 static const char*
1616 _get_win_prop_Accept_focus(const Evas_Object *evas_obj)
1617 {
1618    const E_Client *ec = evas_object_data_get(evas_obj, "E_Client");
1619    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1620
1621    return ec->icccm.accepts_focus ? strdup("TRUE") : strdup("FALSE");
1622 }
1623
1624 static const char*
1625 _get_win_prop_Want_focus(const Evas_Object *evas_obj)
1626 {
1627    const E_Client *ec = evas_object_data_get(evas_obj, "E_Client");
1628    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1629
1630    return ec->want_focus ? strdup("TRUE") : strdup("FALSE");
1631 }
1632
1633 static const char*
1634 _get_win_prop_Take_focus(const Evas_Object *evas_obj)
1635 {
1636    const E_Client *ec = evas_object_data_get(evas_obj, "E_Client");
1637    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1638
1639    return ec->take_focus ? strdup("TRUE") : strdup("FALSE");
1640 }
1641
1642 static const char*
1643 _get_win_prop_Re_manage(const Evas_Object *evas_obj)
1644 {
1645    const E_Client *ec = evas_object_data_get(evas_obj, "E_Client");
1646    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1647
1648    return ec->re_manage ? strdup("TRUE") : strdup("FALSE");
1649 }
1650
1651 static const char*
1652 _set_win_prop_Fullscreen(Evas_Object *evas_obj, const char *prop_value)
1653 {
1654    E_Client *ec = evas_object_data_get(evas_obj, "E_Client");
1655
1656    if(strstr(prop_value, "TRUE"))
1657      e_client_fullscreen(ec, E_FULLSCREEN_RESIZE); /* TODO: what a policy to use? */
1658    else if(strstr(prop_value, "FALSE"))
1659      e_client_unfullscreen(ec);
1660    else
1661      return strdup("invalid property value");
1662
1663    return NULL;
1664 }
1665
1666 static const char*
1667 _get_win_prop_Fullscreen(const Evas_Object *evas_obj)
1668 {
1669    const E_Client *ec = evas_object_data_get(evas_obj, "E_Client");
1670    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1671
1672    return ec->fullscreen ? strdup("TRUE") : strdup("FALSE");
1673 }
1674
1675 static const char*
1676 _set_win_prop_Sticky(Evas_Object *evas_obj, const char *prop_value)
1677 {
1678    E_Client *ec = evas_object_data_get(evas_obj, "E_Client");
1679
1680    if(strstr(prop_value, "TRUE"))
1681      e_client_stick(ec);
1682    else if(strstr(prop_value, "FALSE"))
1683      e_client_unstick(ec);
1684    else
1685      return strdup("invalid property value");
1686
1687    return NULL;
1688 }
1689
1690 static const char*
1691 _get_win_prop_Sticky(const Evas_Object *evas_obj)
1692 {
1693    const E_Client *ec = evas_object_data_get(evas_obj, "E_Client");
1694    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1695
1696    return ec->sticky ? strdup("TRUE") : strdup("FALSE");
1697 }
1698
1699 static const char*
1700 _set_win_prop_Iconic(Evas_Object *evas_obj, const char *prop_value)
1701 {
1702    E_Client *ec = evas_object_data_get(evas_obj, "E_Client");
1703    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1704
1705    if(strstr(prop_value, "TRUE"))
1706      e_client_iconify(ec);
1707    else if(strstr(prop_value, "FALSE"))
1708      e_client_uniconify(ec);
1709    else
1710      return strdup("invalid property value");
1711
1712    return NULL;
1713 }
1714
1715 static const char*
1716 _get_win_prop_Iconic(const Evas_Object *evas_obj)
1717 {
1718    const E_Client *ec = evas_object_data_get(evas_obj, "E_Client");
1719    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1720
1721    return ec->iconic ? strdup("TRUE") : strdup("FALSE");
1722 }
1723
1724 static const char*
1725 _set_win_prop_Focused(Evas_Object *evas_obj, const char *prop_value)
1726 {
1727    E_Client *ec = evas_object_data_get(evas_obj, "E_Client");
1728    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1729
1730    if(strstr(prop_value, "TRUE"))
1731      ec->focused = 1;
1732    else if(strstr(prop_value, "FALSE"))
1733      ec->focused = 0;
1734    else
1735      return strdup("invalid property value");
1736
1737    return NULL;
1738 }
1739
1740 static const char*
1741 _get_win_prop_Focused(const Evas_Object *evas_obj)
1742 {
1743    const E_Client *ec = evas_object_data_get(evas_obj, "E_Client");
1744    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1745
1746    return ec->focused ? strdup("TRUE") : strdup("FALSE");
1747 }
1748
1749 static const char*
1750 _get_win_prop_Moving(const Evas_Object *evas_obj)
1751 {
1752    const E_Client *ec = evas_object_data_get(evas_obj, "E_Client");
1753    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1754
1755    return ec->moving ? strdup("TRUE") : strdup("FALSE");
1756 }
1757
1758 static const char*
1759 _set_win_prop_Hidden(Evas_Object *evas_obj, const char *prop_value)
1760 {
1761    if(strstr(prop_value, "TRUE"))
1762      evas_object_hide(evas_obj);
1763    else if(strstr(prop_value, "FALSE"))
1764      evas_object_show(evas_obj);
1765    else
1766      return strdup("invalid property value");
1767
1768    return NULL;
1769 }
1770
1771 static const char*
1772 _get_win_prop_Hidden(const Evas_Object *evas_obj)
1773 {
1774    const E_Client *ec = evas_object_data_get(evas_obj, "E_Client");
1775    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1776
1777    return ec->hidden ? strdup("TRUE") : strdup("FALSE");
1778 }
1779
1780 static const char*
1781 _get_win_prop_32bit(const Evas_Object *evas_obj)
1782 {
1783    const E_Client *ec = evas_object_data_get(evas_obj, "E_Client");
1784    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1785
1786    return ec->argb ? strdup("TRUE") : strdup("FALSE");
1787 }
1788
1789 static const char*
1790 _set_win_prop_Visible(Evas_Object *evas_obj, const char *prop_value)
1791 {
1792    E_Client *ec = evas_object_data_get(evas_obj, "E_Client");
1793    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1794
1795    if(strstr(prop_value, "TRUE"))
1796      ec->visible = 1;
1797    else if(strstr(prop_value, "FALSE"))
1798      ec->visible = 0;
1799    else
1800      return strdup("invalid property value");
1801
1802    return NULL;
1803 }
1804
1805 static const char*
1806 _get_win_prop_Visible(const Evas_Object *evas_obj)
1807 {
1808    const E_Client *ec = evas_object_data_get(evas_obj, "E_Client");
1809    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1810
1811    return ec->visible ? strdup("TRUE") : strdup("FALSE");
1812 }
1813
1814 /* this code looks awful but to make it sane some global changes are required,
1815  * but I'm not sure I'm allowed to do such changes which relate ONLY to e_info app */
1816 static inline int
1817 _check_layer_idx(const char *layer_name, int layer_idx)
1818 {
1819    char tmp[64] = {0, };
1820
1821    e_comp_layer_name_get(layer_idx, tmp, sizeof(tmp));
1822
1823    return strncmp(tmp, layer_name, strlen(tmp));
1824 }
1825
1826 static int
1827 _e_comp_layer_idx_get(const char *layer_name)
1828 {
1829    if (!layer_name) return E_LAYER_MAX + 1;
1830
1831    if (!_check_layer_idx(layer_name, E_LAYER_BOTTOM))                     return E_LAYER_BOTTOM;
1832    if (!_check_layer_idx(layer_name, E_LAYER_BG))                         return E_LAYER_BG;
1833    if (!_check_layer_idx(layer_name, E_LAYER_DESKTOP))                    return E_LAYER_DESKTOP;
1834    if (!_check_layer_idx(layer_name, E_LAYER_DESKTOP_TOP))                return E_LAYER_DESKTOP_TOP;
1835    if (!_check_layer_idx(layer_name, E_LAYER_CLIENT_DESKTOP))             return E_LAYER_CLIENT_DESKTOP;
1836    if (!_check_layer_idx(layer_name, E_LAYER_CLIENT_BELOW))               return E_LAYER_CLIENT_BELOW;
1837    if (!_check_layer_idx(layer_name, E_LAYER_CLIENT_NORMAL))              return E_LAYER_CLIENT_NORMAL;
1838    if (!_check_layer_idx(layer_name, E_LAYER_CLIENT_ABOVE))               return E_LAYER_CLIENT_ABOVE;
1839    if (!_check_layer_idx(layer_name, E_LAYER_CLIENT_EDGE))                return E_LAYER_CLIENT_EDGE;
1840    if (!_check_layer_idx(layer_name, E_LAYER_CLIENT_FULLSCREEN))          return E_LAYER_CLIENT_FULLSCREEN;
1841    if (!_check_layer_idx(layer_name, E_LAYER_CLIENT_EDGE_FULLSCREEN))     return E_LAYER_CLIENT_EDGE_FULLSCREEN;
1842    if (!_check_layer_idx(layer_name, E_LAYER_CLIENT_POPUP))               return E_LAYER_CLIENT_POPUP;
1843    if (!_check_layer_idx(layer_name, E_LAYER_CLIENT_TOP))                 return E_LAYER_CLIENT_TOP;
1844    if (!_check_layer_idx(layer_name, E_LAYER_CLIENT_PRIO))                return E_LAYER_CLIENT_PRIO;
1845    if (!_check_layer_idx(layer_name, E_LAYER_CLIENT_NOTIFICATION_LOW))    return E_LAYER_CLIENT_NOTIFICATION_LOW;
1846    if (!_check_layer_idx(layer_name, E_LAYER_CLIENT_NOTIFICATION_NORMAL)) return E_LAYER_CLIENT_NOTIFICATION_NORMAL;
1847    if (!_check_layer_idx(layer_name, E_LAYER_CLIENT_NOTIFICATION_HIGH))   return E_LAYER_CLIENT_NOTIFICATION_HIGH;
1848    if (!_check_layer_idx(layer_name, E_LAYER_CLIENT_NOTIFICATION_TOP))    return E_LAYER_CLIENT_NOTIFICATION_TOP;
1849    if (!_check_layer_idx(layer_name, E_LAYER_CLIENT_ALERT_LOW))           return E_LAYER_CLIENT_ALERT_LOW;
1850    if (!_check_layer_idx(layer_name, E_LAYER_CLIENT_ALERT))               return E_LAYER_CLIENT_ALERT;
1851    if (!_check_layer_idx(layer_name, E_LAYER_CLIENT_ALERT_HIGH))          return E_LAYER_CLIENT_ALERT_HIGH;
1852    if (!_check_layer_idx(layer_name, E_LAYER_CLIENT_DRAG))                return E_LAYER_CLIENT_DRAG;
1853    if (!_check_layer_idx(layer_name, E_LAYER_CLIENT_CURSOR))              return E_LAYER_CLIENT_CURSOR;
1854    if (!_check_layer_idx(layer_name, E_LAYER_POPUP))                      return E_LAYER_POPUP;
1855    if (!_check_layer_idx(layer_name, E_LAYER_EFFECT))                     return E_LAYER_EFFECT;
1856    if (!_check_layer_idx(layer_name, E_LAYER_DESK_OBJECT_BELOW))          return E_LAYER_DESK_OBJECT_BELOW;
1857    if (!_check_layer_idx(layer_name, E_LAYER_DESK_OBJECT))                return E_LAYER_DESK_OBJECT;
1858    if (!_check_layer_idx(layer_name, E_LAYER_DESK_OBJECT_ABOVE))          return E_LAYER_DESK_OBJECT_ABOVE;
1859    if (!_check_layer_idx(layer_name, E_LAYER_MENU))                       return E_LAYER_MENU;
1860    if (!_check_layer_idx(layer_name, E_LAYER_DESKLOCK))                   return E_LAYER_DESKLOCK;
1861    if (!_check_layer_idx(layer_name, E_LAYER_MAX))                        return E_LAYER_MAX;
1862
1863    return E_LAYER_MAX + 1;
1864 }
1865
1866 static const char*
1867 _set_win_prop_Layer(Evas_Object *evas_obj, const char *prop_value)
1868 {
1869    E_Client *ec = evas_object_data_get(evas_obj, "E_Client");
1870    int layer_idx;
1871    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1872
1873    layer_idx = _e_comp_layer_idx_get(prop_value);
1874    if (layer_idx == (E_LAYER_MAX + 1))
1875      return strdup("invalid property value");
1876
1877    ec->layer = layer_idx;
1878
1879    return NULL;
1880 }
1881
1882 static const char*
1883 _get_win_prop_Layer(const Evas_Object *evas_obj)
1884 {
1885    const E_Client *ec;
1886    char *str = NULL;
1887
1888    char layer_name[48] = {0,};
1889
1890    ec = evas_object_data_get(evas_obj, "E_Client");
1891    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1892    e_comp_layer_name_get(ec->layer, layer_name, sizeof(layer_name));
1893
1894    if (asprintf(&str, "[%d, %s]", ec->layer, layer_name) < 0)
1895      return NULL;
1896
1897    return str;
1898 }
1899
1900 static const char*
1901 _get_win_prop_Shape_input(const Evas_Object *evas_obj)
1902 {
1903    const E_Client *ec;
1904    char *str = NULL;
1905    int i = 0;
1906
1907    ec = evas_object_data_get(evas_obj, "E_Client");
1908    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1909
1910    if (!ec->shape_input_rects || ec->shape_input_rects_num <= 0)
1911      return strdup("None");
1912
1913    for (i = 0 ; i < ec->shape_input_rects_num ; ++i)
1914      astrcat_(&str, "[%d,%d,%d,%d]\n", ec->shape_input_rects[i].x, ec->shape_input_rects[i].y,
1915              ec->shape_input_rects[i].w, ec->shape_input_rects[i].h);
1916
1917    return str;
1918
1919 fail:
1920    free(str);
1921    return NULL;
1922 }
1923
1924 static const char*
1925 _get_win_prop_Shape_rects(const Evas_Object *evas_obj)
1926 {
1927    const E_Client *ec;
1928    char *str = NULL;
1929    int i = 0;
1930
1931    ec = evas_object_data_get(evas_obj, "E_Client");
1932    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1933
1934    if (!ec->shape_rects || ec->shape_rects_num <= 0)
1935      return strdup("None");
1936
1937    for (i = 0 ; i < ec->shape_rects_num ; ++i)
1938      astrcat_(&str, "[%d,%d,%d,%d]\n", ec->shape_rects[i].x, ec->shape_rects[i].y,
1939              ec->shape_rects[i].w, ec->shape_rects[i].h);
1940
1941    return str;
1942
1943 fail:
1944    free(str);
1945    return NULL;
1946 }
1947
1948 static const char*
1949 _get_win_prop_Transients(const Evas_Object *evas_obj)
1950 {
1951    const E_Client *ec;
1952    char *str = NULL;
1953
1954    const E_Client *child;
1955    const Eina_List *l;
1956
1957    ec = evas_object_data_get(evas_obj, "E_Client");
1958    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1959
1960    if (!ec->transients)
1961      return strdup("None");
1962
1963    EINA_LIST_FOREACH(ec->transients, l, child)
1964      astrcat_(&str, "0x%zx, ", e_client_util_win_get(child));
1965
1966    return str;
1967
1968 fail:
1969    free(str);
1970    return NULL;
1971 }
1972
1973 static const char*
1974 _get_win_prop_ParentWindowID(const Evas_Object *evas_obj)
1975 {
1976    const E_Client *ec;
1977    char *str = NULL;
1978
1979    ec = evas_object_data_get(evas_obj, "E_Client");
1980    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1981
1982    if (!ec->parent)
1983      return strdup("None");
1984
1985    if (asprintf(&str, "0x%zx", e_client_util_win_get(ec->parent)) < 0)
1986      return NULL;
1987
1988    return str;
1989 }
1990
1991 static const char*
1992 _set_win_prop_Geometry(Evas_Object *evas_obj, const char *prop_value)
1993 {
1994    E_Client *ec = evas_object_data_get(evas_obj, "E_Client");
1995    int x = -1, y = -1, w = -1, h = -1;
1996    int ret;
1997
1998    ret = sscanf(prop_value, "%d, %d %dx%d", &x, &y, &w, &h);
1999    EINA_SAFETY_ON_FALSE_RETURN_VAL(ret == 4, (strdup("Invalid format")));
2000
2001    if (x < 0 || y < 0 || w <= 0 || h <= 0)
2002      return strdup("invalid property value");
2003
2004    /* TODO: I have no enough knowledges to say that it's a proper way
2005     *       to change e_client geometry */
2006    e_client_pos_set(ec, x, y);
2007    e_client_size_set(ec, w, h);
2008
2009    return NULL;
2010 }
2011
2012 static const char*
2013 _get_win_prop_Geometry(const Evas_Object *evas_obj)
2014 {
2015    const E_Client *ec;
2016    char *str = NULL;
2017
2018    ec = evas_object_data_get(evas_obj, "E_Client");
2019    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
2020
2021    if (asprintf(&str, "[%d, %d %dx%d]", ec->x, ec->y, ec->w, ec->h) < 0)
2022      return NULL;
2023
2024    return str;
2025 }
2026
2027 static const char*
2028 _get_win_prop_Min_size(const Evas_Object *evas_obj)
2029 {
2030    const E_Client *ec;
2031    char *str = NULL;
2032
2033    ec = evas_object_data_get(evas_obj, "E_Client");
2034    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
2035
2036    if (asprintf(&str, "%dx%d", ec->icccm.min_w, ec->icccm.min_h) < 0)
2037      return NULL;
2038
2039    return str;
2040 }
2041
2042 static const char*
2043 _get_win_prop_Max_size(const Evas_Object *evas_obj)
2044 {
2045    const E_Client *ec;
2046    char *str = NULL;
2047
2048    ec = evas_object_data_get(evas_obj, "E_Client");
2049    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
2050
2051    if (asprintf(&str, "%dx%d", ec->icccm.max_w, ec->icccm.max_h) < 0)
2052      return NULL;
2053
2054    return str;
2055 }
2056
2057 static const char*
2058 _set_win_prop_Role(Evas_Object *evas_obj, const char *prop_value)
2059 {
2060    E_Client *ec = evas_object_data_get(evas_obj, "E_Client");
2061
2062    e_client_window_role_set(ec, prop_value);
2063
2064    return NULL;
2065 }
2066
2067 static const char*
2068 _get_win_prop_Role(const Evas_Object *evas_obj)
2069 {
2070    const E_Client *ec;
2071    char *str = NULL;
2072
2073    ec = evas_object_data_get(evas_obj, "E_Client");
2074    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
2075
2076    if (asprintf(&str, "%s", ec->icccm.window_role ?: "NO ROLE") < 0)
2077      return NULL;
2078
2079    return str;
2080 }
2081
2082 static const char*
2083 _set_win_prop_Window_Name(Evas_Object *evas_obj, const char *prop_value)
2084 {
2085    E_Client *ec = evas_object_data_get(evas_obj, "E_Client");
2086    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
2087
2088    /* TODO: I ain't sure it's a proper order */
2089    if (ec->netwm.name)
2090      eina_stringshare_replace(&ec->netwm.name, prop_value);
2091    else if (ec->icccm.title)
2092      eina_stringshare_replace(&ec->icccm.title, prop_value);
2093    else
2094      eina_stringshare_replace(&ec->netwm.name, prop_value);
2095
2096    return NULL;
2097 }
2098
2099 static const char*
2100 _get_win_prop_Window_Name(const Evas_Object *evas_obj)
2101 {
2102    const E_Client *ec;
2103    char *str = NULL;
2104
2105    ec = evas_object_data_get(evas_obj, "E_Client");
2106
2107    if (asprintf(&str, "%s", e_client_util_name_get(ec) ?: "NO NAME") < 0)
2108      return NULL;
2109
2110    return str;
2111 }
2112
2113 static const char*
2114 _get_win_prop_ResourceID(const Evas_Object *evas_obj)
2115 {
2116    const E_Client *ec;
2117    char *str = NULL;
2118
2119    ec = evas_object_data_get(evas_obj, "E_Client");
2120    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
2121
2122    if (!ec->pixmap)
2123      return strdup("None");
2124
2125    if (asprintf(&str, "%d", e_pixmap_res_id_get(ec->pixmap)) < 0)
2126      return NULL;
2127
2128    return str;
2129 }
2130
2131 static const char*
2132 _get_win_prop_PID(const Evas_Object *evas_obj)
2133 {
2134    const E_Client *ec;
2135    char *str = NULL;
2136    pid_t pid = -1;
2137
2138    ec = evas_object_data_get(evas_obj, "E_Client");
2139    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
2140
2141    if (ec->comp_data)
2142      {
2143         const E_Comp_Wl_Client_Data *cdata = (const E_Comp_Wl_Client_Data*)ec->comp_data;
2144         if (cdata->surface)
2145           wl_client_get_credentials(wl_resource_get_client(cdata->surface), &pid, NULL, NULL);
2146      }
2147
2148    if (asprintf(&str, "%d", pid) < 0)
2149      return NULL;
2150
2151    return str;
2152 }
2153
2154 static const char*
2155 _get_win_prop_Window_ID(const Evas_Object *evas_obj)
2156 {
2157    const E_Client *ec;
2158    char *str = NULL;
2159
2160    ec = evas_object_data_get(evas_obj, "E_Client");
2161
2162    if (asprintf(&str, "0x%zx", e_client_util_win_get(ec)) < 0)
2163      return NULL;
2164
2165    return str;
2166 }
2167
2168 typedef const char* (*get_prop_t)(const Evas_Object *evas_obj);
2169 typedef const char* (*set_prop_t)(Evas_Object *evas_obj, const char *prop_value);
2170
2171 static struct property_manager
2172 {
2173     const char* prop_name;
2174
2175     /*
2176      * get one property
2177      *
2178      * evas_obj - an evas_obj (which is e_client) a property value has to be got for
2179      * return nullptr in case of an error, property value string otherwise
2180      *
2181      * property value string should be freed with free() when it's no longer needed
2182      *
2183      * can be nullptr if this property isn't getable */
2184     get_prop_t get_prop;
2185
2186     /*
2187      * set one property
2188      *
2189      * evas_obj - an evas_obj (which is e_client) a property value has to be set for
2190      * prop_value - a value of property to set
2191      * return pointer to an error string in case of an error, nullptr otherwise
2192      *
2193      * error string should be freed with free() when it's no longer needed
2194      * it's this function responsibility to check property_value sanity
2195      *
2196      * can be nullptr if this property isn't setable */
2197     set_prop_t set_prop;
2198 } win_properties[] =
2199 {
2200     {
2201         "Window_ID",
2202         _get_win_prop_Window_ID,
2203         NULL
2204     },
2205     {
2206         "PID",
2207         _get_win_prop_PID,
2208         NULL
2209     },
2210     {
2211         "ResourceID",
2212         _get_win_prop_ResourceID,
2213         NULL
2214     },
2215     {
2216         "Window_Name",
2217         _get_win_prop_Window_Name,
2218         _set_win_prop_Window_Name
2219     },
2220     {
2221         "Role",
2222         _get_win_prop_Role,
2223         _set_win_prop_Role
2224     },
2225     {
2226         "Geometry",
2227         _get_win_prop_Geometry,
2228         _set_win_prop_Geometry
2229     },
2230     {
2231         "Min_size",
2232         _get_win_prop_Min_size,
2233         NULL
2234     },
2235     {
2236         "Max_size",
2237         _get_win_prop_Max_size,
2238         NULL
2239     },
2240     {
2241         "ParentWindowID",
2242         _get_win_prop_ParentWindowID,
2243         NULL
2244     },
2245     {
2246         "Transients",
2247         _get_win_prop_Transients,
2248         NULL
2249     },
2250     {
2251         "Shape_rects",
2252         _get_win_prop_Shape_rects,
2253         NULL
2254     },
2255     {
2256         "Shape_input",
2257         _get_win_prop_Shape_input,
2258         NULL
2259     },
2260     {
2261         "Layer",
2262         _get_win_prop_Layer,
2263         _set_win_prop_Layer
2264     },
2265     {
2266         "Visible",
2267         _get_win_prop_Visible,
2268         _set_win_prop_Visible
2269     },
2270     {
2271         "32bit",
2272         _get_win_prop_32bit,
2273         NULL
2274     },
2275     {
2276         "Hidden",
2277         _get_win_prop_Hidden,
2278         _set_win_prop_Hidden
2279     },
2280     {
2281         "Moving",
2282         _get_win_prop_Moving,
2283         NULL
2284     },
2285     {
2286         "Focused",
2287         _get_win_prop_Focused,
2288         _set_win_prop_Focused
2289     },
2290     {
2291         "Iconic",
2292         _get_win_prop_Iconic,
2293         _set_win_prop_Iconic
2294     },
2295     {
2296         "Sticky",
2297         _get_win_prop_Sticky,
2298         _set_win_prop_Sticky
2299     },
2300     {
2301         "Fullscreen",
2302         _get_win_prop_Fullscreen,
2303         _set_win_prop_Fullscreen
2304     },
2305     {
2306         "Re_manage",
2307         _get_win_prop_Re_manage,
2308         NULL
2309     },
2310     {
2311        "Accept_focus",
2312        _get_win_prop_Accept_focus,
2313        NULL
2314     },
2315     {
2316         "Take_focus",
2317         _get_win_prop_Take_focus,
2318         NULL
2319     },
2320     {
2321         "Want_focus",
2322         _get_win_prop_Want_focus,
2323         NULL
2324     },
2325     {
2326         "E_Maximize_Policy",
2327         _get_win_prop_E_Maximize_Policy,
2328         NULL
2329     },
2330     {
2331         "E_FullScreen_Policy",
2332         _get_win_prop_E_FullScreen_Policy,
2333         NULL
2334     },
2335     {
2336         "E_Transient_Policy",
2337         _get_win_prop_E_Transient_Policy,
2338         NULL
2339     },
2340     {
2341         "Override",
2342         _get_win_prop_Override,
2343         NULL
2344     },
2345     {
2346         "Input_only",
2347         _get_win_prop_Input_only,
2348         NULL
2349     },
2350     {
2351         "Dialog",
2352         _get_win_prop_Dialog,
2353         NULL
2354     },
2355     {
2356         "Redirected",
2357         _get_win_prop_Redirected,
2358         _set_win_prop_Redirected
2359     },
2360     {
2361         "Layer_block",
2362         _get_win_prop_Layer_block,
2363         NULL
2364     },
2365     {
2366         "Ignored",
2367         _get_win_prop_Ignored,
2368         _set_win_prop_Ignored
2369     },
2370     {
2371         "Maximize_override",
2372         _get_win_prop_Maximize_override,
2373         NULL
2374     },
2375     {
2376         "Transformed",
2377         _get_win_prop_Transformed,
2378         NULL
2379     },
2380     {
2381         "Video Client",
2382         _get_win_prop_Video_Client,
2383         NULL
2384     },
2385     {
2386         "Aux_Hint Client",
2387         _get_win_prop_Aux_Hint,
2388         NULL
2389     },
2390     {
2391         "Subsurface Parent",
2392         _get_win_prop_Subsurface_Parent,
2393         NULL
2394     },
2395     {
2396         "Subsurface Child List",
2397         _get_win_prop_Subsurface_Child_List,
2398         NULL
2399     },
2400     {
2401         "Subsurface Below Child List",
2402         _get_win_prop_Subsurface_Below_Child_List,
2403         NULL
2404     },
2405     {
2406         "Transform",
2407         _get_win_prop_Transform,
2408         NULL
2409     },
2410     {
2411         "Rotation",
2412         _get_win_prop_Rotation,
2413         NULL
2414     },
2415     {
2416         "Input Region",
2417         _get_win_prop_Input_region,
2418         NULL
2419     }
2420 };
2421
2422 #define __WINDOW_PROP_ARG_APPEND(title, value) ({                                    \
2423                                                 eldbus_message_iter_arguments_append(iter, "(ss)", &struct_of_ec);    \
2424                                                 eldbus_message_iter_arguments_append(struct_of_ec, "ss", (title), (value));  \
2425                                                 eldbus_message_iter_container_close(iter, struct_of_ec);})
2426
2427 static Eldbus_Message*
2428 _msg_fill_out_window_props(const Eldbus_Message *msg, Eldbus_Message_Iter *iter, Evas_Object *evas_obj,
2429         const char *property_name, const char *property_value)
2430 {
2431    const int win_property_size = sizeof(win_properties)/sizeof(struct property_manager);
2432    Eldbus_Message_Iter* struct_of_ec;
2433    int idx;
2434
2435    /* accordingly to -prop option rules (if user's provided some property name) */
2436    if (strlen(property_name))
2437      {
2438         /* check the property_name sanity */
2439         for (idx = 0; idx < win_property_size; ++idx)
2440           if (!strncmp(win_properties[idx].prop_name, property_name, sizeof(win_properties[idx])))
2441             break;
2442
2443         if (idx == win_property_size)
2444           return eldbus_message_error_new(msg, INVALID_PROPERTY_NAME,
2445                   "get_window_prop: invalid property name");
2446
2447         /* accordingly to -prop option rules (if user wanna set property) */
2448         if (strlen(property_value))
2449           {
2450              if (win_properties[idx].set_prop)
2451                {
2452                   /* in case of a success we just return an empty reply message */
2453                   const char* error_str = win_properties[idx].set_prop(evas_obj, property_value);
2454                   if (error_str)
2455                     {
2456                        Eldbus_Message* err_msg = eldbus_message_error_new(msg,
2457                                FAIL_TO_SET_PROPERTY, error_str);
2458                        free((void*)error_str);
2459
2460                        return err_msg;
2461                     }
2462                }
2463              else
2464                return eldbus_message_error_new(msg, FAIL_TO_SET_PROPERTY,
2465                        "get_window_prop: this property isn't setable");
2466           }
2467         else /* if wanna get property */
2468           {
2469              if (win_properties[idx].get_prop)
2470                {
2471                   const char* res_str = win_properties[idx].get_prop(evas_obj);
2472                   if (res_str)
2473                     {
2474                        __WINDOW_PROP_ARG_APPEND(win_properties[idx].prop_name, res_str);
2475                        free((void*)res_str);
2476                     }
2477                   else
2478                     return eldbus_message_error_new(msg, FAIL_TO_GET_PROPERTY, "");
2479                }
2480              else
2481                return eldbus_message_error_new(msg, FAIL_TO_GET_PROPERTY,
2482                        "get_window_prop: this property isn't getable");
2483           }
2484      }
2485    else /* if user wanna get all properties */
2486      {
2487        /* to improve readability, if user wanna get properties for several windows, some
2488         * delimiter being used */
2489         __WINDOW_PROP_ARG_APPEND("delimiter", "");
2490
2491         for (idx = 0; idx < win_property_size; ++idx)
2492           {
2493              if (win_properties[idx].get_prop)
2494                {
2495                   const char* res_str = win_properties[idx].get_prop(evas_obj);
2496                   if (res_str)
2497                     {
2498                        __WINDOW_PROP_ARG_APPEND(win_properties[idx].prop_name, res_str);
2499                        free((void*)res_str);
2500                     }
2501                   else
2502                     return eldbus_message_error_new(msg, FAIL_TO_GET_PROPERTY, "");
2503                }
2504           }
2505      }
2506
2507    return NULL;
2508
2509 #undef __WINDOW_PROP_ARG_APPEND
2510 }
2511
2512 /* create the reply message and look for window(s) an user wanna get/set property(ies) for */
2513 static Eldbus_Message *
2514 _msg_window_prop_append(const Eldbus_Message *msg, uint32_t mode, const char *value,
2515         const char *property_name, const char *property_value)
2516 {
2517    const static int WINDOW_ID_MODE = 0;
2518    const static int WINDOW_PID_MODE = 1;
2519    const static int WINDOW_NAME_MODE = 2;
2520
2521    Eldbus_Message_Iter *iter, *array_of_ec;
2522    Eldbus_Message *reply_msg, *error_msg = NULL;
2523    E_Client *ec;
2524    Evas_Object *o;
2525    unsigned long tmp = 0;
2526    uint64_t value_number = 0;
2527    Eina_Bool res = EINA_FALSE;
2528    Eina_Bool window_exists = EINA_FALSE;
2529
2530    if (mode == WINDOW_ID_MODE || mode == WINDOW_PID_MODE)
2531      {
2532         if (!value) value_number = 0;
2533         else
2534           {
2535              if (strlen(value) >= 2 && value[0] == '0' && value[1] == 'x')
2536                res = e_util_string_to_ulong(value, &tmp, 16);
2537              else
2538                res = e_util_string_to_ulong(value, &tmp, 10);
2539
2540              if (res == EINA_FALSE)
2541                {
2542                   ERR("get_window_prop: invalid input arguments");
2543
2544                   return eldbus_message_error_new(msg, INVALID_ARGS,
2545                           "get_window_prop: invalid input arguments");
2546                }
2547              value_number = (uint64_t)tmp;
2548           }
2549      }
2550
2551    /* msg - is a method call message */
2552    reply_msg = eldbus_message_method_return_new(msg);
2553    iter = eldbus_message_iter_get(reply_msg);
2554    eldbus_message_iter_arguments_append(iter, "a(ss)", &array_of_ec);
2555
2556    for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
2557      {
2558         ec = evas_object_data_get(o, "E_Client");
2559         if (!ec) continue;
2560
2561         /* here we're dealing with evas objects which are e_client */
2562
2563         if (mode == WINDOW_ID_MODE)
2564           {
2565              Ecore_Window win = e_client_util_win_get(ec);
2566
2567              if (win == value_number)
2568                {
2569                   window_exists = EINA_TRUE;
2570                   error_msg = _msg_fill_out_window_props(msg, array_of_ec, o, property_name, property_value);
2571                   break;
2572                }
2573           }
2574         else if (mode == WINDOW_PID_MODE)
2575           {
2576              pid_t pid = -1;
2577              if (ec->comp_data)
2578                {
2579                   E_Comp_Wl_Client_Data *cdata = (E_Comp_Wl_Client_Data*)ec->comp_data;
2580                   if (cdata->surface)
2581                     {
2582                        wl_client_get_credentials(wl_resource_get_client(cdata->surface), &pid, NULL, NULL);
2583                     }
2584                }
2585              if (pid == value_number)
2586                {
2587                   window_exists = EINA_TRUE;
2588                   error_msg = _msg_fill_out_window_props(msg, array_of_ec, o, property_name, property_value);
2589                   if (error_msg)
2590                     break;
2591                }
2592           }
2593         else if (mode == WINDOW_NAME_MODE)
2594           {
2595              const char *name = e_client_util_name_get(ec) ?: "NO NAME";
2596
2597              if (name != NULL && value != NULL)
2598                {
2599                   const char *find = strstr(name, value);
2600
2601                   if (find)
2602                     {
2603                        window_exists = EINA_TRUE;
2604                        error_msg = _msg_fill_out_window_props(msg, array_of_ec, o, property_name, property_value);
2605                        if (error_msg)
2606                          break;
2607                     }
2608                }
2609           }
2610      }
2611
2612    eldbus_message_iter_container_close(iter, array_of_ec);
2613
2614    if (window_exists == EINA_TRUE && !error_msg)
2615      return reply_msg;
2616
2617    /* TODO: I'm not sure we gotta do it. But, who's responsible for message freeing if we've not it
2618     *       returned to caller(eldbus)? */
2619    eldbus_message_unref(reply_msg);
2620
2621    /* some error while filling out the reply message */
2622    if (error_msg)
2623      return error_msg;
2624
2625    return eldbus_message_error_new(msg, WIN_NOT_EXIST, "get_window_prop: specified window(s) doesn't exist");
2626 }
2627
2628 static Eldbus_Message *
2629 _e_info_server_cb_scrsaver(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
2630 {
2631    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
2632    E_Info_Cmd_Scrsaver cmd;
2633    double sec;
2634    Eina_Bool res, enabled;
2635    char result[1024];
2636
2637    res = eldbus_message_arguments_get(msg,
2638                                       SIGNATURE_SCRSAVER_CLIENT,
2639                                       &cmd,
2640                                       &sec);
2641    EINA_SAFETY_ON_FALSE_RETURN_VAL(res, reply);
2642
2643    switch (cmd)
2644      {
2645       case E_INFO_CMD_SCRSAVER_INFO:
2646          sec = e_screensaver_timeout_get();
2647          enabled = e_screensaver_enabled_get();
2648          snprintf(result, sizeof(result),
2649                   "[Server] screen saver\n" \
2650                   "\tState: %s\n"           \
2651                   "\tTimeout period: %lf\n",
2652                   enabled ? "Enabled" : "Disabled",
2653                   sec);
2654          break;
2655       case E_INFO_CMD_SCRSAVER_ENABLE:
2656          e_screensaver_enable();
2657          snprintf(result, sizeof(result),
2658                   "[Server] Enabled the screen saver");
2659          break;
2660       case E_INFO_CMD_SCRSAVER_DISABLE:
2661          e_screensaver_disable();
2662          snprintf(result, sizeof(result),
2663                   "[Server] Disabled the screen saver");
2664          break;
2665       case E_INFO_CMD_SCRSAVER_TIMEOUT:
2666          e_screensaver_timeout_set(sec);
2667          snprintf(result, sizeof(result),
2668                   "[Server] Set timeout period of the screen saver: %lf",
2669                   sec);
2670          break;
2671       default:
2672          snprintf(result, sizeof(result),
2673                   "[Server] Error Unknown cmd(%d) for the screen saver",
2674                   cmd);
2675          break;
2676      }
2677
2678    eldbus_message_arguments_append(reply,
2679                                    SIGNATURE_SCRSAVER_SERVER,
2680                                    result);
2681
2682    return reply;
2683 }
2684
2685 static Eldbus_Message *
2686 _e_info_server_cb_window_prop_get(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
2687 {
2688    uint32_t mode = 0;
2689    const char *value = NULL;
2690    const char *property_name = NULL, *property_value = NULL;
2691
2692    if (!eldbus_message_arguments_get(msg, "usss", &mode, &value, &property_name, &property_value))
2693      {
2694         ERR("Error getting arguments.");
2695
2696         return eldbus_message_error_new(msg, GET_CALL_MSG_ARG_ERR,
2697                 "get_window_prop: an attempt to get arguments from method call message failed");
2698      }
2699
2700    /* TODO: it's guaranteed, by client logic, that 'value', 'property_name' and 'property_value'
2701     *       can be ONLY either empty string or string. Should I check this? <if( !property_name )> */
2702    return _msg_window_prop_append(msg, mode, value, property_name, property_value);
2703 }
2704
2705 typedef struct {
2706      Eldbus_Message *reply;
2707      int num;
2708      char *result_str;
2709 } Dump_Win_Data;
2710
2711 static void
2712 _image_save_done_cb(void *data, E_Client* ec EINA_UNUSED, const Eina_Stringshare *dest, E_Capture_Save_State state)
2713 {
2714    Dump_Win_Data *dump = (Dump_Win_Data *)data;
2715
2716    dump->num --;
2717
2718    if (state != E_CAPTURE_SAVE_STATE_DONE)
2719      astrcat_(&dump->result_str, "%s FAILED\n", dest ?: "Can't save the file(Already Exists?)");
2720    else
2721      astrcat_(&dump->result_str, "%s SAVED\n", dest);
2722
2723    if (dump->num <= 0)
2724      {
2725         eldbus_message_arguments_append(dump->reply, "s", dump->result_str);
2726         eldbus_connection_send(e_info_server.edbus_conn, dump->reply, NULL, NULL, -1);
2727         free(dump->result_str);
2728         E_FREE(dump);
2729      }
2730
2731    return;
2732 fail:
2733    free(dump->result_str);
2734
2735    if (dump->num <= 0)
2736      {
2737         eldbus_message_arguments_append(dump->reply, "s", "Failed to make log message...");
2738         eldbus_connection_send(e_info_server.edbus_conn, dump->reply, NULL, NULL, -1);
2739         E_FREE(dump);
2740      }
2741 }
2742
2743 #undef astrcat_
2744
2745 static void _e_info_server_cb_wins_dump_topvwins(const char *dir, Eldbus_Message *reply)
2746 {
2747    Evas_Object *o;
2748    E_Client *ec;
2749    Ecore_Window win;
2750    int rotation = 0;
2751    char fname[PATH_MAX];
2752    Eina_Stringshare *s_fname, *s_dir;
2753    Eina_List *topvwins = NULL;
2754    Dump_Win_Data *dump = NULL;
2755    E_Capture_Save_State state;
2756
2757    for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
2758      {
2759         ec = evas_object_data_get(o, "E_Client");
2760
2761         if (!ec) continue;
2762         if (e_client_util_ignored_get(ec)) continue;
2763
2764         topvwins = eina_list_append(topvwins, ec);
2765      }
2766
2767    if (topvwins)
2768      {
2769         dump = E_NEW(Dump_Win_Data, 1);
2770         EINA_SAFETY_ON_NULL_GOTO(dump, fail);
2771
2772         dump->reply = reply;
2773         dump->num = eina_list_count(topvwins);
2774
2775         s_dir = eina_stringshare_add(dir);
2776
2777         EINA_LIST_FREE(topvwins, ec)
2778           {
2779              win = e_client_util_win_get(ec);
2780              if (ec->comp_data)
2781                rotation = ec->comp_data->scaler.buffer_viewport.buffer.transform * 90;
2782              snprintf(fname, sizeof(fname), "0x%08zx_%d", win, rotation);
2783
2784              s_fname = eina_stringshare_add(fname);
2785
2786              state = e_client_image_save(ec, s_dir, s_fname,
2787                                          _image_save_done_cb, dump, EINA_TRUE);
2788
2789              if (state != E_CAPTURE_SAVE_STATE_START)
2790                dump->num --;
2791
2792              eina_stringshare_del(s_fname);
2793           }
2794         eina_stringshare_del(s_dir);
2795
2796         if (dump->num <= 0)
2797           E_FREE(dump);
2798      }
2799
2800    //no available windows to dump
2801 fail:
2802    if (!dump)
2803      {
2804         eldbus_message_arguments_append(reply, "s", "ERR: There are no topvwins.");
2805         eldbus_connection_send(e_info_server.edbus_conn, reply, NULL, NULL, -1);
2806      }
2807
2808 }
2809
2810 static void _e_info_server_cb_wins_dump_ns(const char *dir)
2811 {
2812    Evas_Object *o;
2813
2814    for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
2815      {
2816         Ecore_Window win;
2817         E_Client *ec;
2818         Evas_Native_Surface *ns = NULL;
2819         Evas_Object *co = NULL; // native surface set
2820         tbm_surface_h tbm_surface = NULL, capturable_tbm_surface = NULL;
2821         char fname[PATH_MAX];
2822         const char *bltin_t = NULL;
2823
2824         ec = evas_object_data_get(o, "E_Client");
2825         win = e_client_util_win_get(ec);
2826
2827         // find obj which have native surface set
2828         bltin_t = evas_object_type_get(o);
2829         if (!e_util_strcmp(bltin_t, "image"))
2830           {
2831              // builtin types "image" could have cw->obj
2832              ns = evas_object_image_native_surface_get(o);
2833              if (ns) co = o;
2834           }
2835
2836         if (!ns)
2837           {
2838              if (!co) co = evas_object_name_child_find(o, "cw->obj", -1);
2839              if (co) ns = evas_object_image_native_surface_get(co);
2840           }
2841
2842         if (!ns)
2843           {
2844              Eina_List *ll;
2845              Evas_Object *c = NULL;
2846
2847              if (evas_object_smart_smart_get(o) &&
2848                  evas_object_smart_data_get(o))
2849                {
2850                   //find smart obj members
2851                   EINA_LIST_REVERSE_FOREACH(evas_object_smart_members_get(o), ll, c)
2852                     {
2853                        if (!co) co = evas_object_name_child_find(c, "cw->obj", -1);
2854                        if (co) ns = evas_object_image_native_surface_get(co);
2855                        if (ns) break;
2856                     }
2857                }
2858           }
2859
2860         if (!ns) continue;
2861
2862         switch (ns->type)
2863           {
2864            case EVAS_NATIVE_SURFACE_WL:
2865               snprintf(fname, sizeof(fname), "%s/0x%08zx_wl_%p.png", dir, win, co);
2866               if (!ns->data.wl.legacy_buffer) continue;
2867
2868               tbm_surface = wayland_tbm_server_get_surface(NULL, ns->data.wl.legacy_buffer);
2869               if (!tbm_surface) continue;
2870
2871               capturable_tbm_surface = e_comp_wl_tbm_capturable_buffer_get(tbm_surface);
2872               if (!capturable_tbm_surface) continue;
2873
2874               tdm_helper_dump_buffer(capturable_tbm_surface, fname);
2875               tbm_surface_internal_unref(capturable_tbm_surface);
2876               break;
2877            case EVAS_NATIVE_SURFACE_TBM:
2878               snprintf(fname, sizeof(fname), "%s/0x%08zx_tbm_%p.png", dir, win, co);
2879               if (!ns->data.tbm.buffer) continue;
2880
2881               capturable_tbm_surface = e_comp_wl_tbm_capturable_buffer_get(ns->data.tbm.buffer);
2882               if (!capturable_tbm_surface) continue;
2883
2884               tdm_helper_dump_buffer(capturable_tbm_surface, fname);
2885               tbm_surface_internal_unref(capturable_tbm_surface);
2886               break;
2887            default:
2888               break;
2889           }
2890      }
2891 }
2892
2893 static void _e_info_server_cb_wins_dump_hwc_wins(const char *dir)
2894 {
2895    E_Comp_Screen *e_comp_screen = NULL;
2896    E_Output *output = NULL;
2897    E_Hwc_Window *hwc_window = NULL;
2898    E_Hwc *hwc = NULL;
2899    Eina_List *o = NULL, *oo = NULL;
2900    Eina_List *l = NULL, *ll = NULL;
2901
2902    e_comp_screen = e_comp->e_comp_screen;
2903    if (!e_comp_screen) return;
2904
2905    EINA_LIST_FOREACH_SAFE(e_comp_screen->outputs, o, oo, output)
2906      {
2907         if (!output) continue;
2908         if (!output->config.enabled) continue;
2909         if (!output->tdm_hwc) continue;
2910
2911          hwc = output->hwc;
2912
2913          EINA_LIST_FOREACH_SAFE(hwc->hwc_windows, l, ll, hwc_window)
2914            {
2915               char fname[PATH_MAX];
2916               tbm_format fmt;
2917               tbm_surface_h capturable_tbm_surface;
2918
2919               if (!hwc_window) continue;
2920               if (!hwc_window->display.buffer.tsurface) continue;
2921
2922               fmt = tbm_surface_get_format(hwc_window->display.buffer.tsurface);
2923               switch (fmt)
2924                 {
2925                  case TBM_FORMAT_ARGB8888:
2926                  case TBM_FORMAT_XRGB8888:
2927                  case TBM_FORMAT_ABGR8888:
2928                  case TBM_FORMAT_XBGR8888:
2929                   if (hwc_window->is_target)
2930                     snprintf(fname, sizeof(fname), "compositor_hwin_%p_tbm_%p", hwc_window, hwc_window->display.buffer.tsurface);
2931                   else
2932                     snprintf(fname, sizeof(fname), "0x%08zx_hwin_%p_tbm_%p", e_client_util_win_get(hwc_window->ec),
2933                              hwc_window, hwc_window->display.buffer.tsurface);
2934
2935                   capturable_tbm_surface = e_comp_wl_tbm_capturable_buffer_get(hwc_window->display.buffer.tsurface);
2936                   if (!capturable_tbm_surface) continue;
2937
2938                   tbm_surface_internal_capture_buffer(capturable_tbm_surface, dir, fname, "png");
2939                   tbm_surface_internal_unref(capturable_tbm_surface);
2940                   break;
2941                  case TBM_FORMAT_YUV420:
2942                  case TBM_FORMAT_YVU420:
2943                  case TBM_FORMAT_NV12:
2944                  case TBM_FORMAT_NV21:
2945                  case TBM_FORMAT_YUYV:
2946                  case TBM_FORMAT_UYVY:
2947                   if (hwc_window->is_target)
2948                     snprintf(fname, sizeof(fname), "compositor_hwin_%p_tbm_%p", hwc_window, hwc_window->display.buffer.tsurface);
2949                   else
2950                     snprintf(fname, sizeof(fname), "0x%08zx_hwin_%p_tbm_%p", e_client_util_win_get(hwc_window->ec),
2951                              hwc_window, hwc_window->display.buffer.tsurface);
2952
2953                   capturable_tbm_surface = e_comp_wl_tbm_capturable_buffer_get(hwc_window->display.buffer.tsurface);
2954                   if (!capturable_tbm_surface) continue;
2955
2956                   tbm_surface_internal_capture_buffer(capturable_tbm_surface, dir, fname, "png");
2957                   tbm_surface_internal_unref(capturable_tbm_surface);
2958                   break;
2959                  default:
2960                   break;
2961                 }
2962            }
2963      }
2964 }
2965
2966 static Eldbus_Message *
2967 _e_info_server_cb_wins_dump(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
2968 {
2969    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
2970    const char *type;
2971    const char *dir;
2972    char log[2048];
2973
2974    if (!eldbus_message_arguments_get(msg, SIGNATURE_DUMP_WINS, &type, &dir))
2975      {
2976         ERR("Error getting arguments.");
2977         return reply;
2978      }
2979
2980    if (!e_util_strcmp(type, "topvwins"))
2981      {
2982         _e_info_server_cb_wins_dump_topvwins(dir, reply);
2983         return NULL;
2984      }
2985    else if (!e_util_strcmp(type, "ns"))
2986      _e_info_server_cb_wins_dump_ns(dir);
2987    else if (!e_util_strcmp(type, "hwc_wins"))
2988      _e_info_server_cb_wins_dump_hwc_wins(dir);
2989
2990    snprintf(log, sizeof(log), "path:%s type:%s Dump Completed\n", dir, type);
2991    eldbus_message_arguments_append(reply, "s", log);
2992    return reply;
2993 }
2994
2995 static Eldbus_Message *
2996 _e_info_server_cb_force_visible(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
2997 {
2998    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
2999    unsigned int obj;
3000    Eina_Bool visible;
3001    Evas_Object *o;
3002    E_Client *ec;
3003
3004    if (!eldbus_message_arguments_get(msg, SIGNATURE_FORCE_VISIBLE_CLIENT, &obj, &visible))
3005      {
3006         ERR("Error getting arguments.");
3007         return reply;
3008      }
3009
3010    o = (Evas_Object*)((uintptr_t)obj);
3011
3012    ec = evas_object_data_get(o, "E_Client");
3013    if (ec && !e_pixmap_resource_get(ec->pixmap))
3014      {
3015         char msg[256];
3016         snprintf(msg, sizeof msg, "obj(%p) doesn't have valid wl_buffer", o);
3017         eldbus_message_arguments_append(reply, "s", msg);
3018         return reply;
3019      }
3020
3021    if (visible)
3022      evas_object_show(o);
3023    else
3024      evas_object_hide(o);
3025
3026    return reply;
3027 }
3028
3029 /* Method Handlers */
3030 static Eldbus_Message *
3031 _e_info_server_cb_subsurface(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
3032 {
3033    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
3034    Eldbus_Message_Iter *iter = eldbus_message_iter_get(reply);
3035    Eldbus_Message_Iter *array_of_ec;
3036    E_Client *ec;
3037    Evas_Object *o;
3038
3039    eldbus_message_iter_arguments_append(iter, "a("SIGNATURE_SUBSURFACE")", &array_of_ec);
3040
3041    // append clients.
3042    for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
3043      {
3044         Eldbus_Message_Iter* struct_of_ec;
3045         Ecore_Window win = 0, parent = 0;
3046         unsigned int buf_id = 0;
3047         int x = 0, y = 0, w = 0, h = 0;
3048         unsigned int transform = 0, visible = 0, alpha = 0, ignore = 0, maskobj = 0, video = 0, stand = 0;
3049         Ecore_Window bgrect = 0;
3050         const char *name = NULL;
3051         E_Comp_Wl_Buffer *buffer;
3052         E_Map *map;
3053
3054         ec = evas_object_data_get(o, "E_Client");
3055         if (!ec)
3056           {
3057              if (!evas_object_visible_get(o)) continue;
3058
3059              name = evas_object_name_get(o);
3060              if (!name) continue;
3061              if (strncmp(name, "below_bg_rectangle", 18)) continue;
3062              win = (Ecore_Window)o;
3063              evas_object_geometry_get(o, &x, &y, &w, &h);
3064              visible = evas_object_visible_get(o);
3065           }
3066         else
3067           {
3068              if (e_object_is_del(E_OBJECT(ec)) || !ec->comp_data) continue;
3069              if (!e_comp_wl_subsurface_check(ec) &&
3070                  !ec->comp_data->sub.list && !ec->comp_data->sub.list_pending &&
3071                  !ec->comp_data->sub.below_list && !ec->comp_data->sub.below_list_pending)
3072                continue;
3073              win = e_client_util_win_get(ec);
3074              if (e_comp_wl_subsurface_check(ec))
3075                {
3076                   parent = e_client_util_win_get(e_comp_wl_subsurface_parent_get(ec));
3077                   stand = e_comp_wl_subsurface_stand_alone_mode_get(ec);
3078                }
3079              buffer = e_pixmap_resource_get(ec->pixmap);
3080              if (buffer)
3081                buf_id = (buffer->resource) ? wl_resource_get_id(buffer->resource) : (WAYLAND_SERVER_RESOURCE_ID_MASK & 99999);
3082              map = e_client_map_get(ec);
3083              if (map)
3084                {
3085                   Evas_Coord x1, x2, y1, y2;
3086                   E_Comp_Wl_Buffer_Viewport *vp = &ec->comp_data->scaler.buffer_viewport;
3087                   e_map_point_coord_get(map, 0, &x1, &y1, NULL);
3088                   e_map_point_coord_get(map, 2, &x2, &y2, NULL);
3089                   x = x1, y = y1, w = x2 - x1, h = y2 - y1;
3090                   transform = vp->buffer.transform;
3091                }
3092              else
3093                evas_object_geometry_get(ec->frame, &x, &y, &w, &h);
3094              e_map_free(map);
3095              visible = evas_object_visible_get(o);
3096              alpha = e_comp_object_alpha_get(ec->frame);
3097              ignore = e_client_util_ignored_get(ec);
3098              if (ec->comp_data->sub.below_obj)
3099                bgrect = (Ecore_Window)ec->comp_data->sub.below_obj;
3100              maskobj = e_comp_object_mask_has(ec->frame);
3101              video = (ec->comp_data->video_client || e_client_video_hw_composition_check(ec)) ? 1 : 0;
3102              name = e_client_util_name_get(ec);
3103              if (!name)
3104                name = "NO NAME";
3105           }
3106
3107         eldbus_message_iter_arguments_append(array_of_ec, "("SIGNATURE_SUBSURFACE")", &struct_of_ec);
3108
3109         eldbus_message_iter_arguments_append
3110            (struct_of_ec, SIGNATURE_SUBSURFACE,
3111             win, parent, buf_id, x, y, w, h, transform, visible, alpha, ignore, maskobj, video, stand, bgrect, name);
3112
3113         eldbus_message_iter_container_close(array_of_ec, struct_of_ec);
3114      }
3115
3116    eldbus_message_iter_container_close(iter, array_of_ec);
3117
3118    return reply;
3119 }
3120
3121 static Eldbus_Message *
3122 _e_info_server_cb_eina_log_levels(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
3123 {
3124    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
3125    const char *start = NULL;
3126    int len = 0;
3127
3128    if (!eldbus_message_arguments_get(msg, "s", &start) || !start)
3129      {
3130         ERR("Error getting arguments.");
3131         return reply;
3132      }
3133
3134    while (1)
3135      {
3136         char module_name[256];
3137         char *end = NULL;
3138         char *tmp = NULL;
3139         int level;
3140
3141         end = strchr(start, ':');
3142         if (!end)
3143            break;
3144
3145         // Parse level, keep going if failed
3146         level = (int)strtol((char *)(end + 1), &tmp, 10);
3147         if (tmp == (end + 1))
3148            goto parse_end;
3149
3150         // Parse name
3151         len = MIN(end - start, (sizeof module_name) - 1);
3152         strncpy(module_name, start, len);
3153         module_name[len] = '\0';
3154
3155                   eina_log_domain_level_set((const char*)module_name, level);
3156
3157 parse_end:
3158         start = strchr(tmp, ',');
3159         if (start)
3160            start++;
3161         else
3162            break;
3163      }
3164
3165    return reply;
3166 }
3167
3168 static Eldbus_Message *
3169 _e_info_server_cb_eina_log_path(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
3170 {
3171    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
3172    const char *path = NULL;
3173
3174    if (!eldbus_message_arguments_get(msg, "s", &path) || !path)
3175      {
3176         ERR("Error getting arguments.");
3177         return reply;
3178      }
3179
3180    e_log_path_set(path);
3181
3182    return reply;
3183 }
3184
3185 #ifdef HAVE_DLOG
3186 static Eldbus_Message *
3187 _e_info_server_cb_dlog_switch(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
3188 {
3189    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
3190    uint32_t onoff;
3191
3192    if (!eldbus_message_arguments_get(msg, "i", &onoff))
3193      {
3194         ERR("Error getting arguments.");
3195         return reply;
3196      }
3197
3198    if ((onoff == 1) || (onoff == 0))
3199      e_log_dlog_enable(onoff);
3200
3201    return reply;
3202 }
3203 #endif
3204
3205 static Eldbus_Message *
3206 _e_info_server_cb_rotation_query(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
3207 {
3208    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
3209
3210    /* TODO: need implementation */
3211
3212    return reply;
3213 }
3214
3215 static void
3216 _e_info_event_rotation_free(void *data EINA_UNUSED, void *event)
3217 {
3218    E_Event_Info_Rotation_Message *ev = event;
3219
3220    e_object_unref(E_OBJECT(ev->zone));
3221    free(ev);
3222 }
3223
3224 static Eldbus_Message *
3225 _e_info_server_cb_rotation_message(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
3226 {
3227    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
3228    E_Event_Info_Rotation_Message *ev;
3229    E_Info_Rotation_Message rot_msg;
3230    E_Zone *z;
3231    Eina_List *l;
3232    uint32_t zone_num;
3233    uint32_t rval;
3234
3235    if (!eldbus_message_arguments_get(msg, "iii", &rot_msg, &zone_num, &rval))
3236      {
3237         ERR("Error getting arguments.");
3238         return reply;
3239      }
3240
3241    if (rot_msg == E_INFO_ROTATION_MESSAGE_SET)
3242      {
3243         /* check if rval is valid */
3244         if ((rval > 270) || (rval % 90 != 0))
3245           return reply;
3246      }
3247
3248    ev = E_NEW(E_Event_Info_Rotation_Message, 1);
3249    if (EINA_UNLIKELY(!ev))
3250      {
3251         ERR("Failed to allocate ""E_Event_Info_Rotation_Message""");
3252         return reply;
3253      }
3254
3255    if (zone_num == -1)
3256      ev->zone = e_zone_current_get();
3257    else
3258      {
3259         EINA_LIST_FOREACH(e_comp->zones, l, z)
3260           {
3261              if (z->num == zone_num)
3262                ev->zone = z;
3263           }
3264      }
3265
3266    if (!ev->zone)
3267      {
3268         ERR("Failed to found zone by given num: num %d", zone_num);
3269         free(ev);
3270         return reply;
3271      }
3272
3273    e_object_ref(E_OBJECT(ev->zone));
3274    ev->message = rot_msg;
3275    ev->rotation = rval;
3276
3277    ecore_event_add(E_EVENT_INFO_ROTATION_MESSAGE, ev, _e_info_event_rotation_free, NULL);
3278
3279    return reply;
3280 }
3281
3282 static void
3283 protocol_cb_client_destroy(struct wl_listener *listener, void *data)
3284 {
3285    struct wl_client *wc = (struct wl_client *)data;
3286    struct timespec tp;
3287    unsigned int time;
3288    pid_t client_pid = -1;
3289    const char *client_name = NULL;
3290    E_Comp_Connected_Client_Info *cinfo;
3291    Eina_List *l;
3292    char strbuf[512], *str_buff = strbuf;
3293    int str_r, str_l;
3294
3295    str_buff[0] = '\0';
3296    str_r = sizeof(strbuf);
3297
3298    wl_client_get_credentials(wc, &client_pid, NULL, NULL);
3299
3300    clock_gettime(CLOCK_MONOTONIC, &tp);
3301    time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
3302
3303    EINA_LIST_FOREACH(e_comp->connected_clients, l, cinfo)
3304      {
3305         if (cinfo->pid == client_pid)
3306           {
3307               client_name = cinfo->name;
3308               break;
3309           }
3310      }
3311
3312    BUF_SNPRINTF("[%10.3f] Server           [PID:%d] client destroying", time / 1000.0, client_pid);
3313    BUF_SNPRINTF(", cmd: %s", client_name ? client_name : "cmd is NULL");
3314
3315    if (log_fp_ptrace)
3316      fprintf(log_fp_ptrace, "%s\n", strbuf);
3317    else
3318      INF("%s", strbuf);
3319
3320    wl_list_remove(&listener->link);
3321    E_FREE(listener);
3322 }
3323
3324 static void
3325 protocol_client_destroy_listener_reg(struct wl_client *client)
3326 {
3327    struct wl_listener *destroy_listener;
3328
3329    destroy_listener = wl_client_get_destroy_listener(client, protocol_cb_client_destroy);
3330    if (destroy_listener) return;
3331
3332    destroy_listener = E_NEW(struct wl_listener, 1);
3333    EINA_SAFETY_ON_NULL_RETURN(destroy_listener);
3334
3335    destroy_listener->notify = protocol_cb_client_destroy;
3336    wl_client_add_destroy_listener(client, destroy_listener);
3337 }
3338
3339 /* wayland private function */
3340 const char *
3341 get_next_argument(const char *signature, struct argument_details *details)
3342 {
3343    details->nullable = 0;
3344    for(; *signature; ++signature)
3345      {
3346         switch(*signature)
3347           {
3348            case 'i':
3349            case 'u':
3350            case 'f':
3351            case 's':
3352            case 'o':
3353            case 'n':
3354            case 'a':
3355            case 'h':
3356              details->type = *signature;
3357              return signature + 1;
3358            case '?':
3359              details->nullable = 1;
3360           }
3361      }
3362    details->type = '\0';
3363    return signature;
3364 }
3365
3366 static void
3367 _e_info_server_protocol_debug_func2(void *user_data, enum wl_protocol_logger_type direction, const struct wl_protocol_logger_message *message)
3368 {
3369    int i;
3370    struct argument_details arg;
3371    struct wl_client *wc = wl_resource_get_client(message->resource);
3372    const char *signature = message->message->signature;
3373    struct timespec tp;
3374    unsigned int time;
3375    pid_t client_pid = -1;
3376    E_Comp_Connected_Client_Info *cinfo;
3377    Eina_List *l;
3378    char strbuf[512], *str_buff = strbuf;
3379    int str_r, str_l;
3380
3381    str_buff[0] = '\0';
3382    str_r = sizeof(strbuf);
3383
3384    if (wc)
3385      {
3386         protocol_client_destroy_listener_reg(wc);
3387         wl_client_get_credentials(wc, &client_pid, NULL, NULL);
3388      }
3389
3390    clock_gettime(CLOCK_MONOTONIC, &tp);
3391    time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
3392
3393    E_Info_Protocol_Log elog = {0,};
3394    elog.type = (direction == WL_PROTOCOL_LOGGER_EVENT)?1:0;
3395    elog.client_pid = client_pid;
3396    elog.target_id = wl_resource_get_id(message->resource);
3397    snprintf(elog.name, PATH_MAX, "%s:%s", wl_resource_get_class(message->resource), message->message->name);
3398    EINA_LIST_FOREACH(e_comp->connected_clients, l, cinfo)
3399      {
3400         if (cinfo->pid == client_pid)
3401           snprintf(elog.cmd, PATH_MAX, "%s", cinfo->name);
3402      }
3403
3404    if (!e_info_protocol_rule_validate(&elog)) return;
3405    BUF_SNPRINTF("[%10.3f] %s%d%s%s@%u.%s(",
3406               time / 1000.0,
3407               elog.type ? "Server -> Client [PID:" : "Server <- Client [PID:",
3408               client_pid, "] ",
3409               wl_resource_get_class(message->resource),
3410               wl_resource_get_id(message->resource),
3411               message->message->name);
3412
3413    for (i = 0; i < message->arguments_count; i++)
3414      {
3415         signature = get_next_argument(signature, &arg);
3416         if (i > 0) BUF_SNPRINTF(", ");
3417
3418         switch (arg.type)
3419           {
3420            case 'u':
3421              BUF_SNPRINTF("%u", message->arguments[i].u);
3422              break;
3423            case 'i':
3424              BUF_SNPRINTF("%d", message->arguments[i].i);
3425              break;
3426            case 'f':
3427              BUF_SNPRINTF("%f",
3428              wl_fixed_to_double(message->arguments[i].f));
3429              break;
3430            case 's':
3431              BUF_SNPRINTF("\"%s\"", message->arguments[i].s);
3432              break;
3433            case 'o':
3434              if (message->arguments[i].o)
3435                BUF_SNPRINTF("%s@%u",
3436                         wl_resource_get_class((struct wl_resource*)message->arguments[i].o),
3437                         wl_resource_get_id((struct wl_resource*)message->arguments[i].o));
3438              else
3439                BUF_SNPRINTF("nil");
3440              break;
3441            case 'n':
3442              BUF_SNPRINTF("new id %s@", (message->message->types[i]) ? message->message->types[i]->name : "[unknown]");
3443              if (message->arguments[i].n != 0)
3444                BUF_SNPRINTF("%u", message->arguments[i].n);
3445              else
3446                BUF_SNPRINTF("nil");
3447              break;
3448            case 'a':
3449              BUF_SNPRINTF("array");
3450              break;
3451            case 'h':
3452              BUF_SNPRINTF("fd %d", message->arguments[i].h);
3453              break;
3454           }
3455      }
3456
3457    BUF_SNPRINTF("), cmd: %s", elog.cmd ? elog.cmd : "cmd is NULL");
3458
3459    if (log_fp_ptrace)
3460      fprintf(log_fp_ptrace, "%s\n", strbuf);
3461    else
3462      INF("%s", strbuf);
3463 }
3464
3465 static Eldbus_Message *
3466 _e_info_server_cb_protocol_trace(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
3467 {
3468    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
3469    const char *path = NULL;
3470
3471    if (!eldbus_message_arguments_get(msg, "s", &path) || !path)
3472      {
3473         ERR("Error getting arguments.");
3474         return reply;
3475      }
3476
3477    if (log_fp_ptrace != NULL)
3478      {
3479         fclose(log_fp_ptrace);
3480         log_fp_ptrace = NULL;
3481      }
3482
3483    if (!strncmp(path, "disable", 7))
3484      {
3485         if (e_info_protocol_logger)
3486           {
3487              wl_protocol_logger_destroy(e_info_protocol_logger);
3488              e_info_protocol_logger = NULL;
3489           }
3490         return reply;
3491      }
3492
3493    /* if path's not elog, we open the new log file. Otherwise, the log will be printed via eina_log */
3494    if (strncmp(path, "elog", 4))
3495      {
3496         log_fp_ptrace = fopen(path, "a");
3497         if (!log_fp_ptrace)
3498           {
3499              ERR("failed: open file(%s)\n", path);
3500              return reply;
3501           }
3502         setvbuf(log_fp_ptrace, NULL, _IOLBF, 512);
3503      }
3504
3505      if (e_info_protocol_logger)
3506        {
3507           wl_protocol_logger_destroy(e_info_protocol_logger);
3508           e_info_protocol_logger = NULL;
3509        }
3510      e_info_protocol_logger = wl_display_add_protocol_logger(e_comp->wl_comp_data->wl.disp, _e_info_server_protocol_debug_func2, NULL);
3511
3512    return reply;
3513 }
3514
3515 static Eldbus_Message *
3516 _e_info_server_cb_protocol_rule(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
3517 {
3518    Eldbus_Message *reply_msg = eldbus_message_method_return_new(msg);
3519    char reply[4096];
3520    int len = sizeof (reply);
3521    int argc = 3;
3522    char *argv[3];
3523
3524    if (!eldbus_message_arguments_get(msg, "sss", &argv[0], &argv[1], &argv[2]) || !argv[0] || !argv[1] || !argv[2])
3525      {
3526         ERR("Error getting arguments.");
3527         return reply_msg;
3528      }
3529
3530    if ((eina_streq(argv[0], "remove") || eina_streq(argv[0], "file")) && eina_streq(argv[2], "no_data"))
3531      argc--;
3532    if ((eina_streq(argv[0], "print") || eina_streq(argv[0], "help")) && eina_streq(argv[1], "no_data") && eina_streq(argv[2], "no_data"))
3533      argc = 1;
3534
3535    e_info_protocol_rule_set(argc, (const char**)&(argv[0]), reply, &len);
3536
3537    eldbus_message_arguments_append(reply_msg, "s", reply);
3538
3539    return reply_msg;
3540 }
3541
3542 static Eldbus_Message *
3543 _e_info_server_cb_keymap_info_get(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
3544 {
3545    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
3546
3547    eldbus_message_arguments_append(reply, "hi", e_comp_input_key->xkb.fd, e_comp_input_key->xkb.size);
3548    return reply;
3549 }
3550
3551 static void
3552 _e_info_server_module_hook_call(const char *module_name, const char *log_path)
3553 {
3554    Eina_List *l;
3555    E_Info_Hook *data;
3556
3557    EINA_LIST_FOREACH(module_hook, l, data)
3558      {
3559         if (!strncmp(data->module_name, module_name, strlen(module_name)))
3560           {
3561              data->func(data->data, log_path);
3562              break;
3563           }
3564      }
3565 }
3566
3567 static void
3568 _e_info_server_module_hook_cleanup(void)
3569 {
3570    E_Info_Hook *hdata;
3571
3572    EINA_LIST_FREE(module_hook, hdata)
3573      {
3574         eina_stringshare_del(hdata->module_name);
3575         E_FREE(hdata);
3576      }
3577 }
3578
3579 /* a hook with given name(module_name) is defined by plug-in modules*/
3580 E_API void
3581 e_info_server_hook_set(const char *module_name, E_Info_Hook_Cb func, void *data)
3582 {
3583    Eina_List *l, *l_next;
3584    E_Info_Hook *hdata, *ndata;
3585
3586    EINA_SAFETY_ON_NULL_RETURN(module_name);
3587
3588    EINA_LIST_FOREACH_SAFE(module_hook, l, l_next, hdata)
3589      {
3590         if (!strncmp(hdata->module_name, module_name, strlen(module_name)))
3591           {
3592              if (!func)
3593                {
3594                   eina_stringshare_del(hdata->module_name);
3595                   E_FREE(hdata);
3596                   module_hook = eina_list_remove_list(module_hook, l);
3597                }
3598              else
3599                {
3600                   hdata->func = func;
3601                   hdata->data = data;
3602                }
3603              return;
3604           }
3605      }
3606
3607    ndata = E_NEW(E_Info_Hook, 1);
3608    EINA_SAFETY_ON_NULL_RETURN(ndata);
3609
3610    ndata->module_name = eina_stringshare_add(module_name);
3611    ndata->func = func;
3612    ndata->data = data;
3613
3614    module_hook = eina_list_append(module_hook, ndata);
3615 }
3616
3617 static Eldbus_Message *
3618 _e_info_server_cb_module_info_get(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
3619 {
3620    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
3621    const char *path = NULL, *module_name = NULL;
3622
3623    if (!eldbus_message_arguments_get(msg, "ss", &module_name, &path) || !module_name || !path)
3624      {
3625         ERR("Error getting arguments.");
3626         return reply;
3627      }
3628
3629    _e_info_server_module_hook_call(module_name, path);
3630
3631    return reply;
3632 }
3633
3634 static Eldbus_Message *
3635 _e_info_server_cb_keygrab_status_get(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
3636 {
3637    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
3638    const char *path = NULL;
3639
3640    if (!eldbus_message_arguments_get(msg, "s", &path) || !path)
3641      {
3642         ERR("Error getting arguments.");
3643         return reply;
3644      }
3645
3646    _e_info_server_module_hook_call("keygrab", path);
3647
3648    return reply;
3649 }
3650
3651 static Eldbus_Message *
3652 _e_info_server_cb_bgcolor_set(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
3653 {
3654    int a, r, g, b;
3655    int pa, pr, pg, pb;
3656    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
3657
3658    EINA_SAFETY_ON_NULL_RETURN_VAL(reply, NULL);
3659
3660    if (!eldbus_message_arguments_get(msg, "iiii", &a, &r, &g, &b))
3661      {
3662         ERR("Error on getting argument from the given message.");
3663         return reply;
3664      }
3665
3666    evas_object_color_get(e_comp->bg_blank_object, &pa, &pr, &pg, &pb);
3667    evas_object_color_set(e_comp->bg_blank_object, r, g, b, a);
3668
3669    INF("The background color of bg_blank_object has been changed.");
3670    INF("(A, R, G, B) : %d, %d, %d, %d -> %d, %d, %d, %d", pa, pr, pg, pb, a, r, g, b);
3671
3672    return reply;
3673 }
3674
3675 static Eldbus_Message *
3676 _e_info_server_cb_punch(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
3677 {
3678    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
3679    int onoff = 0, x = 0, y = 0, w = 0, h = 0;
3680    int a = 0, r = 0, g = 0, b = 0;
3681
3682    if (!eldbus_message_arguments_get(msg, "iiiiiiiii", &onoff, &x, &y, &w, &h, &a, &r, &g, &b))
3683      {
3684         ERR("Error getting arguments.");
3685         return reply;
3686      }
3687
3688    if (onoff)
3689      e_video_debug_screen_punch_set(x, y, w, h, a, r, g, b);
3690    else
3691      e_video_debug_screen_punch_unset();
3692
3693    return reply;
3694 }
3695
3696 static Eldbus_Message *
3697 e_info_server_cb_transform_message(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
3698 {
3699    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
3700    uint32_t enable, transform_id;
3701    uint32_t x, y, sx, sy, degree;
3702    uint32_t background;
3703    unsigned long tmp = 0;
3704    const char *value = NULL;
3705    uint64_t value_number = 0;
3706    Evas_Object *o;
3707    E_Client *ec;
3708    Eina_Bool res = EINA_FALSE;
3709    const char *role = NULL;
3710
3711    if (!eldbus_message_arguments_get(msg, "siiiiiiiis", &value, &transform_id, &enable, &x, &y, &sx, &sy, &degree, &background, &role))
3712      {
3713         ERR("Error getting arguments.");
3714         return reply;
3715      }
3716
3717    if (strlen(value) >= 2 && value[0] == '0' && value[1] == 'x')
3718      res = e_util_string_to_ulong(value, &tmp, 16);
3719    else
3720      res = e_util_string_to_ulong(value, &tmp, 10);
3721
3722    EINA_SAFETY_ON_FALSE_RETURN_VAL(res, reply);
3723
3724    value_number = (uint64_t)tmp;
3725
3726    for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
3727      {
3728         ec = evas_object_data_get(o, "E_Client");
3729         Ecore_Window win;
3730         E_Info_Transform *transform_info;
3731
3732         if (!ec) continue;
3733
3734         win = e_client_util_win_get(ec);
3735
3736         if (win != value_number) continue;
3737         transform_info = _e_info_transform_find(ec, transform_id);
3738
3739         if (transform_info)
3740           {
3741              _e_info_transform_set(transform_info, enable, x, y, sx, sy, degree);
3742
3743              if (!enable)
3744                 _e_info_transform_del_with_id(ec, transform_id);
3745           }
3746         else
3747           {
3748              if (enable)
3749                {
3750                   _e_info_transform_new(ec, transform_id, enable, x, y, sx, sy, degree, background, role);
3751                }
3752           }
3753
3754         break;
3755      }
3756
3757    return reply;
3758 }
3759
3760 static Eldbus_Message *
3761 _e_info_server_cb_desktop_geometry_set(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
3762 {
3763    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
3764    E_Zone *zone;
3765    E_Desk *desk;
3766    int x, y, w, h;
3767
3768    if (!eldbus_message_arguments_get(msg, "iiii", &x, &y, &w, &h))
3769      {
3770         ERR("Error getting arguments.");
3771         return reply;
3772      }
3773
3774    if ((w < 0) || (h < 0))
3775      {
3776         ERR("Error: Invalid parameter w %d h %d", w, h);
3777         return reply;
3778      }
3779
3780    zone = e_zone_current_get();
3781    desk = e_desk_current_get(zone);
3782    e_desk_geometry_set(desk, x, y, w, h);
3783
3784    return reply;
3785 }
3786
3787 static Eldbus_Message *
3788 _e_info_server_cb_desktop_window_control(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
3789 {
3790    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
3791    E_Zone *zone;
3792    E_Desk *desk;
3793    int option;
3794
3795    if (!eldbus_message_arguments_get(msg, "i", &option))
3796      {
3797         ERR("Error getting arguments.");
3798         return reply;
3799      }
3800
3801    zone = e_zone_current_get();
3802    desk = e_desk_current_get(zone);
3803
3804    if (option == 0) // all iconify
3805      {
3806         ELOGF("TEST", "Iconify Visible Windows", NULL);
3807         e_desk_visible_client_iconify_all(desk);
3808      }
3809    else if (option == 1) // restore
3810      {
3811         ELOGF("TEST", "Restore Iconified Windows", NULL);
3812         e_desk_visible_client_restore_all(desk);
3813      }
3814    else if (option == 2) // clear iconify list
3815      {
3816         ELOGF("TEST", "Clear Iconified Windows List", NULL);
3817         e_desk_visible_client_iconified_list_remove_all(desk);
3818      }
3819    else if (option == 3) // toggle
3820      {
3821         Eina_List *iconified_list = e_desk_visible_client_iconified_list_get(desk);
3822         if (iconified_list)
3823           {
3824              ELOGF("TEST", "Toggle. Restore Iconified Windows", NULL);
3825              e_desk_visible_client_restore_all(desk);
3826           }
3827         else
3828           {
3829              ELOGF("TEST", "Toggle. Iconify Visible Windows", NULL);
3830              e_desk_visible_client_iconify_all(desk);
3831           }
3832      }
3833
3834    return reply;
3835 }
3836
3837 static Eldbus_Message *
3838 _e_info_server_cb_desk_zoom(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
3839 {
3840    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
3841    E_Zone *zone;
3842    E_Desk *desk;
3843    double zx, zy;
3844    int cx, cy;
3845
3846    if (!eldbus_message_arguments_get(msg, "ddii", &zx, &zy, &cx, &cy))
3847      {
3848         ERR("Error getting arguments.");
3849         return reply;
3850      }
3851
3852    zone = e_zone_current_get();
3853    desk = e_desk_current_get(zone);
3854
3855    if ((zx != 1.0) || (zy != 1.0))
3856      e_desk_zoom_set(desk, zx, zy, cx, cy);
3857    else
3858      e_desk_zoom_unset(desk);
3859
3860    return reply;
3861 }
3862
3863 #ifdef REFACTOR_DESK_AREA
3864 #else
3865 static E_Desk_Area *_edg_sub1 = NULL;
3866 static E_Desk_Area *_edg_sub2 = NULL;
3867 #endif
3868
3869 static Eldbus_Message *
3870 _e_info_server_cb_desk_area_info(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
3871 {
3872    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
3873
3874 #ifdef REFACTOR_DESK_AREA
3875 #else
3876    E_Zone *zone;
3877    E_Desk *desk;
3878
3879    zone = e_zone_current_get();
3880    desk = e_desk_current_get(zone);
3881
3882    e_desk_desk_area_info_print(desk);
3883 #endif
3884
3885    return reply;
3886 }
3887
3888 static Eldbus_Message *
3889 _e_info_server_cb_desk_area_enable(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
3890 {
3891    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
3892 #ifdef REFACTOR_DESK_AREA
3893 #else
3894    uint32_t enable;
3895
3896    if (!eldbus_message_arguments_get(msg, "i", &enable))
3897      {
3898         ERR("Error getting arguments.");
3899         return reply;
3900      }
3901
3902    if (enable == 1)
3903      {
3904         e_desk_desk_area_enable(e_desk_current_get(e_zone_current_get()));
3905      }
3906    else if (enable == 0)
3907      {
3908         e_desk_desk_area_disable(e_desk_current_get(e_zone_current_get()));
3909      }
3910 #endif
3911    return reply;
3912 }
3913
3914 #ifdef REFACTOR_DESK_AREA
3915 #else
3916 static void _desk_area_new(int sub_edg_id, int x, int y, int w, int h, int layer)
3917 {
3918    E_Zone *zone;
3919    E_Desk *desk;
3920    E_Desk_Area_Layer edg_layer;
3921
3922    zone = e_zone_current_get();
3923    desk = e_desk_current_get(zone);
3924
3925    switch (layer)
3926      {
3927       case 0:   edg_layer = E_DESK_AREA_LAYER_BACKGROUND; break;
3928       case 1:   edg_layer = E_DESK_AREA_LAYER_NORMAL_BELOW; break;
3929       case 2:   edg_layer = E_DESK_AREA_LAYER_NORMAL; break;
3930       case 3:   edg_layer = E_DESK_AREA_LAYER_NORMAL_ABOVE; break;
3931       case 4:   edg_layer = E_DESK_AREA_LAYER_NOTIFICATION_LOW; break;
3932       case 5:   edg_layer = E_DESK_AREA_LAYER_NOTIFICATION_NORMAL; break;
3933       case 6:   edg_layer = E_DESK_AREA_LAYER_NOTIFICATION_HIGH; break;
3934       default:  edg_layer = E_DESK_AREA_LAYER_NORMAL; break;
3935      }
3936
3937    if (sub_edg_id == 1)
3938      {
3939         if (!_edg_sub1)
3940           _edg_sub1 = e_desk_desk_area_add(desk, x, y, w, h, edg_layer);
3941         else
3942           {
3943              e_desk_area_geometry_set(_edg_sub1, x, y, w, h);
3944              e_desk_area_layer_set(_edg_sub1, edg_layer);
3945           }
3946      }
3947    else if (sub_edg_id == 2)
3948      {
3949         if (!_edg_sub2)
3950           _edg_sub2 = e_desk_desk_area_add(desk, x, y, w, h, edg_layer);
3951         else
3952           {
3953              e_desk_area_geometry_set(_edg_sub2, x, y, w, h);
3954              e_desk_area_layer_set(_edg_sub2, edg_layer);
3955           }
3956      }
3957 }
3958 #endif
3959
3960 static Eldbus_Message *
3961 _e_info_server_cb_desk_area_new_sub1(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
3962 {
3963    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
3964
3965 #ifdef REFACTOR_DESK_AREA
3966 #else
3967    E_Client *ec;
3968    int x, y, w, h;
3969    int layer;
3970    Eina_List*l;
3971    Eina_List *ec_list = NULL;
3972
3973    if (!eldbus_message_arguments_get(msg, "iiiii", &x, &y, &w, &h, &layer))
3974      {
3975         ERR("Error getting arguments.");
3976         return reply;
3977      }
3978
3979    _desk_area_new(1, x, y, w, h, layer);
3980
3981    E_CLIENT_REVERSE_FOREACH(ec)
3982      {
3983         ec_list = eina_list_append(ec_list, ec);
3984      }
3985
3986    EINA_LIST_REVERSE_FOREACH(ec_list, l, ec)
3987      {
3988         e_desk_area_ec_reassign(_edg_sub1, ec);
3989      }
3990
3991    //e_desk_area_all_ec_update(_edg_sub1);
3992 #endif
3993
3994    return reply;
3995 }
3996
3997 static Eldbus_Message *
3998 _e_info_server_cb_desk_area_new_sub2(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
3999 {
4000    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
4001
4002 #ifdef REFACTOR_DESK_AREA
4003 #else
4004    int x, y, w, h;
4005    int layer;
4006    E_Client *ec;
4007
4008    if (!eldbus_message_arguments_get(msg, "iiiii", &x, &y, &w, &h, &layer))
4009      {
4010         ERR("Error getting arguments.");
4011         return reply;
4012      }
4013
4014    _desk_area_new(2, x, y, w, h, layer);
4015
4016    E_CLIENT_FOREACH(ec)
4017      {
4018         if (e_policy_client_is_home_screen(ec))
4019           e_desk_area_ec_reassign(_edg_sub2, ec);
4020         else if (e_policy_client_is_quickpanel(ec))
4021           e_desk_area_ec_reassign(_edg_sub2, ec);
4022      }
4023 #endif
4024
4025    return reply;
4026 }
4027
4028 static Eldbus_Message *
4029 _e_info_server_cb_desk_area_remove_sub(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
4030 {
4031    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
4032 #ifdef REFACTOR_DESK_AREA
4033 #else
4034    uint32_t sub_edg_id;
4035    E_Zone *zone;
4036    E_Desk *desk;
4037
4038    if (!eldbus_message_arguments_get(msg, "i", &sub_edg_id))
4039      {
4040         ERR("Error getting arguments.");
4041         return reply;
4042      }
4043
4044    zone = e_zone_current_get();
4045    desk = e_desk_current_get(zone);
4046
4047    if (sub_edg_id == 1)
4048      {
4049         e_desk_desk_area_del(desk, _edg_sub1);
4050         _edg_sub1 = NULL;
4051      }
4052    else if (sub_edg_id == 2)
4053      {
4054         e_desk_desk_area_del(desk, _edg_sub2);
4055         _edg_sub2 = NULL;
4056      }
4057 #endif
4058    return reply;
4059 }
4060
4061 static void
4062 _desk_area_raise(E_Desk_Area *eda, uint32_t raise)
4063 {
4064    E_Zone *zone;
4065    E_Desk *desk;
4066
4067    zone = e_zone_current_get();
4068    desk = e_desk_current_get(zone);
4069    if (!desk) return;
4070
4071    if (!eda)
4072      eda = desk->desk_area.base;
4073
4074    if (eda)
4075      {
4076         if (raise == 1)
4077           {
4078              //e_desk_area_raise(eda);
4079              e_desk_desk_area_raise(eda->desk, eda);
4080           }
4081         else if (raise == 0)
4082           {
4083              //e_desk_area_lower(eda);
4084              e_desk_desk_area_lower(eda->desk, eda);
4085           }
4086      }
4087 }
4088
4089 static Eldbus_Message *
4090 _e_info_server_cb_desk_area_base_raise(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
4091 {
4092    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
4093    uint32_t raise;
4094
4095    if (!eldbus_message_arguments_get(msg, "i", &raise))
4096      {
4097         ERR("Error getting arguments.");
4098         return reply;
4099      }
4100
4101    _desk_area_raise(NULL, raise);
4102
4103    return reply;
4104 }
4105
4106 static Eldbus_Message *
4107 _e_info_server_cb_desk_area_sub1_raise(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
4108 {
4109    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
4110 #ifdef REFACTOR_DESK_AREA
4111 #else
4112    uint32_t raise;
4113
4114    if (!eldbus_message_arguments_get(msg, "i", &raise))
4115      {
4116         ERR("Error getting arguments.");
4117         return reply;
4118      }
4119
4120    if (_edg_sub1)
4121      _desk_area_raise(_edg_sub1, raise);
4122 #endif
4123    return reply;
4124 }
4125
4126 static Eldbus_Message *
4127 _e_info_server_cb_desk_area_sub2_raise(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
4128 {
4129    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
4130 #ifdef REFACTOR_DESK_AREA
4131 #else
4132    uint32_t raise;
4133
4134    if (!eldbus_message_arguments_get(msg, "i", &raise))
4135      {
4136         ERR("Error getting arguments.");
4137         return reply;
4138      }
4139
4140    if (_edg_sub2)
4141      _desk_area_raise(_edg_sub2, raise);
4142 #endif
4143    return reply;
4144 }
4145
4146 static Eldbus_Message *
4147 _e_info_server_cb_desk_area_check_stack(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
4148 {
4149    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
4150    E_Zone *zone;
4151    E_Desk *desk;
4152    E_Desk_Area *eda = NULL;
4153    Eina_List *l;
4154    Eina_List *ll;
4155    Eina_List *edg_ecs_list = NULL;
4156    E_Client *ec;
4157    E_Client *edg_ec;
4158    Evas_Object *o;
4159    int i, j;
4160    Eina_Bool mis_match = EINA_FALSE;
4161
4162    zone = e_zone_current_get();
4163    desk = e_desk_current_get(zone);
4164    if (!desk)
4165      {
4166         ELOGF("EDG_TEST", "No current Desk_Area at a current Zoen... return", NULL);
4167         return reply;
4168      }
4169
4170    if (!desk->desk_area.enable)
4171      {
4172         ELOGF("EDG_TEST", "Desk_Area is not enable... return", NULL);
4173         return reply;
4174      }
4175
4176    for (i=E_DESK_AREA_LAYER_COUNT-1; i>=0; i--)
4177      {
4178         EINA_LIST_FOREACH(desk->desk_area.list[i], l, eda)
4179           {
4180              for (j=E_DESK_AREA_CLIENT_LAYER_MAX-1; j>=0; j--)
4181                {
4182                   EINA_LIST_FOREACH(eda->ec_lists[j], ll, edg_ec)
4183                     {
4184                        edg_ecs_list = eina_list_append(edg_ecs_list, edg_ec);
4185                     }
4186                }
4187           }
4188      }
4189
4190    for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
4191      {
4192         ec = evas_object_data_get(o, "E_Client");
4193         if (!ec) continue;
4194
4195         edg_ec = eina_list_nth(edg_ecs_list, 0);
4196         if (edg_ec != ec)
4197           {
4198              ELOGF("EDG_TEST", "BAD.BAD.BAD... NOT MATCHED!!! edg_ec(win:0x%08zx, ec:%p)", ec, e_client_util_win_get(edg_ec), edg_ec);
4199              mis_match = EINA_TRUE;
4200           }
4201         edg_ecs_list = eina_list_remove(edg_ecs_list, edg_ec);
4202      }
4203
4204    if (!mis_match)
4205      ELOGF("EDG_TEST", "No error. STACK is MATCHED!!!", NULL);
4206    else
4207      ELOGF("EDG_TEST", "Error. STACK is NOT MATCHED!!!", NULL);
4208
4209    return reply;
4210 }
4211
4212 static Eina_Bool
4213 _e_info_server_cb_buffer_change(void *data, int type, void *event)
4214 {
4215    E_Client *ec;
4216    E_Event_Client *ev = event;
4217    Ecore_Window event_win;
4218    char fname[PATH_MAX];
4219    E_Comp_Wl_Buffer *buffer;
4220    tbm_surface_h tbm_surface, capturable_tbm_surface;
4221    struct wl_shm_buffer *shmbuffer = NULL;
4222    void *ptr;
4223    int stride, w, h, rotation, row, col;
4224    char *name, *parsing_name = NULL, *parsing, *tmp;
4225
4226    EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON);
4227    EINA_SAFETY_ON_NULL_RETURN_VAL(ev->ec, ECORE_CALLBACK_PASS_ON);
4228
4229    ec = ev->ec;
4230    if (e_object_is_del(E_OBJECT(ec)))
4231      {
4232         ERR("%s: e_object_is_del(E_OBJECT(ec) return\n", __func__);
4233         return ECORE_CALLBACK_PASS_ON;
4234      }
4235    if (e_client_util_ignored_get(ec))
4236      {
4237         if (!e_info_dump_remote_surface || !ec->remote_surface.provider)
4238           {
4239              ERR("%s: e_client_util_ignored_get(ec) true. return\n", __func__);
4240              return ECORE_CALLBACK_PASS_ON;
4241           }
4242      }
4243
4244    if ((e_info_dump_win_id) && (e_info_dump_win_id != e_client_util_win_get(ec)))
4245      return ECORE_CALLBACK_PASS_ON;
4246
4247    buffer = e_pixmap_resource_get(ec->pixmap);
4248    if (!buffer) return ECORE_CALLBACK_PASS_ON;
4249
4250    rotation = ec->comp_data->scaler.buffer_viewport.buffer.transform * 90;
4251
4252    event_win = e_client_util_win_get(ec);
4253    name = eina_strdup(e_client_util_name_get(ec));
4254    if (name)
4255      {
4256         parsing_name = name;
4257         parsing = strtok_r(name, "/", &tmp);
4258         while(parsing != NULL)
4259           {
4260              parsing_name = parsing;
4261              parsing = strtok_r(NULL, "/", &tmp);
4262           }
4263      }
4264
4265    switch (buffer->type)
4266      {
4267       case E_COMP_WL_BUFFER_TYPE_SHM:
4268         snprintf(fname, sizeof(fname), "buffer_commit_shm_0x%08zx_%s_%d",
4269                  event_win, parsing_name ? parsing_name : "NO_NAME", rotation);
4270         break;
4271       case E_COMP_WL_BUFFER_TYPE_NATIVE:
4272         snprintf(fname, sizeof(fname), "buffer_commit_native_0x%08zx_%s_%d",
4273                  event_win, parsing_name ? parsing_name : "NO_NAME", rotation);
4274         break;
4275       case E_COMP_WL_BUFFER_TYPE_VIDEO:
4276         snprintf(fname, sizeof(fname), "buffer_commit_video_0x%08zx_%s_%d",
4277                  event_win, parsing_name ? parsing_name : "NO_NAME", rotation);
4278         break;
4279       case E_COMP_WL_BUFFER_TYPE_TBM:
4280         snprintf(fname, sizeof(fname), "buffer_commit_tbm_0x%08zx_%s_%d",
4281                  event_win, parsing_name ? parsing_name : "NO_NAME", rotation);
4282         break;
4283       default:
4284         snprintf(fname, sizeof(fname), "buffer_commit_none_0x%08zx_%s_%d",
4285                  event_win, parsing_name ? parsing_name : "NO_NAME", rotation);
4286         break;
4287      }
4288
4289    if (name) free(name);
4290
4291    switch (buffer->type)
4292      {
4293       case E_COMP_WL_BUFFER_TYPE_SHM:
4294         shmbuffer = wl_shm_buffer_get(buffer->resource);
4295         EINA_SAFETY_ON_NULL_RETURN_VAL(shmbuffer, ECORE_CALLBACK_PASS_ON);
4296
4297         ptr = wl_shm_buffer_get_data(shmbuffer);
4298         EINA_SAFETY_ON_NULL_RETURN_VAL(ptr, ECORE_CALLBACK_PASS_ON);
4299
4300         stride = wl_shm_buffer_get_stride(shmbuffer);
4301         w = stride / 4;
4302         h = wl_shm_buffer_get_height(shmbuffer);
4303         tbm_surface_internal_dump_shm_buffer(ptr, w, h, stride, fname);
4304         break;
4305       case E_COMP_WL_BUFFER_TYPE_NATIVE:
4306       case E_COMP_WL_BUFFER_TYPE_VIDEO:
4307       case E_COMP_WL_BUFFER_TYPE_TBM:
4308         tbm_surface = buffer->tbm_surface;
4309         EINA_SAFETY_ON_NULL_RETURN_VAL(tbm_surface, ECORE_CALLBACK_PASS_ON);
4310
4311         capturable_tbm_surface = e_comp_wl_tbm_capturable_buffer_get(tbm_surface);
4312         EINA_SAFETY_ON_NULL_RETURN_VAL(capturable_tbm_surface, ECORE_CALLBACK_PASS_ON);
4313
4314         if (e_info_dump_mark)
4315           {
4316              unsigned int colors[5] = {0xFFFF0000, 0xFF00FF00, 0xFF0000FF, 0xFF00FFFF, 0xFFFF00FF};
4317              tdm_pos pos;
4318              int box_size = 20;
4319              int box = e_info_dump_mark_count * box_size;
4320
4321              w = tbm_surface_get_width(capturable_tbm_surface);
4322              h = tbm_surface_get_height(capturable_tbm_surface);
4323
4324              EINA_SAFETY_ON_FALSE_RETURN_VAL((w > 0), ECORE_CALLBACK_PASS_ON);
4325              EINA_SAFETY_ON_FALSE_RETURN_VAL((h > 0), ECORE_CALLBACK_PASS_ON);
4326
4327              row = (((box / w) * box_size) % h);
4328              col = box % w;
4329
4330              pos.x = col;
4331              pos.y = row;
4332              pos.w = box_size;
4333              pos.h = box_size;
4334
4335              tdm_helper_clear_buffer_color(capturable_tbm_surface, &pos, colors[e_info_dump_mark_count % 5]);
4336              e_info_dump_mark_count++;
4337           }
4338
4339         tbm_surface_internal_dump_buffer(capturable_tbm_surface, fname);
4340         tbm_surface_internal_unref(capturable_tbm_surface);
4341         break;
4342       default:
4343         DBG("Unknown type resource:%u", wl_resource_get_id(buffer->resource));
4344         break;
4345      }
4346    DBG("%s dump excute\n", fname);
4347
4348    return ECORE_CALLBACK_PASS_ON;
4349 }
4350
4351 static char *
4352 _e_info_server_dump_directory_make(const char *path)
4353 {
4354    char *fullpath;
4355    time_t timer;
4356    struct tm *t, *buf;
4357
4358    timer = time(NULL);
4359
4360    buf = calloc (1, sizeof (struct tm));
4361    EINA_SAFETY_ON_NULL_RETURN_VAL(buf, NULL);
4362    t = localtime_r(&timer, buf);
4363    if (!t)
4364      {
4365         free(buf);
4366         ERR("fail to get local time\n");
4367         return NULL;
4368      }
4369
4370    fullpath = (char *)calloc(1, PATH_MAX * sizeof(char));
4371    if (!fullpath)
4372      {
4373         free(buf);
4374         ERR("fail to alloc pathname memory\n");
4375         return NULL;
4376      }
4377
4378    snprintf(fullpath, PATH_MAX, "%s/dump_%04d%02d%02d.%02d%02d%02d", path,
4379             t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
4380
4381    free(buf);
4382
4383    if ((mkdir(fullpath, 0755)) < 0)
4384      {
4385         ERR("%s: mkdir '%s' fail\n", __func__, fullpath);
4386         free(fullpath);
4387         return NULL;
4388      }
4389
4390    return fullpath;
4391 }
4392
4393 static Eldbus_Message *
4394 _e_info_server_cb_buffer_dump(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
4395 {
4396    Eldbus_Message *reply;
4397    int start = 0;
4398    int count = 0;
4399    const char *path = NULL, *win_id_s = NULL;
4400    unsigned long tmp = 0;
4401    double scale;
4402    Eina_Bool ret;
4403
4404    if (!eldbus_message_arguments_get(msg, "iisdis", &start, &count, &path, &scale, &e_info_dump_mark, &win_id_s))
4405      {
4406         return eldbus_message_error_new(msg, GET_CALL_MSG_ARG_ERR,
4407                                         "dump_buffers: an attempt to get arguments from method call message failed");
4408      }
4409
4410    reply = eldbus_message_method_return_new(msg);
4411
4412    if (start == 1)
4413      {
4414         if (e_info_dump_running == 1)
4415           {
4416              eldbus_message_arguments_append(reply, "is", 0, (e_info_dump_path ?: "nopath"));
4417              return reply;
4418           }
4419
4420         if (e_util_strcmp(win_id_s, ""))
4421           {
4422              if (!e_util_strcmp(win_id_s, "server"))
4423                e_info_dump_server_or_client = 1;
4424              else if (!e_util_strcmp(win_id_s, "client"))
4425                e_info_dump_server_or_client = 2;
4426              else
4427                {
4428                   if (strlen(win_id_s) >= 2 && win_id_s[0] == '0' && win_id_s[1] == 'x')
4429                     ret = e_util_string_to_ulong(win_id_s, &tmp, 16);
4430                   else
4431                     ret = e_util_string_to_ulong(win_id_s, &tmp, 10);
4432                   if (!ret)
4433                     {
4434                        eldbus_message_arguments_append(reply, "is", -1, (e_info_dump_path ?: "nopath"));
4435                        return reply;
4436                     }
4437
4438                   e_info_dump_server_or_client = 2;
4439                   e_info_dump_win_id = (uint64_t)tmp;
4440                }
4441           }
4442
4443         e_info_dump_running = 1;
4444         e_info_dump_mark_count = 0;
4445         e_info_dump_count = 1;
4446         e_info_dump_path = _e_info_server_dump_directory_make(path);
4447
4448         if (e_info_dump_path == NULL)
4449           {
4450              e_info_dump_running = 0;
4451              e_info_dump_count = 0;
4452              e_info_dump_win_id = 0;
4453              e_info_dump_server_or_client = 0;
4454              ERR("dump_buffers start fail\n");
4455              eldbus_message_arguments_append(reply, "is", -1, (e_info_dump_path ?: "nopath"));
4456              return reply;
4457           }
4458
4459         /* start dump */
4460         if (scale > 0.0)
4461           tbm_surface_internal_dump_with_scale_start(e_info_dump_path,
4462                                                      e_comp->w,
4463                                                      e_comp->h,
4464                                                      count, scale);
4465         else
4466           tbm_surface_internal_dump_start(e_info_dump_path, e_comp->w, e_comp->h, count);
4467
4468         if (e_info_dump_server_or_client != 2)
4469           {
4470              tdm_helper_dump_start(e_info_dump_path, &e_info_dump_count);
4471              e_hwc_windows_debug_dump_start();
4472           }
4473
4474         if (e_info_dump_server_or_client != 1)
4475           {
4476              E_LIST_HANDLER_APPEND(e_info_dump_hdlrs, E_EVENT_CLIENT_BUFFER_CHANGE,
4477                                    _e_info_server_cb_buffer_change, NULL);
4478           }
4479
4480         eldbus_message_arguments_append(reply, "is", 0, (e_info_dump_path ?: "nopath"));
4481      }
4482    else
4483      {
4484         if (e_info_dump_running == 0)
4485           {
4486              eldbus_message_arguments_append(reply, "is", 0, (e_info_dump_path ?: "nopath"));
4487              return reply;
4488           }
4489
4490         e_info_server_hook_call(E_INFO_SERVER_HOOK_BUFFER_DUMP_BEGIN);
4491         tdm_helper_dump_stop();
4492         e_hwc_windows_debug_dump_stop();
4493         tbm_surface_internal_dump_end();
4494
4495         eldbus_message_arguments_append(reply, "is", 0, (e_info_dump_path ?: "nopath"));
4496
4497         E_FREE_LIST(e_info_dump_hdlrs, ecore_event_handler_del);
4498         e_info_dump_hdlrs = NULL;
4499         if (e_info_dump_path)
4500           {
4501              free(e_info_dump_path);
4502              e_info_dump_path = NULL;
4503           }
4504         e_info_dump_count = 0;
4505         e_info_dump_running = 0;
4506         e_info_dump_mark_count = 0;
4507         e_info_dump_server_or_client = 0;
4508         e_info_dump_win_id = 0;
4509         e_info_server_hook_call(E_INFO_SERVER_HOOK_BUFFER_DUMP_END);
4510      }
4511
4512    return reply;
4513 }
4514
4515 static Eldbus_Message *
4516 _e_info_server_cb_selected_buffer_dump(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
4517 {
4518    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
4519    const char *win_str = NULL;
4520    const char *path = NULL;
4521    uint64_t win_id = 0;
4522    unsigned long tmp;
4523    Evas_Object *o;
4524    Eina_Bool res = EINA_FALSE;
4525
4526    Dump_Win_Data *dump = NULL;
4527    E_Capture_Save_State state;
4528
4529    if (!eldbus_message_arguments_get(msg, "ss", &win_str, &path))
4530      {
4531         ERR("Error getting arguments.");
4532         return reply;
4533      }
4534
4535      if (strlen(win_str) >= 2 && win_str[0] == '0' && win_str[1] == 'x')
4536        res = e_util_string_to_ulong(win_str, &tmp, 16);
4537      else
4538        res = e_util_string_to_ulong(win_str, &tmp, 10);
4539
4540      EINA_SAFETY_ON_FALSE_GOTO(res == EINA_TRUE, end);
4541
4542      win_id = (uint64_t)tmp;
4543
4544    for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
4545      {
4546         E_Client *ec = evas_object_data_get(o, "E_Client");
4547         Ecore_Window win;
4548
4549         char fname[PATH_MAX];
4550         Eina_Stringshare *s_fname, *s_path;
4551
4552         if (!ec) continue;
4553         if (e_client_util_ignored_get(ec)) continue;
4554
4555         win = e_client_util_win_get(ec);
4556
4557         if (win_id != win) continue;
4558
4559         dump = E_NEW(Dump_Win_Data, 1);
4560         EINA_SAFETY_ON_NULL_RETURN_VAL(dump, reply);
4561
4562         dump->num = 1;
4563         dump->reply = reply;
4564
4565         snprintf(fname, sizeof(fname), "0x%08zx", win);
4566
4567         s_fname = eina_stringshare_add(fname);
4568         s_path = eina_stringshare_add(path);
4569
4570         state = e_client_image_save(ec, s_path, s_fname, _image_save_done_cb, dump, EINA_TRUE);
4571
4572         eina_stringshare_del(s_path);
4573         eina_stringshare_del(s_fname);
4574
4575         //creation of window dump job succeeded, reply will be sent after dump ends.
4576         if (state == E_CAPTURE_SAVE_STATE_START)
4577           return NULL;
4578
4579         break;
4580      }
4581
4582    if (dump)
4583      E_FREE(dump);
4584
4585 end:
4586    //send reply with error msg because dump job failed.
4587    eldbus_message_arguments_append(reply, "s", "ERR: Can't start dump job");
4588    return reply;
4589 }
4590
4591 static void
4592 _e_info_server_cb_screen_dump_cb(E_Output *eout, tbm_surface_h surface, void *user_data)
4593 {
4594    char *path = (char *)user_data;
4595    char fname[PATH_MAX];
4596    char dir[PATH_MAX];
4597    char type[PATH_MAX];
4598    char *slash, *dot;
4599    int dlen = 0, flen = 0;
4600
4601    EINA_SAFETY_ON_NULL_GOTO(surface, done);
4602    EINA_SAFETY_ON_NULL_GOTO(path, done);
4603
4604    slash = strrchr(path, '/');
4605    if (slash == NULL)
4606      {
4607         ERR("cannot find /");
4608         goto done;
4609      }
4610    slash += 1;
4611
4612    dlen = strnlen(path, PATH_MAX) - strnlen(slash, PATH_MAX);
4613    if (dlen <= 0)
4614      {
4615         ERR("cannot get path");
4616         goto done;
4617      }
4618    strncpy(dir, path, dlen);
4619    dir[dlen] = '\0';
4620
4621    dot = strrchr(path, '.');
4622    if (dot == NULL)
4623      {
4624         ERR("cannot find .");
4625         goto done;
4626      }
4627
4628    flen = strnlen(slash, PATH_MAX) - strnlen(dot, PATH_MAX);
4629    if (flen <= 0)
4630      {
4631         ERR("cannot get file name");
4632         goto done;
4633      }
4634    strncpy(fname, slash, flen);
4635    fname[flen] = '\0';
4636
4637    dot += 1;
4638    strncpy(type, dot, PATH_MAX);
4639    type[4] = '\0';
4640
4641    tbm_surface_internal_capture_buffer(surface, dir, fname, type);
4642
4643    DBG("_e_info_server_cb_screen_dump_cb done");
4644
4645 done:
4646    if (path != NULL)
4647      free(path);
4648    if (surface != NULL)
4649      tbm_surface_destroy(surface);
4650 }
4651
4652 static Eldbus_Message *
4653 _e_info_server_cb_screen_dump(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
4654 {
4655    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
4656    const char *path = NULL;
4657    tbm_surface_h surface = NULL;
4658    E_Output *eout = NULL;
4659    int w = 0, h = 0;
4660    Eina_Bool ret = EINA_FALSE;
4661    char *path_backup = NULL;
4662
4663    if (!eldbus_message_arguments_get(msg, "s", &path))
4664      {
4665         ERR("Error getting arguments.");
4666         return reply;
4667      }
4668
4669    eout = e_output_find_by_index(0);
4670    if (eout == NULL)
4671      {
4672         ERR("Error get main outpute.");
4673         return reply;
4674      }
4675    e_output_size_get(eout, &w, &h);
4676
4677    surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
4678    if (!surface)
4679      {
4680         ERR("Error create tbm_surface.");
4681         return reply;
4682      }
4683
4684    path_backup = (char *)calloc(1, PATH_MAX * sizeof(char));
4685    if (path_backup == NULL)
4686      {
4687         ERR("Error alloc.");
4688         return reply;
4689      }
4690    strncpy(path_backup, path, PATH_MAX);
4691
4692    ret = e_output_capture(eout, surface, EINA_FALSE, EINA_TRUE, _e_info_server_cb_screen_dump_cb, path_backup);
4693    if (ret)
4694      return reply;
4695    else
4696      ERR("Error fail capture.");
4697
4698    free(path_backup);
4699    tbm_surface_destroy(surface);
4700
4701    return reply;
4702 }
4703
4704 static void
4705 _output_mode_set(E_Comp_Screen *e_comp_screen, int output_idx, int mode_count)
4706 {
4707    E_Output *output;
4708    E_Output_Mode *emode = NULL;
4709    Eina_List *mode_list = NULL;
4710    int num;
4711
4712    EINA_SAFETY_ON_TRUE_RETURN(output_idx > e_comp_screen->num_outputs);
4713
4714    output = eina_list_nth(e_comp_screen->outputs, output_idx);
4715    EINA_SAFETY_ON_NULL_RETURN(output);
4716
4717    mode_list = e_output_mode_list_get(output);
4718    EINA_SAFETY_ON_NULL_RETURN(mode_list);
4719
4720    num = eina_list_count(mode_list);
4721    EINA_SAFETY_ON_TRUE_RETURN(mode_count > num - 1);
4722
4723    emode = eina_list_nth(mode_list, mode_count);
4724    EINA_SAFETY_ON_NULL_RETURN(emode);
4725
4726    if (!e_output_mode_apply(output, emode))
4727      ERR("fail to e_output_mode_apply");
4728 }
4729
4730 static void
4731 _output_mode_msg_clients_append(Eldbus_Message_Iter *iter, E_Comp_Screen *e_comp_screen, int gl, int mode, int output_idx, int mode_count)
4732 {
4733    Eldbus_Message_Iter *array_of_mode;
4734    Eldbus_Message_Iter *struct_of_mode;
4735    int i, count;
4736
4737    eldbus_message_iter_arguments_append(iter, "a("SIGNATURE_OUTPUT_MODE_SERVER")",
4738                                         &array_of_mode);
4739
4740    if (gl == 0)
4741      {
4742         eldbus_message_iter_arguments_append(array_of_mode, "("SIGNATURE_OUTPUT_MODE_SERVER")",
4743                                              &struct_of_mode);
4744         eldbus_message_iter_arguments_append(struct_of_mode, SIGNATURE_OUTPUT_MODE_SERVER,
4745                                              0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "none",
4746                                              0, 0, 0, 0, TDM_OUTPUT_DPMS_OFF);
4747         eldbus_message_iter_container_close(array_of_mode, struct_of_mode);
4748
4749         eldbus_message_iter_container_close(iter, array_of_mode);
4750
4751         return;
4752      }
4753
4754    if (mode == E_INFO_CMD_OUTPUT_MODE_SET)
4755      _output_mode_set(e_comp_screen, output_idx, mode_count);
4756
4757    count = e_comp_screen->num_outputs;
4758
4759    for (i = 0; i < count; i++)
4760      {
4761         E_Output *eout = e_output_find_by_index(i);
4762         E_Output_Mode *current_mode = NULL;
4763         E_Output_Mode *emode = NULL;
4764         Eina_List *modelist = NULL, *l = NULL;
4765         const tdm_output_mode *tmode = NULL;
4766         int current;
4767         unsigned int preferred;
4768         int dpms;
4769
4770         if (eout == NULL) continue;
4771
4772         if (e_output_connected(eout) == EINA_FALSE)
4773           {
4774              eldbus_message_iter_arguments_append(array_of_mode, "("SIGNATURE_OUTPUT_MODE_SERVER")",
4775                                                   &struct_of_mode);
4776              eldbus_message_iter_arguments_append(struct_of_mode, SIGNATURE_OUTPUT_MODE_SERVER,
4777                                                   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "none",
4778                                                   0, i, 0, 1, TDM_OUTPUT_DPMS_OFF);
4779              eldbus_message_iter_container_close(array_of_mode, struct_of_mode);
4780
4781              continue;
4782           }
4783
4784         current_mode = e_output_current_mode_get(eout);
4785         modelist = e_output_mode_list_get(eout);
4786         if (modelist == NULL) continue;
4787
4788         EINA_LIST_FOREACH(modelist, l, emode)
4789           {
4790              if (emode == NULL) continue;
4791
4792              tmode = emode->tmode;
4793
4794              if (tmode->type & TDM_OUTPUT_MODE_TYPE_PREFERRED) preferred = 1;
4795              else preferred = 0;
4796
4797              if (emode == current_mode) current = 1;
4798              else current = 0;
4799
4800              dpms = e_output_dpms_get(eout);
4801
4802              eldbus_message_iter_arguments_append(array_of_mode, "("SIGNATURE_OUTPUT_MODE_SERVER")",
4803                                                   &struct_of_mode);
4804              eldbus_message_iter_arguments_append(struct_of_mode, SIGNATURE_OUTPUT_MODE_SERVER,
4805                                                   tmode->hdisplay, tmode->hsync_start, tmode->hsync_end, tmode->htotal,
4806                                                   tmode->vdisplay, tmode->vsync_start, tmode->vsync_end, tmode->vtotal,
4807                                                   tmode->vrefresh, tmode->vscan, tmode->clock, preferred, tmode->name,
4808                                                   current, i, 1, 1, dpms);
4809              eldbus_message_iter_container_close(array_of_mode, struct_of_mode);
4810           }
4811      }
4812
4813    eldbus_message_iter_container_close(iter, array_of_mode);
4814 }
4815
4816 static Eldbus_Message *
4817 _e_info_server_cb_output_mode(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
4818 {
4819    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
4820    E_Comp_Screen *e_comp_screen = NULL;
4821    tdm_display *tdpy = NULL;
4822    int mode = 0, count = 0, output_idx = 0;
4823
4824    if (!eldbus_message_arguments_get(msg, SIGNATURE_OUTPUT_MODE_CLIENT, &mode, &output_idx, &count))
4825      {
4826         ERR("Error getting arguments.");
4827         return reply;
4828      }
4829
4830    if ((mode == E_INFO_CMD_OUTPUT_MODE_GET) ||
4831        (mode == E_INFO_CMD_OUTPUT_MODE_SET))
4832      {
4833         e_comp_screen = e_comp->e_comp_screen;
4834         tdpy = e_comp_screen->tdisplay;
4835
4836         if (tdpy != NULL)
4837           _output_mode_msg_clients_append(eldbus_message_iter_get(reply), e_comp_screen, 1, mode, output_idx, count);
4838         else
4839           _output_mode_msg_clients_append(eldbus_message_iter_get(reply), e_comp_screen, 0, 0, 0, 0);
4840      }
4841
4842    return reply;
4843 }
4844
4845 static Eldbus_Message *
4846 e_info_server_cb_hwc_trace_message(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
4847 {
4848    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
4849    uint32_t onoff;
4850
4851    if (!eldbus_message_arguments_get(msg, "i", &onoff))
4852      {
4853         ERR("Error getting arguments.");
4854         return reply;
4855      }
4856
4857    if (onoff == 0 || onoff == 1)
4858      {
4859         e_plane_hwc_trace_debug(onoff);
4860         e_hwc_windows_trace_debug(onoff);
4861      }
4862
4863    if (onoff == 2)
4864      e_comp_screen_hwc_info_debug();
4865
4866    return reply;
4867 }
4868
4869 static Eldbus_Message *
4870 e_info_server_cb_damage_trace_message(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
4871 {
4872    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
4873    uint32_t on;
4874
4875    if (!eldbus_message_arguments_get(msg, "i", &on))
4876      {
4877         ERR("Error getting arguments.");
4878         return reply;
4879      }
4880
4881    if (on == 0 || on == 1)
4882      e_comp_object_damage_trace_debug(on);
4883
4884    return reply;
4885 }
4886
4887 static Eldbus_Message *
4888 e_info_server_cb_prstt_trace_message(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
4889 {
4890    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
4891    uint32_t on;
4892
4893    if (!eldbus_message_arguments_get(msg, "i", &on))
4894      {
4895         ERR("Error getting arguments.");
4896         return reply;
4897      }
4898
4899    if (on == 0 || on == 1)
4900      e_presentation_time_trace_debug(on);
4901
4902    return reply;
4903 }
4904
4905 static Eldbus_Message *
4906 e_info_server_cb_hwc(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
4907 {
4908    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
4909    uint32_t info;
4910    E_Output *output;
4911    Eina_List *l;
4912
4913    if (!eldbus_message_arguments_get(msg, "i", &info))
4914      {
4915         ERR("Error getting arguments.");
4916         return reply;
4917      }
4918
4919    if (!e_comp->hwc)
4920      {
4921         ERR("Error HWC is not initialized.");
4922         return reply;
4923      }
4924
4925    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp, reply);
4926    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp->e_comp_screen, reply);
4927
4928    switch (info)
4929      {
4930       case 0:
4931         EINA_LIST_FOREACH(e_comp->e_comp_screen->outputs, l, output)
4932           e_hwc_deactive_set(output->hwc, EINA_TRUE);
4933         break;
4934
4935       case 1:
4936         EINA_LIST_FOREACH(e_comp->e_comp_screen->outputs, l, output)
4937           e_hwc_deactive_set(output->hwc, EINA_FALSE);
4938         break;
4939
4940       default:
4941       case 2:
4942         e_comp_screen_hwc_info_debug();
4943         break;
4944      }
4945
4946    return reply;
4947 }
4948
4949 static Eldbus_Message *
4950 e_info_server_cb_exsync_trace_message(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
4951 {
4952    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
4953    uint32_t on;
4954
4955    if (!eldbus_message_arguments_get(msg, "i", &on))
4956      {
4957         ERR("Error getting arguments.");
4958         return reply;
4959      }
4960
4961    if (on == 0 || on == 1)
4962      e_explicit_sync_trace_debug(on);
4963
4964    return reply;
4965 }
4966
4967 static Eldbus_Message *
4968 e_info_server_cb_show_plane_state(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
4969 {
4970    Eina_List *output_l, *plane_l;
4971    E_Comp_Screen *e_comp_screen = NULL;
4972    E_Output *output = NULL;
4973    E_Plane *plane = NULL;
4974    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
4975
4976    e_comp_screen = e_comp->e_comp_screen;
4977
4978    EINA_LIST_FOREACH(e_comp_screen->outputs, output_l, output)
4979      {
4980         if (!output) continue;
4981
4982         EINA_LIST_FOREACH(output->planes, plane_l, plane)
4983           {
4984              if (!plane) continue;
4985
4986              e_plane_show_state(plane);
4987           }
4988      }
4989
4990    return reply;
4991 }
4992
4993 static void
4994 _msg_show_pending_commit_append(Eldbus_Message_Iter *iter)
4995 {
4996    Eina_List *output_l, *plane_l, *data_l;
4997    Eldbus_Message_Iter *array_of_pending_commit;
4998    E_Comp_Screen *e_comp_screen = NULL;
4999    E_Output *output = NULL;
5000    E_Plane *plane = NULL;
5001    E_Plane_Commit_Data *data = NULL;
5002
5003    eldbus_message_iter_arguments_append(iter, "a("VALUE_TYPE_FOR_PENDING_COMMIT")", &array_of_pending_commit);
5004
5005    e_comp_screen = e_comp->e_comp_screen;
5006
5007    EINA_LIST_FOREACH(e_comp_screen->outputs, output_l, output)
5008      {
5009         if (!output) continue;
5010
5011         EINA_LIST_FOREACH(output->planes, plane_l, plane)
5012           {
5013              if (!plane) continue;
5014
5015              EINA_LIST_FOREACH(plane->commit_data_list, data_l, data)
5016                {
5017                   Eldbus_Message_Iter* struct_of_pending_commit;
5018
5019                   if (!data) continue;
5020
5021                   eldbus_message_iter_arguments_append(array_of_pending_commit, "("VALUE_TYPE_FOR_PENDING_COMMIT")", &struct_of_pending_commit);
5022
5023                   eldbus_message_iter_arguments_append
5024                     (struct_of_pending_commit, VALUE_TYPE_FOR_PENDING_COMMIT,
5025                       (uintptr_t)plane,
5026                       plane->zpos,
5027                       (uintptr_t)data,
5028                       (uintptr_t)data->tsurface);
5029
5030                   eldbus_message_iter_container_close(array_of_pending_commit, struct_of_pending_commit);
5031                }
5032           }
5033      }
5034
5035    eldbus_message_iter_container_close(iter, array_of_pending_commit);
5036 }
5037
5038 static Eldbus_Message *
5039 e_info_server_cb_show_pending_commit(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
5040 {
5041    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
5042
5043    _msg_show_pending_commit_append(eldbus_message_iter_get(reply));
5044
5045    return reply;
5046 }
5047
5048 static E_Client *
5049 _e_info_server_find_client_by_win_id(uint64_t win_id)
5050 {
5051    Ecore_Window win;
5052    Evas_Object *o;
5053    E_Client *ec;
5054
5055    for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
5056      {
5057         ec = evas_object_data_get(o, "E_Client");
5058         if (!ec) continue;
5059
5060         win = e_client_util_win_get(ec);
5061         if (win == win_id)
5062           return ec;
5063      }
5064
5065    return NULL;
5066 }
5067
5068 static void
5069 _msg_client_fps_append(Eldbus_Message_Iter *iter, E_Client *ec)
5070 {
5071    Eldbus_Message_Iter *array_of_fps, *struct_of_fps;
5072    double fps = 0.0;
5073
5074    eldbus_message_iter_arguments_append(iter, "a("VALUE_TYPE_FOR_FPS")", &array_of_fps);
5075
5076    if (e_client_fps_get(ec, &fps))
5077      {
5078         eldbus_message_iter_arguments_append(array_of_fps, "("VALUE_TYPE_FOR_FPS")", &struct_of_fps);
5079         eldbus_message_iter_arguments_append(struct_of_fps,
5080                                             VALUE_TYPE_FOR_FPS,
5081                                             E_INFO_FPS_TYPE_CLIENT_WIN,
5082                                             "none",
5083                                             -999,
5084                                             e_client_util_win_get(ec),
5085                                             fps);
5086         eldbus_message_iter_container_close(array_of_fps, struct_of_fps);
5087      }
5088
5089    eldbus_message_iter_container_close(iter, array_of_fps);
5090 }
5091
5092 static void
5093 _msg_output_fps_append(Eldbus_Message_Iter *iter)
5094 {
5095    Eina_List *output_l, *plane_l, *hwc_l;
5096    Eldbus_Message_Iter *array_of_fps;
5097    E_Comp_Screen *e_comp_screen = NULL;
5098    E_Hwc_Window *hwc_window = NULL;
5099    E_Output *output = NULL;
5100    E_Plane *plane = NULL;
5101    double fps = 0.0;
5102    char output_name[30];
5103
5104    eldbus_message_iter_arguments_append(iter, "a("VALUE_TYPE_FOR_FPS")", &array_of_fps);
5105
5106    e_comp_screen = e_comp->e_comp_screen;
5107
5108    EINA_LIST_FOREACH(e_comp_screen->outputs, output_l, output)
5109      {
5110         if (!output) continue;
5111
5112         strncpy(output_name, output->id, sizeof(char)*29);
5113
5114         if (output->hwc)
5115           {
5116              if (e_hwc_policy_get(output->hwc) == E_HWC_POLICY_WINDOWS)
5117                {
5118                   if (e_hwc_windows_fps_get(output->hwc, &fps))
5119                     {
5120                        Eldbus_Message_Iter* struct_of_fps;
5121
5122                        eldbus_message_iter_arguments_append(array_of_fps, "("VALUE_TYPE_FOR_FPS")", &struct_of_fps);
5123
5124                        eldbus_message_iter_arguments_append
5125                            (struct_of_fps, VALUE_TYPE_FOR_FPS,
5126                              E_INFO_FPS_TYPE_OUTPUT,
5127                              output_name,
5128                              -999,
5129                              0,
5130                              fps);
5131
5132                        eldbus_message_iter_container_close(array_of_fps, struct_of_fps);
5133                     }
5134
5135                   EINA_LIST_FOREACH(output->hwc->hwc_windows, hwc_l, hwc_window)
5136                     {
5137                        E_Hwc_Window_State state;
5138                        Eldbus_Message_Iter* struct_of_fps;
5139
5140                        if(!hwc_window) continue;
5141
5142                        state = e_hwc_window_accepted_state_get(hwc_window);
5143                        if ((state == E_HWC_WINDOW_STATE_CLIENT) || (state == E_HWC_WINDOW_STATE_NONE)) continue;
5144                        if (!e_hwc_window_fps_get(hwc_window, &fps)) continue;
5145
5146                        eldbus_message_iter_arguments_append(array_of_fps, "("VALUE_TYPE_FOR_FPS")", &struct_of_fps);
5147
5148                        eldbus_message_iter_arguments_append
5149                            (struct_of_fps, VALUE_TYPE_FOR_FPS,
5150                              hwc_window->is_target ? E_INFO_FPS_TYPE_HWC_COMP : E_INFO_FPS_TYPE_HWC_WIN,
5151                              output_name,
5152                              hwc_window->zpos,
5153                              hwc_window->is_target ? 0 : e_client_util_win_get(hwc_window->ec),
5154                              fps);
5155
5156                        eldbus_message_iter_container_close(array_of_fps, struct_of_fps);
5157                     }
5158                }
5159              else
5160                {
5161                   EINA_LIST_FOREACH(output->planes, plane_l, plane)
5162                     {
5163                         if (!plane) continue;
5164                         if (!e_plane_fps_get(plane, &fps)) continue;
5165
5166                         Eldbus_Message_Iter* struct_of_fps;
5167
5168                         eldbus_message_iter_arguments_append(array_of_fps, "("VALUE_TYPE_FOR_FPS")", &struct_of_fps);
5169
5170                         eldbus_message_iter_arguments_append
5171                           (struct_of_fps, VALUE_TYPE_FOR_FPS,
5172                             E_INFO_FPS_TYPE_LAYER,
5173                             output_name,
5174                             plane->zpos,
5175                             0,
5176                             plane->fps);
5177
5178                         eldbus_message_iter_container_close(array_of_fps, struct_of_fps);
5179                     }
5180                }
5181           }
5182         else
5183           continue;
5184
5185         memset(output_name, 0x0, sizeof(char)*30);
5186      }
5187
5188    eldbus_message_iter_container_close(iter, array_of_fps);
5189 }
5190
5191 static Eldbus_Message *
5192 _e_info_server_cb_fps_info_get(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
5193 {
5194    const char *win_str;
5195    uint64_t win_id = 0;
5196    unsigned long tmp;
5197    E_Client *ec;
5198    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
5199
5200    if (!eldbus_message_arguments_get(msg, "s", &win_str))
5201      {
5202         ERR("Error getting arguments");
5203         return reply;
5204      }
5205
5206    if (e_util_strcmp(win_str, "none"))
5207      {
5208         if (!e_util_string_to_ulong(win_str, &tmp, 16))
5209           return reply;
5210
5211         win_id = (uint64_t)tmp;
5212
5213         ec = _e_info_server_find_client_by_win_id(win_id);
5214         if (!ec) return reply;
5215
5216         e_client_fps_enable(ec, EINA_TRUE);
5217         _msg_client_fps_append(eldbus_message_iter_get(reply), ec);
5218      }
5219    else
5220      {
5221         e_comp->calc_fps = 1;
5222         _msg_output_fps_append(eldbus_message_iter_get(reply));
5223      }
5224
5225    return reply;
5226 }
5227
5228 static Eldbus_Message *
5229 e_info_server_cb_effect_control(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
5230 {
5231    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
5232    uint32_t onoff;
5233    E_Module *m;
5234
5235    if (!eldbus_message_arguments_get(msg, "i", &onoff))
5236      {
5237         ERR("Error getting arguments.");
5238         return reply;
5239      }
5240
5241    m = e_module_find("e-mod-tizen-effect");
5242
5243    if (onoff == 1)
5244      {
5245         if (!m)
5246           m = e_module_new("e-mod-tizen-effect");
5247         if (m)
5248           e_module_enable(m);
5249      }
5250    else if (onoff == 0)
5251      {
5252         if (m)
5253           {
5254              e_module_disable(m);
5255              e_object_del(E_OBJECT(m));
5256           }
5257      }
5258
5259    return reply;
5260 }
5261
5262 static Eldbus_Message *
5263 e_info_server_cb_quickpanel_control(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
5264 {
5265    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
5266    const char *win_str;
5267    int operation = 0;
5268    unsigned long tmp = 0;
5269    uint64_t win_id = 0;
5270    E_Client *ec = NULL;
5271    Evas_Object *o;
5272    Eina_Bool res = EINA_FALSE;
5273
5274    if (!eldbus_message_arguments_get(msg, "is", &operation, &win_str))
5275      {
5276         ERR("Error getting arguments.");
5277         return reply;
5278      }
5279
5280    if (!e_util_strcmp("default", win_str))
5281      ec = NULL;
5282    else
5283      {
5284         res = e_util_string_to_ulong(win_str, &tmp, 16);
5285         EINA_SAFETY_ON_FALSE_RETURN_VAL(res, reply);
5286
5287         win_id = (uint64_t)tmp;
5288
5289         for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
5290           {
5291              ec = evas_object_data_get(o, "E_Client");
5292              if (!ec) continue;
5293
5294              Ecore_Window win = e_client_util_win_get(ec);
5295
5296              if (win == win_id)
5297                break;
5298           }
5299      }
5300
5301    if ((operation >= 0) && (operation <= 3))
5302      e_qp_control_by_command(ec, operation);
5303
5304    return reply;
5305 }
5306
5307 static Eldbus_Message *
5308 e_info_server_cb_magnifier(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
5309 {
5310    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
5311    uint32_t opcode;
5312
5313    if (!eldbus_message_arguments_get(msg, "i", &opcode))
5314      {
5315         ERR("Error getting arguments.");
5316         return reply;
5317      }
5318
5319    switch (opcode)
5320      {
5321       case 0: // magnifier off test
5322          e_magnifier_stand_alone_mode_set(EINA_FALSE);
5323          e_magnifier_hide(NULL);
5324          e_magnifier_del();
5325          break;
5326
5327       case 1: // magnifier on test
5328          e_magnifier_new();
5329          e_magnifier_stand_alone_mode_set(EINA_TRUE);
5330          e_magnifier_show(NULL);
5331          break;
5332
5333       case 2: // magnifier new
5334          e_magnifier_new();
5335          break;
5336
5337       case 3: // magnifier del
5338          e_magnifier_del();
5339          break;
5340
5341       case 4: // set stand_alone
5342          e_magnifier_stand_alone_mode_set(EINA_TRUE);
5343          break;
5344
5345       case 5: // unset stand_alone
5346          e_magnifier_stand_alone_mode_set(EINA_FALSE);
5347          break;
5348
5349       case 6: // magnifier show
5350          e_magnifier_show(NULL);
5351          break;
5352
5353       case 7: // magnifier hide
5354          e_magnifier_hide(NULL);
5355          break;
5356
5357       default:
5358          break;
5359      }
5360
5361    return reply;
5362 }
5363
5364 static Eldbus_Message *
5365 e_info_server_cb_aux_message(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
5366 {
5367    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
5368    Eldbus_Message_Iter *opt_iter;
5369    const char *win_str, *key, *val, *opt;
5370    Eina_List *options = NULL;
5371    unsigned long tmp = 0;
5372    uint64_t win_id = 0;
5373    E_Client *ec;
5374    Evas_Object *o;
5375    Eina_Bool res = EINA_FALSE;
5376
5377    if (!e_policy)
5378      {
5379         ERR("e_policy is not initialized!");
5380         return reply;
5381      }
5382
5383    if (!eldbus_message_arguments_get(msg, "sssa(s)", &win_str, &key, &val, &opt_iter))
5384      {
5385         ERR("Error getting arguments.");
5386         return reply;
5387      }
5388
5389    while (eldbus_message_iter_get_and_next(opt_iter, 's', &opt))
5390      {
5391         const char *str;
5392
5393         str = eina_stringshare_add(opt);
5394         options = eina_list_append(options, str);
5395      }
5396
5397    res = e_util_string_to_ulong(win_str, &tmp, 16);
5398    EINA_SAFETY_ON_FALSE_RETURN_VAL(res, reply);
5399
5400    win_id = (uint64_t)tmp;
5401
5402    for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
5403      {
5404         ec = evas_object_data_get(o, "E_Client");
5405         if (!ec) continue;
5406
5407         Ecore_Window win = e_client_util_win_get(ec);
5408
5409         if (win == win_id)
5410           {
5411              e_policy_aux_message_send(ec, key, val, options);
5412              break;
5413           }
5414      }
5415
5416    EINA_LIST_FREE(options, opt)
5417       eina_stringshare_del(opt);
5418
5419    return reply;
5420 }
5421
5422 static Eldbus_Message *
5423 e_info_server_cb_aux_hint_add(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
5424 {
5425    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
5426    const char *win_str, *hint, *val;
5427    uint32_t hint_id;
5428    unsigned long tmp = 0;
5429    uint64_t win_id = 0;
5430    E_Client *ec;
5431    Evas_Object *o;
5432    Eina_Bool res = EINA_FALSE;
5433
5434    if (!e_policy)
5435      {
5436         ERR("e_policy is not initialized!");
5437         return reply;
5438      }
5439
5440    if (!eldbus_message_arguments_get(msg, "suss", &win_str, &hint_id, &hint, &val))
5441      {
5442         ERR("Error getting arguments.");
5443         return reply;
5444      }
5445
5446    res = e_util_string_to_ulong(win_str, &tmp, 16);
5447    EINA_SAFETY_ON_FALSE_RETURN_VAL(res, reply);
5448
5449    win_id = (uint64_t)tmp;
5450
5451    for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
5452      {
5453         ec = evas_object_data_get(o, "E_Client");
5454         if (!ec) continue;
5455
5456         if (e_client_util_win_get(ec) == win_id)
5457           {
5458              res = e_hints_aux_hint_add(ec, hint_id, hint, val);
5459              if (res) e_policy_wl_aux_hint_apply(ec);
5460              break;
5461           }
5462      }
5463
5464    return reply;
5465 }
5466
5467 static Eldbus_Message *
5468 e_info_server_cb_aux_hint_del(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
5469 {
5470    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
5471    const char *win_str;
5472    uint32_t hint_id;
5473    unsigned long tmp = 0;
5474    uint64_t win_id = 0;
5475    E_Client *ec;
5476    Evas_Object *o;
5477    Eina_Bool res = EINA_FALSE;
5478
5479    if (!e_policy)
5480      {
5481         ERR("e_policy is not initialized!");
5482         return reply;
5483      }
5484
5485    if (!eldbus_message_arguments_get(msg, "su", &win_str, &hint_id))
5486      {
5487         ERR("Error getting arguments.");
5488         return reply;
5489      }
5490
5491    res = e_util_string_to_ulong(win_str, &tmp, 16);
5492    EINA_SAFETY_ON_FALSE_RETURN_VAL(res, reply);
5493
5494    win_id = (uint64_t)tmp;
5495
5496    for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
5497      {
5498         ec = evas_object_data_get(o, "E_Client");
5499         if (!ec) continue;
5500
5501         if (e_client_util_win_get(ec) == win_id)
5502           {
5503              res = e_hints_aux_hint_del(ec, hint_id);
5504              if (res) e_policy_wl_aux_hint_apply(ec);
5505              break;
5506           }
5507      }
5508
5509    return reply;
5510 }
5511
5512 static Eldbus_Message *
5513 _e_info_server_cb_force_render(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
5514 {
5515    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
5516    E_Info_Cmd_Force_Render cmd;
5517    Eina_Bool res;
5518    char result[1024];
5519    E_Client *ec = NULL;
5520
5521    res = eldbus_message_arguments_get(msg,
5522                                       "i",
5523                                       &cmd);
5524    EINA_SAFETY_ON_FALSE_RETURN_VAL(res, reply);
5525
5526    switch (cmd)
5527      {
5528       case E_INFO_CMD_FRENDER_ALL:
5529          E_CLIENT_FOREACH(ec)
5530            {
5531               if (ec->visible && (!ec->input_only))
5532                 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
5533            }
5534          evas_damage_rectangle_add(e_comp->evas, 0, 0, e_comp->w, e_comp->h);
5535          e_comp_render_queue();
5536          snprintf(result, sizeof(result),
5537                   "[Server] force rendered all clients and canvas\n");
5538          break;
5539       case E_INFO_CMD_FRENDER_CLS:
5540          E_CLIENT_FOREACH(ec)
5541            {
5542               if (ec->visible && (!ec->input_only))
5543                 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
5544            }
5545          e_comp_render_queue();
5546          snprintf(result, sizeof(result),
5547                   "[Server] updated clients' surface");
5548          break;
5549       case E_INFO_CMD_FRENDER_CANVAS:
5550          evas_damage_rectangle_add(e_comp->evas, 0, 0, e_comp->w, e_comp->h);
5551          snprintf(result, sizeof(result),
5552                   "[Server] updated canvas");
5553          break;
5554       default:
5555          snprintf(result, sizeof(result),
5556                   "[Server] Error Unknown cmd(%d) for the render force",
5557                   cmd);
5558          break;
5559      }
5560
5561    eldbus_message_arguments_append(reply,
5562                                    "s",
5563                                    result);
5564
5565    return reply;
5566 }
5567
5568 static Eldbus_Message *
5569 _e_info_server_cb_screen_rotation_pre(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
5570 {
5571    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
5572    int rotation_pre;
5573
5574    if (!eldbus_message_arguments_get(msg, "i", &rotation_pre))
5575      {
5576         ERR("Error getting arguments.");
5577         return reply;
5578      }
5579
5580    if (!e_comp || !e_comp->e_comp_screen)
5581      {
5582         ERR("Error no screen.");
5583         return reply;
5584      }
5585
5586    e_comp_screen_rotation_pre_set(e_comp->e_comp_screen, rotation_pre);
5587
5588    if (e_config->screen_rotation_pre != rotation_pre)
5589      {
5590         if (!e_config_save_block_get())
5591           {
5592              e_config->screen_rotation_pre = rotation_pre;
5593              e_config_save_queue();
5594              INF("Saving screen_rotation_pre (%d) to e.cfg has been scheduled.", rotation_pre);
5595           }
5596         else
5597           {
5598              INF("Since saving to e.cfg is set to block, it's not possible to save screen_rotation_pre (%d).", rotation_pre);
5599           }
5600      }
5601
5602    return reply;
5603 }
5604
5605 static Eldbus_Message *
5606 _e_info_server_cb_screen_rotation(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
5607 {
5608    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
5609    int rotation;
5610
5611    if (!eldbus_message_arguments_get(msg, "i", &rotation))
5612      {
5613         ERR("Error getting arguments.");
5614         return reply;
5615      }
5616
5617    if (!e_comp || !e_comp->e_comp_screen)
5618      {
5619         ERR("Error no screen.");
5620         return reply;
5621      }
5622
5623    e_comp_screen_rotation_setting_set(e_comp->e_comp_screen, rotation);
5624
5625    return reply;
5626 }
5627
5628 static Eldbus_Message *
5629 _e_info_server_cb_remote_surface(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
5630 {
5631    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
5632    int dump_request, info_query;
5633    Eina_Bool res;
5634    Eldbus_Message_Iter *iter, *line_array;
5635
5636    res = eldbus_message_arguments_get(msg,
5637                                       "ii", &dump_request, &info_query);
5638    EINA_SAFETY_ON_FALSE_RETURN_VAL(res, reply);
5639
5640    if (info_query)
5641      {
5642         e_comp_wl_remote_surface_debug_info_get(eldbus_message_iter_get(reply));
5643      }
5644    else if (dump_request != -1)
5645      {
5646         char reply_msg[1024] = "";
5647
5648         e_info_dump_remote_surface = dump_request;
5649
5650         snprintf(reply_msg, sizeof(reply_msg), "Switch %s remote surface dump",
5651                  dump_request? "ON":"OFF");
5652
5653         iter = eldbus_message_iter_get(reply);
5654         eldbus_message_iter_arguments_append(iter, "as", &line_array);
5655         eldbus_message_iter_basic_append(line_array, 's', reply_msg);
5656         eldbus_message_iter_container_close(iter, line_array);
5657      }
5658
5659    return reply;
5660 }
5661
5662 static Ecore_Window
5663 _e_info_server_top_win_at_xy_get(int x, int y)
5664 {
5665    Evas_Object *o;
5666    E_Client *ec;
5667
5668    o = evas_object_top_at_xy_get(e_comp->evas, x, y, EINA_FALSE, EINA_FALSE);
5669    EINA_SAFETY_ON_NULL_RETURN_VAL(o, 0);
5670
5671    ec = evas_object_data_get(o, "E_Client");
5672    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, 0);
5673
5674    return e_client_util_win_get(ec);
5675 }
5676
5677 static Eina_Bool
5678 _e_info_server_cb_ecore_event_filter(void *data, void *loop_data EINA_UNUSED, int type, void *event)
5679 {
5680    Ecore_Event_Mouse_Button *e;
5681    Ecore_Window win;
5682    Ecore_Event_Filter **event_filter;
5683
5684    if (type != ECORE_EVENT_MOUSE_BUTTON_DOWN && type != ECORE_EVENT_MOUSE_BUTTON_UP
5685        && type != ECORE_EVENT_MOUSE_MOVE && type != ECORE_EVENT_MOUSE_WHEEL
5686        && type != ECORE_EVENT_MOUSE_IN && type != ECORE_EVENT_MOUSE_OUT)
5687      return EINA_TRUE;
5688
5689    if (type == ECORE_EVENT_MOUSE_BUTTON_DOWN)
5690      {
5691         e = event;
5692         event_filter = data;
5693
5694         win = _e_info_server_top_win_at_xy_get(e->x, e->y);
5695         EINA_SAFETY_ON_FALSE_RETURN_VAL(win, EINA_FALSE);
5696
5697         ecore_event_filter_del(*event_filter);
5698         free(event_filter);
5699
5700         eldbus_service_signal_emit(e_info_server.iface, E_INFO_SERVER_SIGNAL_WIN_UNDER_TOUCH, (uint64_t)win);
5701      }
5702
5703    return EINA_FALSE;
5704 }
5705
5706 static Eldbus_Message *
5707 _e_info_server_cb_get_win_under_touch(const Eldbus_Service_Interface *iface EINA_UNUSED,
5708                                       const Eldbus_Message *msg)
5709 {
5710    int result = 0;
5711    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
5712    Ecore_Event_Filter **event_filter;;
5713
5714    event_filter = calloc(1, sizeof(Ecore_Event_Filter *));
5715    EINA_SAFETY_ON_NULL_GOTO(event_filter, fail);
5716
5717    *event_filter = ecore_event_filter_add(NULL, _e_info_server_cb_ecore_event_filter,
5718                                           NULL, event_filter);
5719    EINA_SAFETY_ON_NULL_GOTO(*event_filter, fail);
5720
5721    goto finish;
5722
5723 fail:
5724    result = -1;
5725    if (event_filter)
5726      free(event_filter);
5727
5728 finish:
5729    eldbus_message_arguments_append(reply, "i", result);
5730
5731    return reply;
5732 }
5733
5734 static E_Client *
5735 _e_info_server_ec_find_by_win(Ecore_Window win)
5736 {
5737    E_Client *ec;
5738    Evas_Object *o;
5739
5740    for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
5741      {
5742         Ecore_Window w;
5743
5744         ec = evas_object_data_get(o, "E_Client");
5745         if (!ec) continue;
5746
5747         w = e_client_util_win_get(ec);
5748         if (w == win)
5749           return ec;
5750      }
5751
5752    return NULL;
5753 }
5754
5755 const static int KILL_ID_MODE = 1;
5756 const static int KILL_NAME_MODE = 2;
5757 const static int KILL_PID_MODE = 3;
5758 const static int KILL_PID_FORCE_MODE = 5;
5759
5760 static int
5761 _e_info_server_pid_kill(pid_t id, Eldbus_Message_Iter *array_of_string)
5762 {
5763    int cnt = 0;
5764    pid_t pid = -1;
5765    char result[128];
5766
5767    E_Comp_Wl_Data *wl_cdata;
5768    struct wl_list * client_list;
5769    struct wl_client *client;
5770
5771    if (!e_comp) return 0;
5772    if (!(wl_cdata = e_comp->wl_comp_data)) return 0;
5773    if (!wl_cdata->wl.disp) return 0;
5774
5775    client_list = wl_display_get_client_list(wl_cdata->wl.disp);
5776
5777    wl_client_for_each(client, client_list)
5778      {
5779         if (!client) break;
5780         wl_client_get_credentials(client, &pid, NULL, NULL);
5781         if (pid != id) continue;
5782
5783         INF("[%s] client(%p, pid:%d) has been destroyed !", __FUNCTION__, client, pid);
5784         wl_client_destroy(client);
5785
5786         snprintf(result, sizeof(result), "[Server] A client (PID:%d) has been destroyed !", pid);
5787         eldbus_message_iter_arguments_append(array_of_string, VALUE_TYPE_REPLY_KILL, result);
5788         cnt++;
5789         break;
5790      }
5791
5792    return cnt;
5793 }
5794
5795 static int
5796 _e_info_server_ec_kill(uint32_t mode, void *value, Eldbus_Message_Iter *array_of_string)
5797 {
5798    E_Client *ec;
5799    Evas_Object *o;
5800    int count = 0;
5801    char result[1024];
5802
5803    for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
5804      {
5805         const char *ec_name, *find;
5806
5807         ec = evas_object_data_get(o, "E_Client");
5808         if (!ec) continue;
5809         if (e_client_util_ignored_get(ec)) continue;
5810
5811         ec_name = e_client_util_name_get(ec) ?: "NO NAME";
5812
5813         if (mode == KILL_NAME_MODE)
5814           {
5815              find = strstr(ec_name, (const char *)value);
5816
5817              if (!find)
5818                continue;
5819           }
5820         else if (mode == KILL_PID_MODE)
5821           {
5822              pid_t pid = -1;
5823              pid = ec->netwm.pid;
5824              if (pid <= 0)
5825                {
5826                   if (ec->comp_data)
5827                     {
5828                        E_Comp_Wl_Client_Data *cdata = (E_Comp_Wl_Client_Data*)ec->comp_data;
5829                        if (cdata->surface)
5830                        wl_client_get_credentials(wl_resource_get_client(cdata->surface), &pid, NULL, NULL);
5831                     }
5832                }
5833              if (pid != *(pid_t *)value)
5834                continue;
5835           }
5836
5837         count++;
5838         e_client_act_kill_begin(ec);
5839
5840         snprintf(result, sizeof(result), "[Server] killing creator(%s) of resource 0x%zx",
5841                  ec_name, e_client_util_win_get(ec));
5842         eldbus_message_iter_arguments_append(array_of_string, VALUE_TYPE_REPLY_KILL, result);
5843      }
5844
5845    return count;
5846 }
5847
5848 static Eldbus_Message *
5849 _e_info_server_cb_kill_client(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
5850 {
5851    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
5852    Eldbus_Message_Iter *iter = eldbus_message_iter_get(reply);
5853    Eina_Bool res;
5854    char result[1024];
5855    E_Client *ec;
5856    uint64_t uint64_value;
5857    uint32_t mode;
5858    const char *str_value;
5859    int count;
5860    Eldbus_Message_Iter *array_of_string = NULL;
5861
5862    res = eldbus_message_arguments_get(msg, VALUE_TYPE_REQUEST_FOR_KILL,
5863                                       &mode, &uint64_value, &str_value);
5864    if (res != EINA_TRUE)
5865      {
5866         snprintf(result, sizeof(result),
5867                 "[Server] Error: cannot get the arguments from an Eldbus_Message");
5868         goto finish;
5869      }
5870
5871    eldbus_message_iter_arguments_append(iter, "a"VALUE_TYPE_REPLY_KILL, &array_of_string);
5872
5873    if (mode == KILL_ID_MODE)
5874      {
5875         Ecore_Window win = uint64_value;
5876
5877         ec = _e_info_server_ec_find_by_win(win);
5878         if (!ec)
5879           {
5880              snprintf(result, sizeof(result),
5881                      "[Server] Error: cannot find the E_Client.");
5882              goto finish;
5883           }
5884
5885         e_client_act_kill_begin(ec);
5886
5887         snprintf(result, sizeof(result),
5888                 "[Server] killing creator(%s) of resource 0x%zx",
5889                 e_client_util_name_get(ec) ?: "NO NAME", win);
5890      }
5891    else if (mode >= KILL_NAME_MODE && mode <= KILL_PID_FORCE_MODE)
5892      {
5893         if (mode == KILL_NAME_MODE)
5894           count = _e_info_server_ec_kill(mode, (void *)str_value, array_of_string);
5895         else if (mode == KILL_PID_FORCE_MODE)
5896           count = _e_info_server_pid_kill((pid_t)uint64_value, array_of_string);
5897         else
5898           count = _e_info_server_ec_kill(mode, (void *)&uint64_value, array_of_string);
5899
5900         snprintf(result, sizeof(result), "\n[Server] killed %d client(s)", count);
5901      }
5902    else
5903      {
5904         snprintf(result, sizeof(result), "[Server] Error: wrong mode.");
5905      }
5906
5907 finish:
5908    eldbus_message_iter_arguments_append(array_of_string, VALUE_TYPE_REPLY_KILL, result);
5909    eldbus_message_iter_container_close(iter, array_of_string);
5910
5911    return reply;
5912 }
5913
5914 static Eldbus_Message *
5915 _e_info_server_cb_get_windows(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
5916 {
5917    const static int _E_GET_WINDOWS_NAME_MODE = 1;
5918    const static int _E_GET_WINDOWS_PID_MODE = 2;
5919    Eldbus_Message *reply;
5920    Eldbus_Message_Iter *iter;
5921    Eina_Bool res;
5922    E_Client *ec;
5923    char *value;
5924    uint32_t mode;
5925    int count = 0;
5926    Eldbus_Message_Iter *array_of_windows;
5927    Evas_Object *o;
5928    pid_t pid;
5929
5930    res = eldbus_message_arguments_get(msg, "is", &mode, &value);
5931    if (res != EINA_TRUE)
5932      {
5933         return eldbus_message_error_new(msg, GET_CALL_MSG_ARG_ERR,
5934                       "get_windows: an attempt to get arguments from method call message failed");
5935      }
5936
5937    if (mode == _E_GET_WINDOWS_PID_MODE)
5938      {
5939         if (strlen(value) >= 2 && value[0] == '0' && value[1] == 'x')
5940           res = e_util_string_to_int(value, &pid, 16);
5941         else
5942           res = e_util_string_to_int(value, &pid, 10);
5943
5944        if (res == EINA_FALSE)
5945          return eldbus_message_error_new(msg, INVALID_ARGS,
5946                                        "get_windows: invalid input arguments");
5947      }
5948
5949    reply = eldbus_message_method_return_new(msg);
5950    iter = eldbus_message_iter_get(reply);
5951
5952    eldbus_message_iter_arguments_append(iter, "at", &array_of_windows);
5953
5954    for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
5955      {
5956         const char *ec_name, *find;
5957         Ecore_Window win;
5958
5959         ec = evas_object_data_get(o, "E_Client");
5960         if (!ec) continue;
5961
5962         ec_name = e_client_util_name_get(ec) ?: "NO NAME";
5963
5964         if (mode == _E_GET_WINDOWS_NAME_MODE)
5965           {
5966              find = strstr(ec_name, (const char *)value);
5967
5968              if (!find)
5969                continue;
5970           }
5971         else if (mode == _E_GET_WINDOWS_PID_MODE)
5972           {
5973              pid_t ec_pid = -1;
5974
5975              ec_pid = ec->netwm.pid;
5976              if (ec_pid <= 0)
5977                {
5978                   if (ec->comp_data)
5979                     {
5980                        E_Comp_Wl_Client_Data *cdata = (E_Comp_Wl_Client_Data*)ec->comp_data;
5981                        if (cdata->surface)
5982                        wl_client_get_credentials(wl_resource_get_client(cdata->surface), &ec_pid, NULL, NULL);
5983                     }
5984                }
5985              if (ec_pid != pid)
5986                continue;
5987           }
5988
5989         win = e_client_util_win_get(ec);
5990
5991         count++;
5992
5993         eldbus_message_iter_arguments_append(array_of_windows, "t", win);
5994      }
5995
5996    eldbus_message_iter_container_close(iter, array_of_windows);
5997
5998    if (count)
5999      return reply;
6000
6001    eldbus_message_unref(reply);
6002
6003    return eldbus_message_error_new(msg, WIN_NOT_EXIST,
6004                               "get_windows: specified window(s) doesn't exist");
6005 }
6006
6007 static Eldbus_Message *
6008 _e_info_server_cb_get_window_name(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
6009 {
6010    Eldbus_Message *reply;
6011    Eina_Bool res;
6012    E_Client *ec;
6013    uint64_t win;
6014
6015    res = eldbus_message_arguments_get(msg, VALUE_TYPE_REQUEST_FOR_WININFO,
6016                                       &win);
6017    if (res != EINA_TRUE)
6018      {
6019         return eldbus_message_error_new(msg, GET_CALL_MSG_ARG_ERR,
6020                       "get_window_name: an attempt to get arguments from method call message failed");
6021      }
6022
6023    ec = _e_info_server_ec_find_by_win(win);
6024    if (!ec)
6025      {
6026         return eldbus_message_error_new(msg, WIN_NOT_EXIST, "get_window_name: specified window doesn't exist");
6027      }
6028
6029    reply = eldbus_message_method_return_new(msg);
6030
6031    eldbus_message_arguments_append(reply, "s",
6032                                    e_client_util_name_get(ec) ?: "NO NAME");
6033
6034    return reply;
6035 }
6036
6037 static void
6038 _e_info_server_wininfo_tree_info_add(E_Client *ec, Eldbus_Message_Iter *iter,
6039                                  int recurse, int level)
6040 {
6041    Eldbus_Message_Iter *struct_of_child;
6042
6043    if (ec->transients)
6044      {
6045         E_Client *child;
6046         const Eina_List *l;
6047
6048         EINA_LIST_FOREACH(ec->transients, l, child)
6049           {
6050              uint64_t win;
6051              int num_child = -1;
6052              int hwc = -1, hwc_policy = E_HWC_POLICY_NONE, pl_zpos = -999;
6053
6054              if (recurse)
6055                num_child = eina_list_count(child->transients);
6056
6057              if ((!child->iconic) && (!e_client_visibility_get(child)) &&
6058                  evas_object_visible_get(ec->frame))
6059                _e_info_server_ec_hwc_info_get(child, &hwc, &hwc_policy, &pl_zpos);
6060
6061              win = e_client_util_win_get(child);
6062              eldbus_message_iter_arguments_append(iter, "(tsiiiiiiii)", &struct_of_child);
6063              eldbus_message_iter_arguments_append
6064                 (struct_of_child, "tsiiiiiiii", win, e_client_util_name_get(child) ?: "NO NAME",
6065                          num_child, level, child->x, child->y, child->w, child->h, hwc, pl_zpos);
6066              eldbus_message_iter_container_close(iter, struct_of_child);
6067
6068              if (recurse)
6069                 _e_info_server_wininfo_tree_info_add(child, iter, 1, level + 1);
6070           }
6071      }
6072 }
6073
6074 static Eldbus_Message *
6075 _e_info_server_cb_wininfo_tree(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
6076 {
6077    Eldbus_Message *reply;
6078    Eldbus_Message_Iter *iter, *array_of_child;
6079    Eina_Bool res;
6080    E_Client *ec;
6081    uint64_t win;
6082    int recurse;
6083
6084    res = eldbus_message_arguments_get(msg, VALUE_TYPE_REQUEST_FOR_WININFO_TREE,
6085                                       &win, &recurse);
6086    if (res != EINA_TRUE)
6087      {
6088         return eldbus_message_error_new(msg, GET_CALL_MSG_ARG_ERR,
6089                       "wininfo: an attempt to get arguments from method call message failed");
6090      }
6091
6092    ec = _e_info_server_ec_find_by_win(win);
6093    if (!ec)
6094      {
6095         return eldbus_message_error_new(msg, WIN_NOT_EXIST, "wininfo: specified window(s) doesn't exist");
6096      }
6097
6098    reply = eldbus_message_method_return_new(msg);
6099    iter = eldbus_message_iter_get(reply);
6100
6101    eldbus_message_iter_basic_append(iter, 't', (uint64_t)e_client_util_win_get(ec->parent));
6102    eldbus_message_iter_basic_append(iter, 's', e_client_util_name_get(ec->parent) ?: "NO NAME");
6103    eldbus_message_iter_basic_append(iter, 'i', eina_list_count(ec->transients));
6104
6105    array_of_child = eldbus_message_iter_container_new(iter, 'a', "(tsiiiiiiii)");
6106    _e_info_server_wininfo_tree_info_add(ec, array_of_child, recurse, 1);
6107    eldbus_message_iter_container_close(iter, array_of_child);
6108
6109    return reply;
6110 }
6111
6112 static Eldbus_Message *
6113 _e_info_server_cb_wininfo(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
6114 {
6115    Eldbus_Message *reply;
6116    Eina_Bool res;
6117    E_Client *ec;
6118    uint64_t win;
6119    Ecore_Window pwin;
6120    uint32_t res_id = 0;
6121    pid_t pid = -1;
6122    char layer_name[64];
6123    int hwc = -1, hwc_policy = E_HWC_POLICY_NONE, pl_zpos = -999;
6124    int dw, dh, xright, ybelow;;
6125
6126    res = eldbus_message_arguments_get(msg, VALUE_TYPE_REQUEST_FOR_WININFO,
6127                                       &win);
6128    if (res != EINA_TRUE)
6129      {
6130         return eldbus_message_error_new(msg, GET_CALL_MSG_ARG_ERR,
6131                       "wininfo: an attempt to get arguments from method call message failed");
6132      }
6133
6134    ec = _e_info_server_ec_find_by_win(win);
6135    if (!ec)
6136      {
6137         return eldbus_message_error_new(msg, WIN_NOT_EXIST, "wininfo: specified window(s) doesn't exist");
6138      }
6139
6140    e_comp_layer_name_get(ec->layer, layer_name, sizeof(layer_name));
6141
6142    pwin = e_client_util_win_get(ec->parent);
6143
6144    if (ec->pixmap)
6145      res_id = e_pixmap_res_id_get(ec->pixmap);
6146
6147    pid = ec->netwm.pid;
6148    if (pid <= 0)
6149      {
6150         if (ec->comp_data)
6151           {
6152              E_Comp_Wl_Client_Data *cdata = (E_Comp_Wl_Client_Data*)ec->comp_data;
6153              if (cdata->surface)
6154                wl_client_get_credentials(wl_resource_get_client(cdata->surface), &pid, NULL, NULL);
6155           }
6156      }
6157
6158    _e_info_server_ec_hwc_info_get(ec, &hwc, &hwc_policy, &pl_zpos);
6159
6160    ecore_evas_screen_geometry_get(e_comp->ee, NULL, NULL, &dw, &dh);
6161
6162    xright = dw - ec->x - ec->border_size * 2 - ec->w;
6163    ybelow = dh - ec->y - ec->border_size * 2 - ec->h;
6164
6165    reply = eldbus_message_method_return_new(msg);
6166
6167    eldbus_message_arguments_append(reply, VALUE_TYPE_REPLY_WININFO, res_id, pid,
6168                                    ec->x, ec->y, ec->w, ec->h, ec->layer, ec->visible,
6169                                    ec->argb, ec->visibility.opaque, e_client_visibility_get(ec),
6170                                    ec->iconic, evas_object_visible_get(ec->frame),
6171                                    ec->focused, hwc, pl_zpos, (uint64_t)pwin,
6172                                    layer_name, xright, ybelow, ec->border_size,
6173                                    ec->redirected);
6174
6175    return reply;
6176 }
6177
6178 static void
6179 _e_info_server_cb_wininfo_size_hints_append(E_Client *ec, Eldbus_Message_Iter *array_of_hints)
6180 {
6181    char temp[512] = {0};
6182    Evas_Coord w, h, l, r, t, b;
6183    double x, y;
6184
6185    evas_object_size_hint_min_get(ec->frame, &w, &h);
6186    snprintf(temp, sizeof(temp), "   min: h(%d), v(%d)", w, h);
6187    eldbus_message_iter_arguments_append(array_of_hints, "s", temp);
6188
6189    evas_object_size_hint_max_get(ec->frame, &w, &h);
6190    snprintf(temp, sizeof(temp), "   max: h(%d), v(%d)", w, h);
6191    eldbus_message_iter_arguments_append(array_of_hints, "s", temp);
6192
6193    evas_object_size_hint_request_get(ec->frame, &w, &h);
6194    snprintf(temp, sizeof(temp), "   request: h(%d), v(%d)", w, h);
6195    eldbus_message_iter_arguments_append(array_of_hints, "s", temp);
6196
6197    evas_object_size_hint_align_get(ec->frame, &x, &y);
6198    snprintf(temp, sizeof(temp), "   align: x(%f), y(%f)", x, y);
6199    eldbus_message_iter_arguments_append(array_of_hints, "s", temp);
6200
6201    evas_object_size_hint_weight_get(ec->frame, &x, &y);
6202    snprintf(temp, sizeof(temp), "   weight: x(%f), y(%f)", x, y);
6203    eldbus_message_iter_arguments_append(array_of_hints, "s", temp);
6204
6205    evas_object_size_hint_padding_get(ec->frame, &l, &r, &t, &b);
6206    snprintf(temp, sizeof(temp), "   padding: l(%d), r(%d), t(%d), b(%d)",
6207             l, r, t, b);
6208    eldbus_message_iter_arguments_append(array_of_hints, "s", temp);
6209 }
6210
6211 static void
6212 _e_info_server_cb_wininfo_wm_hints_append(E_Client *ec, Eldbus_Message_Iter *array_of_hints)
6213 {
6214    Eina_List *l;
6215    E_Comp_Wl_Aux_Hint *hint;
6216    char temp[512] = {0};
6217
6218    if (!ec->comp_data)
6219      return;
6220
6221    EINA_LIST_FOREACH(ec->comp_data->aux_hint.hints, l, hint)
6222      {
6223         snprintf(temp, sizeof(temp), "%s: %s", hint->hint, hint->val);
6224         eldbus_message_iter_arguments_append(array_of_hints, "s", temp);
6225      }
6226 }
6227
6228 static Eldbus_Message *
6229 _e_info_server_cb_wininfo_hints(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
6230 {
6231    Eldbus_Message *reply;
6232    Eldbus_Message_Iter *iter, *array_of_hints;
6233    Eina_Bool res;
6234    E_Client *ec;
6235    uint64_t win;
6236    int wm_mode;
6237
6238    res = eldbus_message_arguments_get(msg, "it", &wm_mode, &win);
6239    if (res != EINA_TRUE)
6240      {
6241         return eldbus_message_error_new(msg, GET_CALL_MSG_ARG_ERR,
6242                       "wininfo_hints: an attempt to get arguments from method call message failed");
6243      }
6244
6245    ec = _e_info_server_ec_find_by_win(win);
6246    if (!ec)
6247      {
6248         return eldbus_message_error_new(msg, WIN_NOT_EXIST,
6249                       "wininfo_hints: specified window(s) doesn't exist");
6250      }
6251
6252    reply = eldbus_message_method_return_new(msg);
6253    iter = eldbus_message_iter_get(reply);
6254
6255    eldbus_message_iter_arguments_append(iter, "as", &array_of_hints);
6256    if (wm_mode)
6257       _e_info_server_cb_wininfo_wm_hints_append(ec, array_of_hints);
6258    else
6259       _e_info_server_cb_wininfo_size_hints_append(ec, array_of_hints);
6260    eldbus_message_iter_container_close(iter, array_of_hints);
6261
6262    return reply;
6263 }
6264
6265 static Eldbus_Message *
6266 _e_info_server_cb_wininfo_shape(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
6267 {
6268    Eldbus_Message *reply;
6269    Eldbus_Message_Iter *iter, *array_of_shape, *struct_of_shape;
6270    Eina_Bool res;
6271    E_Client *ec;
6272    uint64_t win;
6273    int i;
6274
6275    res = eldbus_message_arguments_get(msg, "t", &win);
6276    if (res != EINA_TRUE)
6277      {
6278         return eldbus_message_error_new(msg, GET_CALL_MSG_ARG_ERR,
6279                       "wininfo_shape: an attempt to get arguments from method call message failed");
6280      }
6281
6282    ec = _e_info_server_ec_find_by_win(win);
6283    if (!ec)
6284      {
6285         return eldbus_message_error_new(msg, WIN_NOT_EXIST, "wininfo_shape: specified window(s) doesn't exist");
6286      }
6287
6288    reply = eldbus_message_method_return_new(msg);
6289    iter = eldbus_message_iter_get(reply);
6290
6291    eldbus_message_iter_basic_append(iter, 'i', ec->shape_rects_num);
6292    array_of_shape = eldbus_message_iter_container_new(iter, 'a', "(iiii)");
6293    for(i = 0; i < ec->shape_rects_num; ++i)
6294      {
6295         eldbus_message_iter_arguments_append(iter, "(iiii)", &struct_of_shape);
6296         eldbus_message_iter_arguments_append
6297            (struct_of_shape, "iiii",
6298             ec->shape_rects[i].x, ec->shape_rects[i].y,
6299             ec->shape_rects[i].w, ec->shape_rects[i].h);
6300         eldbus_message_iter_container_close(iter, struct_of_shape);
6301      }
6302    eldbus_message_iter_container_close(iter, array_of_shape);
6303
6304    eldbus_message_iter_basic_append(iter, 'i', ec->shape_input_rects_num);
6305    array_of_shape = eldbus_message_iter_container_new(iter, 'a', "(iiii)");
6306    for(i = 0; i < ec->shape_input_rects_num; ++i)
6307      {
6308         eldbus_message_iter_arguments_append(iter, "(iiii)", &struct_of_shape);
6309         eldbus_message_iter_arguments_append
6310            (struct_of_shape, "iiii",
6311             ec->shape_input_rects[i].x, ec->shape_input_rects[i].y,
6312             ec->shape_input_rects[i].w, ec->shape_input_rects[i].h);
6313         eldbus_message_iter_container_close(iter, struct_of_shape);
6314      }
6315    eldbus_message_iter_container_close(iter, array_of_shape);
6316
6317    return reply;
6318 }
6319
6320 static Eldbus_Message *
6321 _e_info_server_cb_version_get(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
6322 {
6323    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
6324
6325    eldbus_message_arguments_append(reply, "ss", VERSION, TIZEN_REL_VERSION);
6326
6327    return reply;
6328 }
6329
6330 static Eldbus_Message *
6331 _e_info_server_cb_module_list_get(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
6332 {
6333    Eina_List *module_list = NULL, *l = NULL;
6334    E_Module *mod = NULL;
6335    Eldbus_Message *reply = NULL;
6336    Eldbus_Message_Iter *iter = NULL, *module_array = NULL;
6337    Eldbus_Message_Iter *inner_module_array = NULL;
6338
6339    module_list = e_module_list();
6340    if (module_list == NULL)
6341      {
6342         ERR("cannot get module list");
6343         return eldbus_message_error_new(msg, FAIL_TO_GET_PROPERTY,
6344                                         "module list: e_module_list() returns NULL");
6345      }
6346
6347    // init message
6348    reply = eldbus_message_method_return_new(msg);
6349    iter = eldbus_message_iter_get(reply);
6350
6351    // get module count
6352    eldbus_message_iter_basic_append(iter, 'i', eina_list_count(module_list));
6353
6354    // get module list
6355    eldbus_message_iter_arguments_append(iter, "a(si)", &module_array);
6356    EINA_LIST_FOREACH(module_list, l, mod)
6357      {
6358         char module_name[128] = {0};
6359         int isonoff = 0;
6360         snprintf(module_name, sizeof(module_name), "%s", mod->name);
6361         isonoff = e_module_enabled_get(mod);
6362         eldbus_message_iter_arguments_append(module_array, "(si)", &inner_module_array);
6363         eldbus_message_iter_arguments_append(inner_module_array, "si", module_name, isonoff);
6364         eldbus_message_iter_container_close(module_array, inner_module_array);
6365      }
6366    eldbus_message_iter_container_close(iter, module_array);
6367
6368    return reply;
6369 }
6370
6371 static Eldbus_Message *
6372 _e_info_server_cb_module_load(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
6373 {
6374    Eldbus_Message *reply = NULL;
6375    E_Module *module = NULL;
6376    const char *module_name = NULL;
6377    char msg_to_client[128] = {0};
6378    int res = 0;
6379
6380    if (eldbus_message_arguments_get(msg, "s", &module_name) == EINA_FALSE || module_name == NULL)
6381      {
6382         return eldbus_message_error_new(msg, GET_CALL_MSG_ARG_ERR,
6383                                         "module load: an attempt to get arguments from method call message failed");
6384      }
6385
6386    // find module & enable
6387    module = e_module_find(module_name);
6388    if (module == NULL)
6389      {
6390         module = e_module_new(module_name);
6391      }
6392    if (module == NULL || module->error)
6393      {
6394         snprintf(msg_to_client, sizeof(msg_to_client), "module load: cannot find module name : %s", module_name);
6395         if(module != NULL)
6396           e_object_del(E_OBJECT(module));
6397      }
6398    else
6399      {
6400         if (e_module_enabled_get(module))
6401           {
6402              snprintf(msg_to_client, sizeof(msg_to_client), "enlightenment module[ %s ] is already loaded", module_name);
6403           }
6404         else
6405           {
6406              res = e_module_enable(module);
6407              snprintf(msg_to_client, sizeof(msg_to_client), "enlightenment module[ %s ] load %s", module_name, res?"succeed":"failed");
6408           }
6409      }
6410
6411    // return message to client
6412    reply = eldbus_message_method_return_new(msg);
6413    eldbus_message_arguments_append(reply, "s", msg_to_client);
6414
6415    return reply;
6416 }
6417
6418 static Eldbus_Message *
6419 _e_info_server_cb_module_unload(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
6420 {
6421    Eldbus_Message *reply = NULL;
6422    E_Module *module = NULL;
6423    const char *module_name = NULL;
6424    char msg_to_client[128] = {0};
6425    int res = 0;
6426
6427    if (eldbus_message_arguments_get(msg, "s", &module_name) == EINA_FALSE || module_name == NULL)
6428      {
6429         return eldbus_message_error_new(msg, GET_CALL_MSG_ARG_ERR,
6430                                         "module unload: an attempt to get arguments from method call message failed");
6431      }
6432
6433    module = e_module_find(module_name);
6434    if (module == NULL)
6435      {
6436         snprintf(msg_to_client, sizeof(msg_to_client), "module unload: cannot find module name : %s", module_name);
6437         goto finish;
6438      }
6439    else
6440      {
6441         if (e_module_enabled_get(module))
6442           {
6443              res = e_module_disable(module);
6444              snprintf(msg_to_client, sizeof(msg_to_client), "enlightenment module[ %s ] unload %s", module_name, res?"succeed":"failed");
6445           }
6446         else
6447           {
6448              snprintf(msg_to_client, sizeof(msg_to_client), "enlightenment module[ %s ] is already unloaded", module_name);
6449           }
6450         goto finish;
6451      }
6452
6453 finish:
6454    // return message to client
6455    reply = eldbus_message_method_return_new(msg);
6456    eldbus_message_arguments_append(reply, "s", msg_to_client);
6457
6458    return reply;
6459 }
6460
6461 static Eldbus_Message *
6462 _e_info_server_cb_shutdown(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
6463 {
6464    Eldbus_Message *reply = NULL;
6465    char msg_to_client[128] = {0};
6466
6467    snprintf(msg_to_client, sizeof(msg_to_client), "Enlightenment will be shutdown");
6468    reply = eldbus_message_method_return_new(msg);
6469    eldbus_message_arguments_append(reply, "s", msg_to_client);
6470
6471    ecore_main_loop_quit();
6472
6473    return reply;
6474
6475 }
6476
6477 static Eldbus_Message *
6478 _e_info_server_cb_buffer_flush(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
6479 {
6480    Eldbus_Message *reply = NULL;
6481    int msg_from_client = 0;
6482    char msg_to_client[128] = {0};
6483    E_Client *ec = NULL;
6484    Ecore_Window win = 0;
6485
6486    if (!eldbus_message_arguments_get(msg, "it", &msg_from_client, &win))
6487      {
6488         snprintf(msg_to_client, sizeof(msg_to_client), "Error occured while get message");
6489         goto finish;
6490      }
6491
6492    if (win)
6493      {
6494         // find ec
6495         ec = _e_info_server_ec_find_by_win(win);
6496         if (ec == NULL)
6497           {
6498              snprintf(msg_to_client, sizeof(msg_to_client), "Cannot find win 0x%08zx!", win);
6499              goto finish;
6500           }
6501      }
6502
6503    switch (msg_from_client)
6504      {
6505       case 0:
6506       case 1:
6507          if (ec)
6508            {
6509               // set buffer_flush to specified window
6510               ec->exp_iconify.buffer_flush = msg_from_client;
6511               snprintf(msg_to_client, sizeof(msg_to_client),
6512                        "Successfully changed!\n"
6513                        "win(0x%08zx/%s)->buffer_flush : %s",
6514                        win,
6515                        ec->icccm.name,
6516                        ec->exp_iconify.buffer_flush ? "on" : "off");
6517            }
6518          else
6519            {
6520               // set buffer_flush to all window
6521               e_config->use_buffer_flush = msg_from_client;
6522               for (ec = e_client_top_get(); ec; ec = e_client_below_get(ec))
6523                 {
6524                    ec->exp_iconify.buffer_flush = msg_from_client;
6525                 }
6526
6527               snprintf(msg_to_client, sizeof(msg_to_client),
6528                        "Successfully changed!\n"
6529                        "e_config->use_buffer_flush : %s",
6530                        e_config->use_buffer_flush ? "on" : "off");
6531            }
6532          break;
6533       default:
6534          snprintf(msg_to_client, sizeof(msg_to_client), "Current option: e_config->use_buffer_flush : %s",
6535                   e_config->use_buffer_flush ? "on" : "off");
6536          if (ec)
6537            {
6538               snprintf(msg_to_client + strlen(msg_to_client),
6539                        sizeof(msg_to_client) - strlen(msg_to_client),
6540                        "\n\t\twin(0x%08zx)->buffer_flush : %s",
6541                        win,
6542                        ec->exp_iconify.buffer_flush ? "on" : "off");
6543            }
6544          break;
6545      }
6546
6547 finish:
6548    reply = eldbus_message_method_return_new(msg);
6549    eldbus_message_arguments_append(reply, "s", msg_to_client);
6550
6551    return reply;
6552 }
6553
6554 static Eldbus_Message *
6555 _e_info_server_cb_deiconify_approve(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
6556 {
6557    Eldbus_Message *reply = NULL;
6558    int msg_from_client = 0;
6559    char msg_to_client[128] = {0};
6560    E_Client *ec = NULL;
6561    Ecore_Window win = 0;
6562
6563    if (!eldbus_message_arguments_get(msg, "it", &msg_from_client, &win))
6564      {
6565         snprintf(msg_to_client, sizeof(msg_to_client), "Error occured while get message");
6566         goto finish;
6567      }
6568
6569    if (win)
6570      {
6571         // find ec
6572         ec = _e_info_server_ec_find_by_win(win);
6573         if (ec == NULL)
6574           {
6575              snprintf(msg_to_client, sizeof(msg_to_client), "Cannot find win 0x%08zx!", win);
6576              goto finish;
6577           }
6578      }
6579
6580    switch (msg_from_client)
6581      {
6582       case 0:
6583       case 1:
6584          if (ec)
6585            {
6586               // set deiconify_approve to specified window
6587               ec->exp_iconify.deiconify_update = msg_from_client;
6588               snprintf(msg_to_client, sizeof(msg_to_client),
6589                        "Successfully changed!\n"
6590                        "win(0x%08zx/%s)->deiconify_update : %s",
6591                        win,
6592                        ec->icccm.name,
6593                        ec->exp_iconify.deiconify_update ? "on" : "off");
6594            }
6595          else
6596            {
6597               // set deiconify_approve to all window
6598               e_config->deiconify_approve = msg_from_client;
6599               for (ec = e_client_top_get(); ec; ec = e_client_below_get(ec))
6600                 {
6601                    ec->exp_iconify.deiconify_update = msg_from_client;
6602                 }
6603
6604               snprintf(msg_to_client, sizeof(msg_to_client),
6605                        "Successfully changed!\n"
6606                        "e_config->deiconify_approve : %s",
6607                        e_config->deiconify_approve ? "on" : "off");
6608            }
6609          break;
6610       default:
6611          snprintf(msg_to_client, sizeof(msg_to_client), "Current option: e_config->deiconify_approve : %s",
6612                   e_config->deiconify_approve ? "on" : "off");
6613          if (ec)
6614            {
6615               snprintf(msg_to_client + strlen(msg_to_client),
6616                        sizeof(msg_to_client) - strlen(msg_to_client),
6617                        "\n\t\twin(0x%08zx)->deiconify_update : %s",
6618                        win,
6619                        ec->exp_iconify.deiconify_update ? "on" : "off");
6620            }
6621          break;
6622      }
6623
6624 finish:
6625    reply = eldbus_message_method_return_new(msg);
6626    eldbus_message_arguments_append(reply, "s", msg_to_client);
6627
6628    return reply;
6629 }
6630
6631 static Eldbus_Message *
6632 _e_info_server_cb_key_repeat(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
6633 {
6634    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
6635    const char *path = NULL;
6636    int rate = 0, delay = 0;
6637    FILE *log_fp;
6638
6639    if (!eldbus_message_arguments_get(msg, "sii", &path, &delay, &rate))
6640      {
6641         ERR("Error getting arguments.");
6642         return reply;
6643      }
6644    if (!e_comp_wl) return reply;
6645
6646    if (path && strlen(path) > 0)
6647      {
6648         log_fp = fopen(path, "a");
6649         EINA_SAFETY_ON_NULL_RETURN_VAL(log_fp, reply);
6650
6651         fprintf(log_fp, "\tkeyboard repeat info\n");
6652         fprintf(log_fp, "\t\trate: %d (ms), delay: %d (ms)\n", e_comp_wl->kbd.repeat_rate, e_comp_wl->kbd.repeat_delay);
6653         fclose(log_fp);
6654         log_fp = NULL;
6655      }
6656    else
6657      {
6658         if (delay <= 0) delay = e_comp_wl->kbd.repeat_delay;
6659         if (rate <= 0) rate = e_comp_wl->kbd.repeat_rate;
6660
6661         e_comp_wl_input_keyboard_repeat_set(delay, rate);
6662      }
6663
6664    return reply;
6665 }
6666
6667 static Eldbus_Message *
6668 _e_info_server_cb_memchecker(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
6669 {
6670    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
6671
6672    if (e_comp->func_memory_dump)
6673      {
6674         e_comp->func_memory_dump();
6675      }
6676    else
6677      {
6678         e_comp->func_memory_dump = dlsym(RTLD_NEXT, "e_memcheck_dump");
6679         if (e_comp->func_memory_dump)
6680           e_comp->func_memory_dump();
6681         else
6682           ERR("Not available to dump memory");
6683
6684      }
6685
6686    return reply;
6687 }
6688
6689 static Eina_Bool
6690 _input_rect_timer(void *data)
6691 {
6692    Evas_Object *rect = (Evas_Object *)data;
6693
6694    evas_object_hide(rect);
6695    evas_object_del(rect);
6696
6697    e_comp_render_queue();
6698
6699    return ECORE_CALLBACK_CANCEL;;
6700 }
6701
6702 static void
6703 _input_rect_draw(int x, int y, int w, int h, int time, int color_r, int color_g, int color_b)
6704 {
6705    Evas_Object *rect;
6706    EINA_SAFETY_ON_NULL_RETURN(e_comp->evas);
6707
6708    rect = evas_object_rectangle_add(e_comp->evas);
6709    EINA_SAFETY_ON_NULL_RETURN(rect);
6710
6711    evas_object_color_set(rect, color_r, color_g, color_b, 150);
6712    evas_object_resize(rect, w, h);
6713    evas_object_move(rect, x, y);
6714
6715    evas_object_layer_set(rect, E_LAYER_DESK_OBJECT_ABOVE);
6716
6717    evas_object_show(rect);
6718
6719    e_comp_render_queue();
6720
6721    ecore_timer_add((double)time, _input_rect_timer, rect);
6722 }
6723
6724 static void
6725 _input_region_msg_clients_append(Eldbus_Message_Iter *iter, Evas_Object *obj, int time, int color_r, int color_g, int color_b)
6726 {
6727    Eldbus_Message_Iter *array_of_ec;
6728    Eina_List *list = NULL, *l;
6729    Eina_Rectangle *data;
6730    int x, y;
6731
6732    e_comp_object_input_rect_get(obj, &list);
6733    if (!list) return;
6734
6735    evas_object_geometry_get(obj, &x, &y, NULL, NULL);
6736
6737    eldbus_message_iter_arguments_append(iter, "a(iiii)", &array_of_ec);
6738
6739    EINA_LIST_FOREACH(list, l, data)
6740      {
6741         Eldbus_Message_Iter* struct_of_ec;
6742
6743         eldbus_message_iter_arguments_append(array_of_ec, "(iiii)", &struct_of_ec);
6744
6745         eldbus_message_iter_arguments_append(struct_of_ec, "iiii", data->x, data->y, data->w, data->h);
6746         eldbus_message_iter_container_close(array_of_ec, struct_of_ec);
6747
6748         _input_rect_draw(x + data->x, y + data->y, data->w, data->h, time, color_r, color_g, color_b);
6749      }
6750    eldbus_message_iter_container_close(iter, array_of_ec);
6751
6752    list = eina_list_free(list);
6753 }
6754
6755 static Eldbus_Message *
6756 _e_info_server_cb_input_region(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
6757 {
6758    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
6759    Eldbus_Message_Iter *iter = eldbus_message_iter_get(reply);
6760
6761    Evas_Object *o;
6762    E_Client *ec;
6763    Ecore_Window win;
6764    uint64_t win_id_value = 0;
6765    const char *win_id_str = NULL;
6766    unsigned long tmp = 0;
6767    int time = 0, color_r = 0, color_g = 0, color_b = 0;
6768    Eina_Bool res = EINA_FALSE;
6769
6770    if (!eldbus_message_arguments_get(msg, "siiii", &win_id_str, &time, &color_r, &color_g, &color_b))
6771      {
6772         ERR("Error getting arguments.");
6773         return reply;
6774      }
6775    if (!e_comp) return reply;
6776
6777    if (strlen(win_id_str) >= 2 && win_id_str[0] == '0' && win_id_str[1] == 'x')
6778      res = e_util_string_to_ulong(win_id_str, &tmp, 16);
6779    else
6780      res = e_util_string_to_ulong(win_id_str, &tmp, 10);
6781    if (res == EINA_FALSE)
6782      {
6783         ERR("input_region: invalid input arguments");
6784         return eldbus_message_error_new(msg, INVALID_ARGS,
6785         "input_region: invalid input arguments");
6786      }
6787    win_id_value = (uint64_t)tmp;
6788
6789    for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
6790      {
6791         ec = evas_object_data_get(o, "E_Client");
6792         if (!ec) continue;
6793         if (e_client_util_ignored_get(ec)) continue;
6794
6795         win = e_client_util_win_get(ec);
6796         if (!win || win != win_id_value) continue;
6797
6798         _input_region_msg_clients_append(iter, o, time, color_r, color_g, color_b);
6799         break;
6800      }
6801
6802    return reply;
6803 }
6804
6805 static Eldbus_Message *
6806 _e_info_server_cb_hwc_wins_info_get(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
6807 {
6808    Eldbus_Message *reply;
6809    E_Hwc_Wins_Debug_Cmd cmd;
6810
6811    if (!eldbus_message_arguments_get(msg, "i", &cmd))
6812      {
6813         return eldbus_message_error_new(msg, GET_CALL_MSG_ARG_ERR,
6814                                         "hwc_wins: an attempt to get arguments from method call message failed");
6815      }
6816
6817    reply = eldbus_message_method_return_new(msg);
6818    e_hwc_windows_debug_info_get(eldbus_message_iter_get(reply), cmd);
6819
6820    return reply;
6821 }
6822
6823 static Eldbus_Message *
6824 _e_info_server_cb_screen_info_get(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
6825 {
6826    Eldbus_Message *reply;
6827    E_Hwc_Wins_Debug_Cmd cmd;
6828
6829    if (!eldbus_message_arguments_get(msg, "i", &cmd))
6830      {
6831         return eldbus_message_error_new(msg, GET_CALL_MSG_ARG_ERR,
6832                                         "screen_info: an attempt to get arguments from method call message failed");
6833      }
6834
6835    reply = eldbus_message_method_return_new(msg);
6836    e_comp_screen_debug_info_get(eldbus_message_iter_get(reply));
6837
6838    return reply;
6839 }
6840
6841 static Eldbus_Message *
6842 _e_info_server_cb_focus_policy_ext_set(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
6843 {
6844    Eldbus_Message *reply;
6845    int option = 0, res = -1, previous_policy;
6846    Eina_Bool changed = EINA_FALSE;
6847
6848    if (!eldbus_message_arguments_get(msg, "i", &option))
6849      {
6850         return eldbus_message_error_new(msg, GET_CALL_MSG_ARG_ERR,
6851                                         "focus_policy_ext_set: an attempt to get argument from method call message failed");
6852      }
6853
6854    previous_policy = e_config->focus_policy_ext;
6855
6856    switch (option)
6857      {
6858       case -1:
6859          // get now focus policy ext
6860          break;
6861       case 0:
6862          // use topmost focus
6863          e_config->focus_policy_ext = E_FOCUS_EXT_TOP_STACK;
6864          break;
6865       case 1:
6866       default:
6867          // use focus history
6868          e_config->focus_policy_ext = E_FOCUS_EXT_HISTORY;
6869          break;
6870      }
6871
6872    res = e_config->focus_policy_ext;
6873    if (previous_policy != res)
6874      {
6875         E_Zone *zone = e_zone_current_get();
6876         if (zone && zone->focus)
6877           {
6878              e_focus_del(zone->focus);
6879              zone->focus = e_focus_new(zone, res);
6880              if (!zone->focus)
6881                ERR("Failed to create E_Focus.");
6882           }
6883         changed = EINA_TRUE;
6884      }
6885
6886    reply = eldbus_message_method_return_new(msg);
6887    eldbus_message_arguments_append(reply, "bi", changed, res);
6888
6889    return reply;
6890 }
6891
6892 static Eldbus_Message *
6893 _e_info_server_cb_focus_history(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
6894 {
6895    Eldbus_Message *reply = NULL;
6896
6897    return reply;
6898 }
6899
6900 static Eldbus_Message *
6901 _e_info_server_cb_init_device(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
6902 {
6903    Eldbus_Message *reply;
6904    char *name = NULL, *result = NULL;
6905    unsigned int type = 0x0;
6906
6907    if (!eldbus_message_arguments_get(msg, "us", &type, &name))
6908      {
6909         return eldbus_message_error_new(msg, "InputUtilFailed",
6910                                         "input: an attempt to excute input util from method call message failed");
6911      }
6912
6913    result = e_info_server_input_init_device(type, name);
6914
6915    reply = eldbus_message_method_return_new(msg);
6916
6917    eldbus_message_arguments_append(reply, "s", result);
6918
6919    return reply;
6920 }
6921
6922 static Eldbus_Message *
6923 _e_info_server_cb_deinit_device(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
6924 {
6925    Eldbus_Message *reply;
6926
6927    e_info_server_input_deinit_device();
6928
6929    reply = eldbus_message_method_return_new(msg);
6930
6931    return reply;
6932 }
6933
6934 static Eldbus_Message *
6935 _e_info_server_cb_keygen(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
6936 {
6937    Eldbus_Message *reply;
6938    char *name = NULL, *result = NULL;
6939    int code = 0, state = 0;
6940
6941    if (!eldbus_message_arguments_get(msg, "sii", &name, &code, &state))
6942      {
6943         return eldbus_message_error_new(msg, "KeygenFailed",
6944                                         "keygen: an attempt to generate key event from method call message failed");
6945      }
6946
6947    result = e_info_server_input_keygen(name, code, state);
6948    reply = eldbus_message_method_return_new(msg);
6949
6950    eldbus_message_arguments_append(reply, "s", result);
6951
6952    return reply;
6953 }
6954
6955 static Eldbus_Message *
6956 _e_info_server_cb_touchgen(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
6957 {
6958    Eldbus_Message *reply;
6959    char *result = NULL;
6960    int idx = 0, x = -1, y = -1, state = 0;
6961
6962    if (!eldbus_message_arguments_get(msg, "iiii", &idx, &x, &y, &state))
6963      {
6964         return eldbus_message_error_new(msg, "TouchgenFailed",
6965                                         "toutgen: an attempt to generate touch event from method call message failed");
6966      }
6967
6968    result = e_info_server_input_touchgen(idx, x, y, state);
6969    reply = eldbus_message_method_return_new(msg);
6970
6971    eldbus_message_arguments_append(reply, "s", result);
6972
6973    return reply;
6974 }
6975
6976 static Eldbus_Message *
6977 _e_info_server_cb_mousegen(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
6978 {
6979    Eldbus_Message *reply;
6980    char *result = NULL;
6981    int button = 0, x = -1, y = -1, state = 0;
6982
6983    if (!eldbus_message_arguments_get(msg, "iiii", &button, &x, &y, &state))
6984      {
6985         return eldbus_message_error_new(msg, "MousegenFailed",
6986                                         "mousegen: an attempt to generate mouse event from method call message failed");
6987      }
6988
6989    result = e_info_server_input_mousegen(button, x, y, state);
6990    reply = eldbus_message_method_return_new(msg);
6991
6992    eldbus_message_arguments_append(reply, "s", result);
6993
6994    return reply;
6995 }
6996
6997 static Eldbus_Message *
6998 _e_info_server_cb_mouse_accel(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
6999 {
7000    Eldbus_Message *reply;
7001    char *result = NULL;
7002    int state = 0;
7003
7004    if (!eldbus_message_arguments_get(msg, "i", &state))
7005      {
7006         return eldbus_message_error_new(msg, "Mouse_accelFailed",
7007                                         "mouse_accel: an attempt to set mouse acceleration usage from method call message failed");
7008      }
7009
7010    result = e_info_server_input_mouse_accel_set(state);
7011    reply = eldbus_message_method_return_new(msg);
7012
7013    eldbus_message_arguments_append(reply, "s", result);
7014
7015    return reply;
7016 }
7017
7018 static Eldbus_Message *
7019 _e_info_server_cb_input_log_enable(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
7020 {
7021    Eldbus_Message *reply;
7022    char *result = NULL;
7023    int state = 0;
7024
7025    if (!eldbus_message_arguments_get(msg, "i", &state))
7026      {
7027         return eldbus_message_error_new(msg, "Input_log_enableFailed",
7028                                         "input_log: an attempt to set input_log enable from method call message failed");
7029      }
7030
7031    result = e_info_server_input_log_enable_set(state);
7032    reply = eldbus_message_method_return_new(msg);
7033
7034    eldbus_message_arguments_append(reply, "s", result);
7035
7036    return reply;
7037 }
7038
7039 static Eldbus_Message *
7040 _e_info_server_cb_use_cursor_timer(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
7041 {
7042    Eldbus_Message *reply;
7043    char *result = NULL;
7044    int state = 0;
7045
7046    if (!eldbus_message_arguments_get(msg, "i", &state))
7047      {
7048         return eldbus_message_error_new(msg, "Use_cursor_timerFailed",
7049                                         "cursor_timer: an attempt to set use_cursor_timer from method call message failed");
7050      }
7051
7052    e_comp_wl_input_cursor_timer_enable_set(state);
7053    result = E_INFO_INPUT_RESULT_NONE;
7054    reply = eldbus_message_method_return_new(msg);
7055
7056    eldbus_message_arguments_append(reply, "s", result);
7057
7058    return reply;
7059 }
7060
7061 static Eldbus_Message *
7062 _e_info_server_cb_filter(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
7063 {
7064    Eldbus_Message *reply;
7065    int onoff = -1;
7066    const char *filter_name = NULL, *win_str = NULL;
7067    char msg_to_client[125] = {0};
7068    unsigned long tmp = 0;
7069    uint64_t win_number = 0;
7070    Evas_Object *o;
7071    E_Client *ec;
7072    Ecore_Window win;
7073    Eina_Bool res;
7074
7075    if (!eldbus_message_arguments_get(msg, "sis", &win_str, &onoff, &filter_name))
7076      {
7077         return eldbus_message_error_new(msg, GET_CALL_MSG_ARG_ERR,
7078                                         "filetr: failed to get arguments from method call message");
7079      }
7080    reply = eldbus_message_method_return_new(msg);
7081
7082    if (strlen(win_str) >= 2 && win_str[0] == '0' && win_str[1] == 'x')
7083      res = e_util_string_to_ulong(win_str, &tmp, 16);
7084    else
7085      res = e_util_string_to_ulong(win_str, &tmp, 10);
7086
7087    if (!res)
7088      {
7089         snprintf(msg_to_client, sizeof(msg_to_client), "Invalid window id: %s\n", win_str);
7090         goto reply;
7091      }
7092
7093    win_number = (uint64_t)tmp;
7094
7095    if (win_number != 0x0)
7096      {
7097         for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
7098           {
7099              ec = evas_object_data_get(o, "E_Client");
7100              if (!ec) continue;
7101              win = e_client_util_win_get(ec);
7102              if (win != win_number) continue;
7103
7104              if (onoff == 0)
7105                {
7106                   e_comp_object_image_filter_set(ec->frame, E_COMP_IMAGE_FILTER_NONE);
7107                   snprintf(msg_to_client, sizeof(msg_to_client), "%s window filter has been unset.\n", win_str);
7108                }
7109              else
7110                {
7111                   if (!strcmp(filter_name, "blur"))
7112                     {
7113                        e_comp_object_image_filter_set(ec->frame, E_COMP_IMAGE_FILTER_BLUR);
7114                        snprintf(msg_to_client, sizeof(msg_to_client), "%s window filter %s is set!", win_str, filter_name);
7115                     }
7116                   else if (!strcmp(filter_name, "grayscale"))
7117                     {
7118                        e_comp_object_image_filter_set(ec->frame, E_COMP_IMAGE_FILTER_GRAYSCALE);
7119                        snprintf(msg_to_client, sizeof(msg_to_client), "%s window filter %s is set!", win_str, filter_name);
7120                     }
7121                   else if (!strcmp(filter_name, "inverse_color"))
7122                     {
7123                        e_comp_object_image_filter_set(ec->frame, E_COMP_IMAGE_FILTER_INVERSE);
7124                        snprintf(msg_to_client, sizeof(msg_to_client), "%s window filter %s is set!", win_str, filter_name);
7125                     }
7126                   else
7127                     {
7128                        e_comp_object_image_filter_set(ec->frame, E_COMP_IMAGE_FILTER_NONE);
7129                        snprintf(msg_to_client, sizeof(msg_to_client), "%s window filter %s is NOT supported!", win_str, filter_name);
7130                     }
7131                }
7132
7133              e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
7134              e_comp_object_dirty(ec->frame);
7135              e_comp_object_render(ec->frame);
7136
7137              goto reply;
7138           }
7139         snprintf(msg_to_client, sizeof(msg_to_client), "Invalid window id: %s\n", win_str);
7140         goto reply;
7141      }
7142
7143    if (onoff == -1)
7144      {
7145         char current_filter[15] = {0};
7146         //return current filter mode
7147         switch (e_comp->image_filter)
7148           {
7149            case E_COMP_IMAGE_FILTER_BLUR:
7150               snprintf(current_filter, sizeof(current_filter), "blur");
7151               break;
7152            case E_COMP_IMAGE_FILTER_GRAYSCALE:
7153               snprintf(current_filter, sizeof(current_filter), "grayscale");
7154               break;
7155            case E_COMP_IMAGE_FILTER_INVERSE:
7156               snprintf(current_filter, sizeof(current_filter), "inverse_color");
7157               break;
7158            default:
7159               snprintf(current_filter, sizeof(current_filter), "none");
7160               break;
7161           }
7162
7163         snprintf(msg_to_client, sizeof(msg_to_client),
7164                  "Current filter : %s\n", current_filter);
7165      }
7166    else if (onoff == 0)
7167      {
7168         e_comp_image_filter_set(E_COMP_IMAGE_FILTER_NONE);
7169         snprintf(msg_to_client, sizeof(msg_to_client),
7170                  "Filter has been unset.\n");
7171      }
7172    else
7173      {
7174         if (!strcmp(filter_name, "blur"))
7175           e_comp_image_filter_set(E_COMP_IMAGE_FILTER_BLUR);
7176         else if (!strcmp(filter_name, "grayscale"))
7177           e_comp_image_filter_set(E_COMP_IMAGE_FILTER_GRAYSCALE);
7178         else if (!strcmp(filter_name, "inverse_color"))
7179           e_comp_image_filter_set(E_COMP_IMAGE_FILTER_INVERSE);
7180         else
7181           snprintf(msg_to_client, sizeof(msg_to_client),
7182                    "Filter %s is NOT supported!\n",
7183                    filter_name);
7184
7185         snprintf(msg_to_client, sizeof(msg_to_client),
7186                  "Filter %s is set!\n", filter_name);
7187      }
7188
7189 reply:
7190    eldbus_message_arguments_append(reply, "s", msg_to_client);
7191
7192    return reply;
7193 }
7194
7195 static Eldbus_Message *
7196 _e_info_server_cb_mtrace(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
7197 {
7198    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
7199    int enable;
7200
7201    if (!eldbus_message_arguments_get(msg, "i", &enable))
7202      {
7203         ERR("Error getting argument for enabling mtrace.");
7204         return reply;
7205      }
7206
7207    if (enable)
7208      {
7209         mtrace();
7210         INF("mtrace enable=%d", enable);
7211      }
7212    else
7213      {
7214         muntrace();
7215         INF("mtrace enable=0");
7216      }
7217
7218    return reply;
7219 }
7220
7221 static Eldbus_Message *
7222 _e_info_server_cb_gcov(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
7223 {
7224    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
7225    int mode;
7226
7227    if (!eldbus_message_arguments_get(msg, "i", &mode))
7228      {
7229         ERR("Error getting arguments.");
7230         return reply;
7231      }
7232
7233 #ifdef TIZEN_TEST_GCOV
7234    __gcov_flush();
7235 #endif
7236
7237    return reply;
7238 }
7239
7240 static void
7241 _e_info_server_basic_operation_request(E_Client *ec, const char *operation)
7242 {
7243    if (!ec) return;
7244    if (!operation) return;
7245
7246    if (!e_util_strcmp("lower", operation))
7247      {
7248         e_policy_wl_generate_request(ec, E_POLICY_WL_GENERATE_REQUEST_LOWER);
7249      }
7250    else if (!e_util_strcmp("activate", operation))
7251      {
7252         e_policy_wl_generate_request(ec, E_POLICY_WL_GENERATE_REQUEST_ACTIVATE);
7253      }
7254    else if (!e_util_strcmp("iconify", operation))
7255      {
7256         e_policy_wl_generate_request(ec, E_POLICY_WL_GENERATE_REQUEST_ICONIFY);
7257      }
7258    else if (!e_util_strcmp("uniconify", operation))
7259      {
7260         e_policy_wl_generate_request(ec, E_POLICY_WL_GENERATE_REQUEST_UNICONIFY);
7261      }
7262    else
7263      {
7264         ERR("Not supported operation (%s)", operation);
7265      }
7266 }
7267
7268 static Eldbus_Message *
7269 _e_info_server_cb_basic_operation_generate(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
7270 {
7271    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
7272    const char *win_str, *operation;
7273    unsigned long tmp = 0;
7274    uint64_t win_id = 0;
7275    E_Client *ec;
7276    Evas_Object *o;
7277    Eina_Bool res = EINA_FALSE;
7278
7279    if (!e_policy)
7280      {
7281         ERR("e_policy is not initialized!");
7282         return reply;
7283      }
7284
7285    if (!eldbus_message_arguments_get(msg, "ss", &win_str, &operation))
7286      {
7287         ERR("Error getting arguments.");
7288         return reply;
7289      }
7290
7291    res = e_util_string_to_ulong(win_str, &tmp, 16);
7292    EINA_SAFETY_ON_FALSE_RETURN_VAL(res, reply);
7293
7294    win_id = (uint64_t)tmp;
7295
7296    for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
7297      {
7298         ec = evas_object_data_get(o, "E_Client");
7299         if (!ec) continue;
7300
7301         Ecore_Window win = e_client_util_win_get(ec);
7302
7303         if (win == win_id)
7304           {
7305              _e_info_server_basic_operation_request(ec, operation);
7306              break;
7307           }
7308      }
7309
7310    return reply;
7311 }
7312
7313 static Eldbus_Message *
7314 _e_info_server_cb_process_info(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
7315 {
7316    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
7317    e_process_info_print();
7318    return reply;
7319 }
7320
7321 static Eldbus_Message *
7322 _e_info_server_cb_zone_set(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
7323 {
7324    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
7325    unsigned long tmp = 0;
7326    const char *win_id_str = NULL;
7327    int zone_id = 0;
7328    uint64_t win_id = 0;
7329    Evas_Object *o = NULL;
7330    E_Client *ec = NULL;
7331    E_Zone *zone = NULL;
7332    Eina_Bool res = EINA_FALSE;
7333
7334    if (!eldbus_message_arguments_get(msg, "si", &win_id_str, &zone_id))
7335      {
7336         ERR("Error getting arguments.");
7337         return reply;
7338      }
7339
7340    if (strlen(win_id_str) >= 2 && win_id_str[0] == '0' && win_id_str[1] == 'x')
7341      res = e_util_string_to_ulong(win_id_str, &tmp, 16);
7342    else
7343      res = e_util_string_to_ulong(win_id_str, &tmp, 10);
7344
7345    EINA_SAFETY_ON_FALSE_RETURN_VAL(res, reply);
7346
7347    win_id = (uint64_t)tmp;
7348
7349    for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
7350      {
7351         ec = evas_object_data_get(o, "E_Client");
7352         Ecore_Window win;
7353
7354         if (!ec) continue;
7355
7356         win = e_client_util_win_get(ec);
7357         if (win != win_id) continue;
7358
7359         zone = e_zone_get_by_id(zone_id);
7360         if (zone)
7361           {
7362              e_zone_client_add(zone, ec);
7363           }
7364
7365         break;
7366      }
7367
7368    return reply;
7369 }
7370
7371 static Eldbus_Message *
7372 _e_info_server_cb_input_output_set(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
7373 {
7374    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
7375    const char *input_name = NULL, *output_name = NULL;
7376    Eina_Bool res = EINA_FALSE;
7377
7378    if (!eldbus_message_arguments_get(msg, "ss", &input_name, &output_name))
7379      {
7380         ERR("Error getting arguments.");
7381         return reply;
7382      }
7383
7384    res = e_input_device_output_name_set(NULL, input_name, output_name);
7385    if (res) INF("Succeeded to set input device(%s)'s output name(%s)", input_name, output_name);
7386    else ERR("Failed to set input device(%s)'s output name(%s)", input_name, output_name);
7387
7388    return reply;
7389 }
7390
7391 static Eldbus_Message *
7392 _e_info_server_cb_input_seat_set(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
7393 {
7394    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
7395    const char *input_name = NULL, *seat_name = NULL;
7396    Eina_Bool res = EINA_FALSE;
7397
7398    if (!eldbus_message_arguments_get(msg, "ss", &input_name, &seat_name))
7399      {
7400         ERR("Error getting arguments.");
7401         return reply;
7402      }
7403
7404    res = e_input_device_seat_name_set(NULL, input_name, seat_name);
7405    if (res) INF("Succeeded to set input device(%s)'s seat name(%s)", input_name, seat_name);
7406    else ERR("Failed to set input device(%s)'s seat name(%s)", input_name, seat_name);
7407
7408    return reply;
7409 }
7410
7411 static Eldbus_Message *
7412 e_info_server_cb_resize_ppu_set(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
7413 {
7414    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
7415    unsigned long tmp = 0;
7416    const char *win_id_str = NULL;
7417    uint64_t win_id = 0;
7418    Evas_Object *o = NULL;
7419    E_Client *ec = NULL;
7420    uint32_t ppu = 0;
7421    Eina_Bool res = EINA_FALSE;
7422
7423    if (!eldbus_message_arguments_get(msg, "si", &win_id_str, &ppu))
7424      {
7425         ERR("Error getting arguments.");
7426         return reply;
7427      }
7428
7429    if (strlen(win_id_str) >= 2 && win_id_str[0] == '0' && win_id_str[1] == 'x')
7430      res = e_util_string_to_ulong(win_id_str, &tmp, 16);
7431    else
7432      res = e_util_string_to_ulong(win_id_str, &tmp, 10);
7433
7434    EINA_SAFETY_ON_FALSE_RETURN_VAL(res, reply);
7435
7436    win_id = (uint64_t)tmp;
7437
7438    for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
7439      {
7440         ec = evas_object_data_get(o, "E_Client");
7441         Ecore_Window win;
7442
7443         if (!ec) continue;
7444
7445         win = e_client_util_win_get(ec);
7446         if (win != win_id) continue;
7447
7448         e_client_resize_unit_size_set(ec, ppu);
7449
7450         break;
7451      }
7452
7453    return reply;
7454 }
7455
7456 static void
7457 _e_info_server_prop_set(E_Client *ec, const char *property, int set)
7458 {
7459    if (!ec) return;
7460    if (!property) return;
7461
7462    if (!e_util_strcmp("pin", property))
7463      {
7464         e_client_pinned_set(ec, set);
7465      }
7466    else
7467      {
7468         ERR("Not supported operation (%s)", property);
7469      }
7470 }
7471
7472 static Eldbus_Message *
7473 _e_info_server_cb_prop_set(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
7474 {
7475    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
7476    const char *win_str, *property;
7477    int value;
7478    unsigned long tmp = 0;
7479    uint64_t win_id = 0;
7480    E_Client *ec;
7481    Evas_Object *o;
7482    Eina_Bool res = EINA_FALSE;
7483
7484    if (!eldbus_message_arguments_get(msg, "ssi", &win_str, &property, &value))
7485      {
7486         ERR("Error getting arguments.");
7487         return reply;
7488      }
7489
7490    res = e_util_string_to_ulong(win_str, &tmp, 16);
7491    EINA_SAFETY_ON_FALSE_RETURN_VAL(res, reply);
7492
7493    win_id = (uint64_t)tmp;
7494
7495    for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
7496      {
7497         ec = evas_object_data_get(o, "E_Client");
7498         if (!ec) continue;
7499
7500         Ecore_Window win = e_client_util_win_get(ec);
7501
7502         if (win == win_id)
7503           {
7504              _e_info_server_prop_set(ec, property, value);
7505              break;
7506           }
7507      }
7508
7509    return reply;
7510 }
7511
7512 static Eldbus_Message *
7513 _e_info_server_cb_input_subtype_set(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
7514 {
7515    Eldbus_Message *reply;
7516    const char *input_name = NULL, *subtype_name = NULL;
7517    char *result = NULL;
7518    Eina_Bool res = EINA_FALSE;
7519
7520    if (!eldbus_message_arguments_get(msg, "ss", &input_name, &subtype_name))
7521      {
7522         return eldbus_message_error_new(msg, "Input_subtype_setFailed",
7523                                         "input_subtype_set: an attempt to set device's subtype from method call message failed");;
7524      }
7525
7526    res = e_input_device_subtype_set(NULL, input_name, subtype_name);
7527    if (res)
7528      {
7529         INF("Succeeded to set input device(%s)'s subtype(%s)", input_name, subtype_name);
7530         result = E_INFO_INPUT_RESULT_NONE;
7531      }
7532    else
7533      {
7534         ERR("Failed to set input device(%s)'s subtype(%s)", input_name, subtype_name);
7535         result = "Failed to set subtype";
7536      }
7537
7538    reply = eldbus_message_method_return_new(msg);
7539    eldbus_message_arguments_append(reply, "s", result);
7540
7541    return reply;
7542 }
7543
7544 static Eldbus_Message *
7545 _e_info_server_cb_kvm_transparent_set(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
7546 {
7547    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
7548    int set = 0;
7549
7550    if (!eldbus_message_arguments_get(msg, "i", &set))
7551      {
7552         ERR("Failed to get argument");
7553         return reply;
7554      }
7555
7556    if (set)
7557      {
7558         e_service_kvm_all_kvm_service_transparent_set(EINA_TRUE);
7559      }
7560    else
7561      {
7562         e_service_kvm_all_kvm_service_transparent_set(EINA_FALSE);
7563      }
7564
7565    return reply;
7566 }
7567
7568 //{ "method_name", arguments_from_client, return_values_to_client, _method_cb, ELDBUS_METHOD_FLAG },
7569 static const Eldbus_Method methods[] = {
7570    { "get_window_info", NULL, ELDBUS_ARGS({"iiiiisiiia("VALUE_TYPE_FOR_TOPVWINS")", "array of ec"}), _e_info_server_cb_window_info_get, 0 },
7571    { "get_ec_info", NULL, ELDBUS_ARGS({"iia("VALUE_TYPE_FOR_TOPVWINS")", "array of ec"}),_e_info_server_cb_ec_info_get, 0 },
7572    { "get_all_ec_info", NULL, ELDBUS_ARGS({"iia("VALUE_TYPE_FOR_TOPVWINS")", "array of ec"}),_e_info_server_cb_all_ec_info_get, 0 },
7573    { "get_all_window_info", NULL, ELDBUS_ARGS({"iia("VALUE_TYPE_FOR_TOPVWINS")", "array of ec"}), _e_info_server_cb_all_window_info_get, 0 },
7574    { "get_zone_info", NULL, ELDBUS_ARGS({"("VALUE_TYPE_FOR_ZONE")", "array of zone"}), _e_info_server_cb_zone_info_get, 0 },
7575    { "compobjs", NULL, ELDBUS_ARGS({"a("SIGNATURE_COMPOBJS_CLIENT")", "array of comp objs"}), _e_info_server_cb_compobjs, 0 },
7576    { "subsurface", NULL, ELDBUS_ARGS({"a("SIGNATURE_SUBSURFACE")", "array of ec"}), _e_info_server_cb_subsurface, 0 },
7577    { "dump_wins", ELDBUS_ARGS({SIGNATURE_DUMP_WINS, "directory"}), ELDBUS_ARGS({"s", "result of dump"}), _e_info_server_cb_wins_dump, 0 },
7578    { "set_force_visible", ELDBUS_ARGS({SIGNATURE_FORCE_VISIBLE_CLIENT, "obj"}), ELDBUS_ARGS({SIGNATURE_FORCE_VISIBLE_SERVER, "msg"}), _e_info_server_cb_force_visible, 0 },
7579    { "eina_log_levels", ELDBUS_ARGS({"s", "eina log levels"}), NULL, _e_info_server_cb_eina_log_levels, 0 },
7580    { "eina_log_path", ELDBUS_ARGS({"s", "eina log path"}), NULL, _e_info_server_cb_eina_log_path, 0 },
7581 #ifdef HAVE_DLOG
7582    { "dlog", ELDBUS_ARGS({"i", "using dlog"}), NULL, _e_info_server_cb_dlog_switch, 0},
7583 #endif
7584    { "get_window_prop", ELDBUS_ARGS({"usss", "prop_manage_request"}), ELDBUS_ARGS({"a(ss)", "array_of_ec"}), _e_info_server_cb_window_prop_get, 0},
7585    { "get_connected_clients", NULL, ELDBUS_ARGS({"a(ss)", "array of ec"}), _e_info_server_cb_connected_clients_get, 0 },
7586    { "rotation_query", ELDBUS_ARGS({"i", "query_rotation"}), NULL, _e_info_server_cb_rotation_query, 0},
7587    { "rotation_message", ELDBUS_ARGS({"iii", "rotation_message"}), NULL, _e_info_server_cb_rotation_message, 0},
7588    { "get_res_lists", ELDBUS_ARGS({VALUE_TYPE_REQUEST_RESLIST, "client resource"}), ELDBUS_ARGS({"a("VALUE_TYPE_REPLY_RESLIST")", "array of client resources"}), _e_info_server_cb_res_lists_get, 0 },
7589    { "get_input_devices", NULL, ELDBUS_ARGS({"a("VALUE_TYPE_FOR_INPUTDEV")", "array of input"}), _e_info_server_cb_input_device_info_get, 0},
7590    { "protocol_trace", ELDBUS_ARGS({"s", "protocol_trace"}), NULL, _e_info_server_cb_protocol_trace, 0},
7591    { "protocol_rule", ELDBUS_ARGS({"sss", "protocol_rule"}), ELDBUS_ARGS({"s", "rule request"}), _e_info_server_cb_protocol_rule, 0},
7592    { "bgcolor_set", ELDBUS_ARGS({"iiii", "bgcolor_set"}), NULL, _e_info_server_cb_bgcolor_set, 0},
7593    { "punch", ELDBUS_ARGS({"iiiiiiiii", "punch_geometry"}), NULL, _e_info_server_cb_punch, 0},
7594    { "transform_message", ELDBUS_ARGS({"siiiiiiiis", "transform_message"}), NULL, e_info_server_cb_transform_message, 0},
7595    { "dump_buffers", ELDBUS_ARGS({"iisdis", "dump_buffers"}), ELDBUS_ARGS({"is", "dump_buffers reply"}), _e_info_server_cb_buffer_dump, 0 },
7596    { "dump_selected_buffers", ELDBUS_ARGS({"ss", "dump_selected_buffers"}), ELDBUS_ARGS({"s", "result of dump"}), _e_info_server_cb_selected_buffer_dump, 0 },
7597    { "dump_screen", ELDBUS_ARGS({"s", "dump_screen"}), NULL, _e_info_server_cb_screen_dump, 0 },
7598    { "output_mode", ELDBUS_ARGS({SIGNATURE_OUTPUT_MODE_CLIENT, "output mode"}), ELDBUS_ARGS({"a("SIGNATURE_OUTPUT_MODE_SERVER")", "array of ec"}), _e_info_server_cb_output_mode, 0 },
7599    { "trace_message_hwc", ELDBUS_ARGS({"i", "trace_message_hwc"}), NULL, e_info_server_cb_hwc_trace_message, 0},
7600    { "trace_message_prstt", ELDBUS_ARGS({"i", "trace_message_presentation_time"}), NULL, e_info_server_cb_prstt_trace_message, 0},
7601    { "trace_message_exsync", ELDBUS_ARGS({"i", "trace_message_ex_sync"}), NULL, e_info_server_cb_exsync_trace_message, 0},
7602    { "trace_message_damage", ELDBUS_ARGS({"i", "trace_message_damage"}), NULL, e_info_server_cb_damage_trace_message, 0},
7603    { "hwc", ELDBUS_ARGS({"i", "hwc"}), NULL, e_info_server_cb_hwc, 0},
7604    { "show_plane_state", NULL, NULL, e_info_server_cb_show_plane_state, 0},
7605    { "show_pending_commit", NULL, ELDBUS_ARGS({"a("VALUE_TYPE_FOR_PENDING_COMMIT")", "array of pending commit"}), e_info_server_cb_show_pending_commit, 0},
7606    { "get_fps_info", ELDBUS_ARGS({"s", "fps request"}), ELDBUS_ARGS({"a("VALUE_TYPE_FOR_FPS")", "array of fps"}), _e_info_server_cb_fps_info_get, 0},
7607    { "get_keymap", NULL, ELDBUS_ARGS({"hi", "keymap fd"}), _e_info_server_cb_keymap_info_get, 0},
7608    { "effect_control", ELDBUS_ARGS({"i", "effect_control"}), NULL, e_info_server_cb_effect_control, 0},
7609    { "quickpanel_control", ELDBUS_ARGS({"i", "operation"}, {"s","window id" }), NULL, e_info_server_cb_quickpanel_control, 0},
7610    { "get_keygrab_status", ELDBUS_ARGS({"s", "get_keygrab_status"}), NULL, _e_info_server_cb_keygrab_status_get, 0},
7611    { "get_module_info", ELDBUS_ARGS({"ss", "get_module_info"}), NULL, _e_info_server_cb_module_info_get, 0},
7612    { "aux_msg", ELDBUS_ARGS({"s","window id" }, {"s", "key"}, {"s", "value"}, {"as", "options"}), NULL, e_info_server_cb_aux_message, 0},
7613    { "aux_hint_add", ELDBUS_ARGS({"s","window id" }, {"u", "hint id"}, {"s", "hint"}, {"s", "value"}), NULL, e_info_server_cb_aux_hint_add, 0},
7614    { "aux_hint_del", ELDBUS_ARGS({"s","window id" }, {"u", "hint id"}), NULL, e_info_server_cb_aux_hint_del, 0},
7615    { "scrsaver", ELDBUS_ARGS({SIGNATURE_SCRSAVER_CLIENT, "scrsaver_params"}), ELDBUS_ARGS({SIGNATURE_SCRSAVER_SERVER, "scrsaver_result"}), _e_info_server_cb_scrsaver, 0},
7616    { "desktop_geometry_set", ELDBUS_ARGS({"iiii", "Geometry"}), NULL, _e_info_server_cb_desktop_geometry_set, 0},
7617    { "desktop_window_control", ELDBUS_ARGS({"i", "Window Control option"}), NULL, _e_info_server_cb_desktop_window_control, 0},
7618    { "desk_zoom", ELDBUS_ARGS({"ddii", "Zoom"}), NULL, _e_info_server_cb_desk_zoom, 0},
7619    { "desk_area_info", NULL, NULL, _e_info_server_cb_desk_area_info, 0},
7620    { "desk_area_enable", ELDBUS_ARGS({"i", "enable"}), NULL, _e_info_server_cb_desk_area_enable, 0},
7621    { "desk_area_new_sub1", ELDBUS_ARGS({"iiiii", "geometry"}), NULL, _e_info_server_cb_desk_area_new_sub1, 0},
7622    { "desk_area_new_sub2", ELDBUS_ARGS({"iiiii", "geometry"}), NULL, _e_info_server_cb_desk_area_new_sub2, 0},
7623    { "desk_area_remove_sub", ELDBUS_ARGS({"i", "sub_id"}), NULL, _e_info_server_cb_desk_area_remove_sub, 0},
7624    { "desk_area_base_raise", ELDBUS_ARGS({"i", "raise"}), NULL, _e_info_server_cb_desk_area_base_raise, 0},
7625    { "desk_area_sub1_raise", ELDBUS_ARGS({"i", "raise"}), NULL, _e_info_server_cb_desk_area_sub1_raise, 0},
7626    { "desk_area_sub2_raise", ELDBUS_ARGS({"i", "raise"}), NULL, _e_info_server_cb_desk_area_sub2_raise, 0},
7627    { "desk_area_check_stack", NULL, NULL, _e_info_server_cb_desk_area_check_stack, 0},
7628    { "frender", ELDBUS_ARGS({"i", "frender"}), ELDBUS_ARGS({"s", "force_render_result"}), _e_info_server_cb_force_render, 0},
7629    { "screen_rotation_pre", ELDBUS_ARGS({"i", "value"}), NULL, _e_info_server_cb_screen_rotation_pre, 0},
7630    { "screen_rotation", ELDBUS_ARGS({"i", "value"}), NULL, _e_info_server_cb_screen_rotation, 0},
7631    { "remote_surface", ELDBUS_ARGS({"ii", "remote surface query"}), ELDBUS_ARGS({"as", "remote surfac information"}), _e_info_server_cb_remote_surface, 0},
7632    { "get_win_under_touch", NULL, ELDBUS_ARGS({"i", "result"}), _e_info_server_cb_get_win_under_touch, 0 },
7633    { "kill_client", ELDBUS_ARGS({VALUE_TYPE_REQUEST_FOR_KILL, "window"}), ELDBUS_ARGS({"a"VALUE_TYPE_REPLY_KILL, "kill result"}), _e_info_server_cb_kill_client, 0 },
7634    { "get_window_name", ELDBUS_ARGS({"t", "window"}), ELDBUS_ARGS({"s", "window name"}), _e_info_server_cb_get_window_name, 0 },
7635    { "get_windows", ELDBUS_ARGS({"is", "mode, value"}), ELDBUS_ARGS({"at", "array_of_windows"}), _e_info_server_cb_get_windows, 0 },
7636    { "wininfo", ELDBUS_ARGS({VALUE_TYPE_REQUEST_FOR_WININFO, "window"}), ELDBUS_ARGS({VALUE_TYPE_REPLY_WININFO, "window info"}), _e_info_server_cb_wininfo, 0 },
7637    { "wininfo_tree", ELDBUS_ARGS({VALUE_TYPE_REQUEST_FOR_WININFO_TREE, "wininfo_tree"}), ELDBUS_ARGS({VALUE_TYPE_REPLY_WININFO_TREE, "window tree info"}), _e_info_server_cb_wininfo_tree, 0 },
7638    { "wininfo_hints", ELDBUS_ARGS({"it", "mode, window"}), ELDBUS_ARGS({"as", "window hints"}), _e_info_server_cb_wininfo_hints, 0 },
7639    { "wininfo_shape", ELDBUS_ARGS({"t", "window"}), ELDBUS_ARGS({"ia(iiii)ia(iiii)", "window shape"}), _e_info_server_cb_wininfo_shape, 0 },
7640    { "get_version", NULL, ELDBUS_ARGS({"ss", "version of E20"}), _e_info_server_cb_version_get, 0 },
7641    { "module_list_get", NULL, ELDBUS_ARGS({"ia(si)", "module list"}), _e_info_server_cb_module_list_get, 0 },
7642    { "module_load", ELDBUS_ARGS({"s", "target module"}), ELDBUS_ARGS({"s", "load result"}), _e_info_server_cb_module_load, 0 },
7643    { "module_unload", ELDBUS_ARGS({"s", "target module"}), ELDBUS_ARGS({"s", "unload result"}), _e_info_server_cb_module_unload, 0 },
7644    { "shutdown", NULL, ELDBUS_ARGS({"s", "shutdown result"}), _e_info_server_cb_shutdown, 0 },
7645    { "buffer_flush", ELDBUS_ARGS({"it", "option"}), ELDBUS_ARGS({"s", "buffer_flush status"}), _e_info_server_cb_buffer_flush, 0},
7646    { "deiconify_approve", ELDBUS_ARGS({"it", "option"}), ELDBUS_ARGS({"s", "deiconify_approve status"}), _e_info_server_cb_deiconify_approve, 0},
7647    { "key_repeat", ELDBUS_ARGS({"sii", "option"}), NULL, _e_info_server_cb_key_repeat, 0},
7648    { "mtrace", ELDBUS_ARGS({"i", "enable"}), NULL, _e_info_server_cb_mtrace, 0},
7649    { "dump_memchecker", NULL, NULL, _e_info_server_cb_memchecker, 0},
7650    { "magnifier", ELDBUS_ARGS({"i", "magnifier"}), NULL, e_info_server_cb_magnifier, 0},
7651    { "input_region", ELDBUS_ARGS({"siiii", "options"}), ELDBUS_ARGS({"a(iiii)", "path"}), _e_info_server_cb_input_region, 0},
7652    { "hwc_wins", ELDBUS_ARGS({"i", "option"}), ELDBUS_ARGS({"as", "hwc wins info"}), _e_info_server_cb_hwc_wins_info_get, 0 },
7653    { "screen_info", ELDBUS_ARGS({"i", "option"}), ELDBUS_ARGS({"as", "screen info"}), _e_info_server_cb_screen_info_get, 0 },
7654    { "focus_policy_ext_set", ELDBUS_ARGS({"i", "option"}), ELDBUS_ARGS({"bi", "isChanged and result"}), _e_info_server_cb_focus_policy_ext_set, 0 },
7655    { "focus_history", NULL, ELDBUS_ARGS({"a(ubbbs)", "history array"}), _e_info_server_cb_focus_history, 0 },
7656    { "init_device", ELDBUS_ARGS({"us", "device information"}), ELDBUS_ARGS({"s", "result message"}), _e_info_server_cb_init_device, 0},
7657    { "deinit_device", NULL, NULL, _e_info_server_cb_deinit_device, 0},
7658    { "keygen", ELDBUS_ARGS({"sii", "key information"}), ELDBUS_ARGS({"s", "result message"}), _e_info_server_cb_keygen, 0},
7659    { "touchgen", ELDBUS_ARGS({"iiii", "touch information"}), ELDBUS_ARGS({"s", "result message"}), _e_info_server_cb_touchgen, 0},
7660    { "mousegen", ELDBUS_ARGS({"iiii", "mouse information"}), ELDBUS_ARGS({"s", "result message"}), _e_info_server_cb_mousegen, 0},
7661    { "mouse_accel", ELDBUS_ARGS({"i", "set mouse acceleration"}), ELDBUS_ARGS({"s", "result message"}), _e_info_server_cb_mouse_accel, 0},
7662    { "input_log_enable", ELDBUS_ARGS({"i", "set input log enable"}), ELDBUS_ARGS({"s", "result message"}), _e_info_server_cb_input_log_enable, 0},
7663    { "use_cursor_timer", ELDBUS_ARGS({"i", "set use_cursor_timer enable"}), ELDBUS_ARGS({"s", "result message"}), _e_info_server_cb_use_cursor_timer, 0},
7664    { "filter", ELDBUS_ARGS({"sis", "win_id, on(1)/off(0), filter name"}), ELDBUS_ARGS({"s", "result of request"}), _e_info_server_cb_filter, 0},
7665    { "gcov", ELDBUS_ARGS({"i", "option"}), NULL, _e_info_server_cb_gcov, 0},
7666    { "basic_op_gen", ELDBUS_ARGS({"s","window id" }, {"s", "operation"}), NULL, _e_info_server_cb_basic_operation_generate, 0},
7667    { "process_info", NULL, ELDBUS_ARGS({"s", "process information"}), _e_info_server_cb_process_info, 0 },
7668    { "zone_set", ELDBUS_ARGS({"si", "zone set"}), NULL, _e_info_server_cb_zone_set, 0 },
7669    { "input_output_set", ELDBUS_ARGS({"ss", "set input device's output name"}), NULL, _e_info_server_cb_input_output_set, 0 },
7670    { "input_seat_set", ELDBUS_ARGS({"ss", "set input device's seat"}), NULL, _e_info_server_cb_input_seat_set, 0 },
7671    { "resize_ppu_set", ELDBUS_ARGS({"si", "set resize ppu"}), NULL, e_info_server_cb_resize_ppu_set, 0},
7672    { "prop_set", ELDBUS_ARGS({"s","window id" }, {"s", "property"}, {"i", "set value"}), NULL, _e_info_server_cb_prop_set, 0},
7673    { "input_subtype_set", ELDBUS_ARGS({"ss", "set input device's subtype(subclas)"}), ELDBUS_ARGS({"s", "result message"}), _e_info_server_cb_input_subtype_set, 0 },
7674    { "kvm_transparent", ELDBUS_ARGS({"i", "set kvm service window to transparent"}), NULL, _e_info_server_cb_kvm_transparent_set, 0 },
7675    { NULL, NULL, NULL, NULL, 0 }
7676 };
7677
7678 static const Eldbus_Signal signals[] = {
7679    [E_INFO_SERVER_SIGNAL_WIN_UNDER_TOUCH] = {"win_under_touch", ELDBUS_ARGS({ "t", "win_under_touch" }), 0},
7680    { }
7681 };
7682
7683 static const Eldbus_Service_Interface_Desc iface_desc = {
7684      IFACE, methods, signals, NULL, NULL, NULL
7685 };
7686
7687 Eina_Bool
7688 e_info_server_protocol_rule_path_init(char *rule_path)
7689 {
7690     char reply[4096];
7691     int len = sizeof (reply);
7692     char *argv[2];
7693     int argc = 2;
7694
7695     if (!rule_path || strlen(rule_path) <= 0)
7696         return EINA_FALSE;
7697
7698     argv[0] = "file";
7699     argv[1] = rule_path;
7700
7701     e_info_protocol_rule_set(argc, (const char**)&(argv[0]), reply, &len);
7702
7703     INF("%s: rule_path : %s\n", __func__, rule_path);
7704     INF("%s\n", reply);
7705
7706     return EINA_TRUE;
7707 }
7708
7709 Eina_Bool
7710 e_info_server_protocol_trace_path_init(char *trace_path)
7711 {
7712    if (!trace_path || strlen(trace_path) <= 0)
7713      return EINA_FALSE;
7714
7715    INF("%s: trace_path : %s\n", __func__, trace_path);
7716
7717    log_fp_ptrace = fopen(trace_path, "a");
7718
7719    if (!log_fp_ptrace)
7720      {
7721         ERR("failed: open file(%s)\n", trace_path);
7722         return EINA_FALSE;
7723      }
7724
7725    setvbuf(log_fp_ptrace, NULL, _IOLBF, 512);
7726    if (e_info_protocol_logger)
7727      {
7728         wl_protocol_logger_destroy(e_info_protocol_logger);
7729         e_info_protocol_logger = NULL;
7730      }
7731
7732    e_info_protocol_logger = wl_display_add_protocol_logger(e_comp->wl_comp_data->wl.disp, _e_info_server_protocol_debug_func2, NULL);
7733
7734    return EINA_TRUE;
7735 }
7736
7737 static Eina_Bool
7738 _e_info_server_dbus_init(void *data EINA_UNUSED)
7739 {
7740    char *s = NULL;
7741
7742    e_info_server.iface = eldbus_service_interface_register(e_info_server.edbus_conn,
7743                                                            PATH,
7744                                                            &iface_desc);
7745    EINA_SAFETY_ON_NULL_GOTO(e_info_server.iface, err);
7746
7747    E_EVENT_INFO_ROTATION_MESSAGE = ecore_event_type_new();
7748
7749    e_info_protocol_init();
7750
7751    s = e_util_env_get("E_INFO_RULE_FILE");
7752    e_info_server_protocol_rule_path_init(s);
7753    E_FREE(s);
7754
7755    s = e_util_env_get("E_INFO_TRACE_FILE");
7756    e_info_server_protocol_trace_path_init(s);
7757    E_FREE(s);
7758
7759    e_main_hook_call(E_MAIN_HOOK_E_INFO_READY);
7760
7761    return ECORE_CALLBACK_CANCEL;
7762
7763 err:
7764    e_info_server_shutdown();
7765
7766    return ECORE_CALLBACK_CANCEL;
7767 }
7768
7769 static Eina_Bool
7770 _e_info_server_cb_dbus_init_done(void *data, int type, void *event)
7771 {
7772    E_DBus_Conn_Init_Done_Event *e = event;
7773
7774    if (e->status == E_DBUS_CONN_INIT_SUCCESS && e->conn_type == e_info_server.edbus_conn_type)
7775      {
7776         e_info_server.edbus_conn = e_dbus_conn_connection_ref(e_info_server.edbus_conn_type);
7777
7778         if (e_info_server.edbus_conn)
7779           _e_info_server_dbus_init(NULL);
7780      }
7781
7782    ecore_event_handler_del(e_info_server.dbus_init_done_handler);
7783    e_info_server.dbus_init_done_handler = NULL;
7784
7785    return ECORE_CALLBACK_PASS_ON;
7786 }
7787
7788
7789 EINTERN int
7790 e_info_server_init(void)
7791 {
7792    char *s;
7793    s = e_util_env_get("MALLOC_TRACE");
7794
7795    if (s)
7796      E_FREE(s);
7797    else
7798      e_util_env_set("MALLOC_TRACE", "/tmp/e20_mtrace");
7799
7800    e_info_server.edbus_conn = NULL;
7801    e_info_server.edbus_conn_type = ELDBUS_CONNECTION_TYPE_SYSTEM;
7802    e_info_server.dbus_init_done_handler = NULL;
7803
7804    if (e_dbus_conn_init() > 0)
7805      {
7806         e_info_server.dbus_init_done_handler = ecore_event_handler_add(E_EVENT_DBUS_CONN_INIT_DONE, _e_info_server_cb_dbus_init_done, NULL);
7807         e_dbus_conn_dbus_init(e_info_server.edbus_conn_type);
7808      }
7809
7810    return 1;
7811 }
7812
7813 EINTERN int
7814 e_info_server_shutdown(void)
7815 {
7816    if (e_info_server.dbus_init_done_handler)
7817      {
7818          ecore_event_handler_del(e_info_server.dbus_init_done_handler);
7819          e_info_server.dbus_init_done_handler = NULL;
7820      }
7821
7822    if (e_info_server.iface)
7823      {
7824         eldbus_service_interface_unregister(e_info_server.iface);
7825         e_info_server.iface = NULL;
7826      }
7827
7828    if (e_info_server.edbus_conn)
7829      {
7830         eldbus_name_release(e_info_server.edbus_conn, BUS, NULL, NULL);
7831         e_dbus_conn_connection_unref(e_info_server.edbus_conn);
7832         e_info_server.edbus_conn = NULL;
7833      }
7834
7835    e_dbus_conn_shutdown();
7836
7837    if (e_info_transform_list)
7838      {
7839         E_Info_Transform *info;
7840         Eina_List *l, *l_next;
7841
7842         EINA_LIST_FOREACH_SAFE(e_info_transform_list, l, l_next, info)
7843           {
7844              _e_info_transform_del(info);
7845           }
7846
7847         eina_list_free(e_info_transform_list);
7848         e_info_transform_list = NULL;
7849      }
7850
7851    if (e_info_dump_running == 1)
7852      {
7853         tdm_helper_dump_stop();
7854         tbm_surface_internal_dump_end();
7855      }
7856    if (e_info_dump_hdlrs)
7857      {
7858         E_FREE_LIST(e_info_dump_hdlrs, ecore_event_handler_del);
7859         e_info_dump_hdlrs = NULL;
7860      }
7861    if (e_info_dump_path)
7862      {
7863         free(e_info_dump_path);
7864         e_info_dump_path = NULL;
7865      }
7866    e_info_dump_count = 0;
7867    e_info_dump_running = 0;
7868
7869    if (module_hook) _e_info_server_module_hook_cleanup();
7870
7871    e_info_protocol_shutdown();
7872
7873    return 1;
7874 }
7875
7876 EINTERN void
7877 e_info_server_dump_client(E_Client *ec, char *fname)
7878 {
7879    void *data = NULL;
7880    int w = 0, h = 0;
7881    Ecore_Evas *ee = NULL;
7882    Evas_Object *img = NULL;
7883    int res;
7884
7885    if (!ec) return;
7886    if (e_client_util_ignored_get(ec)) return;
7887
7888    struct wl_shm_buffer *shmbuffer = NULL;
7889    E_Comp_Wl_Buffer *buffer = e_pixmap_resource_get(ec->pixmap);
7890    if (!buffer) return;
7891
7892    if (buffer->type == E_COMP_WL_BUFFER_TYPE_SHM)
7893      {
7894         shmbuffer = wl_shm_buffer_get(buffer->resource);
7895         if (shmbuffer)
7896           {
7897              data = wl_shm_buffer_get_data(shmbuffer);
7898              w = wl_shm_buffer_get_stride(shmbuffer) / 4;
7899              h = wl_shm_buffer_get_height(shmbuffer);
7900           }
7901      }
7902    else if (buffer->type == E_COMP_WL_BUFFER_TYPE_NATIVE)
7903      {
7904         tbm_surface_info_s surface_info;
7905         tbm_surface_h tbm_surface = wayland_tbm_server_get_surface(NULL, buffer->resource);
7906
7907         EINA_SAFETY_ON_NULL_RETURN(tbm_surface);
7908         memset(&surface_info, 0, sizeof(tbm_surface_info_s));
7909         res = tbm_surface_map(tbm_surface, TBM_SURF_OPTION_READ, &surface_info);
7910         if (res != TBM_SURFACE_ERROR_NONE)
7911           return;
7912
7913         data = surface_info.planes[0].ptr;
7914         w = surface_info.planes[0].stride / 4;
7915         h = surface_info.height;
7916      }
7917    else if (buffer->type == E_COMP_WL_BUFFER_TYPE_TBM)
7918      {
7919         tbm_surface_info_s surface_info;
7920         tbm_surface_h tbm_surface = buffer->tbm_surface;
7921
7922         EINA_SAFETY_ON_NULL_RETURN(tbm_surface);
7923         memset(&surface_info, 0, sizeof(tbm_surface_info_s));
7924         res = tbm_surface_map(tbm_surface, TBM_SURF_OPTION_READ, &surface_info);
7925         if (res != TBM_SURFACE_ERROR_NONE)
7926           return;
7927
7928         data = surface_info.planes[0].ptr;
7929         w = surface_info.planes[0].stride / 4;
7930         h = surface_info.height;
7931      }
7932    else
7933      {
7934         ERR("Invalid resource:%u", wl_resource_get_id(buffer->resource));
7935      }
7936
7937    EINA_SAFETY_ON_NULL_GOTO(data, err);
7938
7939    ee = ecore_evas_buffer_new(1, 1);
7940    EINA_SAFETY_ON_NULL_GOTO(ee, err);
7941
7942    img = evas_object_image_add(ecore_evas_get(ee));
7943    EINA_SAFETY_ON_NULL_GOTO(img, err);
7944
7945    evas_object_image_alpha_set(img, EINA_TRUE);
7946    evas_object_image_size_set(img, w, h);
7947    evas_object_image_data_set(img, data);
7948
7949    if (!evas_object_image_save(img, fname, NULL, "compress=1 quality=100"))
7950      ERR("Cannot save window to '%s'", fname);
7951
7952 err:
7953    if (data)
7954      {
7955         if (buffer->type == E_COMP_WL_BUFFER_TYPE_NATIVE)
7956           {
7957              tbm_surface_h tbm_surface = wayland_tbm_server_get_surface(NULL, buffer->resource);
7958              tbm_surface_unmap(tbm_surface);
7959           }
7960         else if (buffer->type == E_COMP_WL_BUFFER_TYPE_TBM)
7961           {
7962              tbm_surface_h tbm_surface = buffer->tbm_surface;
7963              tbm_surface_unmap(tbm_surface);
7964           }
7965      }
7966
7967    if (img) evas_object_del(img);
7968    if (ee) ecore_evas_free(ee);
7969 }
7970
7971
7972 static E_Info_Transform*
7973 _e_info_transform_new(E_Client *ec, int id, int enable, int x, int y, int sx, int sy, int degree, int background, const char *role)
7974 {
7975    E_Info_Transform *result = NULL;
7976    result = _e_info_transform_find(ec, id);
7977
7978    if (!result)
7979      {
7980         result = (E_Info_Transform*)malloc(sizeof(E_Info_Transform));
7981         EINA_SAFETY_ON_NULL_RETURN_VAL(result, NULL);
7982         memset(result, 0, sizeof(E_Info_Transform));
7983         result->id = id;
7984         result->ec = ec;
7985         result->transform = e_util_transform_new();
7986         e_util_transform_role_set(result->transform, role);
7987         result->background = background;
7988         result->enable = 0;
7989         _e_info_transform_set(result, enable, x, y, sx, sy, degree);
7990         e_info_transform_list = eina_list_append(e_info_transform_list, result);
7991      }
7992
7993    return result;
7994 }
7995
7996 static E_Info_Transform*
7997 _e_info_transform_find(E_Client *ec, int id)
7998 {
7999    Eina_List *l;
8000    E_Info_Transform *transform;
8001    E_Info_Transform *result = NULL;
8002
8003    EINA_LIST_FOREACH(e_info_transform_list, l, transform)
8004      {
8005         if (transform->ec == ec && transform->id == id)
8006           {
8007              result =  transform;
8008              break;
8009           }
8010      }
8011
8012    return result;
8013 }
8014
8015 static void
8016 _e_info_transform_set(E_Info_Transform *transform, int enable, int x, int y, int sx, int sy, int degree)
8017 {
8018    if (!transform) return;
8019    if (!transform->transform) return;
8020
8021    if (transform->background)
8022      {
8023         e_util_transform_bg_move(transform->transform, (double)x, (double)y, 0.0);
8024         e_util_transform_bg_scale(transform->transform, (double)sx / 100.0, (double)sy / 100.0, 1.0);
8025         e_util_transform_bg_rotation(transform->transform, 0.0, 0.0, degree);
8026      }
8027    else
8028      {
8029         e_util_transform_move(transform->transform, (double)x, (double)y, 0.0);
8030         e_util_transform_scale(transform->transform, (double)sx / 100.0, (double)sy / 100.0, 1.0);
8031         e_util_transform_rotation(transform->transform, 0.0, 0.0, degree);
8032      }
8033
8034    if (enable != transform->enable)
8035      {
8036         if (enable)
8037           e_client_transform_core_add(transform->ec, transform->transform);
8038         else
8039           e_client_transform_core_remove(transform->ec, transform->transform);
8040
8041         transform->enable = enable;
8042      }
8043
8044    e_client_transform_core_update(transform->ec);
8045 }
8046
8047 static void
8048 _e_info_transform_del(E_Info_Transform *transform)
8049 {
8050    if (!transform) return;
8051
8052    e_info_transform_list = eina_list_remove(e_info_transform_list, transform);
8053
8054    if (transform->enable)
8055      {
8056         e_client_transform_core_remove(transform->ec, transform->transform);
8057      }
8058
8059    e_util_transform_del(transform->transform);
8060    free(transform);
8061 }
8062
8063 static void
8064 _e_info_transform_del_with_id(E_Client *ec, int id)
8065 {
8066    E_Info_Transform *transform = NULL;
8067    if (!ec) return;
8068
8069    transform = _e_info_transform_find(ec, id);
8070
8071    if (transform)
8072       _e_info_transform_del(transform);
8073 }