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