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