e_comp_screen: change e_comp->ee alloc function to ecore_evas_tbm_allocfunc_new
[platform/upstream/enlightenment.git] / src / bin / e_comp_screen.c
1 #include "e.h"
2 #include "Eeze.h"
3
4 #define PATH "/org/enlightenment/wm"
5 #define IFACE "org.enlightenment.wm.screen_rotation"
6
7 static Eldbus_Connection *e_comp_screen_conn;
8 static Eldbus_Service_Interface *e_comp_screen_iface;
9
10 static Eina_List *event_handlers = NULL;
11
12 static Eina_Bool dont_set_e_input_keymap = EINA_FALSE;
13 static Eina_Bool dont_use_xkb_cache = EINA_FALSE;
14
15 E_API int              E_EVENT_SCREEN_CHANGE = 0;
16
17 enum
18 {
19    E_COMP_SCREEN_SIGNAL_ROTATION_CHANGED = 0
20 };
21
22 typedef struct _E_Comp_Screen_Tzsr
23 {
24    struct wl_resource *resource; /* tizen_screen_rotation */
25    E_Client           *ec;
26 } E_Comp_Screen_Tzsr;
27
28 static Eina_List *tzsr_list;
29 static E_Client_Hook *tzsr_client_hook_del;
30
31 static E_Comp_Screen_Tzsr*
32 _tz_surface_rotation_find(E_Client *ec)
33 {
34    E_Comp_Screen_Tzsr *tzsr;
35    Eina_List *l;
36
37    EINA_LIST_FOREACH(tzsr_list, l, tzsr)
38      {
39         if (tzsr->ec == ec)
40           return tzsr;
41      }
42
43    return NULL;
44 }
45
46 static E_Comp_Screen_Tzsr*
47 _tz_surface_rotation_find_with_resource(struct wl_resource *resource)
48 {
49    E_Comp_Screen_Tzsr *tzsr;
50    Eina_List *l;
51
52    EINA_LIST_FOREACH(tzsr_list, l, tzsr)
53      {
54         if (tzsr->resource == resource)
55           return tzsr;
56      }
57
58    return NULL;
59 }
60
61 static void
62 _tz_surface_rotation_free(E_Comp_Screen_Tzsr *tzsr)
63 {
64    ELOGF("TRANSFORM", "|tzsr(%p) freed", NULL, tzsr->ec, tzsr);
65    tzsr_list = eina_list_remove(tzsr_list, tzsr);
66    free(tzsr);
67 }
68
69 static void
70 _tz_screen_rotation_cb_client_del(void *data, E_Client *ec)
71 {
72    E_Comp_Screen_Tzsr *tzsr = _tz_surface_rotation_find(ec);
73    if (!tzsr) return;
74    _tz_surface_rotation_free(tzsr);
75 }
76
77 static void
78 _tz_screen_rotation_get_ignore_output_transform(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface)
79 {
80    E_Comp_Screen_Tzsr *tzsr;
81    E_Client *ec;
82
83    ec = wl_resource_get_user_data(surface);
84    EINA_SAFETY_ON_NULL_RETURN(ec);
85
86    tzsr = _tz_surface_rotation_find(ec);
87    if (tzsr) return;
88
89    tzsr = E_NEW(E_Comp_Screen_Tzsr, 1);
90    if (!tzsr)
91      {
92         wl_client_post_no_memory(client);
93         return;
94      }
95
96    tzsr->resource = resource;
97    tzsr->ec = ec;
98
99    ELOGF("TRANSFORM", "|tzsr(%p) client_ignore(%d)", NULL, ec, tzsr, e_config->screen_rotation_client_ignore);
100
101    tzsr_list = eina_list_append(tzsr_list, tzsr);
102
103    /* make all clients ignore the output tramsform
104     * we will decide later when hwc prepared.
105     */
106    e_comp_screen_rotation_ignore_output_transform_send(ec, EINA_TRUE);
107 }
108
109 static void
110 _tz_screen_rotation_iface_cb_destroy(struct wl_client *client, struct wl_resource *resource)
111 {
112    wl_resource_destroy(resource);
113 }
114
115 static const struct tizen_screen_rotation_interface _tz_screen_rotation_interface =
116 {
117    _tz_screen_rotation_get_ignore_output_transform,
118    _tz_screen_rotation_iface_cb_destroy,
119 };
120
121 static void _tz_screen_rotation_cb_destroy(struct wl_resource *resource)
122 {
123    E_Comp_Screen_Tzsr *tzsr = _tz_surface_rotation_find_with_resource(resource);
124    if (!tzsr) return;
125    _tz_surface_rotation_free(tzsr);
126 }
127
128 static void
129 _tz_screen_rotation_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
130 {
131    struct wl_resource *res;
132
133    if (!(res = wl_resource_create(client, &tizen_screen_rotation_interface, version, id)))
134      {
135         ERR("Could not create tizen_screen_rotation resource: %m");
136         wl_client_post_no_memory(client);
137         return;
138      }
139
140    wl_resource_set_implementation(res, &_tz_screen_rotation_interface, NULL, _tz_screen_rotation_cb_destroy);
141 }
142
143 static Eldbus_Message *
144 _e_comp_screen_dbus_get_cb(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
145 {
146    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
147    int rotation = 0;
148
149    if (e_comp && e_comp->e_comp_screen)
150      rotation = e_comp->e_comp_screen->rotation;
151
152    DBG("got screen-rotation 'get' request: %d", rotation);
153
154    eldbus_message_arguments_append(reply, "i", rotation);
155
156    return reply;
157 }
158
159 static const Eldbus_Method methods[] =
160 {
161    {"get", NULL, ELDBUS_ARGS({"i", "int32"}), _e_comp_screen_dbus_get_cb, 0},
162    {}
163 };
164
165 static const Eldbus_Signal signals[] = {
166    [E_COMP_SCREEN_SIGNAL_ROTATION_CHANGED] = {"changed", ELDBUS_ARGS({ "i", "rotation" }), 0},
167    {}
168 };
169
170 static const Eldbus_Service_Interface_Desc iface_desc = {
171      IFACE, methods, signals, NULL, NULL, NULL
172 };
173
174 static Eina_Bool
175 _e_comp_screen_dbus_init(void *data EINA_UNUSED)
176 {
177    E_Comp_Screen *e_comp_screen = e_comp->e_comp_screen;
178
179    if (e_comp_screen_conn) return ECORE_CALLBACK_CANCEL;
180
181    if (!e_comp_screen_conn)
182      e_comp_screen_conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SYSTEM);
183
184    if(!e_comp_screen_conn)
185      {
186         ecore_timer_add(1, _e_comp_screen_dbus_init, NULL);
187         return ECORE_CALLBACK_CANCEL;
188      }
189
190    e_comp_screen_iface = eldbus_service_interface_register(e_comp_screen_conn,
191                                                            PATH,
192                                                            &iface_desc);
193    EINA_SAFETY_ON_NULL_GOTO(e_comp_screen_iface, err);
194
195    if (e_comp_screen->rotation)
196      {
197         eldbus_service_signal_emit(e_comp_screen_iface, E_COMP_SCREEN_SIGNAL_ROTATION_CHANGED, e_comp_screen->rotation);
198         ELOGF("TRANSFORM", "screen-rotation sends signal: %d", NULL, NULL, e_comp_screen->rotation);
199      }
200
201    return ECORE_CALLBACK_CANCEL;
202
203 err:
204    if (e_comp_screen_conn)
205      {
206         eldbus_connection_unref(e_comp_screen_conn);
207         e_comp_screen_conn = NULL;
208      }
209
210    return ECORE_CALLBACK_CANCEL;
211 }
212
213 static char *
214 _layer_cap_to_str(tdm_layer_capability caps, tdm_layer_capability cap)
215 {
216    if (caps & cap)
217      {
218         if (cap == TDM_LAYER_CAPABILITY_CURSOR) return "cursor ";
219         else if (cap == TDM_LAYER_CAPABILITY_PRIMARY) return "primary ";
220         else if (cap == TDM_LAYER_CAPABILITY_OVERLAY) return "overlay ";
221         else if (cap == TDM_LAYER_CAPABILITY_GRAPHIC) return "graphics ";
222         else if (cap == TDM_LAYER_CAPABILITY_VIDEO) return "video ";
223         else if (cap == TDM_LAYER_CAPABILITY_TRANSFORM) return "transform ";
224         else if (cap == TDM_LAYER_CAPABILITY_RESEVED_MEMORY) return "reserved_memory ";
225         else if (cap == TDM_LAYER_CAPABILITY_NO_CROP) return "no_crop ";
226         else return "unkown";
227      }
228    return "";
229 }
230
231 static Eina_Bool
232 _e_comp_screen_commit_idle_cb(void *data EINA_UNUSED)
233 {
234    Eina_List *l, *ll;
235    E_Comp_Screen *e_comp_screen = NULL;
236    E_Output *output = NULL;
237
238    if (!e_comp->e_comp_screen) goto end;
239
240    if (e_config->comp_canvas_norender.use)
241      evas_norender(e_comp->evas);
242
243    e_comp_screen = e_comp->e_comp_screen;
244
245    EINA_LIST_FOREACH_SAFE(e_comp_screen->outputs, l, ll, output)
246      {
247         if (!output) continue;
248         if (!output->config.enabled) continue;
249
250         e_output_hwc_apply(output->output_hwc);
251
252         if (!e_output_commit(output))
253              ERR("fail to commit e_comp_screen->outputs.");
254
255         if (!e_output_render(output))
256              ERR("fail to render e_comp_screen->outputs.");
257      }
258 end:
259    return ECORE_CALLBACK_RENEW;
260 }
261
262 static Eina_Bool
263 _e_comp_screen_cb_input_device_add(void *data, int type, void *event)
264 {
265    E_Input_Event_Input_Device_Add *e;
266    E_Comp *comp = data;
267
268    if (!(e = event)) goto end;
269
270    if (e->caps & E_INPUT_SEAT_POINTER)
271      {
272         if (comp->wl_comp_data->ptr.num_devices == 0)
273           {
274              e_pointer_object_set(comp->pointer, NULL, 0, 0);
275              e_comp_wl_input_pointer_enabled_set(EINA_TRUE);
276           }
277         comp->wl_comp_data->ptr.num_devices++;
278      }
279    if (e->caps & E_INPUT_SEAT_KEYBOARD)
280      {
281         comp->wl_comp_data->kbd.num_devices++;
282         e_comp_wl_input_keyboard_enabled_set(EINA_TRUE);
283      }
284    if (e->caps & E_INPUT_SEAT_TOUCH)
285      {
286         e_comp_wl_input_touch_enabled_set(EINA_TRUE);
287         comp->wl_comp_data->touch.num_devices++;
288      }
289
290 end:
291    return ECORE_CALLBACK_PASS_ON;
292 }
293
294 static void
295 _e_comp_screen_pointer_renew(E_Input_Event_Input_Device_Del *ev)
296 {
297      if ((e_comp_wl->ptr.num_devices == 0) && e_comp_wl->ptr.ec && e_comp_wl->ptr.ec->pointer_enter_sent)
298      {
299         if (e_comp_wl->input_device_manager.last_device_ptr)
300           {
301              Evas_Device *last_ptr = NULL, *dev;
302              Eina_List *list, *l;
303
304              list = (Eina_List *)evas_device_list(evas_object_evas_get(e_comp_wl->ptr.ec->frame), NULL);
305              EINA_LIST_FOREACH(list, l, dev)
306                {
307                   if ((!strncmp(evas_device_name_get(dev), e_comp_wl->input_device_manager.last_device_ptr->name, strlen(e_comp_wl->input_device_manager.last_device_ptr->name))) &&
308                       (!strncmp(evas_device_description_get(dev), e_comp_wl->input_device_manager.last_device_ptr->identifier, strlen(e_comp_wl->input_device_manager.last_device_ptr->identifier))) &&
309                       (evas_device_class_get(dev) == (Evas_Device_Class)e_comp_wl->input_device_manager.last_device_ptr->clas))
310                     {
311                        last_ptr = dev;
312                        break;
313                     }
314                }
315              if (last_ptr)
316                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);
317           }
318      }
319 }
320
321 static Eina_Bool
322 _e_comp_screen_cb_input_device_del(void *data, int type, void *event)
323 {
324    E_Input_Event_Input_Device_Del *e;
325    E_Comp *comp = data;
326
327    if (!(e = event)) goto end;
328
329    if (e->caps & E_INPUT_SEAT_POINTER)
330      {
331         comp->wl_comp_data->ptr.num_devices--;
332         if (comp->wl_comp_data->ptr.num_devices == 0)
333           {
334              e_comp_wl_input_pointer_enabled_set(EINA_FALSE);
335              e_pointer_object_set(comp->pointer, NULL, 0, 0);
336              e_pointer_hide(e_comp->pointer);
337
338              _e_comp_screen_pointer_renew(e);
339           }
340      }
341    if (e->caps & E_INPUT_SEAT_KEYBOARD)
342      {
343         comp->wl_comp_data->kbd.num_devices--;
344         if (comp->wl_comp_data->kbd.num_devices == 0)
345           {
346              e_comp_wl_input_keyboard_enabled_set(EINA_FALSE);
347           }
348      }
349    if (e->caps & E_INPUT_SEAT_TOUCH)
350      {
351         comp->wl_comp_data->touch.num_devices--;
352         if (comp->wl_comp_data->touch.num_devices == 0)
353           {
354              e_comp_wl_input_touch_enabled_set(EINA_FALSE);
355           }
356      }
357
358 end:
359
360    return ECORE_CALLBACK_PASS_ON;
361 }
362
363 static void
364 _e_comp_screen_cb_ee_resize(Ecore_Evas *ee EINA_UNUSED)
365 {
366    e_comp_canvas_update();
367 }
368
369 static Eina_Bool
370 _e_comp_screen_cb_event(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
371 {
372    E_Comp_Screen *e_comp_screen;
373    tdm_error ret;
374
375    if (!(e_comp_screen = data)) return ECORE_CALLBACK_RENEW;
376
377    ret = tdm_display_handle_events(e_comp_screen->tdisplay);
378    if (ret != TDM_ERROR_NONE)
379      ERR("tdm_display_handle_events failed");
380
381    return ECORE_CALLBACK_RENEW;
382 }
383
384 static E_Comp_Screen *
385 _e_comp_screen_new(E_Comp *comp)
386 {
387    E_Comp_Screen *e_comp_screen = NULL;
388    tdm_error error = TDM_ERROR_NONE;
389    tdm_display_capability capabilities;
390    const tbm_format *pp_formats;
391    int count, i;
392    int fd;
393
394    e_comp_screen = E_NEW(E_Comp_Screen, 1);
395    if (!e_comp_screen) return NULL;
396
397    /* tdm display init */
398    e_comp_screen->tdisplay = tdm_display_init(&error);
399    if (!e_comp_screen->tdisplay)
400      {
401         ERR("fail to get tdm_display\n");
402         free(e_comp_screen);
403         return NULL;
404      }
405
406    e_comp_screen->fd = -1;
407    tdm_display_get_fd(e_comp_screen->tdisplay, &fd);
408    if (fd < 0)
409      {
410         ERR("fail to get tdm_display fd\n");
411         goto fail;
412      }
413
414    e_comp_screen->fd = dup(fd);
415
416    e_comp_screen->hdlr =
417      ecore_main_fd_handler_add(e_comp_screen->fd, ECORE_FD_READ,
418                                _e_comp_screen_cb_event, e_comp_screen, NULL, NULL);
419
420    /* tdm display init */
421    e_comp_screen->bufmgr = tbm_bufmgr_init(-1);
422    if (!e_comp_screen->bufmgr)
423      {
424         ERR("tbm_bufmgr_init failed\n");
425         goto fail;
426      }
427
428    error = tdm_display_get_capabilities(e_comp_screen->tdisplay, &capabilities);
429    if (error != TDM_ERROR_NONE)
430      {
431         ERR("tdm get_capabilities failed");
432         goto fail;
433      }
434
435    /* check the pp_support */
436    if (capabilities & TDM_DISPLAY_CAPABILITY_PP)
437      {
438         error = tdm_display_get_pp_available_formats(e_comp_screen->tdisplay, &pp_formats, &count);
439         if (error != TDM_ERROR_NONE)
440           ERR("fail to get available pp formats");
441         else
442           {
443              e_comp_screen->pp_enabled = EINA_TRUE;
444              for (i = 0 ; i < count ; i++)
445                e_comp_screen->available_pp_formats = eina_list_append(e_comp_screen->available_pp_formats, &pp_formats[i]);
446           }
447      }
448
449    if (e_comp_socket_init("tdm-socket"))
450      PRCTL("[Winsys] change permission and create sym link for %s", "tdm-socket");
451
452    return e_comp_screen;
453
454 fail:
455    if (e_comp_screen->bufmgr) tbm_bufmgr_deinit(e_comp_screen->bufmgr);
456    if (e_comp_screen->fd >= 0) close(e_comp_screen->fd);
457    if (e_comp_screen->hdlr) ecore_main_fd_handler_del(e_comp_screen->hdlr);
458    if (e_comp_screen->tdisplay) tdm_display_deinit(e_comp_screen->tdisplay);
459
460    free(e_comp_screen);
461
462    return NULL;
463 }
464
465 static void
466 _e_comp_screen_del(E_Comp_Screen *e_comp_screen)
467 {
468    Eina_List *l = NULL, *ll = NULL;
469    tbm_format *formats;
470
471    if (!e_comp_screen) return;
472
473    if (e_comp_screen->pp_enabled)
474      {
475         EINA_LIST_FOREACH_SAFE(e_comp_screen->available_pp_formats, l, ll, formats)
476           {
477              if (!formats) continue;
478              e_comp_screen->available_pp_formats = eina_list_remove(e_comp_screen->available_pp_formats, l);
479           }
480      }
481    if (e_comp_screen->bufmgr) tbm_bufmgr_deinit(e_comp_screen->bufmgr);
482    if (e_comp_screen->fd >= 0) close(e_comp_screen->fd);
483    if (e_comp_screen->hdlr) ecore_main_fd_handler_del(e_comp_screen->hdlr);
484    if (e_comp_screen->tdisplay) tdm_display_deinit(e_comp_screen->tdisplay);
485
486    free(e_comp_screen);
487 }
488
489 static void
490 _e_comp_screen_deinit_outputs(E_Comp_Screen *e_comp_screen)
491 {
492    E_Output *output;
493    Eina_List *l, *ll;
494
495    // free up e_outputs
496    EINA_LIST_FOREACH_SAFE(e_comp_screen->outputs, l, ll, output)
497      {
498         e_comp_screen->outputs = eina_list_remove_list(e_comp_screen->outputs, l);
499         e_output_del(output);
500      }
501
502    e_output_shutdown();
503 }
504
505 static Eina_Bool
506 _e_comp_screen_init_outputs(E_Comp_Screen *e_comp_screen)
507 {
508    E_Output *output = NULL;
509    E_Output_Mode *mode = NULL;
510    tdm_display *tdisplay = e_comp_screen->tdisplay;
511    int num_outputs;
512    int i;
513    Eina_Bool scale_updated = EINA_FALSE;
514
515    /* init e_output */
516    if (!e_output_init())
517      {
518         ERR("fail to e_output_init.");
519         return EINA_FALSE;
520      }
521
522    /* get the num of outputs */
523    tdm_display_get_output_count(tdisplay, &num_outputs);
524    if (num_outputs < 1)
525      {
526         ERR("fail to get tdm_display_get_output_count\n");
527         return EINA_FALSE;
528      }
529    e_comp_screen->num_outputs = num_outputs;
530
531    INF("E_COMP_SCREEN: num_outputs = %i", e_comp_screen->num_outputs);
532
533    for (i = 0; i < num_outputs; i++)
534      {
535         output = e_output_new(e_comp_screen, i);
536         if (!output) goto fail;
537
538         if (!e_output_update(output))
539           {
540             ERR("fail to e_output_update.");
541             goto fail;
542           }
543
544         e_comp_screen->outputs = eina_list_append(e_comp_screen->outputs, output);
545
546         if (!e_output_connected(output)) continue;
547
548         /* setting with the best mode and enable the output */
549         mode = e_output_best_mode_find(output);
550         if (!mode)
551           {
552              ERR("fail to get best mode.");
553              goto fail;
554           }
555
556         if (!e_output_mode_apply(output, mode))
557           {
558              ERR("fail to e_output_mode_apply.");
559              goto fail;
560           }
561         if (!e_output_dpms_set(output, E_OUTPUT_DPMS_ON))
562           {
563              ERR("fail to e_output_dpms.");
564              goto fail;
565           }
566
567         /* update e_scale with first available output size */
568         if ((e_config->scale.for_tdm) && (!scale_updated))
569           {
570              double target_inch;
571              int dpi;
572
573              target_inch = (round((sqrt(output->info.size.w * output->info.size.w + output->info.size.h * output->info.size.h) / 25.4) * 10) / 10);
574              dpi = (round((sqrt(mode->w * mode->w + mode->h * mode->h) / target_inch) * 10) / 10);
575
576              e_scale_manual_update(dpi);
577              scale_updated = EINA_TRUE;
578           }
579      }
580
581    //TODO: if there is no output connected, make the fake output which is connected.
582
583
584    return EINA_TRUE;
585 fail:
586    _e_comp_screen_deinit_outputs(e_comp_screen);
587
588    return EINA_FALSE;
589 }
590
591 static void *
592 _e_comp_screen_tbm_queue_alloc(void *data EINA_UNUSED, int w, int h)
593 {
594    E_Comp_Screen *e_comp_screen = NULL;
595    tbm_surface_queue_h tqueue = NULL;
596
597    tqueue = tbm_surface_queue_create(3, w, h, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
598
599    e_comp->e_comp_screen->tqueue = tqueue;
600
601    return (void *)tqueue;
602 }
603
604 static void
605 _e_comp_screen_tbm_queue_free(void *data EINA_UNUSED, void *tbm_queue)
606 {
607    E_Comp_Screen *e_comp_screen = NULL;
608
609    tbm_surface_queue_destroy(tbm_queue);
610    e_comp->e_comp_screen->tqueue = NULL;
611 }
612
613 E_API void
614 _e_comp_screen_keymap_set(struct xkb_context **ctx, struct xkb_keymap **map)
615 {
616    char *keymap_path = NULL;
617    struct xkb_context *context;
618    struct xkb_keymap *keymap;
619    struct xkb_rule_names names = {0,};
620    const char* default_rules, *default_model, *default_layout, *default_variant, *default_options;
621
622    TRACE_INPUT_BEGIN(_e_comp_screen_keymap_set);
623
624    context = xkb_context_new(0);
625    EINA_SAFETY_ON_NULL_RETURN(context);
626
627    /* assemble xkb_rule_names so we can fetch keymap */
628    memset(&names, 0, sizeof(names));
629
630    default_rules = e_comp_wl_input_keymap_default_rules_get();
631    default_model = e_comp_wl_input_keymap_default_model_get();
632    default_layout = e_comp_wl_input_keymap_default_layout_get();
633    default_variant = e_comp_wl_input_keymap_default_variant_get();
634    default_options = e_comp_wl_input_keymap_default_options_get();
635
636    names.rules = strdup(default_rules);
637    names.model = strdup(default_model);
638    names.layout = strdup(default_layout);
639    if (default_variant) names.variant = strdup(default_variant);
640    if (default_options) names.options = strdup(default_options);
641
642    keymap = e_comp_wl_input_keymap_compile(context, names, &keymap_path);
643    eina_stringshare_del(keymap_path);
644    EINA_SAFETY_ON_NULL_GOTO(keymap, cleanup);
645
646    *ctx = context;
647    *map = keymap;
648
649    if (dont_set_e_input_keymap == EINA_FALSE)
650      {
651         e_input_device_keyboard_cached_context_set(*ctx);
652         e_input_device_keyboard_cached_keymap_set(*map);
653      }
654
655 cleanup:
656    free((char *)names.rules);
657    free((char *)names.model);
658    free((char *)names.layout);
659    if (names.variant) free((char *)names.variant);
660    if (names.options) free((char *)names.options);
661
662    TRACE_INPUT_END();
663 }
664
665 static int
666 _e_comp_screen_e_screen_sort_cb(const void *data1, const void *data2)
667 {
668    const E_Output *s1 = data1, *s2 = data2;
669    int dif;
670
671    dif = -(s1->config.priority - s2->config.priority);
672    if (dif == 0)
673      {
674         dif = s1->config.geom.x - s2->config.geom.x;
675         if (dif == 0)
676           dif = s1->config.geom.y - s2->config.geom.y;
677      }
678    return dif;
679 }
680
681 static void
682 _e_comp_screen_e_screen_free(E_Screen *scr)
683 {
684    free(scr->id);
685    free(scr);
686 }
687
688 static void
689 _e_comp_screen_e_screens_set(E_Comp_Screen *e_comp_screen, Eina_List *screens)
690 {
691    E_FREE_LIST(e_comp_screen->e_screens, _e_comp_screen_e_screen_free);
692    e_comp_screen->e_screens = screens;
693 }
694
695 static void
696 _e_comp_screen_engine_deinit(void)
697 {
698    if (!e_comp) return;
699    if (!e_comp->e_comp_screen) return;
700
701    _e_comp_screen_deinit_outputs(e_comp->e_comp_screen);
702    _e_comp_screen_del(e_comp->e_comp_screen);
703    e_comp->e_comp_screen = NULL;
704 }
705
706 static Eina_Bool
707 _e_comp_screen_engine_init(void)
708 {
709    E_Comp_Screen *e_comp_screen = NULL;
710    int w = 0, h = 0, scr_w = 1, scr_h = 1;
711    int screen_rotation;
712    char buf[1024];
713    E_Output *output = NULL;
714    tbm_surface_queue_h tqueue = NULL;
715
716    INF("ecore evase engine init with TDM. HWC.");
717
718    /* check the screen rotation */
719    screen_rotation = (e_config->screen_rotation_pre + e_config->screen_rotation_setting) % 360;
720
721    INF("E_COMP_SCREEN: screen_rotation_pre %d and screen_rotation_setting %d",
722        e_config->screen_rotation_pre, e_config->screen_rotation_setting);
723
724    /* set env for use tbm_surface_queue*/
725    setenv("USE_EVAS_SOFTWARE_TBM_ENGINE", "1", 1);
726    //setenv("USE_EVAS_GL_TBM_ENGINE", "1", 1);
727
728    /* set gl available if we have ecore_evas support */
729    if (ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_OPENGL_DRM) ||
730        ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_OPENGL_TBM))
731      e_comp_gl_set(EINA_TRUE);
732
733    /* e_comp_screen new */
734    e_comp_screen = _e_comp_screen_new(e_comp);
735    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen, EINA_FALSE);
736
737    e_comp->e_comp_screen = e_comp_screen;
738    e_comp_screen->rotation = screen_rotation;
739
740    e_main_ts_begin("\tE_Outputs Init");
741    if (!_e_comp_screen_init_outputs(e_comp_screen))
742      {
743         e_main_ts_end("\tE_Outputs Init Failed");
744         e_error_message_show(_("Enlightenment cannot initialize outputs!\n"));
745         _e_comp_screen_engine_deinit();
746         return EINA_FALSE;
747      }
748    e_main_ts_end("\tE_Outputs Init Done");
749
750    /* get the primary output */
751    output = e_comp_screen_primary_output_get(e_comp_screen);
752    if (!output)
753      {
754         e_error_message_show(_("Fail to get the primary output!\n"));
755         _e_comp_screen_engine_deinit();
756         return EINA_FALSE;
757      }
758
759    /* get the size of the primary output */
760    e_output_size_get(output, &scr_w, &scr_h);
761
762    /* if output is disconnected, set the default width, height */
763    if (scr_w == 0 || scr_h == 0)
764      {
765         scr_w = 2;
766         scr_h = 1;
767
768         if (!e_output_fake_config_set(output, scr_w, scr_h))
769           {
770              e_error_message_show(_("Fail to set the fake output config!\n"));
771              _e_comp_screen_engine_deinit();
772              return EINA_FALSE;
773           }
774      }
775
776    INF("GL available:%d config engine:%d screen size:%dx%d",
777        e_comp_gl_get(), e_comp_config_get()->engine, scr_w, scr_h);
778
779    if ((e_comp_gl_get()) &&
780        (e_comp_config_get()->engine == E_COMP_ENGINE_GL))
781      {
782         e_main_ts_begin("\tEE_GL_DRM New");
783         e_comp->ee = ecore_evas_tbm_allocfunc_new("gl_tbm", scr_w, scr_h, _e_comp_screen_tbm_queue_alloc, _e_comp_screen_tbm_queue_free, NULL);
784         snprintf(buf, sizeof(buf), "\tEE_GL_DRM New Done %p %dx%d", e_comp->ee, scr_w, scr_h);
785         e_main_ts_end(buf);
786
787         if (!e_comp->ee)
788           e_comp_gl_set(EINA_FALSE);
789         else
790           {
791              Evas_GL *evasgl = NULL;
792              Evas_GL_API *glapi = NULL;
793
794              e_main_ts_begin("\tEvas_GL New");
795              evasgl = evas_gl_new(ecore_evas_get(e_comp->ee));
796              if (evasgl)
797                {
798                   glapi = evas_gl_api_get(evasgl);
799                   if (!((glapi) && (glapi->evasglBindWaylandDisplay)))
800                     {
801                        e_comp_gl_set(EINA_FALSE);
802                        ecore_evas_free(e_comp->ee);
803                        e_comp->ee = NULL;
804                        e_main_ts_end("\tEvas_GL New Failed 1");
805                     }
806                   else
807                     {
808                        e_main_ts_end("\tEvas_GL New Done");
809                     }
810                }
811              else
812                {
813                   e_comp_gl_set(EINA_FALSE);
814                   ecore_evas_free(e_comp->ee);
815                   e_comp->ee = NULL;
816                   e_main_ts_end("\tEvas_GL New Failed 2");
817                }
818              evas_gl_free(evasgl);
819           }
820      }
821
822    /* fallback to framebuffer drm (non-accel) */
823    if (!e_comp->ee)
824      {
825         e_main_ts_begin("\tEE_DRM New");
826         e_comp->ee = ecore_evas_tbm_allocfunc_new("software_tbm", scr_w, scr_h, _e_comp_screen_tbm_queue_alloc, _e_comp_screen_tbm_queue_free, NULL);
827         snprintf(buf, sizeof(buf), "\tEE_DRM New Done %p %dx%d", e_comp->ee, scr_w, scr_h);
828         e_main_ts_end(buf);
829      }
830
831    if (!e_comp->ee)
832      {
833         e_error_message_show(_("Enlightenment cannot initialize outputs!\n"));
834         _e_comp_screen_engine_deinit();
835         return EINA_FALSE;
836      }
837
838    ecore_evas_data_set(e_comp->ee, "comp", e_comp);
839
840    ecore_evas_callback_resize_set(e_comp->ee, _e_comp_screen_cb_ee_resize);
841
842    if (screen_rotation)
843      {
844         /* SHOULD called with resize option after ecore_evas_resize */
845         ecore_evas_rotation_with_resize_set(e_comp->ee, screen_rotation);
846         ecore_evas_geometry_get(e_comp->ee, NULL, NULL, &w, &h);
847
848         snprintf(buf, sizeof(buf), "\tEE Rotate and Resize %d, %dx%d", screen_rotation, w, h);
849         e_main_ts(buf);
850      }
851
852    if (!E_EVENT_SCREEN_CHANGE) E_EVENT_SCREEN_CHANGE = ecore_event_type_new();
853
854    ecore_event_add(E_EVENT_SCREEN_CHANGE, NULL, NULL, NULL);
855
856    e_comp_screen_e_screens_setup(e_comp_screen, -1, -1);
857
858    /* update the screen, outputs and planes at the idle enterer of the ecore_loop */
859    ecore_idle_enterer_add(_e_comp_screen_commit_idle_cb, e_comp);
860
861    return EINA_TRUE;
862 }
863
864 EINTERN void
865 e_comp_screen_e_screens_setup(E_Comp_Screen *e_comp_screen, int rw, int rh)
866 {
867    int i;
868    E_Screen *screen;
869    Eina_List *outputs = NULL, *outputs_rem;
870    Eina_List *e_screens = NULL;
871    Eina_List *l, *ll;
872    E_Output *output, *s2, *s_chosen;
873    Eina_Bool removed;
874
875    if (!e_comp_screen->outputs) goto out;
876    // put screens in tmp list
877    EINA_LIST_FOREACH(e_comp_screen->outputs, l, output)
878      {
879         if ((output->config.enabled) &&
880             (output->config.geom.w > 0) &&
881             (output->config.geom.h > 0))
882           {
883              outputs = eina_list_append(outputs, output);
884           }
885      }
886    // remove overlapping screens - if a set of screens overlap, keep the
887    // smallest/lowest res
888    do
889      {
890         removed = EINA_FALSE;
891
892         EINA_LIST_FOREACH(outputs, l, output)
893           {
894              outputs_rem = NULL;
895
896              EINA_LIST_FOREACH(l->next, ll, s2)
897                {
898                   if (E_INTERSECTS(output->config.geom.x, output->config.geom.y,
899                                    output->config.geom.w, output->config.geom.h,
900                                    s2->config.geom.x, s2->config.geom.y,
901                                    s2->config.geom.w, s2->config.geom.h))
902                     {
903                        if (!outputs_rem)
904                          outputs_rem = eina_list_append(outputs_rem, output);
905                        outputs_rem = eina_list_append(outputs_rem, s2);
906                     }
907                }
908              // we have intersecting screens - choose the lowest res one
909              if (outputs_rem)
910                {
911                   removed = EINA_TRUE;
912                   // find the smallest screen (chosen one)
913                   s_chosen = NULL;
914                   EINA_LIST_FOREACH(outputs_rem, ll, s2)
915                     {
916                        if (!s_chosen) s_chosen = s2;
917                        else
918                          {
919                             if ((s_chosen->config.geom.w *
920                                  s_chosen->config.geom.h) >
921                                 (s2->config.geom.w *
922                                  s2->config.geom.h))
923                               s_chosen = s2;
924                          }
925                     }
926                   // remove all from screens but the chosen one
927                   EINA_LIST_FREE(outputs_rem, s2)
928                     {
929                        if (s2 != s_chosen)
930                          outputs = eina_list_remove_list(outputs, l);
931                     }
932                   // break our list walk and try again
933                   break;
934                }
935           }
936      }
937    while (removed);
938    // sort screens by priority etc.
939    outputs = eina_list_sort(outputs, 0, _e_comp_screen_e_screen_sort_cb);
940    i = 0;
941    EINA_LIST_FOREACH(outputs, l, output)
942      {
943         screen = E_NEW(E_Screen, 1);
944         if (!screen) continue;
945         screen->escreen = screen->screen = i;
946         screen->x = output->config.geom.x;
947         screen->y = output->config.geom.y;
948
949         if (output->config.rotation % 180)
950           {
951              screen->w = output->config.geom.h;
952              screen->h = output->config.geom.w;
953           }
954         else
955           {
956              screen->w = output->config.geom.w;
957              screen->h = output->config.geom.h;
958           }
959
960         if (output->id) screen->id = strdup(output->id);
961
962         e_screens = eina_list_append(e_screens, screen);
963         INF("E INIT: SCREEN: [%i][%i], %ix%i+%i+%i",
964             i, i, screen->w, screen->h, screen->x, screen->y);
965         i++;
966      }
967    eina_list_free(outputs);
968    // if we have NO screens at all (above - i will be 0) AND we have no
969    // existing screens set up in xinerama - then just say root window size
970    // is the entire screen. this should handle the case where you unplug ALL
971    // screens from an existing setup (unplug external monitors and/or close
972    // laptop lid), in which case as long as at least one screen is configured
973    // in xinerama, it will be left-as is until next time we re-eval screen
974    // setup and have at least one screen
975    printf("e_comp_screen_e_screens_setup............... %i %p\n", i, e_comp_screen->e_screens);
976    if ((i == 0) && (!e_comp_screen->e_screens))
977      {
978 out:
979         screen = E_NEW(E_Screen, 1);
980         if (!screen) return;
981         screen->escreen = screen->screen = 0;
982         screen->x = 0;
983         screen->y = 0;
984         if ((rw > 0) && (rh > 0))
985           screen->w = rw, screen->h = rh;
986         else
987           {
988              if (e_comp_screen->rotation % 180)
989                ecore_evas_geometry_get(e_comp->ee, NULL, NULL, &screen->h, &screen->w);
990              else
991                ecore_evas_geometry_get(e_comp->ee, NULL, NULL, &screen->w, &screen->h);
992           }
993         e_screens = eina_list_append(e_screens, screen);
994      }
995    _e_comp_screen_e_screens_set(e_comp_screen, e_screens);
996 }
997
998 EINTERN const Eina_List *
999 e_comp_screen_e_screens_get(E_Comp_Screen *e_comp_screen)
1000 {
1001    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen, NULL);
1002
1003    return e_comp_screen->e_screens;
1004 }
1005
1006 E_API Eina_Bool
1007 e_comp_screen_init()
1008 {
1009    E_Comp *comp;
1010    int w, h;
1011    struct xkb_context *ctx = NULL;
1012    struct xkb_keymap *map = NULL;
1013
1014    TRACE_DS_BEGIN(E_COMP_SCREEN:INIT);
1015    if (!(comp = e_comp))
1016      {
1017         TRACE_DS_END();
1018         EINA_SAFETY_ON_NULL_RETURN_VAL(comp, EINA_FALSE);
1019      }
1020
1021    /* keymap */
1022    dont_set_e_input_keymap = getenv("NO_E_INPUT_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
1023    dont_use_xkb_cache = getenv("NO_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
1024
1025    if (e_config->xkb.use_cache && !dont_use_xkb_cache)
1026      {
1027         e_main_ts_begin("\tDRM Keymap Init");
1028         _e_comp_screen_keymap_set(&ctx, &map);
1029         e_main_ts_end("\tDRM Keymap Init Done");
1030      }
1031
1032    if (!_e_comp_screen_engine_init())
1033      {
1034         ERR("Could not initialize the ecore_evas engine.");
1035         goto failed_comp_screen;
1036      }
1037
1038    if (!e_input_init(e_comp->ee))
1039      {
1040         ERR("Could not initialize the e_input.");
1041         goto failed_comp_screen;
1042      }
1043
1044    e_main_ts("\tE_Comp_Wl Init");
1045    if (!e_comp_wl_init())
1046      {
1047         goto failed_comp_screen_with_ts;
1048      }
1049    e_main_ts_end("\tE_Comp_Wl Init Done");
1050
1051    /* get the current screen geometry */
1052    ecore_evas_geometry_get(e_comp->ee, NULL, NULL, &w, &h);
1053
1054    /* canvas */
1055    e_main_ts_begin("\tE_Comp_Canvas Init");
1056    if (!e_comp_canvas_init(w, h))
1057      {
1058         e_error_message_show(_("Enlightenment cannot initialize outputs!\n"));
1059         goto failed_comp_screen_with_ts;
1060      }
1061    e_main_ts_end("\tE_Comp_Canvas Init Done");
1062
1063    /* pointer */
1064    ecore_evas_pointer_xy_get(e_comp->ee,
1065                              &e_comp_wl->ptr.x,
1066                              &e_comp_wl->ptr.y);
1067
1068    evas_event_feed_mouse_in(e_comp->evas, 0, NULL);
1069
1070    e_main_ts_begin("\tE_Pointer New");
1071    if ((comp->pointer = e_pointer_canvas_new(comp->ee, EINA_TRUE)))
1072      {
1073         e_pointer_hide(comp->pointer);
1074      }
1075    e_main_ts_end("\tE_Pointer New Done");
1076
1077    /* FIXME: We need a way to trap for user changing the keymap inside of E
1078     *        without the event coming from X11 */
1079
1080    /* FIXME: We should make a decision here ...
1081     *
1082     * Fetch the keymap from drm, OR set this to what the E config is....
1083     */
1084
1085    /* FIXME: This is just for testing at the moment....
1086     * happens to jive with what drm does */
1087    e_main_ts_begin("\tE_Comp_WL Keymap Init");
1088    e_comp_wl_input_keymap_set(e_comp_wl_input_keymap_default_rules_get(),
1089                               e_comp_wl_input_keymap_default_model_get(),
1090                               e_comp_wl_input_keymap_default_layout_get(),
1091                               e_comp_wl_input_keymap_default_variant_get(),
1092                               e_comp_wl_input_keymap_default_options_get(),
1093                               ctx, map);
1094    e_main_ts_end("\tE_Comp_WL Keymap Init Done");
1095
1096    /* try to add tizen_video to wayland globals */
1097    if (!wl_global_create(e_comp_wl->wl.disp, &tizen_screen_rotation_interface, 1,
1098                          NULL, _tz_screen_rotation_cb_bind))
1099      {
1100         ERR("Could not add tizen_screen_rotation to wayland globals");
1101         goto failed_comp_screen;
1102      }
1103
1104    /* this setup function is called after e_comp_canvas_init */
1105    if (!e_comp_screen_setup(e_comp->e_comp_screen))
1106      {
1107         ERR("fail to e_comp_screen_setup");
1108         return EINA_FALSE;
1109      }
1110
1111    if (eldbus_init() == 0)
1112      {
1113         ERR("eldbus_init failed");
1114         goto failed_comp_screen;
1115      }
1116
1117    _e_comp_screen_dbus_init(NULL);
1118
1119    tzsr_client_hook_del = e_client_hook_add(E_CLIENT_HOOK_DEL, _tz_screen_rotation_cb_client_del, NULL);
1120
1121    E_LIST_HANDLER_APPEND(event_handlers, E_INPUT_EVENT_INPUT_DEVICE_ADD, _e_comp_screen_cb_input_device_add, comp);
1122    E_LIST_HANDLER_APPEND(event_handlers, E_INPUT_EVENT_INPUT_DEVICE_DEL, _e_comp_screen_cb_input_device_del, comp);
1123
1124    if (e_comp->e_comp_screen->rotation > 0)
1125      {
1126          const Eina_List *l;
1127          E_Input_Device *dev;
1128
1129          EINA_LIST_FOREACH(e_input_devices_get(), l, dev)
1130            {
1131                e_input_device_touch_rotation_set(dev, e_comp->e_comp_screen->rotation);
1132                e_input_device_rotation_set(dev, e_comp->e_comp_screen->rotation);
1133
1134                INF("EE Input Device Rotate: %d", e_comp->e_comp_screen->rotation);
1135            }
1136      }
1137
1138    TRACE_DS_END();
1139
1140    return EINA_TRUE;
1141
1142 failed_comp_screen_with_ts:
1143    e_main_ts_end("\tE_Comp_Screen init failed");
1144 failed_comp_screen:
1145
1146    e_input_shutdown();
1147    _e_comp_screen_engine_deinit();
1148
1149    TRACE_DS_END();
1150
1151    return EINA_FALSE;
1152 }
1153
1154 E_API void
1155 e_comp_screen_shutdown()
1156 {
1157    if (!e_comp) return;
1158    if (!e_comp->e_comp_screen) return;
1159
1160    if (e_comp_screen_iface)
1161      {
1162         eldbus_service_interface_unregister(e_comp_screen_iface);
1163         e_comp_screen_iface = NULL;
1164      }
1165
1166    if (e_comp_screen_conn)
1167      {
1168         eldbus_connection_unref(e_comp_screen_conn);
1169         e_comp_screen_conn = NULL;
1170      }
1171
1172    eldbus_shutdown();
1173
1174    _e_comp_screen_deinit_outputs(e_comp->e_comp_screen);
1175
1176    e_client_hook_del(tzsr_client_hook_del);
1177    tzsr_client_hook_del = NULL;
1178
1179    dont_set_e_input_keymap = EINA_FALSE;
1180    dont_use_xkb_cache = EINA_FALSE;
1181    E_FREE_LIST(event_handlers, ecore_event_handler_del);
1182
1183    /* delete e_comp_sreen */
1184    _e_comp_screen_del(e_comp->e_comp_screen);
1185    e_comp->e_comp_screen = NULL;
1186 }
1187
1188 EINTERN Eina_Bool
1189 e_comp_screen_setup(E_Comp_Screen *e_comp_screen)
1190 {
1191    Eina_List *l, *ll;
1192    E_Output *output = NULL;
1193
1194    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen, EINA_FALSE);
1195
1196    EINA_LIST_FOREACH_SAFE(e_comp_screen->outputs, l, ll, output)
1197      {
1198         if (!output) continue;
1199         if (!output->config.enabled) continue;
1200
1201         if (!e_output_setup(output))
1202           {
1203              ERR("fail to e_output_setup.");
1204              continue;
1205           }
1206
1207         INF("Enlightenment succeeded to initialize e_output_setup()!\n");
1208      }
1209
1210    return EINA_TRUE;
1211 }
1212
1213 E_API Eina_Bool
1214 e_comp_screen_rotation_setting_set(E_Comp_Screen *e_comp_screen, int rotation)
1215 {
1216    E_Output *output = NULL, *o;
1217    const Eina_List *l;
1218    int w, h;
1219    int screen_rotation;
1220    E_Input_Device *dev;
1221
1222    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen, EINA_FALSE);
1223    EINA_SAFETY_ON_TRUE_RETURN_VAL(rotation % 90, EINA_FALSE);
1224    EINA_SAFETY_ON_TRUE_RETURN_VAL(rotation < 0, EINA_FALSE);
1225    EINA_SAFETY_ON_TRUE_RETURN_VAL(rotation > 270, EINA_FALSE);
1226
1227    if (e_config->screen_rotation_setting == rotation) return EINA_TRUE;
1228
1229    EINA_LIST_FOREACH(e_comp_screen->outputs, l, o)
1230      {
1231         unsigned int pipe = 0;
1232         tdm_error error;
1233
1234         error = tdm_output_get_pipe(o->toutput, &pipe);
1235         if (error != TDM_ERROR_NONE || pipe != 0)
1236           continue;
1237
1238         output = o;
1239         break;
1240      }
1241
1242    if (!output)
1243      {
1244         ERR("couldn't find the primary output");
1245         return EINA_FALSE;
1246      }
1247
1248    screen_rotation = (e_config->screen_rotation_pre + rotation) % 360;
1249
1250    if (!e_output_rotate(output, screen_rotation))
1251      return EINA_FALSE;
1252
1253    /* TODO: need to save e_config->screen_rotation_setting to e_config data file */
1254    e_config->screen_rotation_setting = rotation;
1255    e_comp_screen->rotation = screen_rotation;
1256
1257    ecore_evas_rotation_with_resize_set(e_comp->ee, e_comp_screen->rotation);
1258    ecore_evas_geometry_get(e_comp->ee, NULL, NULL, &w, &h);
1259
1260    /* rendering forcely to prepare HWC */
1261    e_comp_render_queue();
1262    e_comp_hwc_end(__FUNCTION__);
1263
1264    EINA_LIST_FOREACH(e_input_devices_get(), l, dev)
1265      {
1266          e_input_device_touch_rotation_set(dev, e_comp_screen->rotation);
1267          e_input_device_rotation_set(dev, e_comp_screen->rotation);
1268
1269          INF("EE Input Device Rotate: %d", e_comp_screen->rotation);
1270      }
1271
1272    if (e_comp_screen_iface)
1273      {
1274         eldbus_service_signal_emit(e_comp_screen_iface, E_COMP_SCREEN_SIGNAL_ROTATION_CHANGED, e_comp_screen->rotation);
1275         ELOGF("TRANSFORM", "screen-rotation sends signal: %d", NULL, NULL, e_comp_screen->rotation);
1276      }
1277
1278    INF("EE Rotated and Resized: %d, %dx%d", e_comp_screen->rotation, w, h);
1279
1280    return EINA_TRUE;
1281 }
1282
1283 E_API void
1284 e_comp_screen_rotation_ignore_output_transform_send(E_Client *ec, Eina_Bool ignore)
1285 {
1286    E_Comp_Screen_Tzsr *tzsr = _tz_surface_rotation_find(ec);
1287
1288    if (!tzsr) return;
1289
1290    /* if client have to considers the output transform */
1291    if (!ignore)
1292      {
1293         /* exception */
1294         if (e_config->screen_rotation_client_ignore)
1295           {
1296              ELOGF("TRANSFORM", "|tzsr(%p) ignore_output_transform: client_ignore", NULL, ec, tzsr);
1297              return;
1298           }
1299
1300         if (e_policy_client_is_quickpanel(ec))
1301            {
1302               ELOGF("TRANSFORM", "|tzsr(%p) ignore_output_transform: quickpanel", NULL, ec, tzsr);
1303               return;
1304            }
1305      }
1306
1307    ELOGF("TRANSFORM", "|tzsr(%p) ignore_output_transform(%d)", NULL, ec, tzsr, ignore);
1308
1309    tizen_screen_rotation_send_ignore_output_transform(tzsr->resource, ec->comp_data->surface, ignore);
1310 }
1311
1312 EINTERN Eina_Bool
1313 e_comp_screen_rotation_ignore_output_transform_watch(E_Client *ec)
1314 {
1315    return (_tz_surface_rotation_find(ec)) ? EINA_TRUE : EINA_FALSE;
1316 }
1317
1318 EINTERN E_Output *
1319 e_comp_screen_primary_output_get(E_Comp_Screen *e_comp_screen)
1320 {
1321    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen, NULL);
1322
1323    E_Output *output = NULL, *o = NULL;
1324    Eina_List *l = NULL;
1325    int highest_priority = 0;
1326
1327    /* find the highest priority of the e_output */
1328    EINA_LIST_FOREACH(e_comp_screen->outputs, l, o)
1329      {
1330         if (highest_priority < o->config.priority)
1331           {
1332              highest_priority = o->config.priority;
1333              output = o;
1334           }
1335      }
1336
1337    return output;
1338 }
1339
1340 EINTERN Eina_Bool
1341 e_comp_screen_pp_support(void)
1342 {
1343    E_Comp_Screen *e_comp_screen = NULL;
1344    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp, EINA_FALSE);
1345
1346    e_comp_screen = e_comp->e_comp_screen;
1347    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen, EINA_FALSE);
1348    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen->tdisplay, EINA_FALSE);
1349
1350    return e_comp_screen->pp_enabled;
1351 }
1352
1353
1354 EINTERN Eina_List *
1355 e_comp_screen_pp_available_formats_get(void)
1356 {
1357   E_Comp_Screen *e_comp_screen = NULL;
1358   EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp, EINA_FALSE);
1359
1360   e_comp_screen = e_comp->e_comp_screen;
1361   EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen, EINA_FALSE);
1362   EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen->tdisplay, EINA_FALSE);
1363
1364   if (!e_comp_screen->pp_enabled)
1365     {
1366        ERR("pp does not support.");
1367        return NULL;
1368     }
1369
1370    return e_comp_screen->available_pp_formats;
1371 }
1372
1373 EINTERN void
1374 e_comp_screen_hwc_info_debug(void)
1375 {
1376    EINA_SAFETY_ON_NULL_RETURN(e_comp);
1377    EINA_SAFETY_ON_NULL_RETURN(e_comp->e_comp_screen);
1378
1379    E_Comp_Screen *e_comp_screen = e_comp->e_comp_screen;
1380    E_Output *output = NULL;
1381    E_Plane *plane = NULL;
1382    Eina_List *l_o, *ll_o;
1383    Eina_List *l_l, *ll_l;
1384    tdm_output_conn_status conn_status;
1385    int output_idx = 0;
1386    tdm_layer_capability layer_capabilities;
1387    char layer_cap[4096] = {0, };
1388
1389    INF("HWC: HWC Information ==========================================================");
1390    EINA_LIST_FOREACH_SAFE(e_comp_screen->outputs, l_o, ll_o, output)
1391      {
1392         if (!output) continue;
1393
1394         if (e_output_hwc_policy_get(output->output_hwc) == E_OUTPUT_HWC_POLICY_PLANES)
1395           {
1396              tdm_output_get_conn_status(output->toutput, &conn_status);
1397              if (conn_status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) continue;
1398
1399              INF("HWC: HWC Output(%d):(x, y, w, h)=(%d, %d, %d, %d) Information.",
1400                  ++output_idx,
1401                  output->config.geom.x, output->config.geom.y, output->config.geom.w, output->config.geom.h);
1402              INF("HWC:  num_layers=%d", output->plane_count);
1403              EINA_LIST_FOREACH_SAFE(output->planes, l_l, ll_l, plane)
1404                {
1405                    if (!plane) continue;
1406                    /* FIXME: hwc extension doesn't provide thing like layer */
1407                    tdm_layer_get_capabilities(plane->tlayer, &layer_capabilities);
1408                    snprintf(layer_cap, sizeof(layer_cap), "%s%s%s%s%s%s%s%s",
1409                             _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_CURSOR),
1410                             _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_PRIMARY),
1411                             _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_OVERLAY),
1412                             _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_GRAPHIC),
1413                             _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_VIDEO),
1414                             _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_TRANSFORM),
1415                             _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_RESEVED_MEMORY),
1416                             _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_NO_CROP));
1417                    INF("HWC:  index=%d zpos=%d ec=%p %s",
1418                        plane->index, plane->zpos,
1419                        plane->ec?plane->ec:NULL,
1420                        layer_cap);
1421                }
1422           }
1423         else
1424           {
1425              /* TODO: construct debug info for outputs managed by the hwc-wins */
1426              INF("HWC: HWC Output(%d) managed by hwc-wins.", ++output_idx);
1427              continue;
1428           }
1429      }
1430    INF("HWC: =========================================================================");
1431 }