summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Michael <cp.michael@samsung.com>2015-02-24 13:25:22 -0500
committerChris Michael <cp.michael@samsung.com>2015-02-24 13:25:22 -0500
commita8eb773752892ed2c5574b4d71416aa6ac312f39 (patch)
treeaf8884174a43dc407583647d8a1bdd654e89061a
parentbe6c62eb34686634d06fa0522ee4d23fbd5ab9f8 (diff)
downloadenlightenment-a8eb773752892ed2c5574b4d71416aa6ac312f39.tar.gz
Fix T2131 (crash when creating wl_outputs)
This fixes the crash and creates outputs based on e_randr configuration (when in wayland-client mode). Signed-off-by: Chris Michael <cp.michael@samsung.com>
-rw-r--r--src/bin/e_comp_wl.c206
1 files changed, 159 insertions, 47 deletions
diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c
index c05f405dac..3e55011803 100644
--- a/src/bin/e_comp_wl.c
+++ b/src/bin/e_comp_wl.c
@@ -1,9 +1,6 @@
#define E_COMP_WL
#include "e.h"
-#include <Evas_Engine_Drm.h>
-#include <Ecore_Drm.h>
-
/* handle include for printing uint64_t */
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
@@ -714,6 +711,46 @@ _e_comp_wl_client_evas_init(E_Client *ec)
ec->comp_data->evas_init = EINA_TRUE;
}
+#ifndef HAVE_WAYLAND_ONLY
+static Eina_Bool
+_e_comp_wl_cb_randr_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
+{
+ Eina_List *l;
+ E_Randr2_Screen *screen;
+ unsigned int transform = WL_OUTPUT_TRANSFORM_NORMAL;
+
+ EINA_LIST_FOREACH(e_randr2->screens, l, screen)
+ {
+ if (!screen->config.enabled) continue;
+ switch (screen->config.rotation)
+ {
+ case 90:
+ transform = WL_OUTPUT_TRANSFORM_90;
+ break;
+ case 180:
+ transform = WL_OUTPUT_TRANSFORM_180;
+ break;
+ case 270:
+ transform = WL_OUTPUT_TRANSFORM_270;
+ break;
+ case 0:
+ default:
+ transform = WL_OUTPUT_TRANSFORM_NORMAL;
+ break;
+ }
+
+ e_comp_wl_output_init(screen->id, screen->info.screen,
+ screen->info.name,
+ screen->config.geom.x, screen->config.geom.y,
+ screen->config.geom.w, screen->config.geom.h,
+ screen->info.size.w, screen->info.size.h,
+ screen->config.mode.refresh, 0, transform);
+ }
+
+ return ECORE_CALLBACK_RENEW;
+}
+#endif
+
static Eina_Bool
_e_comp_wl_cb_comp_object_add(void *data EINA_UNUSED, int type EINA_UNUSED, E_Event_Comp_Object *ev)
{
@@ -1346,15 +1383,22 @@ static void
_e_comp_wl_compositor_cb_del(E_Comp *comp)
{
E_Comp_Data *cdata;
+ E_Comp_Wl_Output *output;
/* get existing compositor data */
if (!(cdata = comp->wl_comp_data)) return;
+ EINA_LIST_FREE(cdata->outputs, output)
+ {
+ if (output->id) eina_stringshare_del(output->id);
+ if (output->make) eina_stringshare_del(output->make);
+ if (output->model) eina_stringshare_del(output->model);
+ free(output);
+ }
+
/* delete fd handler */
if (cdata->fd_hdlr) ecore_main_fd_handler_del(cdata->fd_hdlr);
- eina_list_free(cdata->output.resources);
-
/* free allocated data structure */
free(cdata);
}
@@ -2249,59 +2293,55 @@ _e_comp_wl_client_cb_resize_end(void *data EINA_UNUSED, E_Client *ec)
static void
_e_comp_wl_cb_output_unbind(struct wl_resource *resource)
{
- E_Comp_Data *cdata = wl_resource_get_user_data(resource);
+ E_Comp_Wl_Output *output;
+ E_Comp_Data *cdata;
- cdata->output.resources =
- eina_list_remove(cdata->output.resources, resource);
+ if (!(output = wl_resource_get_user_data(resource))) return;
+ if (!(cdata = e_comp->wl_comp_data)) return;
+
+ cdata->outputs = eina_list_remove(cdata->outputs, output);
+
+ if (output->id) eina_stringshare_del(output->id);
+ if (output->make) eina_stringshare_del(output->make);
+ if (output->model) eina_stringshare_del(output->model);
+ free(output);
}
static void
_e_comp_wl_cb_output_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
{
- E_Comp_Data *cdata = data;
- Evas_Engine_Info_Drm *einfo;
- Ecore_Drm_Device *dev;
- Eina_List *l;
- Ecore_Drm_Output *output;
+ E_Comp_Wl_Output *output;
+ E_Comp_Data *cdata;
struct wl_resource *resource;
- einfo = (Evas_Engine_Info_Drm *)evas_engine_info_get(e_comp->evas);
- dev = einfo->info.dev;
+ if (!(output = data)) return;
+ if (!(cdata = e_comp->wl_comp_data)) return;
resource =
wl_resource_create(client, &wl_output_interface, MIN(version, 2), id);
- if (resource == NULL)
+ if (!resource)
{
wl_client_post_no_memory(client);
return;
}
- cdata->output.resources =
- eina_list_append(cdata->output.resources, resource);
-
- wl_resource_set_implementation(resource, NULL, data, NULL);
- wl_resource_set_user_data(resource, cdata);
- EINA_LIST_FOREACH(dev->outputs, l, output)
- {
- int ox, oy, rw, rh, pw, ph;
- unsigned int spo, rr;
- const char *make, *model;
+ output->resource = resource;
+ cdata->outputs = eina_list_append(cdata->outputs, output);
- ecore_drm_output_position_get(output, &ox, &oy);
- ecore_drm_output_current_resolution_get(output, &rw, &rh, &rr);
- ecore_drm_output_physical_size_get(output, &pw, &ph);
- spo = ecore_drm_output_subpixel_order_get(output);
- make = ecore_drm_output_model_get(output);
- model = ecore_drm_output_make_get(output);
+ wl_resource_set_implementation(resource, NULL, output,
+ _e_comp_wl_cb_output_unbind);
+ wl_resource_set_user_data(resource, output);
- wl_output_send_geometry(resource, ox, oy, pw, ph, spo, make, model,
- 0/* output transform*/);
+ wl_output_send_geometry(resource, output->x, output->y,
+ output->phys_width, output->phys_height,
+ output->subpixel, output->make, output->model,
+ output->transform);
- if (version >= WL_OUTPUT_SCALE_SINCE_VERSION)
- wl_output_send_scale(resource, 1/* current scale */);
+ if (version >= WL_OUTPUT_SCALE_SINCE_VERSION)
+ wl_output_send_scale(resource, e_scale);
- wl_output_send_mode(resource, 3/*preferred + current */, rw, rh, rr);
- }
+ /* 3 == preferred + current */
+ wl_output_send_mode(resource, 3, output->w, output->h, output->refresh);
if (version >= WL_OUTPUT_DONE_SINCE_VERSION)
wl_output_send_done(resource);
@@ -2326,6 +2366,9 @@ _e_comp_wl_compositor_create(void)
/* create new compositor data */
cdata = E_NEW(E_Comp_Data, 1);
+ /* set compositor wayland data */
+ comp->wl_comp_data = cdata;
+
/* set wayland log handler */
wl_log_set_handler_server(_e_comp_wl_log_cb_print);
@@ -2367,12 +2410,10 @@ _e_comp_wl_compositor_create(void)
ERR("Could not add subcompositor to wayland globals: %m");
goto comp_global_err;
}
- if (!wl_global_create(cdata->wl.disp, &wl_output_interface, 2,
- cdata, _e_comp_wl_cb_output_bind))
- {
- ERR("Could not add output to wayland globals: %m");
- goto comp_global_err;
- }
+
+#ifndef HAVE_WAYLAND_ONLY
+ _e_comp_wl_cb_randr_change(NULL, 0, NULL);
+#endif
/* try to init data manager */
if (!e_comp_wl_data_manager_init(cdata))
@@ -2452,9 +2493,6 @@ _e_comp_wl_compositor_create(void)
e_comp_wl_input_keyboard_enabled_set(cdata, EINA_TRUE);
}
- /* set compositor wayland data */
- comp->wl_comp_data = cdata;
-
return EINA_TRUE;
input_err:
@@ -2496,6 +2534,11 @@ e_comp_wl_init(void)
/* clients_win_hash = eina_hash_int64_new(NULL); */
/* add event handlers to catch E events */
+#ifndef HAVE_WAYLAND_ONLY
+ E_LIST_HANDLER_APPEND(handlers, E_EVENT_RANDR_CHANGE,
+ _e_comp_wl_cb_randr_change, NULL);
+#endif
+
E_LIST_HANDLER_APPEND(handlers, E_EVENT_COMP_OBJECT_ADD,
_e_comp_wl_cb_comp_object_add, NULL);
@@ -2546,6 +2589,10 @@ e_comp_wl_surface_create_signal_get(E_Comp *comp)
EINTERN void
e_comp_wl_shutdown(void)
{
+#ifndef HAVE_WAYLAND_ONLY
+ _e_comp_wl_compositor_cb_del(e_comp);
+#endif
+
/* free handlers */
E_FREE_LIST(handlers, ecore_event_handler_del);
@@ -2753,3 +2800,68 @@ e_comp_wl_idle_time_get(void)
{
return (ecore_loop_time_get() - _last_event_time);
}
+
+EAPI void
+e_comp_wl_output_init(const char *id, const char *make, const char *model, int x, int y, int w, int h, int pw, int ph, unsigned int refresh, unsigned int subpixel, unsigned int transform)
+{
+ E_Comp_Data *cdata;
+ E_Comp_Wl_Output *output;
+ Eina_List *l;
+
+ if (!(cdata = e_comp->wl_comp_data)) return;
+
+ EINA_LIST_FOREACH(cdata->outputs, l, output)
+ {
+ if (!strcmp(output->id, id))
+ {
+ output->x = x;
+ output->y = y;
+ output->w = w;
+ output->h = h;
+ output->phys_width = pw;
+ output->phys_height = ph;
+ output->refresh = refresh * 1000;
+ output->subpixel = subpixel;
+ output->transform = transform;
+
+ wl_output_send_geometry(output->resource, output->x, output->y,
+ output->phys_width, output->phys_height,
+ output->subpixel,
+ output->make, output->model,
+ output->transform);
+
+ if (wl_resource_get_version(output->resource) >=
+ WL_OUTPUT_SCALE_SINCE_VERSION)
+ wl_output_send_scale(output->resource, e_scale);
+
+ /* 3 == preferred + current */
+ wl_output_send_mode(output->resource, 3, output->w, output->h,
+ output->refresh);
+
+ if (wl_resource_get_version(output->resource) >=
+ WL_OUTPUT_DONE_SINCE_VERSION)
+ wl_output_send_done(output->resource);
+
+ return;
+ }
+ }
+
+ if (!(output = E_NEW(E_Comp_Wl_Output, 1))) return;
+
+ output->x = x;
+ output->y = y;
+ output->w = w;
+ output->h = h;
+ output->phys_width = pw;
+ output->phys_height = ph;
+ output->refresh = refresh * 1000;
+ output->subpixel = subpixel;
+ output->transform = transform;
+ if (id) output->id = eina_stringshare_add(id);
+ if (make) output->make = eina_stringshare_add(make);
+ if (model) output->model = eina_stringshare_add(model);
+
+ output->global =
+ wl_global_create(cdata->wl.disp, &wl_output_interface, 2,
+ output, _e_comp_wl_cb_output_bind);
+}