e_input: make an internal header
[platform/upstream/enlightenment.git] / src / bin / e_comp_screen.c
1 #include "e.h"
2 #include "e_client_intern.h"
3 #include "e_utils_intern.h"
4 #include "e_scale_intern.h"
5 #include "e_comp_canvas_intern.h"
6 #include "e_comp_screen_intern.h"
7 #include "e_comp_wl_input_intern.h"
8 #include "e_comp_wl_intern.h"
9 #include "e_explicit_sync_intern.h"
10 #include "e_comp_wl_tizen_hwc_intern.h"
11 #include "e_comp_intern.h"
12 #include "e_input_intern.h"
13
14 #include "Eeze.h"
15 #include <tizen-extension-server-protocol.h>
16 #include <device/board-internal.h>
17 #include <tbm_drm_helper.h>
18 #include <gbm.h>
19
20 #define PATH "/org/enlightenment/wm"
21 #define IFACE "org.enlightenment.wm.screen_rotation"
22
23 static Ecore_Event_Handler *dbus_init_done_handler;
24 static Eldbus_Connection *edbus_conn = NULL;
25 static Eldbus_Connection_Type edbus_conn_type = ELDBUS_CONNECTION_TYPE_SYSTEM;
26 static Eldbus_Service_Interface *e_comp_screen_iface;
27
28 static Eina_List *event_handlers = NULL;
29 static Eina_List *output_hooks = NULL;
30
31 static Eina_Bool dont_set_e_input_keymap = EINA_FALSE;
32 static Eina_Bool dont_use_xkb_cache = EINA_FALSE;
33
34 EINTERN int E_EVENT_SCREEN_CHANGE = 0;
35
36 enum
37 {
38    E_COMP_SCREEN_SIGNAL_ROTATION_CHANGED = 0
39 };
40
41 typedef struct _E_Comp_Screen_Tzsr
42 {
43    struct wl_resource *resource; /* tizen_screen_rotation */
44    E_Client           *ec;
45    struct wl_listener ec_destroy;
46 } E_Comp_Screen_Tzsr;
47
48 static Eina_List *tzsr_list;
49 static E_Client_Hook *tzsr_client_hook_del;
50
51 static void _tz_screen_rotation_cb_ec_destroy(struct wl_listener *listener, void *data);
52
53 static E_Comp_Screen_Tzsr*
54 _tz_surface_rotation_find(E_Client *ec)
55 {
56    E_Comp_Screen_Tzsr *tzsr = NULL;
57    struct wl_listener *listener;
58
59    listener = e_client_destroy_listener_get(ec, _tz_screen_rotation_cb_ec_destroy);
60    if (listener)
61      return wl_container_of(listener, tzsr, ec_destroy);
62
63    return tzsr;
64 }
65
66 static void
67 _tz_surface_rotation_free(E_Comp_Screen_Tzsr *tzsr)
68 {
69    ELOGF("TRANSFORM", "|tzsr(%p) freed", tzsr->ec, tzsr);
70    tzsr_list = eina_list_remove(tzsr_list, tzsr);
71    wl_list_remove(&tzsr->ec_destroy.link);
72    free(tzsr);
73 }
74
75 static void
76 _tz_screen_rotation_cb_ec_destroy(struct wl_listener *listener, void *data)
77 {
78    E_Comp_Screen_Tzsr *tzsr;
79
80    tzsr = wl_container_of(listener, tzsr, ec_destroy);
81    _tz_surface_rotation_free(tzsr);
82 }
83
84 static void
85 _tz_screen_rotation_get_ignore_output_transform(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface)
86 {
87    E_Comp_Screen_Tzsr *tzsr;
88    E_Client *ec;
89    E_Hwc_Policy hwc_policy;
90    E_Output *output;
91    E_Zone *zone;
92    Eina_Bool ignore = EINA_TRUE;
93
94    ec = e_client_from_surface_resource(surface);
95    EINA_SAFETY_ON_NULL_RETURN(ec);
96
97    tzsr = _tz_surface_rotation_find(ec);
98    if (tzsr) return;
99
100    tzsr = E_NEW(E_Comp_Screen_Tzsr, 1);
101    if (!tzsr)
102      {
103         wl_client_post_no_memory(client);
104         return;
105      }
106
107    tzsr->resource = resource;
108    tzsr->ec = ec;
109
110    tzsr->ec_destroy.notify = _tz_screen_rotation_cb_ec_destroy;
111    e_client_destroy_listener_add(ec, &tzsr->ec_destroy);
112
113    tzsr_list = eina_list_append(tzsr_list, tzsr);
114
115    zone = e_comp_zone_find_by_ec(ec);
116    if (zone)
117      {
118         output = e_output_find(zone->output_id);
119         if (output)
120           {
121              hwc_policy = e_hwc_policy_get(output->hwc);
122              if (hwc_policy == E_HWC_POLICY_WINDOWS)
123                ignore = EINA_FALSE;
124           }
125      }
126
127    ELOGF("TRANSFORM", "|tzsr(%p) client_ignore(%d) ignore(%d)",
128          ec, tzsr, e_config->screen_rotation_client_ignore, ignore);
129
130    e_comp_screen_rotation_ignore_output_transform_send(ec, ignore);
131 }
132
133 static void
134 _tz_screen_rotation_iface_cb_destroy(struct wl_client *client, struct wl_resource *resource)
135 {
136    wl_resource_destroy(resource);
137 }
138
139 static const struct tizen_screen_rotation_interface _tz_screen_rotation_interface =
140 {
141    _tz_screen_rotation_get_ignore_output_transform,
142    _tz_screen_rotation_iface_cb_destroy,
143 };
144
145 static void _tz_screen_rotation_cb_destroy(struct wl_resource *resource)
146 {
147    E_Comp_Screen_Tzsr *tzsr;
148    Eina_List *l, *ll;
149
150    EINA_LIST_FOREACH_SAFE(tzsr_list, l, ll, tzsr)
151      {
152         if (tzsr->resource == resource)
153           _tz_surface_rotation_free(tzsr);
154      }
155 }
156
157 static void
158 _tz_screen_rotation_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
159 {
160    struct wl_resource *res;
161
162    if (!(res = wl_resource_create(client, &tizen_screen_rotation_interface, version, id)))
163      {
164         ERR("Could not create tizen_screen_rotation resource: %m");
165         wl_client_post_no_memory(client);
166         return;
167      }
168
169    wl_resource_set_implementation(res, &_tz_screen_rotation_interface, NULL, _tz_screen_rotation_cb_destroy);
170 }
171
172 static Eldbus_Message *
173 _e_comp_screen_dbus_get_cb(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
174 {
175    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
176    int rotation = 0;
177
178    if (e_comp && e_comp->e_comp_screen)
179      rotation = e_comp->e_comp_screen->rotation;
180
181    ELOGF("COMP_SCREEN","got screen-rotation 'get' request: %d", NULL, rotation);
182
183    eldbus_message_arguments_append(reply, "i", rotation);
184
185    return reply;
186 }
187
188 static const Eldbus_Method methods[] =
189 {
190    {"get", NULL, ELDBUS_ARGS({"i", "int32"}), _e_comp_screen_dbus_get_cb, 0},
191    {}
192 };
193
194 static const Eldbus_Signal signals[] = {
195    [E_COMP_SCREEN_SIGNAL_ROTATION_CHANGED] = {"changed", ELDBUS_ARGS({ "i", "rotation" }), 0},
196    {}
197 };
198
199 static const Eldbus_Service_Interface_Desc iface_desc = {
200      IFACE, methods, signals, NULL, NULL, NULL
201 };
202
203 static void
204 _e_comp_screen_dbus_init()
205 {
206    E_Comp_Screen *e_comp_screen = e_comp->e_comp_screen;
207
208    e_comp_screen_iface = eldbus_service_interface_register(edbus_conn,
209                                                            PATH,
210                                                            &iface_desc);
211    EINA_SAFETY_ON_NULL_GOTO(e_comp_screen_iface, err);
212
213    if (e_comp_screen->rotation)
214      {
215         eldbus_service_signal_emit(e_comp_screen_iface, E_COMP_SCREEN_SIGNAL_ROTATION_CHANGED, e_comp_screen->rotation);
216         ELOGF("TRANSFORM", "screen-rotation sends signal: %d", NULL, e_comp_screen->rotation);
217      }
218
219    return;
220
221 err:
222    if (edbus_conn)
223      {
224         e_dbus_conn_connection_unref(edbus_conn);
225         edbus_conn = NULL;
226      }
227
228    return;
229 }
230
231 static char *
232 _layer_cap_to_str(tdm_layer_capability caps, tdm_layer_capability cap)
233 {
234    if (caps & cap)
235      {
236         if (cap == TDM_LAYER_CAPABILITY_CURSOR) return "cursor ";
237         else if (cap == TDM_LAYER_CAPABILITY_PRIMARY) return "primary ";
238         else if (cap == TDM_LAYER_CAPABILITY_OVERLAY) return "overlay ";
239         else if (cap == TDM_LAYER_CAPABILITY_GRAPHIC) return "graphics ";
240         else if (cap == TDM_LAYER_CAPABILITY_VIDEO) return "video ";
241         else if (cap == TDM_LAYER_CAPABILITY_TRANSFORM) return "transform ";
242         else if (cap == TDM_LAYER_CAPABILITY_RESEVED_MEMORY) return "reserved_memory ";
243         else if (cap == TDM_LAYER_CAPABILITY_NO_CROP) return "no_crop ";
244         else return "unkown";
245      }
246    return "";
247 }
248
249 static Eina_Bool
250 _e_comp_screen_commit_idle_cb(void *data EINA_UNUSED)
251 {
252    Eina_List *l, *ll;
253    E_Comp_Screen *e_comp_screen = NULL;
254    E_Output *output = NULL;
255
256    if (!e_comp->e_comp_screen) goto end;
257
258    if (e_config->comp_canvas_norender.use)
259      evas_norender(e_comp->evas);
260
261    if (e_comp->canvas_render_delayed) goto end;
262
263    e_comp_screen = e_comp->e_comp_screen;
264
265    EINA_LIST_FOREACH_SAFE(e_comp_screen->outputs, l, ll, output)
266      {
267         if (!output) continue;
268         if (!output->config.enabled) continue;
269
270         if (!e_output_commit(output))
271              ERR("fail to commit e_comp_screen->outputs.");
272
273         if (!e_output_render(output))
274              ERR("fail to render e_comp_screen->outputs.");
275      }
276 end:
277    return ECORE_CALLBACK_RENEW;
278 }
279
280 static void
281 _e_comp_screen_input_rotation_set(int rotation)
282 {
283    if (rotation > 0)
284      {
285         const Eina_List *l;
286         E_Input_Device *dev;
287
288         EINA_LIST_FOREACH(e_input_devices_get(), l, dev)
289           {
290              e_input_device_touch_rotation_set(dev, rotation);
291              e_input_device_rotation_set(dev, rotation);
292
293              ELOGF("COMP_SCREEN","EE Input Device Rotate: %d", NULL, rotation);
294           }
295      }
296 }
297
298 static Eina_Bool
299 _e_comp_screen_cb_input_device_add(void *data, int type, void *event)
300 {
301    Ecore_Event_Device_Info *e;
302    E_Comp *comp = data;
303
304    if (!(e = event)) goto end;
305
306    if (e->clas == ECORE_DEVICE_CLASS_MOUSE)
307      {
308         if (comp->wl_comp_data->ptr.num_devices == 0)
309           {
310              e_pointer_object_set(comp->pointer, NULL, 0, 0);
311              e_comp_wl_input_pointer_enabled_set(EINA_TRUE);
312           }
313         comp->wl_comp_data->ptr.num_devices++;
314      }
315    else if (e->clas == ECORE_DEVICE_CLASS_KEYBOARD)
316      {
317         comp->wl_comp_data->kbd.num_devices++;
318         e_comp_wl_input_keyboard_enabled_set(EINA_TRUE);
319      }
320    else if (e->clas == ECORE_DEVICE_CLASS_TOUCH)
321      {
322         e_comp_wl_input_touch_enabled_set(EINA_TRUE);
323         _e_comp_screen_input_rotation_set(e_comp->e_comp_screen->rotation);
324         comp->wl_comp_data->touch.num_devices++;
325      }
326
327 end:
328    return ECORE_CALLBACK_PASS_ON;
329 }
330
331 static void
332 _e_comp_screen_pointer_renew(void)
333 {
334      if ((e_comp_wl->ptr.num_devices == 0) && e_comp_wl->ptr.ec && e_comp_wl->ptr.ec->pointer_enter_sent)
335      {
336         if (e_devicemgr->last_device_ptr)
337           {
338              Evas_Device *last_ptr = NULL, *dev;
339              Eina_List *list, *l;
340              const char *name;
341              const char *description;
342
343              list = (Eina_List *)evas_device_list(evas_object_evas_get(e_comp_wl->ptr.ec->frame), NULL);
344              EINA_LIST_FOREACH(list, l, dev)
345                {
346                   name = evas_device_name_get(dev);
347                   description = evas_device_description_get(dev);
348
349                   if (!name || !description) continue;
350                   if ((!strncmp(name, e_devicemgr->last_device_ptr->name, strlen(e_devicemgr->last_device_ptr->name))) &&
351                       (!strncmp(description, e_devicemgr->last_device_ptr->identifier, strlen(e_devicemgr->last_device_ptr->identifier))) &&
352                       (evas_device_class_get(dev) == (Evas_Device_Class)e_devicemgr->last_device_ptr->clas))
353                     {
354                        last_ptr = dev;
355                        break;
356                     }
357                }
358              if (last_ptr)
359                e_comp_wl_mouse_out_renew(e_comp_wl->ptr.ec, 0, wl_fixed_to_int(e_comp_wl->ptr.x), wl_fixed_to_int(e_comp_wl->ptr.y), NULL, NULL, NULL, ecore_time_get(), EVAS_EVENT_FLAG_NONE, last_ptr, NULL);
360           }
361      }
362 }
363
364 static Eina_Bool
365 _e_comp_screen_cb_input_device_del(void *data, int type, void *event)
366 {
367    Ecore_Event_Device_Info *e;
368    E_Comp *comp = data;
369
370    if (!(e = event)) goto end;
371
372    if (e->clas == ECORE_DEVICE_CLASS_MOUSE)
373      {
374         comp->wl_comp_data->ptr.num_devices--;
375         if (comp->wl_comp_data->ptr.num_devices == 0)
376           {
377              e_comp_wl_input_pointer_enabled_set(EINA_FALSE);
378              e_pointer_object_set(comp->pointer, NULL, 0, 0);
379              e_pointer_hide(e_comp->pointer);
380
381              _e_comp_screen_pointer_renew();
382           }
383      }
384    else if (e->clas == ECORE_DEVICE_CLASS_KEYBOARD)
385      {
386         comp->wl_comp_data->kbd.num_devices--;
387         if (comp->wl_comp_data->kbd.num_devices == 0)
388           {
389              e_comp_wl_input_keyboard_enabled_set(EINA_FALSE);
390           }
391      }
392    else if (e->clas == ECORE_DEVICE_CLASS_TOUCH)
393      {
394         comp->wl_comp_data->touch.num_devices--;
395         if (comp->wl_comp_data->touch.num_devices == 0)
396           {
397              e_comp_wl_input_touch_enabled_set(EINA_FALSE);
398           }
399      }
400
401 end:
402
403    return ECORE_CALLBACK_PASS_ON;
404 }
405
406 static Eina_Bool
407 _e_comp_screen_size_update(E_Comp_Screen *e_comp_screen)
408 {
409    E_Output *output;
410    int sum_w = 0, max_h = 0, output_w, output_h;
411    Eina_List *l;
412
413    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen, EINA_FALSE);
414
415    /* we place external output to the right of primary output */
416    EINA_LIST_FOREACH(e_comp_screen->outputs, l, output)
417      {
418         if (!e_output_connected(output)) continue;
419
420         e_output_size_get(output, &output_w, &output_h);
421         sum_w += output_w;
422
423         if (max_h < output_h)
424           max_h = output_h;
425      }
426
427    e_comp_screen->w = sum_w;
428    e_comp_screen->h = max_h;
429
430    if (e_comp->ee)
431      {
432         /* rotation should be reset because tbm_surface_queue or gbm_surface of
433          * ecore_evas is created without rotation
434          * and rotation of ecore_evas is reset after it is resized
435          */
436         if (e_comp_screen->rotation)
437           ecore_evas_rotation_with_resize_set(e_comp->ee, 0);
438
439         ecore_evas_resize(e_comp->ee, e_comp_screen->w, e_comp_screen->h);
440
441         if (e_comp_screen->rotation)
442           ecore_evas_rotation_with_resize_set(e_comp->ee, e_comp_screen->rotation);
443      }
444
445    return EINA_TRUE;
446 }
447
448 static Eina_Bool
449 _e_comp_screen_cb_event(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
450 {
451    E_Comp_Screen *e_comp_screen;
452    tdm_error ret;
453
454    if (!(e_comp_screen = data)) return ECORE_CALLBACK_RENEW;
455
456    ret = tdm_display_handle_events(e_comp_screen->tdisplay);
457    if (ret != TDM_ERROR_NONE)
458      ERR("tdm_display_handle_events failed");
459
460    return ECORE_CALLBACK_RENEW;
461 }
462
463 static E_Comp_Screen *
464 _e_comp_screen_new(E_Comp *comp)
465 {
466    E_Comp_Screen *e_comp_screen = NULL;
467    tdm_error error = TDM_ERROR_NONE;
468    tdm_display_capability capabilities;
469    const tbm_format *pp_formats;
470    int count, i;
471    int fd;
472
473    e_comp_screen = E_NEW(E_Comp_Screen, 1);
474    if (!e_comp_screen) return NULL;
475
476    /* tdm display init */
477    e_main_ts_begin("\tTDM Display Init");
478    e_comp_screen->tdisplay = tdm_display_init(&error);
479    if (!e_comp_screen->tdisplay)
480      {
481         e_main_ts_end("\tTDM Display Init Failed");
482         ERR("fail to get tdm_display\n");
483         free(e_comp_screen);
484         return NULL;
485      }
486    e_main_ts_end("\tTDM Display Init Done");
487
488    e_comp_screen->gdevice_fd = -1;
489    e_comp_screen->fd = -1;
490    tdm_display_get_fd(e_comp_screen->tdisplay, &fd);
491    if (fd < 0)
492      {
493         ERR("fail to get tdm_display fd\n");
494         goto fail;
495      }
496
497    e_comp_screen->fd = dup(fd);
498
499    e_comp_screen->hdlr =
500      ecore_main_fd_handler_add(e_comp_screen->fd, ECORE_FD_READ,
501                                _e_comp_screen_cb_event, e_comp_screen, NULL, NULL);
502    /* tdm display init */
503    e_main_ts_begin("\tTBM Bufmgr Server Init");
504    e_comp_screen->bufmgr = tbm_bufmgr_server_init();
505    if (!e_comp_screen->bufmgr)
506      {
507         e_main_ts_end("\tTBM Bufmgr Server Init Failed");
508         ERR("tbm_bufmgr_init failed\n");
509         goto fail;
510      }
511    e_main_ts_end("\tTBM Bufmgr Server Init Done");
512
513    error = tdm_display_get_capabilities(e_comp_screen->tdisplay, &capabilities);
514    if (error != TDM_ERROR_NONE)
515      {
516         ERR("tdm get_capabilities failed");
517         goto fail;
518      }
519
520    /* check the pp_support */
521    if (capabilities & TDM_DISPLAY_CAPABILITY_PP)
522      {
523         error = tdm_display_get_pp_available_formats(e_comp_screen->tdisplay, &pp_formats, &count);
524         if (error != TDM_ERROR_NONE)
525           ERR("fail to get available pp formats");
526         else
527           {
528              e_comp_screen->pp_enabled = EINA_TRUE;
529              for (i = 0 ; i < count ; i++)
530                e_comp_screen->available_pp_formats = eina_list_append(e_comp_screen->available_pp_formats, &pp_formats[i]);
531           }
532      }
533
534    e_main_ts_begin("\ttdm-socket Init");
535    if (e_comp_socket_init("tdm-socket"))
536      PRCTL("[Winsys] change permission and create sym link for %s", "tdm-socket");
537    e_main_ts_end("\ttdm-socket Init Done");
538
539    return e_comp_screen;
540
541 fail:
542    if (e_comp_screen->bufmgr) tbm_bufmgr_deinit(e_comp_screen->bufmgr);
543    if (e_comp_screen->fd >= 0) close(e_comp_screen->fd);
544    if (e_comp_screen->hdlr) ecore_main_fd_handler_del(e_comp_screen->hdlr);
545    if (e_comp_screen->tdisplay) tdm_display_deinit(e_comp_screen->tdisplay);
546
547    free(e_comp_screen);
548    TRACE_DS_END();
549
550    return NULL;
551 }
552
553 static void
554 _e_comp_screen_del(E_Comp_Screen *e_comp_screen)
555 {
556    Eina_List *l = NULL, *ll = NULL;
557    tbm_format *formats;
558
559    if (!e_comp_screen) return;
560
561    if (e_comp_screen->pp_enabled)
562      {
563         EINA_LIST_FOREACH_SAFE(e_comp_screen->available_pp_formats, l, ll, formats)
564           {
565              if (!formats) continue;
566              e_comp_screen->available_pp_formats = eina_list_remove(e_comp_screen->available_pp_formats, l);
567           }
568      }
569
570    if (e_comp_screen->gdevice) gbm_device_destroy(e_comp_screen->gdevice);
571    if (e_comp_screen->gdevice_fd >= 0) close(e_comp_screen->gdevice_fd);
572    if (e_comp_screen->bufmgr) tbm_bufmgr_deinit(e_comp_screen->bufmgr);
573    if (e_comp_screen->fd >= 0) close(e_comp_screen->fd);
574    if (e_comp_screen->hdlr) ecore_main_fd_handler_del(e_comp_screen->hdlr);
575    if (e_comp_screen->tdisplay) tdm_display_deinit(e_comp_screen->tdisplay);
576
577    free(e_comp_screen);
578 }
579
580 static void
581 _e_comp_screen_output_mode_change_cb(tdm_output *toutput, unsigned int index, void *user_data)
582 {
583    E_Comp_Screen *e_comp_screen = user_data;
584    E_Output *output = NULL;
585    Eina_Bool find = EINA_FALSE;
586    int count, num;
587    E_Output_Mode *set_emode = NULL, *current_emode = NULL;
588    E_Output_Mode *emode = NULL;
589    Eina_List *modelist = NULL, *l, *ll;
590
591    EINA_SAFETY_ON_NULL_RETURN(e_comp_screen);
592
593    EINA_LIST_FOREACH_SAFE(e_comp_screen->outputs, l, ll, output)
594      {
595         if (output->toutput == toutput)
596           {
597              find = EINA_TRUE;
598              break;
599           }
600      }
601    EINA_SAFETY_ON_FALSE_RETURN(find == EINA_TRUE);
602
603    current_emode = e_output_current_mode_get(output);
604    EINA_SAFETY_ON_NULL_RETURN(current_emode);
605
606    modelist = e_output_mode_list_get(output);
607    if (modelist)
608      {
609         num = eina_list_count(modelist);
610         EINA_SAFETY_ON_FALSE_RETURN(index < num);
611
612         count = 0;
613         EINA_LIST_FOREACH(modelist, l, emode)
614           {
615              if (count == index)
616                {
617                   set_emode = emode;
618                   break;
619                }
620              count++;
621           }
622
623         if (set_emode)
624           {
625              EINA_SAFETY_ON_TRUE_RETURN(current_emode == set_emode);
626
627              ELOGF("COMP_SCREEN","request mode change(%d) (%dx%d, %lf) -> (%dx%d, %lf)\n",
628                    NULL, index, current_emode->w, current_emode->h, current_emode->refresh,
629                    set_emode->w, set_emode->h, set_emode->refresh);
630
631              e_output_external_mode_change(output, set_emode);
632           }
633      }
634 }
635
636 static void
637 _e_comp_screen_output_destroy_cb(tdm_output *toutput, void *user_data)
638 {
639    E_Comp_Screen *e_comp_screen = user_data;
640    E_Output *output = NULL;
641    Eina_List *l, *ll;
642
643    EINA_SAFETY_ON_NULL_RETURN(e_comp_screen);
644
645    tdm_output_remove_destroy_handler(toutput, _e_comp_screen_output_destroy_cb, e_comp_screen);
646
647    EINA_LIST_FOREACH_SAFE(e_comp_screen->outputs, l, ll, output)
648      {
649         if (output->toutput == toutput)
650           {
651              e_comp_screen->num_outputs--;
652              e_comp_screen->outputs = eina_list_remove_list(e_comp_screen->outputs, l);
653              e_output_del(output);
654           }
655      }
656 }
657
658 static void
659 _e_comp_screen_output_create_cb(tdm_display *dpy, tdm_output *toutput, void *user_data)
660 {
661    E_Comp_Screen *e_comp_screen = user_data;
662    E_Output *output = NULL;
663    tdm_error ret = TDM_ERROR_NONE;
664
665    EINA_SAFETY_ON_NULL_RETURN(e_comp_screen);
666
667    TRACE_DS_BEGIN(OUTPUT:NEW);
668    output = e_output_new(e_comp_screen, e_comp_screen->num_outputs);
669    EINA_SAFETY_ON_NULL_GOTO(output, fail);
670    if (output->toutput != toutput) goto fail;
671    TRACE_DS_END();
672
673    TRACE_DS_BEGIN(OUTPUT:UPDATE);
674    if (!e_output_update(output))
675      {
676         ERR("fail to e_output_update.");
677         e_output_del(output);
678         goto fail;
679      }
680    TRACE_DS_END();
681
682    /* todo : add tdm_output_add_mode_change_request_handler()*/
683    ret = tdm_output_add_mode_change_request_handler(toutput, _e_comp_screen_output_mode_change_cb, e_comp_screen);
684    if (ret != TDM_ERROR_NONE)
685      {
686         ERR("fail to add output mode change handler.");
687         e_output_del(output);
688         return;
689      }
690
691    ret = tdm_output_add_destroy_handler(toutput, _e_comp_screen_output_destroy_cb, e_comp_screen);
692    if (ret != TDM_ERROR_NONE)
693      {
694         ERR("fail to add output destroy handler.");
695         e_output_del(output);
696         return;
697      }
698
699    e_comp_screen->outputs = eina_list_append(e_comp_screen->outputs, output);
700    e_comp_screen->num_outputs++;
701
702    return;
703
704 fail:
705    TRACE_DS_END();
706 }
707
708 static void
709 _e_comp_screen_deinit_outputs(E_Comp_Screen *e_comp_screen)
710 {
711    E_Output *output;
712    Eina_List *l, *ll;
713
714    tdm_display_remove_output_create_handler(e_comp_screen->tdisplay, _e_comp_screen_output_create_cb, e_comp_screen);
715
716    e_hwc_ecore_evas_deinit();
717
718    // free up e_outputs
719    EINA_LIST_FOREACH_SAFE(e_comp_screen->outputs, l, ll, output)
720      {
721         e_comp_screen->outputs = eina_list_remove_list(e_comp_screen->outputs, l);
722         e_output_del(output);
723      }
724
725    e_explicit_sync_deinit();
726    e_egl_sync_deinit();
727    e_hwc_deinit();
728    e_hwc_windows_deinit();
729    e_hwc_planes_deinit();
730    e_output_shutdown();
731 }
732
733 static Eina_Bool
734 _e_comp_screen_fake_output_set(E_Comp_Screen *e_comp_screen)
735 {
736    E_Output *primary_output = NULL;
737
738    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen, EINA_FALSE);
739
740    primary_output = e_comp_screen_primary_output_get(e_comp_screen);
741    EINA_SAFETY_ON_NULL_RETURN_VAL(primary_output, EINA_FALSE);
742
743    if (!e_output_hwc_setup(primary_output))
744      {
745         ERR("fail to e_output_hwc_setup.");
746         return EINA_FALSE;
747      }
748
749    if (!e_output_fake_config_set(primary_output, 2, 1))
750      {
751         e_error_message_show(_("Fail to set the fake output config!\n"));
752         e_hwc_ecore_evas_deinit();
753         return EINA_FALSE;
754      }
755
756    return EINA_TRUE;
757 }
758
759 static Eina_Bool
760 _e_comp_screen_init_outputs(E_Comp_Screen *e_comp_screen)
761 {
762    E_Output *output = NULL;
763    E_Output_Mode *mode = NULL;
764    tdm_display *tdisplay = e_comp_screen->tdisplay;
765    int num_outputs;
766    int i;
767    Eina_Bool scale_updated = EINA_FALSE;
768    Eina_Bool connection_check = EINA_FALSE;
769    tdm_error err = TDM_ERROR_NONE;
770    char bootmode[32];
771    int ret;
772
773    /* init e_output */
774    if (!e_output_init())
775      {
776         ERR("fail to e_output_init.");
777         return EINA_FALSE;
778      }
779
780    /* get the num of outputs */
781    err = tdm_display_get_output_count(tdisplay, &num_outputs);
782    if ((err != TDM_ERROR_NONE) ||
783        (num_outputs < 1))
784      {
785         ERR("fail to get tdm_display_get_output_count\n");
786         return EINA_FALSE;
787      }
788    e_comp_screen->num_outputs = num_outputs;
789
790    ELOGF("COMP_SCREEN","num_outputs = %i", NULL, e_comp_screen->num_outputs);
791
792    if (!e_hwc_init())
793      {
794         ERR("e_hwc_init failed");
795         goto fail;
796      }
797
798    if (!e_hwc_planes_init())
799      {
800         ERR("e_hwc_planes_init failed");
801         goto fail;
802      }
803
804    if (!e_hwc_windows_init())
805      {
806         ERR("e_hwc_windows_init failed");
807         goto fail;
808      }
809
810    for (i = 0; i < num_outputs; i++)
811      {
812         e_main_ts_begin("\tE_Output New");
813         output = e_output_new(e_comp_screen, i);
814         if (!output)
815           {
816              e_main_ts_end("\tE_Output New Failed");
817              goto fail;
818           }
819
820         e_main_ts_begin("\tE_Output Update");
821         if (!e_output_update(output))
822           {
823             e_main_ts_end("\tE_Output Update Failed");
824             ERR("fail to e_output_update.");
825             goto fail;
826           }
827         e_main_ts_end("\tE_Output Update Done");
828
829         e_comp_screen->outputs = eina_list_append(e_comp_screen->outputs, output);
830
831         if (!e_output_connected(output)) continue;
832
833         connection_check = EINA_TRUE;
834
835         /* setting with the best mode and enable the output */
836         e_main_ts_begin("\tE_Output Find Best Mode");
837         mode = e_output_best_mode_find(output);
838         if (!mode)
839           {
840              e_main_ts_end("\tE_Output Find Best Mode Failed");
841              ERR("fail to get best mode.");
842              goto fail;
843           }
844         e_main_ts_end("\tE_Output Find Best Mode Done");
845
846         e_main_ts_begin("\tE_Output Mode Apply");
847         if (!e_output_mode_apply(output, mode))
848           {
849              e_main_ts_end("\tE_Output Mode Apply Failed");
850              ERR("fail to e_output_mode_apply.");
851              goto fail;
852           }
853         e_main_ts_end("\tE_Output Mode Apply Done");
854
855         e_main_ts_begin("\tE_Output Set DPMS ON");
856         ret = device_board_get_boot_mode(bootmode, sizeof(bootmode));
857         if (!ret && !e_util_strcmp(bootmode, "silent"))
858           {
859              INF("silent reboot. do not set dpms");
860           }
861         else
862           {
863              if (!e_output_dpms_set(output, E_OUTPUT_DPMS_ON))
864                {
865                   e_main_ts_end("\tE_Output Set DPMS ON Failed");
866                   ERR("fail to e_output_dpms.");
867                   goto fail;
868                }
869           }
870
871         e_main_ts_end("\tE_Output Set DPMS ON Done");
872
873         e_main_ts_begin("\tE_Output Hwc Setup");
874         if (!e_output_hwc_setup(output))
875           {
876              e_main_ts_end("\tE_Output Hwc Setup Failed");
877              ERR("fail to e_output_hwc_setup.");
878              goto fail;
879           }
880         e_main_ts_end("\tE_Output Hwc Setup Done");
881
882         /* update e_scale with first available output size */
883         if ((e_config->scale.for_tdm) && (!scale_updated))
884           {
885              double target_inch;
886              int dpi;
887
888              target_inch = (round((sqrt(output->info.size.w * output->info.size.w + output->info.size.h * output->info.size.h) / 25.4) * 10) / 10);
889              dpi = (round((sqrt(mode->w * mode->w + mode->h * mode->h) / target_inch) * 10) / 10);
890
891              e_scale_manual_update(dpi);
892              scale_updated = EINA_TRUE;
893           }
894      }
895
896    //TODO: if there is no output connected, make the fake output which is connected.
897    if (!connection_check)
898      {
899         if (!_e_comp_screen_fake_output_set(e_comp_screen))
900           goto fail;
901      }
902
903    _e_comp_screen_size_update(e_comp_screen);
904
905    e_main_ts_begin("\tE_Hwc Ecore_Evas Init");
906    if (!e_hwc_ecore_evas_init())
907      {
908         e_main_ts_end("\ttE_Hwc Ecore_Evas Init Failed");
909         ERR("fail to e_hwc_ecore_evas_init");
910         goto fail;
911      }
912    e_main_ts_end("\tE_Hwc Ecore_Evas Init Done");
913
914    if (tdm_display_add_output_create_handler(tdisplay, _e_comp_screen_output_create_cb, e_comp_screen)) goto fail;
915
916    return EINA_TRUE;
917 fail:
918    _e_comp_screen_deinit_outputs(e_comp_screen);
919
920    return EINA_FALSE;
921 }
922
923 E_API void
924 e_comp_screen_keymap_set(struct xkb_context **ctx, struct xkb_keymap **map)
925 {
926    char *keymap_path = NULL;
927    struct xkb_context *context;
928    struct xkb_keymap *keymap;
929    struct xkb_rule_names names = {0,};
930    const char* default_rules, *default_model, *default_layout, *default_variant, *default_options;
931
932    TRACE_INPUT_BEGIN(e_comp_screen_keymap_set);
933
934    context = xkb_context_new(0);
935    EINA_SAFETY_ON_NULL_RETURN(context);
936
937    /* assemble xkb_rule_names so we can fetch keymap */
938    memset(&names, 0, sizeof(names));
939
940    default_rules = e_comp_wl_input_keymap_default_rules_get();
941    default_model = e_comp_wl_input_keymap_default_model_get();
942    default_layout = e_comp_wl_input_keymap_default_layout_get();
943    default_variant = e_comp_wl_input_keymap_default_variant_get();
944    default_options = e_comp_wl_input_keymap_default_options_get();
945
946    names.rules = strdup(default_rules);
947    names.model = strdup(default_model);
948    names.layout = strdup(default_layout);
949    if (default_variant) names.variant = strdup(default_variant);
950    if (default_options) names.options = strdup(default_options);
951
952    keymap = e_comp_wl_input_keymap_compile(context, names, &keymap_path);
953    eina_stringshare_del(keymap_path);
954    EINA_SAFETY_ON_NULL_GOTO(keymap, cleanup);
955
956    *ctx = context;
957    *map = keymap;
958
959    if (dont_set_e_input_keymap == EINA_FALSE)
960      {
961         e_input_device_keyboard_cached_context_set(*ctx);
962         e_input_device_keyboard_cached_keymap_set(*map);
963      }
964
965 cleanup:
966    free((char *)names.rules);
967    free((char *)names.model);
968    free((char *)names.layout);
969    if (names.variant) free((char *)names.variant);
970    if (names.options) free((char *)names.options);
971
972    TRACE_INPUT_END();
973 }
974
975 static void
976 _e_comp_screen_e_screen_free(E_Screen *scr)
977 {
978    free(scr->id);
979    free(scr);
980 }
981
982 static void
983 _e_comp_screen_e_screens_set(E_Comp_Screen *e_comp_screen, Eina_List *screens)
984 {
985    E_FREE_LIST(e_comp_screen->e_screens, _e_comp_screen_e_screen_free);
986    e_comp_screen->e_screens = screens;
987 }
988
989 static void
990 _e_comp_screen_engine_deinit(void)
991 {
992    if (!e_comp) return;
993    if (!e_comp->e_comp_screen) return;
994
995    _e_comp_screen_deinit_outputs(e_comp->e_comp_screen);
996    _e_comp_screen_del(e_comp->e_comp_screen);
997    e_comp->e_comp_screen = NULL;
998 }
999
1000 static Eina_Bool
1001 _e_comp_screen_engine_init(void)
1002 {
1003    E_Comp_Screen *e_comp_screen = NULL;
1004    int screen_rotation;
1005
1006    /* check the screen rotation */
1007    screen_rotation = (e_config->screen_rotation_pre + e_config->screen_rotation_setting) % 360;
1008
1009    ELOGF("COMP_SCREEN","screen_rotation_pre %d and screen_rotation_setting %d",
1010          NULL, e_config->screen_rotation_pre, e_config->screen_rotation_setting);
1011
1012    /* e_comp_screen new */
1013    e_main_ts_begin("\tE_Comp_Screen New");
1014    e_comp_screen = _e_comp_screen_new(e_comp);
1015    if (!e_comp_screen)
1016      {
1017         e_main_ts_end("\tE_Comp_Screen New Failed");
1018         e_error_message_show(_("Enlightenment cannot create e_comp_screen!\n"));
1019         return EINA_FALSE;
1020      }
1021    e_main_ts_end("\tE_Comp_Screen New Done");
1022
1023    e_comp->e_comp_screen = e_comp_screen;
1024    e_comp_screen->rotation_pre = e_config->screen_rotation_pre;
1025    e_comp_screen->rotation_setting = e_config->screen_rotation_setting;
1026    e_comp_screen->rotation = screen_rotation;
1027
1028    e_main_ts_begin("\tE_Comp_Screen Outputs Init");
1029    if (!_e_comp_screen_init_outputs(e_comp_screen))
1030      {
1031         e_main_ts_end("\tE_Comp_Screen Outputs Init Failed");
1032         e_error_message_show(_("Enlightenment cannot initialize outputs!\n"));
1033         _e_comp_screen_engine_deinit();
1034         return EINA_FALSE;
1035      }
1036    e_main_ts_end("\tE_Comp_Screen Outputs Init Done");
1037
1038    if (!E_EVENT_SCREEN_CHANGE) E_EVENT_SCREEN_CHANGE = ecore_event_type_new();
1039
1040    ecore_event_add(E_EVENT_SCREEN_CHANGE, NULL, NULL, NULL);
1041
1042    e_comp_screen_e_screens_setup(e_comp_screen, -1, -1);
1043
1044    /* update the screen, outputs and planes at the idle enterer of the ecore_loop */
1045    ecore_idle_enterer_add(_e_comp_screen_commit_idle_cb, e_comp);
1046
1047    return EINA_TRUE;
1048 }
1049
1050 static Eina_Bool
1051 _e_comp_screen_cb_dbus_init_done(void *data, int type, void *event)
1052 {
1053    E_DBus_Conn_Init_Done_Event *e = event;
1054
1055    if (e->status == E_DBUS_CONN_INIT_SUCCESS && e->conn_type == edbus_conn_type)
1056      {
1057         edbus_conn = e_dbus_conn_connection_ref(edbus_conn_type);
1058
1059         if (edbus_conn)
1060           _e_comp_screen_dbus_init();
1061      }
1062
1063    ecore_event_handler_del(dbus_init_done_handler);
1064    dbus_init_done_handler = NULL;
1065
1066    return ECORE_CALLBACK_PASS_ON;
1067 }
1068
1069 EINTERN void
1070 e_comp_screen_e_screens_setup(E_Comp_Screen *e_comp_screen, int rw, int rh)
1071 {
1072    E_Screen *screen;
1073    E_Output *output;
1074    Eina_List *e_screens = NULL;
1075    Eina_List *l;
1076    int i = 0, right_x = 0;
1077
1078    output = e_comp_screen_primary_output_get(e_comp_screen);
1079    /* No pirmary output means that there is no output at the system */
1080    if (!output) goto out;
1081
1082    EINA_LIST_FOREACH(e_comp_screen->outputs, l, output)
1083      {
1084         screen = E_NEW(E_Screen, 1);
1085         if (!screen) return;
1086
1087         screen->escreen = screen->screen = i;
1088
1089         if (output->config.rotation % 180)
1090           {
1091              screen->w = output->config.geom.h;
1092              screen->h = output->config.geom.w;
1093           }
1094         else
1095           {
1096              screen->w = output->config.geom.w;
1097              screen->h = output->config.geom.h;
1098           }
1099
1100         if (e_output_connected(output))
1101           {
1102              output->config.geom.x = right_x;
1103              right_x += output->config.geom.w;
1104           }
1105         else
1106           {
1107              output->config.geom.x = 0;
1108           }
1109
1110         screen->x = output->config.geom.x;
1111         screen->y = output->config.geom.y;
1112
1113         if (output->id) screen->id = strdup(output->id);
1114
1115         e_screens = eina_list_append(e_screens, screen);
1116         ELOGF("COMP_SCREEN","E INIT: SCREEN: [%i][%i], %ix%i+%i+%i",
1117               NULL, i, i, screen->w, screen->h, screen->x, screen->y);
1118         i++;
1119      }
1120
1121    ELOGF("COMP_SCREEN","e_comp_screen_e_screens_setup............... %i %p\n", NULL, i, e_comp_screen->e_screens);
1122
1123    ecore_event_add(E_EVENT_SCREEN_CHANGE, NULL, NULL, NULL);
1124
1125    _e_comp_screen_e_screens_set(e_comp_screen, e_screens);
1126
1127    return;
1128 out:
1129    screen = E_NEW(E_Screen, 1);
1130    if (!screen) return;
1131    screen->escreen = screen->screen = 0;
1132    screen->x = 0;
1133    screen->y = 0;
1134    if ((rw > 0) && (rh > 0))
1135      screen->w = rw, screen->h = rh;
1136    else
1137      {
1138         if (e_comp_screen->rotation % 180)
1139           ecore_evas_geometry_get(e_comp->ee, NULL, NULL, &screen->h, &screen->w);
1140         else
1141           ecore_evas_geometry_get(e_comp->ee, NULL, NULL, &screen->w, &screen->h);
1142      }
1143    e_screens = eina_list_append(e_screens, screen);
1144
1145    ELOGF("COMP_SCREEN","E INIT: SCREEN: No Physical Screen : [%i][%i], %ix%i+%i+%i",
1146          NULL, i, i, screen->w, screen->h, screen->x, screen->y);
1147
1148    _e_comp_screen_e_screens_set(e_comp_screen, e_screens);
1149 }
1150
1151 EINTERN const Eina_List *
1152 e_comp_screen_e_screens_get(E_Comp_Screen *e_comp_screen)
1153 {
1154    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen, NULL);
1155
1156    return e_comp_screen->e_screens;
1157 }
1158
1159 static void
1160 _e_comp_screen_cb_output_connect_status_change(void *data, E_Output *output)
1161 {
1162    _e_comp_screen_size_update(e_comp->e_comp_screen);
1163 }
1164
1165 static void
1166 _e_comp_screen_cb_output_mode_change(void *data, E_Output *output)
1167 {
1168    _e_comp_screen_size_update(e_comp->e_comp_screen);
1169 }
1170
1171 EINTERN Eina_Bool
1172 e_comp_screen_init()
1173 {
1174    E_Comp *comp;
1175    int w, h, ptr_x = 0, ptr_y = 0;
1176    struct xkb_context *ctx = NULL;
1177    struct xkb_keymap *map = NULL;
1178
1179    if (!(comp = e_comp))
1180      EINA_SAFETY_ON_NULL_RETURN_VAL(comp, EINA_FALSE);
1181
1182    /* keymap */
1183    dont_set_e_input_keymap = getenv("NO_E_INPUT_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
1184    dont_use_xkb_cache = getenv("NO_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
1185
1186    if (e_config->xkb.use_cache && !dont_use_xkb_cache)
1187      {
1188         e_main_ts_begin("\tDRM Keymap Init");
1189         e_comp_screen_keymap_set(&ctx, &map);
1190         e_main_ts_end("\tDRM Keymap Init Done");
1191      }
1192
1193    e_main_ts_begin("\tE_Comp_Screen_Engine Init");
1194    if (!_e_comp_screen_engine_init())
1195      {
1196         e_main_ts_end("\tE_Comp_Screen_Engine Init Failed");
1197         ERR("Could not initialize the ecore_evas engine.");
1198         goto failed_comp_screen;
1199      }
1200    e_main_ts_end("\tE_Comp_Screen_Engine Init Done");
1201
1202    e_main_ts_begin("\tE_Input Init");
1203    if (!e_input_init(e_comp->ee))
1204      {
1205         e_main_ts_end("\tE_Input Init Failed");
1206         ERR("Could not initialize the e_input.");
1207         goto failed_comp_screen;
1208      }
1209    e_main_ts_end("\tE_Input Init Done");
1210
1211    e_main_ts_begin("\tE_Comp_Wl Init");
1212    if (!e_comp_wl_init())
1213      {
1214         e_main_ts_begin("\tE_Comp_Wl Init Failed");
1215         goto failed_comp_screen;
1216      }
1217    e_main_ts_end("\tE_Comp_Wl Init Done");
1218
1219    /* get the current screen geometry */
1220    ecore_evas_geometry_get(e_comp->ee, NULL, NULL, &w, &h);
1221
1222    /* canvas */
1223    e_main_ts_begin("\tE_Comp_Canvas Init");
1224    if (!e_comp_canvas_init(w, h))
1225      {
1226         e_main_ts_end("\tE_Comp_Canvas Init Failed");
1227         e_error_message_show(_("Enlightenment cannot initialize outputs!\n"));
1228         goto failed_comp_screen;
1229      }
1230    e_main_ts_end("\tE_Comp_Canvas Init Done");
1231
1232    e_main_ts_begin("\tE_Egl_Sync Init");
1233    if (e_egl_sync_init())
1234      ELOGF("E_EGL_SYNC", "Enabled the E_Egl_Sync", NULL);
1235    e_main_ts_end("\tE_Egl_Sync Init Done");
1236
1237    e_main_ts_begin("\tE_Explicit_Sync Init");
1238    if (e_explicit_sync_init())
1239      ELOGF("EX-SYNC", "Enabled the E_Explicit_Sync", NULL);
1240    e_main_ts_end("\tE_Explicit_Sync Init Done");
1241
1242    /* pointer */
1243    e_input_device_pointer_xy_get(NULL, &ptr_x, &ptr_y);
1244    e_comp_wl->ptr.x = wl_fixed_from_int(ptr_x);
1245    e_comp_wl->ptr.y = wl_fixed_from_int(ptr_y);
1246
1247    evas_event_feed_mouse_in(e_comp->evas, 0, NULL);
1248
1249    e_main_ts_begin("\tE_Pointer New");
1250    if ((comp->pointer = e_pointer_canvas_new(comp->ee, EINA_TRUE)))
1251      {
1252         e_pointer_hide(comp->pointer);
1253      }
1254    e_main_ts_end("\tE_Pointer New Done");
1255
1256    /* FIXME: We need a way to trap for user changing the keymap inside of E
1257     *        without the event coming from X11 */
1258
1259    /* FIXME: We should make a decision here ...
1260     *
1261     * Fetch the keymap from drm, OR set this to what the E config is....
1262     */
1263
1264    /* FIXME: This is just for testing at the moment....
1265     * happens to jive with what drm does */
1266    e_main_ts_begin("\tE_Comp_WL Keymap Init");
1267    e_comp_wl_input_keymap_set(e_comp_wl_input_keymap_default_rules_get(),
1268                               e_comp_wl_input_keymap_default_model_get(),
1269                               e_comp_wl_input_keymap_default_layout_get(),
1270                               e_comp_wl_input_keymap_default_variant_get(),
1271                               e_comp_wl_input_keymap_default_options_get(),
1272                               ctx, map);
1273    e_main_ts_end("\tE_Comp_WL Keymap Init Done");
1274
1275    /* try to add tizen_video to wayland globals */
1276    if (!wl_global_create(e_comp_wl->wl.disp, &tizen_screen_rotation_interface, 1,
1277                          NULL, _tz_screen_rotation_cb_bind))
1278      {
1279         ERR("Could not add tizen_screen_rotation to wayland globals");
1280         goto failed_comp_screen;
1281      }
1282
1283    if (!e_comp_wl_tizen_hwc_init())
1284      {
1285         e_main_ts_end("\e_comp_wl_tizen_hwc_init Init Failed");
1286         e_error_message_show(_("Enlightenment cannot initialize tizen_hwc!\n"));
1287         goto failed_comp_screen;
1288      }
1289
1290    e_main_ts_begin("\tDBUS Init");
1291    dbus_init_done_handler = NULL;
1292    if (e_dbus_conn_init() > 0)
1293      {
1294         dbus_init_done_handler = ecore_event_handler_add(E_EVENT_DBUS_CONN_INIT_DONE, _e_comp_screen_cb_dbus_init_done, NULL);
1295         e_dbus_conn_dbus_init(edbus_conn_type);
1296      }
1297    e_main_ts_end("\tDBUS Init Done");
1298
1299    E_LIST_HANDLER_APPEND(event_handlers, ECORE_EVENT_DEVICE_ADD, _e_comp_screen_cb_input_device_add, comp);
1300    E_LIST_HANDLER_PREPEND(event_handlers, ECORE_EVENT_DEVICE_DEL, _e_comp_screen_cb_input_device_del, comp);
1301
1302    E_OUTPUT_HOOK_APPEND(output_hooks, E_OUTPUT_HOOK_CONNECT_STATUS_CHANGE, _e_comp_screen_cb_output_connect_status_change, comp);
1303    E_OUTPUT_HOOK_APPEND(output_hooks, E_OUTPUT_HOOK_MODE_CHANGE, _e_comp_screen_cb_output_mode_change, comp);
1304
1305    _e_comp_screen_input_rotation_set(e_comp->e_comp_screen->rotation);
1306
1307    return EINA_TRUE;
1308
1309 failed_comp_screen:
1310
1311    e_comp_wl_tizen_hwc_shutdown();
1312    e_input_shutdown();
1313    _e_comp_screen_engine_deinit();
1314
1315    return EINA_FALSE;
1316 }
1317
1318 EINTERN void
1319 e_comp_screen_shutdown()
1320 {
1321    if (!e_comp) return;
1322    if (!e_comp->e_comp_screen) return;
1323
1324    e_comp_wl_tizen_hwc_shutdown();
1325
1326    if (e_comp_screen_iface)
1327      {
1328         eldbus_service_interface_unregister(e_comp_screen_iface);
1329         e_comp_screen_iface = NULL;
1330      }
1331
1332    if (edbus_conn)
1333      {
1334         e_dbus_conn_connection_unref(edbus_conn);
1335         edbus_conn = NULL;
1336      }
1337
1338    e_dbus_conn_shutdown();
1339
1340    _e_comp_screen_deinit_outputs(e_comp->e_comp_screen);
1341
1342    E_FREE_LIST(output_hooks, e_output_hook_del);
1343
1344    e_client_hook_del(tzsr_client_hook_del);
1345    tzsr_client_hook_del = NULL;
1346
1347    dont_set_e_input_keymap = EINA_FALSE;
1348    dont_use_xkb_cache = EINA_FALSE;
1349    E_FREE_LIST(event_handlers, ecore_event_handler_del);
1350
1351    /* delete e_comp_sreen */
1352    _e_comp_screen_del(e_comp->e_comp_screen);
1353    e_comp->e_comp_screen = NULL;
1354 }
1355
1356 static E_Output *
1357 _e_comp_screen_output_find_primary(E_Comp_Screen *e_comp_screen)
1358 {
1359    E_Output *output = NULL, *o;
1360    const Eina_List *l;
1361
1362    EINA_LIST_FOREACH(e_comp_screen->outputs, l, o)
1363      {
1364         unsigned int pipe = 0;
1365         tdm_error error;
1366
1367         error = tdm_output_get_pipe(o->toutput, &pipe);
1368         if (error != TDM_ERROR_NONE || pipe != 0)
1369           continue;
1370
1371         output = o;
1372         break;
1373      }
1374
1375    if (!output)
1376      {
1377         ERR("couldn't find the primary output");
1378         return NULL;
1379      }
1380
1381    return output;
1382 }
1383
1384 static Eina_Bool
1385 _e_comp_screen_rotation_set(E_Comp_Screen *e_comp_screen, int screen_rotation,
1386   void (*setter)(E_Comp_Screen *e_comp_screen, int data), int data)
1387 {
1388    E_Output *output = NULL;
1389    E_Input_Device *dev;
1390    const Eina_List *l;
1391    int w, h;
1392
1393    output = _e_comp_screen_output_find_primary(e_comp_screen);
1394    if (!output)
1395      return EINA_FALSE;
1396
1397    if (!e_output_rotate(output, screen_rotation))
1398      return EINA_FALSE;
1399
1400    e_comp_screen->rotation = screen_rotation;
1401    if (setter)
1402       setter(e_comp_screen, data);
1403
1404    ecore_evas_rotation_with_resize_set(e_comp->ee, e_comp_screen->rotation);
1405    ecore_evas_geometry_get(e_comp->ee, NULL, NULL, &w, &h);
1406
1407    /* rendering forcely to prepare HWC */
1408    e_comp_render_queue();
1409    e_comp_hwc_end(__FUNCTION__);
1410
1411    EINA_LIST_FOREACH(e_input_devices_get(), l, dev)
1412      {
1413          e_input_device_touch_rotation_set(dev, e_comp_screen->rotation);
1414          e_input_device_rotation_set(dev, e_comp_screen->rotation);
1415
1416          ELOGF("COMP_SCREEN","EE Input Device Rotate: %d", NULL, e_comp_screen->rotation);
1417      }
1418
1419    if (e_comp_screen_iface)
1420      {
1421         eldbus_service_signal_emit(e_comp_screen_iface, E_COMP_SCREEN_SIGNAL_ROTATION_CHANGED, e_comp_screen->rotation);
1422         ELOGF("COMP_SCREEN", "screen-rotation sends signal: %d", NULL, e_comp_screen->rotation);
1423      }
1424
1425    ELOGF("COMP_SCREEN","EE Rotated and Resized: %d, %dx%d", NULL, e_comp_screen->rotation, w, h);
1426
1427    return EINA_TRUE;
1428 }
1429
1430 static void
1431 _e_comp_screen_rotation_pre_setter(E_Comp_Screen *e_comp_screen, int rotation_pre)
1432 {
1433    e_comp_screen->rotation_pre = rotation_pre;
1434    ELOGF("COMP_SCREEN","EE RotationPre: %d", NULL, rotation_pre);
1435 }
1436
1437 EINTERN Eina_Bool
1438 e_comp_screen_rotation_pre_set(E_Comp_Screen *e_comp_screen, int rotation_pre)
1439 {
1440    int screen_rotation;
1441
1442    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen, EINA_FALSE);
1443    EINA_SAFETY_ON_TRUE_RETURN_VAL(rotation_pre % 90, EINA_FALSE);
1444    EINA_SAFETY_ON_TRUE_RETURN_VAL(rotation_pre < 0, EINA_FALSE);
1445    EINA_SAFETY_ON_TRUE_RETURN_VAL(rotation_pre > 270, EINA_FALSE);
1446
1447    if (e_comp_screen->rotation_pre == rotation_pre) return EINA_TRUE;
1448
1449    screen_rotation = (rotation_pre + e_comp_screen->rotation_setting) % 360;
1450
1451    return _e_comp_screen_rotation_set(e_comp_screen, screen_rotation,
1452      _e_comp_screen_rotation_pre_setter, rotation_pre);
1453 }
1454
1455 static void
1456 _e_comp_screen_rotation_setting_setter(E_Comp_Screen *e_comp_screen, int rotation)
1457 {
1458    e_comp_screen->rotation_setting = rotation;
1459    ELOGF("COMP_SCREEN","EE RotationSetting: %d", NULL, rotation);
1460 }
1461
1462 E_API Eina_Bool
1463 e_comp_screen_rotation_setting_set(E_Comp_Screen *e_comp_screen, int rotation)
1464 {
1465    int screen_rotation;
1466
1467    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen, EINA_FALSE);
1468    EINA_SAFETY_ON_TRUE_RETURN_VAL(rotation % 90, EINA_FALSE);
1469    EINA_SAFETY_ON_TRUE_RETURN_VAL(rotation < 0, EINA_FALSE);
1470    EINA_SAFETY_ON_TRUE_RETURN_VAL(rotation > 270, EINA_FALSE);
1471
1472    if (e_comp_screen->rotation_setting == rotation) return EINA_TRUE;
1473
1474    screen_rotation = (e_comp_screen->rotation_pre + rotation) % 360;
1475
1476    return _e_comp_screen_rotation_set(e_comp_screen, screen_rotation,
1477      _e_comp_screen_rotation_setting_setter, rotation);
1478 }
1479
1480 E_API void
1481 e_comp_screen_rotation_ignore_output_transform_send(E_Client *ec, Eina_Bool ignore)
1482 {
1483    E_Comp_Screen_Tzsr *tzsr = _tz_surface_rotation_find(ec);
1484    E_Comp_Wl_Client_Data *cdata;
1485
1486    if (!tzsr) return;
1487
1488    /* if client have to considers the output transform */
1489    if (!ignore)
1490      {
1491         /* exception */
1492         if (e_config->screen_rotation_client_ignore)
1493           {
1494              ELOGF("TRANSFORM", "|tzsr(%p) ignore_output_transform: client_ignore", ec, tzsr);
1495              return;
1496           }
1497
1498         if (e_policy_client_is_quickpanel(ec))
1499            {
1500               ELOGF("TRANSFORM", "|tzsr(%p) ignore_output_transform: quickpanel", ec, tzsr);
1501               return;
1502            }
1503      }
1504
1505    ELOGF("TRANSFORM", "|tzsr(%p) ignore_output_transform(%d)", ec, tzsr, ignore);
1506
1507    cdata = e_client_cdata_get(ec);
1508    tizen_screen_rotation_send_ignore_output_transform(tzsr->resource, cdata->surface, ignore);
1509 }
1510
1511 EINTERN Eina_Bool
1512 e_comp_screen_rotation_ignore_output_transform_watch(E_Client *ec)
1513 {
1514    return (_tz_surface_rotation_find(ec)) ? EINA_TRUE : EINA_FALSE;
1515 }
1516
1517 EINTERN E_Output *
1518 e_comp_screen_primary_output_get(E_Comp_Screen *e_comp_screen)
1519 {
1520    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen, NULL);
1521
1522    E_Output *output = NULL, *o = NULL;
1523    Eina_List *l = NULL;
1524    int highest_priority = 0;
1525
1526    /* find the highest priority of the e_output */
1527    EINA_LIST_FOREACH(e_comp_screen->outputs, l, o)
1528      {
1529         if (highest_priority < o->config.priority)
1530           {
1531              highest_priority = o->config.priority;
1532              output = o;
1533           }
1534      }
1535
1536    return output;
1537 }
1538
1539 EINTERN Eina_Bool
1540 e_comp_screen_pp_support(void)
1541 {
1542    E_Comp_Screen *e_comp_screen = NULL;
1543    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp, EINA_FALSE);
1544
1545    e_comp_screen = e_comp->e_comp_screen;
1546    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen, EINA_FALSE);
1547    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen->tdisplay, EINA_FALSE);
1548
1549    return e_comp_screen->pp_enabled;
1550 }
1551
1552
1553 EINTERN Eina_List *
1554 e_comp_screen_pp_available_formats_get(void)
1555 {
1556   E_Comp_Screen *e_comp_screen = NULL;
1557   EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp, EINA_FALSE);
1558
1559   e_comp_screen = e_comp->e_comp_screen;
1560   EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen, EINA_FALSE);
1561   EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen->tdisplay, EINA_FALSE);
1562
1563   if (!e_comp_screen->pp_enabled)
1564     {
1565        ERR("pp does not support.");
1566        return NULL;
1567     }
1568
1569    return e_comp_screen->available_pp_formats;
1570 }
1571
1572 EINTERN void
1573 e_comp_screen_hwc_info_debug(void)
1574 {
1575    EINA_SAFETY_ON_NULL_RETURN(e_comp);
1576    EINA_SAFETY_ON_NULL_RETURN(e_comp->e_comp_screen);
1577
1578    E_Comp_Screen *e_comp_screen = e_comp->e_comp_screen;
1579    E_Output *output = NULL;
1580    E_Plane *plane = NULL;
1581    Eina_List *l_o, *ll_o;
1582    Eina_List *l_l, *ll_l;
1583    tdm_output_conn_status conn_status;
1584    int output_idx = 0;
1585    tdm_layer_capability layer_capabilities;
1586    char layer_cap[4096] = {0, };
1587    int i;
1588    const tdm_prop *tprops;
1589    int count;
1590
1591    INF("HWC: HWC Information ==========================================================");
1592    EINA_LIST_FOREACH_SAFE(e_comp_screen->outputs, l_o, ll_o, output)
1593      {
1594         tdm_error err = TDM_ERROR_NONE;
1595
1596         if (!output) continue;
1597
1598         if (e_hwc_policy_get(output->hwc) == E_HWC_POLICY_PLANES)
1599           {
1600              err = tdm_output_get_conn_status(output->toutput, &conn_status);
1601              if (err != TDM_ERROR_NONE) continue;
1602              if (conn_status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) continue;
1603
1604              INF("HWC: HWC Output(%d):(x, y, w, h)=(%d, %d, %d, %d) Information.",
1605                  ++output_idx,
1606                  output->config.geom.x, output->config.geom.y, output->config.geom.w, output->config.geom.h);
1607              INF("HWC:  num_layers=%d", output->plane_count);
1608              EINA_LIST_FOREACH_SAFE(output->planes, l_l, ll_l, plane)
1609                {
1610                    if (!plane) continue;
1611                    /* FIXME: hwc extension doesn't provide thing like layer */
1612                    tdm_layer_get_capabilities(plane->tlayer, &layer_capabilities);
1613                    snprintf(layer_cap, sizeof(layer_cap), "%s%s%s%s%s%s%s%s",
1614                             _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_CURSOR),
1615                             _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_PRIMARY),
1616                             _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_OVERLAY),
1617                             _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_GRAPHIC),
1618                             _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_VIDEO),
1619                             _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_TRANSFORM),
1620                             _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_RESEVED_MEMORY),
1621                             _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_NO_CROP));
1622                    INF("HWC:  index=%d zpos=%d ec=%p %s",
1623                        plane->index, plane->zpos,
1624                        plane->ec?plane->ec:NULL,
1625                        layer_cap);
1626                }
1627           }
1628         else
1629           {
1630              /* TODO: construct debug info for outputs managed by the hwc-wins */
1631              INF("HWC: HWC Output(%d) managed by hwc-wins.", ++output_idx);
1632
1633              if (!e_hwc_windows_get_available_properties(output->hwc, &tprops, &count))
1634                {
1635                   ERR("e_hwc_windows_get_video_available_properties failed");
1636                   return;
1637                }
1638              INF(">>>>>>>> Available UI props : count = %d", count);
1639              for (i = 0; i < count; i++)
1640                INF("   [%d] %s, %u", i, tprops[i].name, tprops[i].id);
1641
1642              if (!e_hwc_windows_get_video_available_properties(output->hwc, &tprops, &count))
1643                {
1644                   ERR("e_hwc_windows_get_video_available_properties failed");
1645                   return;
1646                }
1647              INF(">>>>>>>> Available VIDEO props : count = %d", count);
1648              for (i = 0; i < count; i++)
1649                INF("   [%d] %s, %u", i, tprops[i].name, tprops[i].id);
1650           }
1651      }
1652    INF("HWC: =========================================================================");
1653 }
1654
1655 #define NUM_SW_FORMAT   (sizeof(sw_formats) / sizeof(sw_formats[0]))
1656
1657 static tbm_format sw_formats[] = {
1658      TBM_FORMAT_ARGB8888,
1659      TBM_FORMAT_XRGB8888,
1660      TBM_FORMAT_YUV420,
1661      TBM_FORMAT_YVU420,
1662 };
1663
1664 static tdm_layer *
1665 _e_comp_screen_video_tdm_layer_get(tdm_output *output)
1666 {
1667    int i, count = 0;
1668 #ifdef CHECKING_PRIMARY_ZPOS
1669    int primary_idx = 0, primary_zpos = 0;
1670    tdm_layer *primary_layer;
1671 #endif
1672
1673    EINA_SAFETY_ON_NULL_RETURN_VAL(output, NULL);
1674
1675    tdm_output_get_layer_count(output, &count);
1676    for (i = 0; i < count; i++)
1677      {
1678         tdm_layer *layer = tdm_output_get_layer(output, i, NULL);
1679         tdm_layer_capability capabilities = 0;
1680         EINA_SAFETY_ON_NULL_RETURN_VAL(layer, NULL);
1681
1682         tdm_layer_get_capabilities(layer, &capabilities);
1683         if (capabilities & TDM_LAYER_CAPABILITY_VIDEO)
1684           return layer;
1685      }
1686
1687 #ifdef CHECKING_PRIMARY_ZPOS
1688    tdm_output_get_primary_index(output, &primary_idx);
1689    primary_layer = tdm_output_get_layer(output, primary_idx, NULL);
1690    EINA_SAFETY_ON_NULL_RETURN_VAL(primary_layer, NULL);
1691    tdm_layer_get_zpos(primary_layer, &primary_zpos);
1692 #endif
1693
1694    for (i = 0; i < count; i++)
1695      {
1696         tdm_layer *layer = tdm_output_get_layer(output, i, NULL);
1697         tdm_layer_capability capabilities = 0;
1698         EINA_SAFETY_ON_NULL_RETURN_VAL(layer, NULL);
1699
1700         tdm_layer_get_capabilities(layer, &capabilities);
1701         if (capabilities & TDM_LAYER_CAPABILITY_OVERLAY)
1702           {
1703 #ifdef CHECKING_PRIMARY_ZPOS
1704              int zpos = 0;
1705              tdm_layer_get_zpos(layer, &zpos);
1706              if (zpos >= primary_zpos) continue;
1707 #endif
1708              return layer;
1709           }
1710      }
1711
1712    return NULL;
1713 }
1714
1715 static E_Output *
1716 _e_comp_screen_eoutput_get_by_toutput(tdm_output *output)
1717 {
1718    Eina_List *l;
1719    E_Output *eo;
1720
1721    EINA_LIST_FOREACH(e_comp->e_comp_screen->outputs, l, eo)
1722       if (eo->toutput == output)
1723         return eo;
1724
1725    return NULL;
1726 }
1727
1728 E_API Eina_Bool
1729 e_comp_screen_available_video_formats_get(const tbm_format **formats, int *count)
1730 {
1731    E_Output *output;
1732    tdm_output *toutput;
1733    tdm_layer *layer;
1734    tdm_error error;
1735
1736    *count = 0;
1737
1738    if (e_comp_screen_pp_support())
1739      {
1740         error = tdm_display_get_pp_available_formats(e_comp->e_comp_screen->tdisplay, formats, count);
1741         if (error == TDM_ERROR_NONE)
1742           return EINA_TRUE;
1743      }
1744
1745    /* get the first output */
1746    toutput = tdm_display_get_output(e_comp->e_comp_screen->tdisplay, 0, NULL);
1747    if (!toutput)
1748      return EINA_FALSE;
1749
1750    output = _e_comp_screen_eoutput_get_by_toutput(toutput);
1751    if (!output)
1752      return EINA_FALSE;
1753
1754    if (e_hwc_policy_get(output->hwc) != E_HWC_POLICY_WINDOWS)
1755      {
1756         /* get the first suitable layer */
1757         layer = _e_comp_screen_video_tdm_layer_get(toutput);
1758         if (layer)
1759           {
1760              tdm_layer_get_available_formats(layer, formats, count);
1761           }
1762         else
1763           {
1764              *formats = sw_formats;
1765              *count = NUM_SW_FORMAT;
1766           }
1767      }
1768    else
1769      {
1770         error = tdm_hwc_get_video_supported_formats(output->hwc->thwc, formats, count);
1771         if (error != TDM_ERROR_NONE)
1772           {
1773              *formats = sw_formats;
1774              *count = NUM_SW_FORMAT;
1775           }
1776      }
1777
1778    return EINA_TRUE;
1779 }
1780
1781 EINTERN void *
1782 e_comp_screen_gbm_device_get(E_Comp_Screen *e_comp_screen)
1783 {
1784    int fd;
1785
1786    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen, NULL);
1787
1788    if (e_comp_screen->gdevice) return e_comp_screen->gdevice;
1789
1790    fd = tbm_drm_helper_get_master_fd();
1791    EINA_SAFETY_ON_FALSE_RETURN_VAL(fd >= 0, NULL);
1792
1793    e_comp_screen->gdevice = gbm_create_device(fd);
1794    if (!e_comp_screen->gdevice)
1795      {
1796         ERR("fail to create gbm device");
1797         close(fd);
1798         return NULL;
1799      }
1800
1801    e_comp_screen->gdevice_fd = fd;
1802
1803    return e_comp_screen->gdevice;
1804 }
1805
1806 EINTERN Eina_Bool
1807 e_comp_screen_size_get(E_Comp_Screen *e_comp_screen, int *w, int *h)
1808 {
1809    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen, EINA_FALSE);
1810
1811    if (w) *w = e_comp_screen->w;
1812    if (h) *h = e_comp_screen->h;
1813
1814    return EINA_TRUE;
1815 }
1816 static char *
1817 _e_comp_screen_dpms_to_string(E_OUTPUT_DPMS dpms)
1818 {
1819    switch (dpms)
1820      {
1821         case E_OUTPUT_DPMS_ON:
1822           return "DPMS_ON";
1823           break;
1824         case E_OUTPUT_DPMS_STANDBY:
1825           return "DPMS_STANDBY";
1826           break;
1827         case E_OUTPUT_DPMS_SUSPEND:
1828           return "DPMS_SUSPEND";
1829           break;
1830         case E_OUTPUT_DPMS_OFF:
1831           return "DPMS_OFF";
1832           break;
1833         default:
1834           return "Unknown";
1835      }
1836 }
1837
1838 EINTERN void
1839 e_comp_screen_debug_info_get(Eldbus_Message_Iter *iter)
1840 {
1841    Eldbus_Message_Iter *line_array;
1842    E_Comp_Screen *e_comp_screen = NULL;
1843    E_Output *output = NULL;
1844    E_Hwc *hwc = NULL;
1845    Eina_List *l;
1846    char info_str[1024];
1847
1848    e_comp_screen = e_comp->e_comp_screen;
1849
1850    eldbus_message_iter_arguments_append(iter, "as", &line_array);
1851    if (!e_comp_screen)
1852      {
1853         eldbus_message_iter_basic_append(line_array,
1854                                          's',
1855                                          "e_comp_screen not initialized..");
1856         eldbus_message_iter_container_close(iter, line_array);
1857         return;
1858      }
1859
1860    eldbus_message_iter_basic_append(line_array, 's',
1861    "===========================================================================================");
1862    eldbus_message_iter_basic_append(line_array, 's',
1863    " idx      id           status       dpms     (   x  ,   y  ) ( w    x    h ) ");
1864    eldbus_message_iter_basic_append(line_array, 's',
1865    "===========================================================================================");
1866
1867    EINA_LIST_FOREACH(e_comp_screen->outputs, l, output)
1868      {
1869         if (!output) continue;
1870         hwc = output->hwc;
1871         if (!output->hwc) continue;
1872         if (e_hwc_policy_get(hwc) == E_HWC_POLICY_NONE) continue;
1873
1874         snprintf(info_str, sizeof(info_str), "%2d %12s %15s %10s   (%5d , %5d) (%5d x %5d)",
1875                  output->index, output->id,
1876                  output->info.connected ? "connected" : "disconnected",
1877                  _e_comp_screen_dpms_to_string(output->dpms),
1878                  output->config.geom.x, output->config.geom.y,
1879                  output->config.geom.w, output->config.geom.h);
1880
1881         eldbus_message_iter_basic_append(line_array, 's', info_str);
1882      }
1883
1884    eldbus_message_iter_basic_append(line_array, 's',
1885    "===========================================================================================");
1886
1887    eldbus_message_iter_container_close(iter, line_array);
1888 }