e_comp_screen: fix the bug
[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
28 #include <tizen-extension-server-protocol.h>
29 #include <device/board-internal.h>
30 #include <tbm_drm_helper.h>
31 #include <gbm.h>
32
33 #define PATH "/org/enlightenment/wm"
34 #define IFACE "org.enlightenment.wm.screen_rotation"
35
36 static Ecore_Event_Handler *dbus_init_done_handler;
37 static Eldbus_Connection *edbus_conn = NULL;
38 static Eldbus_Connection_Type edbus_conn_type = ELDBUS_CONNECTION_TYPE_SYSTEM;
39 static Eldbus_Service_Interface *e_comp_screen_iface;
40
41 static Eina_List *event_handlers = NULL;
42 static Eina_List *output_hooks = NULL;
43
44 EINTERN int E_EVENT_SCREEN_CHANGE = 0;
45
46 enum
47 {
48    E_COMP_SCREEN_SIGNAL_ROTATION_CHANGED = 0
49 };
50
51 static Eldbus_Message *
52 _e_comp_screen_dbus_get_cb(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
53 {
54    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
55    int rotation = 0;
56
57    if (e_comp && e_comp->e_comp_screen)
58      rotation = e_comp->e_comp_screen->rotation;
59
60    ELOGF("COMP_SCREEN","got screen-rotation 'get' request: %d", NULL, rotation);
61
62    eldbus_message_arguments_append(reply, "i", rotation);
63
64    return reply;
65 }
66
67 static const Eldbus_Method methods[] =
68 {
69    {"get", NULL, ELDBUS_ARGS({"i", "int32"}), _e_comp_screen_dbus_get_cb, 0},
70    {}
71 };
72
73 static const Eldbus_Signal signals[] = {
74    [E_COMP_SCREEN_SIGNAL_ROTATION_CHANGED] = {"changed", ELDBUS_ARGS({ "i", "rotation" }), 0},
75    {}
76 };
77
78 static const Eldbus_Service_Interface_Desc iface_desc = {
79      IFACE, methods, signals, NULL, NULL, NULL
80 };
81
82 static void
83 _e_comp_screen_dbus_init()
84 {
85    E_Comp_Screen *e_comp_screen = e_comp->e_comp_screen;
86
87    e_comp_screen_iface = eldbus_service_interface_register(edbus_conn,
88                                                            PATH,
89                                                            &iface_desc);
90    EINA_SAFETY_ON_NULL_GOTO(e_comp_screen_iface, err);
91
92    if (e_comp_screen->rotation)
93      {
94         eldbus_service_signal_emit(e_comp_screen_iface, E_COMP_SCREEN_SIGNAL_ROTATION_CHANGED, e_comp_screen->rotation);
95         ELOGF("TRANSFORM", "screen-rotation sends signal: %d", NULL, e_comp_screen->rotation);
96      }
97
98    return;
99
100 err:
101    if (edbus_conn)
102      {
103         e_dbus_conn_connection_unref(edbus_conn);
104         edbus_conn = NULL;
105      }
106
107    return;
108 }
109
110 static char *
111 _layer_cap_to_str(tdm_layer_capability caps, tdm_layer_capability cap)
112 {
113    if (caps & cap)
114      {
115         if (cap == TDM_LAYER_CAPABILITY_CURSOR) return "cursor ";
116         else if (cap == TDM_LAYER_CAPABILITY_PRIMARY) return "primary ";
117         else if (cap == TDM_LAYER_CAPABILITY_OVERLAY) return "overlay ";
118         else if (cap == TDM_LAYER_CAPABILITY_GRAPHIC) return "graphics ";
119         else if (cap == TDM_LAYER_CAPABILITY_VIDEO) return "video ";
120         else if (cap == TDM_LAYER_CAPABILITY_TRANSFORM) return "transform ";
121         else if (cap == TDM_LAYER_CAPABILITY_RESEVED_MEMORY) return "reserved_memory ";
122         else if (cap == TDM_LAYER_CAPABILITY_NO_CROP) return "no_crop ";
123         else return "unkown";
124      }
125    return "";
126 }
127
128 static Eina_Bool
129 _e_comp_screen_commit_idle_cb(void *data EINA_UNUSED)
130 {
131    Eina_List *l, *ll;
132    E_Comp_Screen *e_comp_screen = NULL;
133    E_Output *output = NULL;
134
135    if (!e_comp->e_comp_screen) goto end;
136
137    if (e_config->comp_canvas_norender.use)
138      evas_norender(e_comp->evas);
139
140    if (e_comp->canvas_render_delayed) goto end;
141
142    e_comp_screen = e_comp->e_comp_screen;
143
144    EINA_LIST_FOREACH_SAFE(e_comp_screen->outputs, l, ll, output)
145      {
146         if (!output) continue;
147         if (!output->config.enabled) continue;
148
149         if (!e_output_commit(output))
150              ERR("fail to commit e_comp_screen->outputs.");
151
152         if (!e_output_render(output))
153              ERR("fail to render e_comp_screen->outputs.");
154      }
155 end:
156    return ECORE_CALLBACK_RENEW;
157 }
158
159 static void
160 _e_comp_screen_input_rotation_set(int rotation)
161 {
162    if (rotation > 0)
163      {
164         const Eina_List *l;
165         E_Input_Device *dev;
166
167         EINA_LIST_FOREACH(e_input_devices_get(), l, dev)
168           {
169              e_input_device_touch_rotation_set(dev, rotation);
170              e_input_device_rotation_set(dev, rotation);
171
172              ELOGF("COMP_SCREEN","EE Input Device Rotate: %d", NULL, rotation);
173           }
174      }
175 }
176
177 static Eina_Bool
178 _e_comp_screen_cb_input_device_add(void *data, int type, void *event)
179 {
180    Ecore_Event_Device_Info *e;
181    E_Comp *comp = data;
182
183    if (!(e = event)) goto end;
184
185    if (e->clas == ECORE_DEVICE_CLASS_MOUSE)
186      {
187         if (comp->wl_comp_data->ptr.num_devices == 0)
188           {
189              e_pointer_object_set(comp->pointer, NULL, 0, 0);
190              e_comp_wl_input_pointer_enabled_set(EINA_TRUE);
191           }
192         comp->wl_comp_data->ptr.num_devices++;
193      }
194    else if (e->clas == ECORE_DEVICE_CLASS_TOUCH)
195      {
196         e_comp_wl_input_touch_enabled_set(EINA_TRUE);
197         _e_comp_screen_input_rotation_set(e_comp->e_comp_screen->rotation);
198         comp->wl_comp_data->touch.num_devices++;
199      }
200
201 end:
202    return ECORE_CALLBACK_PASS_ON;
203 }
204
205 static void
206 _e_comp_screen_pointer_renew(void)
207 {
208      if ((e_comp_wl->ptr.num_devices == 0) && e_comp_wl->ptr.ec && e_comp_wl->ptr.ec->pointer_enter_sent)
209      {
210         if (e_devicemgr->last_device_ptr)
211           {
212              Evas_Device *last_ptr = NULL, *dev;
213              Eina_List *list, *l;
214              const char *name;
215              const char *description;
216
217              list = (Eina_List *)evas_device_list(evas_object_evas_get(e_comp_wl->ptr.ec->frame), NULL);
218              EINA_LIST_FOREACH(list, l, dev)
219                {
220                   name = evas_device_name_get(dev);
221                   description = evas_device_description_get(dev);
222
223                   if (!name || !description) continue;
224                   if ((!strncmp(name, e_devicemgr->last_device_ptr->name, strlen(e_devicemgr->last_device_ptr->name))) &&
225                       (!strncmp(description, e_devicemgr->last_device_ptr->identifier, strlen(e_devicemgr->last_device_ptr->identifier))) &&
226                       (evas_device_class_get(dev) == (Evas_Device_Class)e_devicemgr->last_device_ptr->clas))
227                     {
228                        last_ptr = dev;
229                        break;
230                     }
231                }
232              if (last_ptr)
233                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);
234           }
235      }
236 }
237
238 static Eina_Bool
239 _e_comp_screen_cb_input_device_del(void *data, int type, void *event)
240 {
241    Ecore_Event_Device_Info *e;
242    E_Comp *comp = data;
243
244    if (!(e = event)) goto end;
245
246    if (e->clas == ECORE_DEVICE_CLASS_MOUSE)
247      {
248         comp->wl_comp_data->ptr.num_devices--;
249         if (comp->wl_comp_data->ptr.num_devices == 0)
250           {
251              e_comp_wl_input_pointer_enabled_set(EINA_FALSE);
252              e_pointer_object_set(comp->pointer, NULL, 0, 0);
253              e_pointer_hide(e_comp->pointer);
254
255              _e_comp_screen_pointer_renew();
256           }
257      }
258    else if (e->clas == ECORE_DEVICE_CLASS_TOUCH)
259      {
260         comp->wl_comp_data->touch.num_devices--;
261         if (comp->wl_comp_data->touch.num_devices == 0)
262           {
263              e_comp_wl_input_touch_enabled_set(EINA_FALSE);
264           }
265      }
266
267 end:
268
269    return ECORE_CALLBACK_PASS_ON;
270 }
271
272 static Eina_Bool
273 _e_comp_screen_size_update(E_Comp_Screen *e_comp_screen)
274 {
275    E_Output *output;
276    int sum_w = 0, max_h = 0, output_w, output_h;
277    Eina_List *l;
278
279    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen, EINA_FALSE);
280
281    /* we place external output to the right of primary output */
282    EINA_LIST_FOREACH(e_comp_screen->outputs, l, output)
283      {
284         if (!e_output_connected(output)) continue;
285
286         e_output_size_get(output, &output_w, &output_h);
287         sum_w += output_w;
288
289         if (max_h < output_h)
290           max_h = output_h;
291      }
292
293    e_comp_screen->w = sum_w;
294    e_comp_screen->h = max_h;
295
296    if (e_comp->ee)
297      {
298         /* rotation should be reset because tbm_surface_queue or gbm_surface of
299          * ecore_evas is created without rotation
300          * and rotation of ecore_evas is reset after it is resized
301          */
302         if (e_comp_screen->rotation)
303           ecore_evas_rotation_with_resize_set(e_comp->ee, 0);
304
305         ecore_evas_resize(e_comp->ee, e_comp_screen->w, e_comp_screen->h);
306
307         if (e_comp_screen->rotation)
308           ecore_evas_rotation_with_resize_set(e_comp->ee, e_comp_screen->rotation);
309      }
310
311    return EINA_TRUE;
312 }
313
314 static Eina_Bool
315 _e_comp_screen_cb_event(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
316 {
317    E_Comp_Screen *e_comp_screen;
318    tdm_error ret;
319
320    if (!(e_comp_screen = data)) return ECORE_CALLBACK_RENEW;
321
322    ret = tdm_display_handle_events(e_comp_screen->tdisplay);
323    if (ret != TDM_ERROR_NONE)
324      ERR("tdm_display_handle_events failed");
325
326    return ECORE_CALLBACK_RENEW;
327 }
328
329 static E_Comp_Screen *
330 _e_comp_screen_new(E_Comp *comp)
331 {
332    E_Comp_Screen *e_comp_screen = NULL;
333    tdm_error error = TDM_ERROR_NONE;
334    tdm_display_capability capabilities;
335    const tbm_format *pp_formats;
336    int count, i;
337    int fd;
338
339    e_comp_screen = E_NEW(E_Comp_Screen, 1);
340    if (!e_comp_screen) return NULL;
341
342    /* tdm display init */
343    e_main_ts_begin("\tTDM Display Init");
344    e_comp_screen->tdisplay = tdm_display_init(&error);
345    if (!e_comp_screen->tdisplay)
346      {
347         e_main_ts_end("\tTDM Display Init Failed");
348         ERR("fail to get tdm_display\n");
349         free(e_comp_screen);
350         return NULL;
351      }
352    e_main_ts_end("\tTDM Display Init Done");
353
354    e_comp_screen->gdevice_fd = -1;
355    e_comp_screen->fd = -1;
356    tdm_display_get_fd(e_comp_screen->tdisplay, &fd);
357    if (fd < 0)
358      {
359         ERR("fail to get tdm_display fd\n");
360         goto fail;
361      }
362
363    e_comp_screen->fd = dup(fd);
364
365    e_comp_screen->hdlr =
366      ecore_main_fd_handler_add(e_comp_screen->fd, ECORE_FD_READ,
367                                _e_comp_screen_cb_event, e_comp_screen, NULL, NULL);
368    /* tdm display init */
369    e_main_ts_begin("\tTBM Bufmgr Server Init");
370    e_comp_screen->bufmgr = tbm_bufmgr_server_init();
371    if (!e_comp_screen->bufmgr)
372      {
373         e_main_ts_end("\tTBM Bufmgr Server Init Failed");
374         ERR("tbm_bufmgr_init failed\n");
375         goto fail;
376      }
377    e_main_ts_end("\tTBM Bufmgr Server Init Done");
378
379    error = tdm_display_get_capabilities(e_comp_screen->tdisplay, &capabilities);
380    if (error != TDM_ERROR_NONE)
381      {
382         ERR("tdm get_capabilities failed");
383         goto fail;
384      }
385
386    /* check the pp_support */
387    if (capabilities & TDM_DISPLAY_CAPABILITY_PP)
388      {
389         error = tdm_display_get_pp_available_formats(e_comp_screen->tdisplay, &pp_formats, &count);
390         if (error != TDM_ERROR_NONE)
391           ERR("fail to get available pp formats");
392         else
393           {
394              e_comp_screen->pp_enabled = EINA_TRUE;
395              for (i = 0 ; i < count ; i++)
396                e_comp_screen->available_pp_formats = eina_list_append(e_comp_screen->available_pp_formats, &pp_formats[i]);
397           }
398      }
399
400    e_main_ts_begin("\ttdm-socket Init");
401    if (e_comp_socket_init("tdm-socket"))
402      PRCTL("[Winsys] change permission and create sym link for %s", "tdm-socket");
403    e_main_ts_end("\ttdm-socket Init Done");
404
405    return e_comp_screen;
406
407 fail:
408    if (e_comp_screen->bufmgr) tbm_bufmgr_deinit(e_comp_screen->bufmgr);
409    if (e_comp_screen->fd >= 0) close(e_comp_screen->fd);
410    if (e_comp_screen->hdlr) ecore_main_fd_handler_del(e_comp_screen->hdlr);
411    if (e_comp_screen->tdisplay) tdm_display_deinit(e_comp_screen->tdisplay);
412
413    free(e_comp_screen);
414    TRACE_DS_END();
415
416    return NULL;
417 }
418
419 static void
420 _e_comp_screen_del(E_Comp_Screen *e_comp_screen)
421 {
422    Eina_List *l = NULL, *ll = NULL;
423    tbm_format *formats;
424
425    if (!e_comp_screen) return;
426
427    if (e_comp_screen->pp_enabled)
428      {
429         EINA_LIST_FOREACH_SAFE(e_comp_screen->available_pp_formats, l, ll, formats)
430           {
431              if (!formats) continue;
432              e_comp_screen->available_pp_formats = eina_list_remove(e_comp_screen->available_pp_formats, l);
433           }
434      }
435
436    if (e_comp_screen->gdevice) gbm_device_destroy(e_comp_screen->gdevice);
437    if (e_comp_screen->gdevice_fd >= 0) close(e_comp_screen->gdevice_fd);
438    if (e_comp_screen->bufmgr) tbm_bufmgr_deinit(e_comp_screen->bufmgr);
439    if (e_comp_screen->fd >= 0) close(e_comp_screen->fd);
440    if (e_comp_screen->hdlr) ecore_main_fd_handler_del(e_comp_screen->hdlr);
441    if (e_comp_screen->tdisplay) tdm_display_deinit(e_comp_screen->tdisplay);
442
443    free(e_comp_screen);
444 }
445
446 static void
447 _e_comp_screen_output_mode_change_cb(tdm_output *toutput, unsigned int index, void *user_data)
448 {
449    E_Comp_Screen *e_comp_screen = user_data;
450    E_Output *output = NULL;
451    Eina_Bool find = EINA_FALSE;
452    int count, num;
453    E_Output_Mode *set_emode = NULL, *current_emode = NULL;
454    E_Output_Mode *emode = NULL;
455    Eina_List *modelist = NULL, *l, *ll;
456
457    EINA_SAFETY_ON_NULL_RETURN(e_comp_screen);
458
459    EINA_LIST_FOREACH_SAFE(e_comp_screen->outputs, l, ll, output)
460      {
461         if (output->toutput == toutput)
462           {
463              find = EINA_TRUE;
464              break;
465           }
466      }
467    EINA_SAFETY_ON_FALSE_RETURN(find == EINA_TRUE);
468
469    current_emode = e_output_current_mode_get(output);
470    EINA_SAFETY_ON_NULL_RETURN(current_emode);
471
472    modelist = e_output_mode_list_get(output);
473    if (modelist)
474      {
475         num = eina_list_count(modelist);
476         EINA_SAFETY_ON_FALSE_RETURN(index < num);
477
478         count = 0;
479         EINA_LIST_FOREACH(modelist, l, emode)
480           {
481              if (count == index)
482                {
483                   set_emode = emode;
484                   break;
485                }
486              count++;
487           }
488
489         if (set_emode)
490           {
491              EINA_SAFETY_ON_TRUE_RETURN(current_emode == set_emode);
492
493              ELOGF("COMP_SCREEN","request mode change(%d) (%dx%d, %lf) -> (%dx%d, %lf)\n",
494                    NULL, index, current_emode->w, current_emode->h, current_emode->refresh,
495                    set_emode->w, set_emode->h, set_emode->refresh);
496
497              e_output_external_mode_change(output, set_emode);
498           }
499      }
500 }
501
502 static void
503 _e_comp_screen_output_destroy_cb(tdm_output *toutput, void *user_data)
504 {
505    E_Comp_Screen *e_comp_screen = user_data;
506    E_Output *output = NULL;
507    Eina_List *l, *ll;
508
509    EINA_SAFETY_ON_NULL_RETURN(e_comp_screen);
510
511    tdm_output_remove_destroy_handler(toutput, _e_comp_screen_output_destroy_cb, e_comp_screen);
512
513    EINA_LIST_FOREACH_SAFE(e_comp_screen->outputs, l, ll, output)
514      {
515         if (output->toutput == toutput)
516           {
517              e_comp_screen->num_outputs--;
518              e_comp_screen->outputs = eina_list_remove_list(e_comp_screen->outputs, l);
519              e_output_del(output);
520           }
521      }
522 }
523
524 static void
525 _e_comp_screen_output_create_cb(tdm_display *dpy, tdm_output *toutput, void *user_data)
526 {
527    E_Comp_Screen *e_comp_screen = user_data;
528    E_Output *output = NULL;
529    tdm_error ret = TDM_ERROR_NONE;
530
531    EINA_SAFETY_ON_NULL_RETURN(e_comp_screen);
532
533    TRACE_DS_BEGIN(OUTPUT:NEW);
534    output = e_output_new(e_comp_screen, e_comp_screen->num_outputs);
535    EINA_SAFETY_ON_NULL_GOTO(output, fail);
536    if (output->toutput != toutput) goto fail;
537    TRACE_DS_END();
538
539    TRACE_DS_BEGIN(OUTPUT:UPDATE);
540    if (!e_output_update(output))
541      {
542         ERR("fail to e_output_update.");
543         e_output_del(output);
544         goto fail;
545      }
546    TRACE_DS_END();
547
548    /* todo : add tdm_output_add_mode_change_request_handler()*/
549    ret = tdm_output_add_mode_change_request_handler(toutput, _e_comp_screen_output_mode_change_cb, e_comp_screen);
550    if (ret != TDM_ERROR_NONE)
551      {
552         ERR("fail to add output mode change handler.");
553         e_output_del(output);
554         return;
555      }
556
557    ret = tdm_output_add_destroy_handler(toutput, _e_comp_screen_output_destroy_cb, e_comp_screen);
558    if (ret != TDM_ERROR_NONE)
559      {
560         ERR("fail to add output destroy handler.");
561         e_output_del(output);
562         return;
563      }
564
565    e_comp_screen->outputs = eina_list_append(e_comp_screen->outputs, output);
566    e_comp_screen->num_outputs++;
567
568    return;
569
570 fail:
571    TRACE_DS_END();
572 }
573
574 static void
575 _e_comp_screen_deinit_outputs(E_Comp_Screen *e_comp_screen)
576 {
577    E_Output *output;
578    Eina_List *l, *ll;
579
580    tdm_display_remove_output_create_handler(e_comp_screen->tdisplay, _e_comp_screen_output_create_cb, e_comp_screen);
581
582    e_hwc_ecore_evas_deinit();
583
584    // free up e_outputs
585    EINA_LIST_FOREACH_SAFE(e_comp_screen->outputs, l, ll, output)
586      {
587         e_comp_screen->outputs = eina_list_remove_list(e_comp_screen->outputs, l);
588         e_output_del(output);
589      }
590
591    e_explicit_sync_deinit();
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_Comp_Wl Init");
1013    if (!e_comp_wl_init())
1014      {
1015         e_main_ts_begin("\tE_Comp_Wl Init Failed");
1016         goto failed_comp_screen;
1017      }
1018    e_main_ts_end("\tE_Comp_Wl 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_Explicit_Sync Init");
1039    if (e_explicit_sync_init())
1040      ELOGF("EX-SYNC", "Enabled the E_Explicit_Sync", NULL);
1041    e_main_ts_end("\tE_Explicit_Sync Init Done");
1042
1043    e_main_ts_begin("\tE_Linux_Dmabuf Init");
1044    e_linux_dmabuf_init(e_comp_wl->wl.disp);
1045    e_main_ts_end("\tE_Linux_Dmabuf Init Done");
1046
1047    /* pointer */
1048    e_input_device_pointer_xy_get(NULL, &ptr_x, &ptr_y);
1049    e_comp_wl->ptr.x = wl_fixed_from_int(ptr_x);
1050    e_comp_wl->ptr.y = wl_fixed_from_int(ptr_y);
1051
1052    evas_event_feed_mouse_in(e_comp->evas, 0, NULL);
1053
1054    e_main_ts_begin("\tE_Pointer New");
1055    if ((comp->pointer = e_pointer_canvas_new(comp->ee, EINA_TRUE)))
1056      {
1057         e_pointer_hide(comp->pointer);
1058      }
1059    e_main_ts_end("\tE_Pointer New Done");
1060
1061    /* FIXME: We need a way to trap for user changing the keymap inside of E
1062     *        without the event coming from X11 */
1063
1064    /* FIXME: We should make a decision here ...
1065     *
1066     * Fetch the keymap from drm, OR set this to what the E config is....
1067     */
1068
1069    /* FIXME: This is just for testing at the moment....
1070     * happens to jive with what drm does */
1071
1072    if (!e_input_thread_mode_get())
1073      {
1074         e_main_ts_begin("\tE_Comp_WL Keymap Init");
1075         e_comp_wl_input_keymap_init();
1076         e_main_ts_begin("\tE_Comp_WL Keymap Init Done");
1077      }
1078
1079    if (!e_screen_rotation_init())
1080      {
1081         e_main_ts_end("\e_screen_rotation_init Init Failed");
1082         goto failed_comp_screen;
1083      }
1084
1085    if (!e_comp_wl_tizen_hwc_init())
1086      {
1087         e_main_ts_end("\e_comp_wl_tizen_hwc_init Init Failed");
1088         e_error_message_show(_("Enlightenment cannot initialize tizen_hwc!\n"));
1089         goto failed_comp_screen;
1090      }
1091
1092    e_main_ts_begin("\tDBUS Init");
1093    dbus_init_done_handler = NULL;
1094    if (e_dbus_conn_init() > 0)
1095      {
1096         dbus_init_done_handler = ecore_event_handler_add(E_EVENT_DBUS_CONN_INIT_DONE, _e_comp_screen_cb_dbus_init_done, NULL);
1097         e_dbus_conn_dbus_init(edbus_conn_type);
1098      }
1099    e_main_ts_end("\tDBUS Init Done");
1100
1101    E_LIST_HANDLER_APPEND(event_handlers, ECORE_EVENT_DEVICE_ADD, _e_comp_screen_cb_input_device_add, comp);
1102    E_LIST_HANDLER_PREPEND(event_handlers, ECORE_EVENT_DEVICE_DEL, _e_comp_screen_cb_input_device_del, comp);
1103
1104    E_OUTPUT_HOOK_APPEND(output_hooks, E_OUTPUT_HOOK_CONNECT_STATUS_CHANGE, _e_comp_screen_cb_output_connect_status_change, comp);
1105    E_OUTPUT_HOOK_APPEND(output_hooks, E_OUTPUT_HOOK_MODE_CHANGE, _e_comp_screen_cb_output_mode_change, comp);
1106
1107    _e_comp_screen_input_rotation_set(e_comp->e_comp_screen->rotation);
1108
1109    return EINA_TRUE;
1110
1111 failed_comp_screen:
1112
1113    e_screen_rotation_shutdown();
1114    e_comp_wl_tizen_hwc_shutdown();
1115    e_input_shutdown();
1116    _e_comp_screen_engine_deinit();
1117
1118    return EINA_FALSE;
1119 }
1120
1121 EINTERN void
1122 e_comp_screen_shutdown()
1123 {
1124    if (!e_comp) return;
1125    if (!e_comp->e_comp_screen) return;
1126
1127    e_screen_rotation_shutdown();
1128    e_comp_wl_tizen_hwc_shutdown();
1129
1130    if (e_comp_screen_iface)
1131      {
1132         eldbus_service_interface_unregister(e_comp_screen_iface);
1133         e_comp_screen_iface = NULL;
1134      }
1135
1136    if (edbus_conn)
1137      {
1138         e_dbus_conn_connection_unref(edbus_conn);
1139         edbus_conn = NULL;
1140      }
1141
1142    e_dbus_conn_shutdown();
1143
1144    _e_comp_screen_deinit_outputs(e_comp->e_comp_screen);
1145
1146    E_FREE_LIST(output_hooks, e_output_hook_del);
1147
1148    E_FREE_LIST(event_handlers, ecore_event_handler_del);
1149
1150    /* delete e_comp_sreen */
1151    _e_comp_screen_del(e_comp->e_comp_screen);
1152    e_comp->e_comp_screen = NULL;
1153 }
1154
1155 static E_Output *
1156 _e_comp_screen_output_find_primary(E_Comp_Screen *e_comp_screen)
1157 {
1158    E_Output *output = NULL, *o;
1159    const Eina_List *l;
1160
1161    EINA_LIST_FOREACH(e_comp_screen->outputs, l, o)
1162      {
1163         unsigned int pipe = 0;
1164         tdm_error error;
1165
1166         error = tdm_output_get_pipe(o->toutput, &pipe);
1167         if (error != TDM_ERROR_NONE || pipe != 0)
1168           continue;
1169
1170         output = o;
1171         break;
1172      }
1173
1174    if (!output)
1175      {
1176         ERR("couldn't find the primary output");
1177         return NULL;
1178      }
1179
1180    return output;
1181 }
1182
1183 static Eina_Bool
1184 _e_comp_screen_rotation_set(E_Comp_Screen *e_comp_screen, int screen_rotation,
1185   void (*setter)(E_Comp_Screen *e_comp_screen, int data), int data)
1186 {
1187    E_Output *output = NULL;
1188    E_Input_Device *dev;
1189    const Eina_List *l;
1190    int w, h;
1191
1192    output = _e_comp_screen_output_find_primary(e_comp_screen);
1193    if (!output)
1194      return EINA_FALSE;
1195
1196    if (!e_output_rotate(output, screen_rotation))
1197      return EINA_FALSE;
1198
1199    e_comp_screen->rotation = screen_rotation;
1200    if (setter)
1201       setter(e_comp_screen, data);
1202
1203    ecore_evas_rotation_with_resize_set(e_comp->ee, e_comp_screen->rotation);
1204    ecore_evas_geometry_get(e_comp->ee, NULL, NULL, &w, &h);
1205
1206    /* rendering forcely to prepare HWC */
1207    e_comp_render_queue();
1208    e_comp_hwc_end(__FUNCTION__);
1209
1210    EINA_LIST_FOREACH(e_input_devices_get(), l, dev)
1211      {
1212          e_input_device_touch_rotation_set(dev, e_comp_screen->rotation);
1213          e_input_device_rotation_set(dev, e_comp_screen->rotation);
1214
1215          ELOGF("COMP_SCREEN","EE Input Device Rotate: %d", NULL, e_comp_screen->rotation);
1216      }
1217
1218    if (e_comp_screen_iface)
1219      {
1220         eldbus_service_signal_emit(e_comp_screen_iface, E_COMP_SCREEN_SIGNAL_ROTATION_CHANGED, e_comp_screen->rotation);
1221         ELOGF("COMP_SCREEN", "screen-rotation sends signal: %d", NULL, e_comp_screen->rotation);
1222      }
1223
1224    ELOGF("COMP_SCREEN","EE Rotated and Resized: %d, %dx%d", NULL, e_comp_screen->rotation, w, h);
1225
1226    return EINA_TRUE;
1227 }
1228
1229 static void
1230 _e_comp_screen_rotation_pre_setter(E_Comp_Screen *e_comp_screen, int rotation_pre)
1231 {
1232    e_comp_screen->rotation_pre = rotation_pre;
1233    ELOGF("COMP_SCREEN","EE RotationPre: %d", NULL, rotation_pre);
1234 }
1235
1236 EINTERN Eina_Bool
1237 e_comp_screen_rotation_pre_set(E_Comp_Screen *e_comp_screen, int rotation_pre)
1238 {
1239    int screen_rotation;
1240
1241    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen, EINA_FALSE);
1242    EINA_SAFETY_ON_TRUE_RETURN_VAL(rotation_pre % 90, EINA_FALSE);
1243    EINA_SAFETY_ON_TRUE_RETURN_VAL(rotation_pre < 0, EINA_FALSE);
1244    EINA_SAFETY_ON_TRUE_RETURN_VAL(rotation_pre > 270, EINA_FALSE);
1245
1246    if (e_comp_screen->rotation_pre == rotation_pre) return EINA_TRUE;
1247
1248    screen_rotation = (rotation_pre + e_comp_screen->rotation_setting) % 360;
1249
1250    return _e_comp_screen_rotation_set(e_comp_screen, screen_rotation,
1251      _e_comp_screen_rotation_pre_setter, rotation_pre);
1252 }
1253
1254 static void
1255 _e_comp_screen_rotation_setting_setter(E_Comp_Screen *e_comp_screen, int rotation)
1256 {
1257    e_comp_screen->rotation_setting = rotation;
1258    ELOGF("COMP_SCREEN","EE RotationSetting: %d", NULL, rotation);
1259 }
1260
1261 E_API Eina_Bool
1262 e_comp_screen_rotation_setting_set(E_Comp_Screen *e_comp_screen, int rotation)
1263 {
1264    int screen_rotation;
1265
1266    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen, EINA_FALSE);
1267    EINA_SAFETY_ON_TRUE_RETURN_VAL(rotation % 90, EINA_FALSE);
1268    EINA_SAFETY_ON_TRUE_RETURN_VAL(rotation < 0, EINA_FALSE);
1269    EINA_SAFETY_ON_TRUE_RETURN_VAL(rotation > 270, EINA_FALSE);
1270
1271    if (e_comp_screen->rotation_setting == rotation) return EINA_TRUE;
1272
1273    screen_rotation = (e_comp_screen->rotation_pre + rotation) % 360;
1274
1275    return _e_comp_screen_rotation_set(e_comp_screen, screen_rotation,
1276      _e_comp_screen_rotation_setting_setter, rotation);
1277 }
1278
1279 E_API void
1280 e_comp_screen_rotation_ignore_output_transform_send(E_Client *ec, Eina_Bool ignore)
1281 {
1282    /* if client have to considers the output transform */
1283    if (!ignore)
1284      {
1285         /* exception */
1286         if (e_config->screen_rotation_client_ignore)
1287           {
1288              ELOGF("TRANSFORM", "|ignore_output_transform: client_ignore", ec);
1289              return;
1290           }
1291
1292         if (e_policy_client_is_quickpanel(ec))
1293            {
1294               ELOGF("TRANSFORM", "|ignore_output_transform: quickpanel", ec);
1295               return;
1296            }
1297      }
1298
1299    e_screen_rotation_ignore_output_transform_send(ec, ignore);
1300 }
1301
1302 EINTERN E_Output *
1303 e_comp_screen_primary_output_get(E_Comp_Screen *e_comp_screen)
1304 {
1305    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen, NULL);
1306
1307    E_Output *output = NULL, *o = NULL;
1308    Eina_List *l = NULL;
1309    int highest_priority = 0;
1310
1311    /* find the highest priority of the e_output */
1312    EINA_LIST_FOREACH(e_comp_screen->outputs, l, o)
1313      {
1314         if (highest_priority < o->config.priority)
1315           {
1316              highest_priority = o->config.priority;
1317              output = o;
1318           }
1319      }
1320
1321    return output;
1322 }
1323
1324 EINTERN Eina_Bool
1325 e_comp_screen_pp_support(void)
1326 {
1327    E_Comp_Screen *e_comp_screen = NULL;
1328    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp, EINA_FALSE);
1329
1330    e_comp_screen = e_comp->e_comp_screen;
1331    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen, EINA_FALSE);
1332    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen->tdisplay, EINA_FALSE);
1333
1334    return e_comp_screen->pp_enabled;
1335 }
1336
1337
1338 EINTERN Eina_List *
1339 e_comp_screen_pp_available_formats_get(void)
1340 {
1341   E_Comp_Screen *e_comp_screen = NULL;
1342   EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp, EINA_FALSE);
1343
1344   e_comp_screen = e_comp->e_comp_screen;
1345   EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen, EINA_FALSE);
1346   EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen->tdisplay, EINA_FALSE);
1347
1348   if (!e_comp_screen->pp_enabled)
1349     {
1350        ERR("pp does not support.");
1351        return NULL;
1352     }
1353
1354    return e_comp_screen->available_pp_formats;
1355 }
1356
1357 EINTERN void
1358 e_comp_screen_hwc_info_debug(void)
1359 {
1360    EINA_SAFETY_ON_NULL_RETURN(e_comp);
1361    EINA_SAFETY_ON_NULL_RETURN(e_comp->e_comp_screen);
1362
1363    E_Comp_Screen *e_comp_screen = e_comp->e_comp_screen;
1364    E_Output *output = NULL;
1365    E_Plane *plane = NULL;
1366    Eina_List *l_o, *ll_o;
1367    Eina_List *l_l, *ll_l;
1368    tdm_output_conn_status conn_status;
1369    int output_idx = 0;
1370    tdm_layer_capability layer_capabilities;
1371    char layer_cap[4096] = {0, };
1372    int i;
1373    const tdm_prop *tprops;
1374    int count;
1375
1376    INF("HWC: HWC Information ==========================================================");
1377    EINA_LIST_FOREACH_SAFE(e_comp_screen->outputs, l_o, ll_o, output)
1378      {
1379         tdm_error err = TDM_ERROR_NONE;
1380
1381         if (!output) continue;
1382
1383         if (e_hwc_policy_get(output->hwc) == E_HWC_POLICY_PLANES)
1384           {
1385              err = tdm_output_get_conn_status(output->toutput, &conn_status);
1386              if (err != TDM_ERROR_NONE) continue;
1387              if (conn_status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) continue;
1388
1389              INF("HWC: HWC Output(%d):(x, y, w, h)=(%d, %d, %d, %d) Information.",
1390                  ++output_idx,
1391                  output->config.geom.x, output->config.geom.y, output->config.geom.w, output->config.geom.h);
1392              INF("HWC:  num_layers=%d", output->plane_count);
1393              EINA_LIST_FOREACH_SAFE(output->planes, l_l, ll_l, plane)
1394                {
1395                    if (!plane) continue;
1396                    /* FIXME: hwc extension doesn't provide thing like layer */
1397                    tdm_layer_get_capabilities(plane->tlayer, &layer_capabilities);
1398                    snprintf(layer_cap, sizeof(layer_cap), "%s%s%s%s%s%s%s%s",
1399                             _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_CURSOR),
1400                             _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_PRIMARY),
1401                             _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_OVERLAY),
1402                             _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_GRAPHIC),
1403                             _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_VIDEO),
1404                             _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_TRANSFORM),
1405                             _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_RESEVED_MEMORY),
1406                             _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_NO_CROP));
1407                    INF("HWC:  index=%d zpos=%d ec=%p %s",
1408                        plane->index, plane->zpos,
1409                        plane->ec?plane->ec:NULL,
1410                        layer_cap);
1411                }
1412           }
1413         else
1414           {
1415              /* TODO: construct debug info for outputs managed by the hwc-wins */
1416              INF("HWC: HWC Output(%d) managed by hwc-wins.", ++output_idx);
1417
1418              if (!e_hwc_windows_get_available_properties(output->hwc, &tprops, &count))
1419                {
1420                   ERR("e_hwc_windows_get_video_available_properties failed");
1421                   return;
1422                }
1423              INF(">>>>>>>> Available UI props : count = %d", count);
1424              for (i = 0; i < count; i++)
1425                INF("   [%d] %s, %u", i, tprops[i].name, tprops[i].id);
1426
1427              if (!e_hwc_windows_get_video_available_properties(output->hwc, &tprops, &count))
1428                {
1429                   ERR("e_hwc_windows_get_video_available_properties failed");
1430                   return;
1431                }
1432              INF(">>>>>>>> Available VIDEO props : count = %d", count);
1433              for (i = 0; i < count; i++)
1434                INF("   [%d] %s, %u", i, tprops[i].name, tprops[i].id);
1435           }
1436      }
1437    INF("HWC: =========================================================================");
1438 }
1439
1440 #define NUM_SW_FORMAT   (sizeof(sw_formats) / sizeof(sw_formats[0]))
1441
1442 static tbm_format sw_formats[] = {
1443      TBM_FORMAT_ARGB8888,
1444      TBM_FORMAT_XRGB8888,
1445      TBM_FORMAT_YUV420,
1446      TBM_FORMAT_YVU420,
1447 };
1448
1449 static tdm_layer *
1450 _e_comp_screen_video_tdm_layer_get(tdm_output *output)
1451 {
1452    int i, count = 0;
1453 #ifdef CHECKING_PRIMARY_ZPOS
1454    int primary_idx = 0, primary_zpos = 0;
1455    tdm_layer *primary_layer;
1456 #endif
1457
1458    EINA_SAFETY_ON_NULL_RETURN_VAL(output, NULL);
1459
1460    tdm_output_get_layer_count(output, &count);
1461    for (i = 0; i < count; i++)
1462      {
1463         tdm_layer *layer = tdm_output_get_layer(output, i, NULL);
1464         tdm_layer_capability capabilities = 0;
1465         EINA_SAFETY_ON_NULL_RETURN_VAL(layer, NULL);
1466
1467         tdm_layer_get_capabilities(layer, &capabilities);
1468         if (capabilities & TDM_LAYER_CAPABILITY_VIDEO)
1469           return layer;
1470      }
1471
1472 #ifdef CHECKING_PRIMARY_ZPOS
1473    tdm_output_get_primary_index(output, &primary_idx);
1474    primary_layer = tdm_output_get_layer(output, primary_idx, NULL);
1475    EINA_SAFETY_ON_NULL_RETURN_VAL(primary_layer, NULL);
1476    tdm_layer_get_zpos(primary_layer, &primary_zpos);
1477 #endif
1478
1479    for (i = 0; i < count; i++)
1480      {
1481         tdm_layer *layer = tdm_output_get_layer(output, i, NULL);
1482         tdm_layer_capability capabilities = 0;
1483         EINA_SAFETY_ON_NULL_RETURN_VAL(layer, NULL);
1484
1485         tdm_layer_get_capabilities(layer, &capabilities);
1486         if (capabilities & TDM_LAYER_CAPABILITY_OVERLAY)
1487           {
1488 #ifdef CHECKING_PRIMARY_ZPOS
1489              int zpos = 0;
1490              tdm_layer_get_zpos(layer, &zpos);
1491              if (zpos >= primary_zpos) continue;
1492 #endif
1493              return layer;
1494           }
1495      }
1496
1497    return NULL;
1498 }
1499
1500 static E_Output *
1501 _e_comp_screen_eoutput_get_by_toutput(tdm_output *output)
1502 {
1503    Eina_List *l;
1504    E_Output *eo;
1505
1506    EINA_LIST_FOREACH(e_comp->e_comp_screen->outputs, l, eo)
1507       if (eo->toutput == output)
1508         return eo;
1509
1510    return NULL;
1511 }
1512
1513 E_API Eina_Bool
1514 e_comp_screen_available_video_formats_get(const tbm_format **formats, int *count)
1515 {
1516    E_Output *output;
1517    tdm_output *toutput;
1518    tdm_layer *layer;
1519    tdm_error error;
1520
1521    *count = 0;
1522
1523    if (e_comp_screen_pp_support())
1524      {
1525         error = tdm_display_get_pp_available_formats(e_comp->e_comp_screen->tdisplay, formats, count);
1526         if (error == TDM_ERROR_NONE)
1527           return EINA_TRUE;
1528      }
1529
1530    /* get the first output */
1531    toutput = tdm_display_get_output(e_comp->e_comp_screen->tdisplay, 0, NULL);
1532    if (!toutput)
1533      return EINA_FALSE;
1534
1535    output = _e_comp_screen_eoutput_get_by_toutput(toutput);
1536    if (!output)
1537      return EINA_FALSE;
1538
1539    if (e_hwc_policy_get(output->hwc) != E_HWC_POLICY_WINDOWS)
1540      {
1541         /* get the first suitable layer */
1542         layer = _e_comp_screen_video_tdm_layer_get(toutput);
1543         if (layer)
1544           {
1545              tdm_layer_get_available_formats(layer, formats, count);
1546           }
1547         else
1548           {
1549              *formats = sw_formats;
1550              *count = NUM_SW_FORMAT;
1551           }
1552      }
1553    else
1554      {
1555         error = tdm_hwc_get_video_supported_formats(output->hwc->thwc, formats, count);
1556         if (error != TDM_ERROR_NONE)
1557           {
1558              *formats = sw_formats;
1559              *count = NUM_SW_FORMAT;
1560           }
1561      }
1562
1563    return EINA_TRUE;
1564 }
1565
1566 EINTERN void *
1567 e_comp_screen_gbm_device_get(E_Comp_Screen *e_comp_screen)
1568 {
1569    int fd;
1570
1571    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen, NULL);
1572
1573    if (e_comp_screen->gdevice) return e_comp_screen->gdevice;
1574
1575    fd = tbm_drm_helper_get_master_fd();
1576    EINA_SAFETY_ON_FALSE_RETURN_VAL(fd >= 0, NULL);
1577
1578    e_comp_screen->gdevice = gbm_create_device(fd);
1579    if (!e_comp_screen->gdevice)
1580      {
1581         ERR("fail to create gbm device");
1582         close(fd);
1583         return NULL;
1584      }
1585
1586    e_comp_screen->gdevice_fd = fd;
1587
1588    return e_comp_screen->gdevice;
1589 }
1590
1591 EINTERN Eina_Bool
1592 e_comp_screen_size_get(E_Comp_Screen *e_comp_screen, int *w, int *h)
1593 {
1594    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen, EINA_FALSE);
1595
1596    if (w) *w = e_comp_screen->w;
1597    if (h) *h = e_comp_screen->h;
1598
1599    return EINA_TRUE;
1600 }
1601 static char *
1602 _e_comp_screen_dpms_to_string(E_OUTPUT_DPMS dpms)
1603 {
1604    switch (dpms)
1605      {
1606         case E_OUTPUT_DPMS_ON:
1607           return "DPMS_ON";
1608           break;
1609         case E_OUTPUT_DPMS_STANDBY:
1610           return "DPMS_STANDBY";
1611           break;
1612         case E_OUTPUT_DPMS_SUSPEND:
1613           return "DPMS_SUSPEND";
1614           break;
1615         case E_OUTPUT_DPMS_OFF:
1616           return "DPMS_OFF";
1617           break;
1618         default:
1619           return "Unknown";
1620      }
1621 }
1622
1623 EINTERN void
1624 e_comp_screen_debug_info_get(Eldbus_Message_Iter *iter)
1625 {
1626    Eldbus_Message_Iter *line_array;
1627    E_Comp_Screen *e_comp_screen = NULL;
1628    E_Output *output = NULL;
1629    E_Hwc *hwc = NULL;
1630    Eina_List *l;
1631    char info_str[1024];
1632
1633    e_comp_screen = e_comp->e_comp_screen;
1634
1635    eldbus_message_iter_arguments_append(iter, "as", &line_array);
1636    if (!e_comp_screen)
1637      {
1638         eldbus_message_iter_basic_append(line_array,
1639                                          's',
1640                                          "e_comp_screen not initialized..");
1641         eldbus_message_iter_container_close(iter, line_array);
1642         return;
1643      }
1644
1645    eldbus_message_iter_basic_append(line_array, 's',
1646    "===========================================================================================");
1647    eldbus_message_iter_basic_append(line_array, 's',
1648    " idx      id           status       dpms     (   x  ,   y  ) ( w    x    h ) ");
1649    eldbus_message_iter_basic_append(line_array, 's',
1650    "===========================================================================================");
1651
1652    EINA_LIST_FOREACH(e_comp_screen->outputs, l, output)
1653      {
1654         if (!output) continue;
1655         hwc = output->hwc;
1656         if (!output->hwc) continue;
1657         if (e_hwc_policy_get(hwc) == E_HWC_POLICY_NONE) continue;
1658
1659         snprintf(info_str, sizeof(info_str), "%2d %12s %15s %10s   (%5d , %5d) (%5d x %5d)",
1660                  output->index, output->id,
1661                  output->info.connected ? "connected" : "disconnected",
1662                  _e_comp_screen_dpms_to_string(output->dpms),
1663                  output->config.geom.x, output->config.geom.y,
1664                  output->config.geom.w, output->config.geom.h);
1665
1666         eldbus_message_iter_basic_append(line_array, 's', info_str);
1667      }
1668
1669    eldbus_message_iter_basic_append(line_array, 's',
1670    "===========================================================================================");
1671
1672    eldbus_message_iter_container_close(iter, line_array);
1673 }
1674
1675 E_API Eina_List *
1676 e_comp_screen_outputs_get(E_Comp_Screen *e_comp_screen)
1677 {
1678    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen, NULL);
1679
1680    return e_comp_screen->outputs;
1681 }