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