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