4 #define PATH "/org/enlightenment/wm"
5 #define IFACE "org.enlightenment.wm.screen_rotation"
7 static Eldbus_Connection *e_comp_screen_conn;
8 static Eldbus_Service_Interface *e_comp_screen_iface;
10 static Eina_List *event_handlers = NULL;
12 static Eina_Bool dont_set_e_input_keymap = EINA_FALSE;
13 static Eina_Bool dont_use_xkb_cache = EINA_FALSE;
15 E_API int E_EVENT_SCREEN_CHANGE = 0;
19 E_COMP_SCREEN_SIGNAL_ROTATION_CHANGED = 0
22 typedef struct _E_Comp_Screen_Tzsr
24 struct wl_resource *resource; /* tizen_screen_rotation */
28 static Eina_List *tzsr_list;
29 static E_Client_Hook *tzsr_client_hook_del;
31 static E_Comp_Screen_Tzsr*
32 _tz_surface_rotation_find(E_Client *ec)
34 E_Comp_Screen_Tzsr *tzsr;
37 EINA_LIST_FOREACH(tzsr_list, l, tzsr)
46 static E_Comp_Screen_Tzsr*
47 _tz_surface_rotation_find_with_resource(struct wl_resource *resource)
49 E_Comp_Screen_Tzsr *tzsr;
52 EINA_LIST_FOREACH(tzsr_list, l, tzsr)
54 if (tzsr->resource == resource)
62 _tz_surface_rotation_free(E_Comp_Screen_Tzsr *tzsr)
64 ELOGF("TRANSFORM", "|tzsr(%p) freed", NULL, tzsr->ec, tzsr);
65 tzsr_list = eina_list_remove(tzsr_list, tzsr);
70 _tz_screen_rotation_cb_client_del(void *data, E_Client *ec)
72 E_Comp_Screen_Tzsr *tzsr = _tz_surface_rotation_find(ec);
74 _tz_surface_rotation_free(tzsr);
78 _tz_screen_rotation_get_ignore_output_transform(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface)
80 E_Comp_Screen_Tzsr *tzsr;
83 ec = wl_resource_get_user_data(surface);
84 EINA_SAFETY_ON_NULL_RETURN(ec);
86 tzsr = _tz_surface_rotation_find(ec);
89 tzsr = E_NEW(E_Comp_Screen_Tzsr, 1);
92 wl_client_post_no_memory(client);
96 tzsr->resource = resource;
99 ELOGF("TRANSFORM", "|tzsr(%p) client_ignore(%d)", NULL, ec, tzsr, e_config->screen_rotation_client_ignore);
101 tzsr_list = eina_list_append(tzsr_list, tzsr);
103 /* make all clients ignore the output tramsform
104 * we will decide later when hwc prepared.
106 e_comp_screen_rotation_ignore_output_transform_send(ec, EINA_TRUE);
110 _tz_screen_rotation_iface_cb_destroy(struct wl_client *client, struct wl_resource *resource)
112 wl_resource_destroy(resource);
115 static const struct tizen_screen_rotation_interface _tz_screen_rotation_interface =
117 _tz_screen_rotation_get_ignore_output_transform,
118 _tz_screen_rotation_iface_cb_destroy,
121 static void _tz_screen_rotation_cb_destroy(struct wl_resource *resource)
123 E_Comp_Screen_Tzsr *tzsr = _tz_surface_rotation_find_with_resource(resource);
125 _tz_surface_rotation_free(tzsr);
129 _tz_screen_rotation_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
131 struct wl_resource *res;
133 if (!(res = wl_resource_create(client, &tizen_screen_rotation_interface, version, id)))
135 ERR("Could not create tizen_screen_rotation resource: %m");
136 wl_client_post_no_memory(client);
140 wl_resource_set_implementation(res, &_tz_screen_rotation_interface, NULL, _tz_screen_rotation_cb_destroy);
143 static Eldbus_Message *
144 _e_comp_screen_dbus_get_cb(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
146 Eldbus_Message *reply = eldbus_message_method_return_new(msg);
149 if (e_comp && e_comp->e_comp_screen)
150 rotation = e_comp->e_comp_screen->rotation;
152 DBG("got screen-rotation 'get' request: %d", rotation);
154 eldbus_message_arguments_append(reply, "i", rotation);
159 static const Eldbus_Method methods[] =
161 {"get", NULL, ELDBUS_ARGS({"i", "int32"}), _e_comp_screen_dbus_get_cb, 0},
165 static const Eldbus_Signal signals[] = {
166 [E_COMP_SCREEN_SIGNAL_ROTATION_CHANGED] = {"changed", ELDBUS_ARGS({ "i", "rotation" }), 0},
170 static const Eldbus_Service_Interface_Desc iface_desc = {
171 IFACE, methods, signals, NULL, NULL, NULL
175 _e_comp_screen_dbus_init(void *data EINA_UNUSED)
177 E_Comp_Screen *e_comp_screen = e_comp->e_comp_screen;
179 if (e_comp_screen_conn) return ECORE_CALLBACK_CANCEL;
181 if (!e_comp_screen_conn)
182 e_comp_screen_conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SYSTEM);
184 if(!e_comp_screen_conn)
186 ecore_timer_add(1, _e_comp_screen_dbus_init, NULL);
187 return ECORE_CALLBACK_CANCEL;
190 e_comp_screen_iface = eldbus_service_interface_register(e_comp_screen_conn,
193 EINA_SAFETY_ON_NULL_GOTO(e_comp_screen_iface, err);
195 if (e_comp_screen->rotation)
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);
201 return ECORE_CALLBACK_CANCEL;
204 if (e_comp_screen_conn)
206 eldbus_connection_unref(e_comp_screen_conn);
207 e_comp_screen_conn = NULL;
210 return ECORE_CALLBACK_CANCEL;
214 _layer_cap_to_str(tdm_layer_capability caps, tdm_layer_capability cap)
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";
232 _e_comp_screen_commit_idle_cb(void *data EINA_UNUSED)
235 E_Comp_Screen *e_comp_screen = NULL;
236 E_Output *output = NULL;
238 if (!e_comp->e_comp_screen) goto end;
240 if (e_config->comp_canvas_norender.use)
241 evas_norender(e_comp->evas);
243 e_comp_screen = e_comp->e_comp_screen;
245 EINA_LIST_FOREACH_SAFE(e_comp_screen->outputs, l, ll, output)
247 if (!output) continue;
248 if (!output->config.enabled) continue;
250 e_output_hwc_apply(output->output_hwc);
252 if (!e_output_commit(output))
253 ERR("fail to commit e_comp_screen->outputs.");
255 if (!e_output_render(output))
256 ERR("fail to render e_comp_screen->outputs.");
259 return ECORE_CALLBACK_RENEW;
263 _e_comp_screen_cb_input_device_add(void *data, int type, void *event)
265 E_Input_Event_Input_Device_Add *e;
268 if (!(e = event)) goto end;
270 if (e->caps & E_INPUT_SEAT_POINTER)
272 if (comp->wl_comp_data->ptr.num_devices == 0)
274 e_pointer_object_set(comp->pointer, NULL, 0, 0);
275 e_comp_wl_input_pointer_enabled_set(EINA_TRUE);
277 comp->wl_comp_data->ptr.num_devices++;
279 if (e->caps & E_INPUT_SEAT_KEYBOARD)
281 comp->wl_comp_data->kbd.num_devices++;
282 e_comp_wl_input_keyboard_enabled_set(EINA_TRUE);
284 if (e->caps & E_INPUT_SEAT_TOUCH)
286 e_comp_wl_input_touch_enabled_set(EINA_TRUE);
287 comp->wl_comp_data->touch.num_devices++;
291 return ECORE_CALLBACK_PASS_ON;
295 _e_comp_screen_pointer_renew(E_Input_Event_Input_Device_Del *ev)
297 if ((e_comp_wl->ptr.num_devices == 0) && e_comp_wl->ptr.ec && e_comp_wl->ptr.ec->pointer_enter_sent)
299 if (e_comp_wl->input_device_manager.last_device_ptr)
301 Evas_Device *last_ptr = NULL, *dev;
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)
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))
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);
322 _e_comp_screen_cb_input_device_del(void *data, int type, void *event)
324 E_Input_Event_Input_Device_Del *e;
327 if (!(e = event)) goto end;
329 if (e->caps & E_INPUT_SEAT_POINTER)
331 comp->wl_comp_data->ptr.num_devices--;
332 if (comp->wl_comp_data->ptr.num_devices == 0)
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);
338 _e_comp_screen_pointer_renew(e);
341 if (e->caps & E_INPUT_SEAT_KEYBOARD)
343 comp->wl_comp_data->kbd.num_devices--;
344 if (comp->wl_comp_data->kbd.num_devices == 0)
346 e_comp_wl_input_keyboard_enabled_set(EINA_FALSE);
349 if (e->caps & E_INPUT_SEAT_TOUCH)
351 comp->wl_comp_data->touch.num_devices--;
352 if (comp->wl_comp_data->touch.num_devices == 0)
354 e_comp_wl_input_touch_enabled_set(EINA_FALSE);
360 return ECORE_CALLBACK_PASS_ON;
364 _e_comp_screen_cb_ee_resize(Ecore_Evas *ee EINA_UNUSED)
366 e_comp_canvas_update();
370 _e_comp_screen_cb_event(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
372 E_Comp_Screen *e_comp_screen;
375 if (!(e_comp_screen = data)) return ECORE_CALLBACK_RENEW;
377 ret = tdm_display_handle_events(e_comp_screen->tdisplay);
378 if (ret != TDM_ERROR_NONE)
379 ERR("tdm_display_handle_events failed");
381 return ECORE_CALLBACK_RENEW;
384 static E_Comp_Screen *
385 _e_comp_screen_new(E_Comp *comp)
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;
394 e_comp_screen = E_NEW(E_Comp_Screen, 1);
395 if (!e_comp_screen) return NULL;
397 /* tdm display init */
398 e_comp_screen->tdisplay = tdm_display_init(&error);
399 if (!e_comp_screen->tdisplay)
401 ERR("fail to get tdm_display\n");
406 e_comp_screen->fd = -1;
407 tdm_display_get_fd(e_comp_screen->tdisplay, &fd);
410 ERR("fail to get tdm_display fd\n");
414 e_comp_screen->fd = dup(fd);
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);
420 /* tdm display init */
421 e_comp_screen->bufmgr = tbm_bufmgr_init(-1);
422 if (!e_comp_screen->bufmgr)
424 ERR("tbm_bufmgr_init failed\n");
428 error = tdm_display_get_capabilities(e_comp_screen->tdisplay, &capabilities);
429 if (error != TDM_ERROR_NONE)
431 ERR("tdm get_capabilities failed");
435 /* check the pp_support */
436 if (capabilities & TDM_DISPLAY_CAPABILITY_PP)
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");
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]);
449 if (e_comp_socket_init("tdm-socket"))
450 PRCTL("[Winsys] change permission and create sym link for %s", "tdm-socket");
452 return e_comp_screen;
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);
466 _e_comp_screen_del(E_Comp_Screen *e_comp_screen)
468 Eina_List *l = NULL, *ll = NULL;
471 if (!e_comp_screen) return;
473 if (e_comp_screen->pp_enabled)
475 EINA_LIST_FOREACH_SAFE(e_comp_screen->available_pp_formats, l, ll, formats)
477 if (!formats) continue;
478 e_comp_screen->available_pp_formats = eina_list_remove(e_comp_screen->available_pp_formats, l);
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);
490 _e_comp_screen_deinit_outputs(E_Comp_Screen *e_comp_screen)
496 EINA_LIST_FOREACH_SAFE(e_comp_screen->outputs, l, ll, output)
498 e_comp_screen->outputs = eina_list_remove_list(e_comp_screen->outputs, l);
499 e_output_del(output);
506 _e_comp_screen_init_outputs(E_Comp_Screen *e_comp_screen)
508 E_Output *output = NULL;
509 E_Output_Mode *mode = NULL;
510 tdm_display *tdisplay = e_comp_screen->tdisplay;
513 Eina_Bool scale_updated = EINA_FALSE;
516 if (!e_output_init())
518 ERR("fail to e_output_init.");
522 /* get the num of outputs */
523 tdm_display_get_output_count(tdisplay, &num_outputs);
526 ERR("fail to get tdm_display_get_output_count\n");
529 e_comp_screen->num_outputs = num_outputs;
531 INF("E_COMP_SCREEN: num_outputs = %i", e_comp_screen->num_outputs);
533 for (i = 0; i < num_outputs; i++)
535 output = e_output_new(e_comp_screen, i);
536 if (!output) goto fail;
538 if (!e_output_update(output))
540 ERR("fail to e_output_update.");
544 e_comp_screen->outputs = eina_list_append(e_comp_screen->outputs, output);
546 if (!e_output_connected(output)) continue;
548 /* setting with the best mode and enable the output */
549 mode = e_output_best_mode_find(output);
552 ERR("fail to get best mode.");
556 if (!e_output_mode_apply(output, mode))
558 ERR("fail to e_output_mode_apply.");
561 if (!e_output_dpms_set(output, E_OUTPUT_DPMS_ON))
563 ERR("fail to e_output_dpms.");
567 /* update e_scale with first available output size */
568 if ((e_config->scale.for_tdm) && (!scale_updated))
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);
576 e_scale_manual_update(dpi);
577 scale_updated = EINA_TRUE;
581 //TODO: if there is no output connected, make the fake output which is connected.
586 _e_comp_screen_deinit_outputs(e_comp_screen);
592 _e_comp_screen_tbm_queue_alloc(void *data EINA_UNUSED, int w, int h)
594 E_Comp_Screen *e_comp_screen = NULL;
595 tbm_surface_queue_h tqueue = NULL;
597 tqueue = tbm_surface_queue_create(3, w, h, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
599 e_comp->e_comp_screen->tqueue = tqueue;
601 return (void *)tqueue;
605 _e_comp_screen_tbm_queue_free(void *data EINA_UNUSED, void *tbm_queue)
607 E_Comp_Screen *e_comp_screen = NULL;
609 tbm_surface_queue_destroy(tbm_queue);
610 e_comp->e_comp_screen->tqueue = NULL;
614 _e_comp_screen_keymap_set(struct xkb_context **ctx, struct xkb_keymap **map)
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;
622 TRACE_INPUT_BEGIN(_e_comp_screen_keymap_set);
624 context = xkb_context_new(0);
625 EINA_SAFETY_ON_NULL_RETURN(context);
627 /* assemble xkb_rule_names so we can fetch keymap */
628 memset(&names, 0, sizeof(names));
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();
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);
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);
649 if (dont_set_e_input_keymap == EINA_FALSE)
651 e_input_device_keyboard_cached_context_set(*ctx);
652 e_input_device_keyboard_cached_keymap_set(*map);
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);
666 _e_comp_screen_e_screen_sort_cb(const void *data1, const void *data2)
668 const E_Output *s1 = data1, *s2 = data2;
671 dif = -(s1->config.priority - s2->config.priority);
674 dif = s1->config.geom.x - s2->config.geom.x;
676 dif = s1->config.geom.y - s2->config.geom.y;
682 _e_comp_screen_e_screen_free(E_Screen *scr)
689 _e_comp_screen_e_screens_set(E_Comp_Screen *e_comp_screen, Eina_List *screens)
691 E_FREE_LIST(e_comp_screen->e_screens, _e_comp_screen_e_screen_free);
692 e_comp_screen->e_screens = screens;
696 _e_comp_screen_engine_deinit(void)
699 if (!e_comp->e_comp_screen) return;
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;
707 _e_comp_screen_engine_init(void)
709 E_Comp_Screen *e_comp_screen = NULL;
710 int w = 0, h = 0, scr_w = 1, scr_h = 1;
713 E_Output *output = NULL;
714 tbm_surface_queue_h tqueue = NULL;
716 INF("ecore evase engine init with TDM. HWC.");
718 /* check the screen rotation */
719 screen_rotation = (e_config->screen_rotation_pre + e_config->screen_rotation_setting) % 360;
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);
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);
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);
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);
737 e_comp->e_comp_screen = e_comp_screen;
738 e_comp_screen->rotation = screen_rotation;
740 e_main_ts_begin("\tE_Outputs Init");
741 if (!_e_comp_screen_init_outputs(e_comp_screen))
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();
748 e_main_ts_end("\tE_Outputs Init Done");
750 /* get the primary output */
751 output = e_comp_screen_primary_output_get(e_comp_screen);
754 e_error_message_show(_("Fail to get the primary output!\n"));
755 _e_comp_screen_engine_deinit();
759 /* get the size of the primary output */
760 e_output_size_get(output, &scr_w, &scr_h);
762 /* if output is disconnected, set the default width, height */
763 if (scr_w == 0 || scr_h == 0)
768 if (!e_output_fake_config_set(output, scr_w, scr_h))
770 e_error_message_show(_("Fail to set the fake output config!\n"));
771 _e_comp_screen_engine_deinit();
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);
779 if ((e_comp_gl_get()) &&
780 (e_comp_config_get()->engine == E_COMP_ENGINE_GL))
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);
788 e_comp_gl_set(EINA_FALSE);
791 Evas_GL *evasgl = NULL;
792 Evas_GL_API *glapi = NULL;
794 e_main_ts_begin("\tEvas_GL New");
795 evasgl = evas_gl_new(ecore_evas_get(e_comp->ee));
798 glapi = evas_gl_api_get(evasgl);
799 if (!((glapi) && (glapi->evasglBindWaylandDisplay)))
801 e_comp_gl_set(EINA_FALSE);
802 ecore_evas_free(e_comp->ee);
804 e_main_ts_end("\tEvas_GL New Failed 1");
808 e_main_ts_end("\tEvas_GL New Done");
813 e_comp_gl_set(EINA_FALSE);
814 ecore_evas_free(e_comp->ee);
816 e_main_ts_end("\tEvas_GL New Failed 2");
818 evas_gl_free(evasgl);
822 /* fallback to framebuffer drm (non-accel) */
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);
833 e_error_message_show(_("Enlightenment cannot initialize outputs!\n"));
834 _e_comp_screen_engine_deinit();
838 ecore_evas_data_set(e_comp->ee, "comp", e_comp);
840 ecore_evas_callback_resize_set(e_comp->ee, _e_comp_screen_cb_ee_resize);
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);
848 snprintf(buf, sizeof(buf), "\tEE Rotate and Resize %d, %dx%d", screen_rotation, w, h);
852 if (!E_EVENT_SCREEN_CHANGE) E_EVENT_SCREEN_CHANGE = ecore_event_type_new();
854 ecore_event_add(E_EVENT_SCREEN_CHANGE, NULL, NULL, NULL);
856 e_comp_screen_e_screens_setup(e_comp_screen, -1, -1);
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);
865 e_comp_screen_e_screens_setup(E_Comp_Screen *e_comp_screen, int rw, int rh)
869 Eina_List *outputs = NULL, *outputs_rem;
870 Eina_List *e_screens = NULL;
872 E_Output *output, *s2, *s_chosen;
875 if (!e_comp_screen->outputs) goto out;
876 // put screens in tmp list
877 EINA_LIST_FOREACH(e_comp_screen->outputs, l, output)
879 if ((output->config.enabled) &&
880 (output->config.geom.w > 0) &&
881 (output->config.geom.h > 0))
883 outputs = eina_list_append(outputs, output);
886 // remove overlapping screens - if a set of screens overlap, keep the
887 // smallest/lowest res
890 removed = EINA_FALSE;
892 EINA_LIST_FOREACH(outputs, l, output)
896 EINA_LIST_FOREACH(l->next, ll, s2)
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))
904 outputs_rem = eina_list_append(outputs_rem, output);
905 outputs_rem = eina_list_append(outputs_rem, s2);
908 // we have intersecting screens - choose the lowest res one
912 // find the smallest screen (chosen one)
914 EINA_LIST_FOREACH(outputs_rem, ll, s2)
916 if (!s_chosen) s_chosen = s2;
919 if ((s_chosen->config.geom.w *
920 s_chosen->config.geom.h) >
926 // remove all from screens but the chosen one
927 EINA_LIST_FREE(outputs_rem, s2)
930 outputs = eina_list_remove_list(outputs, l);
932 // break our list walk and try again
938 // sort screens by priority etc.
939 outputs = eina_list_sort(outputs, 0, _e_comp_screen_e_screen_sort_cb);
941 EINA_LIST_FOREACH(outputs, l, output)
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;
949 if (output->config.rotation % 180)
951 screen->w = output->config.geom.h;
952 screen->h = output->config.geom.w;
956 screen->w = output->config.geom.w;
957 screen->h = output->config.geom.h;
960 if (output->id) screen->id = strdup(output->id);
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);
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))
979 screen = E_NEW(E_Screen, 1);
981 screen->escreen = screen->screen = 0;
984 if ((rw > 0) && (rh > 0))
985 screen->w = rw, screen->h = rh;
988 if (e_comp_screen->rotation % 180)
989 ecore_evas_geometry_get(e_comp->ee, NULL, NULL, &screen->h, &screen->w);
991 ecore_evas_geometry_get(e_comp->ee, NULL, NULL, &screen->w, &screen->h);
993 e_screens = eina_list_append(e_screens, screen);
995 _e_comp_screen_e_screens_set(e_comp_screen, e_screens);
998 EINTERN const Eina_List *
999 e_comp_screen_e_screens_get(E_Comp_Screen *e_comp_screen)
1001 EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen, NULL);
1003 return e_comp_screen->e_screens;
1007 e_comp_screen_init()
1011 struct xkb_context *ctx = NULL;
1012 struct xkb_keymap *map = NULL;
1014 TRACE_DS_BEGIN(E_COMP_SCREEN:INIT);
1015 if (!(comp = e_comp))
1018 EINA_SAFETY_ON_NULL_RETURN_VAL(comp, EINA_FALSE);
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;
1025 if (e_config->xkb.use_cache && !dont_use_xkb_cache)
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");
1032 if (!_e_comp_screen_engine_init())
1034 ERR("Could not initialize the ecore_evas engine.");
1035 goto failed_comp_screen;
1038 if (!e_input_init(e_comp->ee))
1040 ERR("Could not initialize the e_input.");
1041 goto failed_comp_screen;
1044 e_main_ts("\tE_Comp_Wl Init");
1045 if (!e_comp_wl_init())
1047 goto failed_comp_screen_with_ts;
1049 e_main_ts_end("\tE_Comp_Wl Init Done");
1051 /* get the current screen geometry */
1052 ecore_evas_geometry_get(e_comp->ee, NULL, NULL, &w, &h);
1055 e_main_ts_begin("\tE_Comp_Canvas Init");
1056 if (!e_comp_canvas_init(w, h))
1058 e_error_message_show(_("Enlightenment cannot initialize outputs!\n"));
1059 goto failed_comp_screen_with_ts;
1061 e_main_ts_end("\tE_Comp_Canvas Init Done");
1064 ecore_evas_pointer_xy_get(e_comp->ee,
1068 evas_event_feed_mouse_in(e_comp->evas, 0, NULL);
1070 e_main_ts_begin("\tE_Pointer New");
1071 if ((comp->pointer = e_pointer_canvas_new(comp->ee, EINA_TRUE)))
1073 e_pointer_hide(comp->pointer);
1075 e_main_ts_end("\tE_Pointer New Done");
1077 /* FIXME: We need a way to trap for user changing the keymap inside of E
1078 * without the event coming from X11 */
1080 /* FIXME: We should make a decision here ...
1082 * Fetch the keymap from drm, OR set this to what the E config is....
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(),
1094 e_main_ts_end("\tE_Comp_WL Keymap Init Done");
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))
1100 ERR("Could not add tizen_screen_rotation to wayland globals");
1101 goto failed_comp_screen;
1104 /* this setup function is called after e_comp_canvas_init */
1105 if (!e_comp_screen_setup(e_comp->e_comp_screen))
1107 ERR("fail to e_comp_screen_setup");
1111 if (eldbus_init() == 0)
1113 ERR("eldbus_init failed");
1114 goto failed_comp_screen;
1117 _e_comp_screen_dbus_init(NULL);
1119 tzsr_client_hook_del = e_client_hook_add(E_CLIENT_HOOK_DEL, _tz_screen_rotation_cb_client_del, NULL);
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);
1124 if (e_comp->e_comp_screen->rotation > 0)
1127 E_Input_Device *dev;
1129 EINA_LIST_FOREACH(e_input_devices_get(), l, dev)
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);
1134 INF("EE Input Device Rotate: %d", e_comp->e_comp_screen->rotation);
1142 failed_comp_screen_with_ts:
1143 e_main_ts_end("\tE_Comp_Screen init failed");
1147 _e_comp_screen_engine_deinit();
1155 e_comp_screen_shutdown()
1157 if (!e_comp) return;
1158 if (!e_comp->e_comp_screen) return;
1160 if (e_comp_screen_iface)
1162 eldbus_service_interface_unregister(e_comp_screen_iface);
1163 e_comp_screen_iface = NULL;
1166 if (e_comp_screen_conn)
1168 eldbus_connection_unref(e_comp_screen_conn);
1169 e_comp_screen_conn = NULL;
1174 _e_comp_screen_deinit_outputs(e_comp->e_comp_screen);
1176 e_client_hook_del(tzsr_client_hook_del);
1177 tzsr_client_hook_del = NULL;
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);
1183 /* delete e_comp_sreen */
1184 _e_comp_screen_del(e_comp->e_comp_screen);
1185 e_comp->e_comp_screen = NULL;
1189 e_comp_screen_setup(E_Comp_Screen *e_comp_screen)
1192 E_Output *output = NULL;
1194 EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen, EINA_FALSE);
1196 EINA_LIST_FOREACH_SAFE(e_comp_screen->outputs, l, ll, output)
1198 if (!output) continue;
1199 if (!output->config.enabled) continue;
1201 if (!e_output_setup(output))
1203 ERR("fail to e_output_setup.");
1207 INF("Enlightenment succeeded to initialize e_output_setup()!\n");
1214 e_comp_screen_rotation_setting_set(E_Comp_Screen *e_comp_screen, int rotation)
1216 E_Output *output = NULL, *o;
1219 int screen_rotation;
1220 E_Input_Device *dev;
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);
1227 if (e_config->screen_rotation_setting == rotation) return EINA_TRUE;
1229 EINA_LIST_FOREACH(e_comp_screen->outputs, l, o)
1231 unsigned int pipe = 0;
1234 error = tdm_output_get_pipe(o->toutput, &pipe);
1235 if (error != TDM_ERROR_NONE || pipe != 0)
1244 ERR("couldn't find the primary output");
1248 screen_rotation = (e_config->screen_rotation_pre + rotation) % 360;
1250 if (!e_output_rotate(output, screen_rotation))
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;
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);
1260 /* rendering forcely to prepare HWC */
1261 e_comp_render_queue();
1262 e_comp_hwc_end(__FUNCTION__);
1264 EINA_LIST_FOREACH(e_input_devices_get(), l, dev)
1266 e_input_device_touch_rotation_set(dev, e_comp_screen->rotation);
1267 e_input_device_rotation_set(dev, e_comp_screen->rotation);
1269 INF("EE Input Device Rotate: %d", e_comp_screen->rotation);
1272 if (e_comp_screen_iface)
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);
1278 INF("EE Rotated and Resized: %d, %dx%d", e_comp_screen->rotation, w, h);
1284 e_comp_screen_rotation_ignore_output_transform_send(E_Client *ec, Eina_Bool ignore)
1286 E_Comp_Screen_Tzsr *tzsr = _tz_surface_rotation_find(ec);
1290 /* if client have to considers the output transform */
1294 if (e_config->screen_rotation_client_ignore)
1296 ELOGF("TRANSFORM", "|tzsr(%p) ignore_output_transform: client_ignore", NULL, ec, tzsr);
1300 if (e_policy_client_is_quickpanel(ec))
1302 ELOGF("TRANSFORM", "|tzsr(%p) ignore_output_transform: quickpanel", NULL, ec, tzsr);
1307 ELOGF("TRANSFORM", "|tzsr(%p) ignore_output_transform(%d)", NULL, ec, tzsr, ignore);
1309 tizen_screen_rotation_send_ignore_output_transform(tzsr->resource, ec->comp_data->surface, ignore);
1313 e_comp_screen_rotation_ignore_output_transform_watch(E_Client *ec)
1315 return (_tz_surface_rotation_find(ec)) ? EINA_TRUE : EINA_FALSE;
1319 e_comp_screen_primary_output_get(E_Comp_Screen *e_comp_screen)
1321 EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen, NULL);
1323 E_Output *output = NULL, *o = NULL;
1324 Eina_List *l = NULL;
1325 int highest_priority = 0;
1327 /* find the highest priority of the e_output */
1328 EINA_LIST_FOREACH(e_comp_screen->outputs, l, o)
1330 if (highest_priority < o->config.priority)
1332 highest_priority = o->config.priority;
1341 e_comp_screen_pp_support(void)
1343 E_Comp_Screen *e_comp_screen = NULL;
1344 EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp, EINA_FALSE);
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);
1350 return e_comp_screen->pp_enabled;
1355 e_comp_screen_pp_available_formats_get(void)
1357 E_Comp_Screen *e_comp_screen = NULL;
1358 EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp, EINA_FALSE);
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);
1364 if (!e_comp_screen->pp_enabled)
1366 ERR("pp does not support.");
1370 return e_comp_screen->available_pp_formats;
1374 e_comp_screen_hwc_info_debug(void)
1376 EINA_SAFETY_ON_NULL_RETURN(e_comp);
1377 EINA_SAFETY_ON_NULL_RETURN(e_comp->e_comp_screen);
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;
1386 tdm_layer_capability layer_capabilities;
1387 char layer_cap[4096] = {0, };
1389 INF("HWC: HWC Information ==========================================================");
1390 EINA_LIST_FOREACH_SAFE(e_comp_screen->outputs, l_o, ll_o, output)
1392 if (!output) continue;
1394 if (e_output_hwc_policy_get(output->output_hwc) == E_OUTPUT_HWC_POLICY_PLANES)
1396 tdm_output_get_conn_status(output->toutput, &conn_status);
1397 if (conn_status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) continue;
1399 INF("HWC: HWC Output(%d):(x, y, w, h)=(%d, %d, %d, %d) Information.",
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)
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,
1425 /* TODO: construct debug info for outputs managed by the hwc-wins */
1426 INF("HWC: HWC Output(%d) managed by hwc-wins.", ++output_idx);
1430 INF("HWC: =========================================================================");