discomfitor pushed a commit to branch master. http://git.enlightenment.org/core/enlightenment.git/commit/?id=a452baafca195328e045020456a5411c2b8dbdb6
commit a452baafca195328e045020456a5411c2b8dbdb6 Author: Mike Blumenkrantz <zm...@osg.samsung.com> Date: Wed Apr 22 19:24:33 2015 -0400 move comp_x screen setup code into e_randr this was not x-specific, so move it for use in wl compositors --- src/bin/e_comp_wl.c | 3 +- src/bin/e_comp_x.c | 148 +++------------------------------------------------- src/bin/e_randr2.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++ src/bin/e_randr2.h | 1 + 4 files changed, 141 insertions(+), 143 deletions(-) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index b84781b..33f44c6 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -2497,7 +2497,8 @@ e_comp_wl_init(void) /* add event handlers to catch E events */ if (e_comp->comp_type != E_PIXMAP_TYPE_X) - e_randr2_init(); + if (e_randr2_init()) + e_randr2_screens_setup(-1, -1); E_LIST_HANDLER_APPEND(handlers, E_EVENT_RANDR_CHANGE, _e_comp_wl_cb_randr_change, NULL); diff --git a/src/bin/e_comp_x.c b/src/bin/e_comp_x.c index fcb06e6..e719852 100644 --- a/src/bin/e_comp_x.c +++ b/src/bin/e_comp_x.c @@ -4532,139 +4532,6 @@ _e_comp_x_cb_frame_extents_request(void *data EINA_UNUSED, int ev_type EINA_UNUS return ECORE_CALLBACK_RENEW; } -static int -_e_comp_x_cinerama_screen_sort_cb(const void *data1, const void *data2) -{ - const E_Randr2_Screen *s1 = data1, *s2 = data2; - int dif; - - dif = -(s1->config.priority - s2->config.priority); - if (dif == 0) - { - dif = s1->config.geom.x - s2->config.geom.x; - if (dif == 0) - dif = s1->config.geom.y - s2->config.geom.y; - } - return dif; -} - -static Eina_Bool -_e_comp_x_xinerama_setup(int rw, int rh) -{ - int i; - E_Screen *screen; - Eina_List *screens = NULL, *screens_rem; - Eina_List *all_screens = NULL; - Eina_List *l, *ll; - E_Randr2_Screen *s, *s2, *s_chosen; - Eina_Bool removed; - - e_comp_x_randr_screen_iface_set(); - if (!e_randr2_init()) return 0; - - // put screens in tmp list - EINA_LIST_FOREACH(e_randr2->screens, l, s) - { - if ((s->config.enabled) && - (s->config.geom.w > 0) && - (s->config.geom.h > 0)) - { - screens = eina_list_append(screens, s); - } - } - // remove overlapping screens - if a set of screens overlap, keep the - // smallest/lowest res - do - { - removed = EINA_FALSE; - - EINA_LIST_FOREACH(screens, l, s) - { - screens_rem = NULL; - - EINA_LIST_FOREACH(l->next, ll, s2) - { - if (E_INTERSECTS(s->config.geom.x, s->config.geom.y, - s->config.geom.w, s->config.geom.h, - s2->config.geom.x, s2->config.geom.y, - s2->config.geom.w, s2->config.geom.h)) - { - if (!screens_rem) - screens_rem = eina_list_append(screens_rem, s); - screens_rem = eina_list_append(screens_rem, s2); - } - } - // we have intersecting screens - choose the lowest res one - if (screens_rem) - { - removed = EINA_TRUE; - // find the smallest screen (chosen one) - s_chosen = NULL; - EINA_LIST_FOREACH(screens_rem, ll, s2) - { - if (!s_chosen) s_chosen = s2; - else - { - if ((s_chosen->config.geom.w * - s_chosen->config.geom.h) > - (s2->config.geom.w * - s2->config.geom.h)) - s_chosen = s2; - } - } - // remove all from screens but the chosen one - EINA_LIST_FREE(screens_rem, s2) - { - if (s2 != s_chosen) - screens = eina_list_remove_list(screens, l); - } - // break our list walk and try again - break; - } - } - } - while (removed); - // sort screens by priority etc. - screens = eina_list_sort(screens, eina_list_count(screens), - _e_comp_x_cinerama_screen_sort_cb); - i = 0; - EINA_LIST_FOREACH(screens, l, s) - { - screen = E_NEW(E_Screen, 1); - screen->escreen = screen->screen = i; - screen->x = s->config.geom.x; - screen->y = s->config.geom.y; - screen->w = s->config.geom.w; - screen->h = s->config.geom.h; - all_screens = eina_list_append(all_screens, screen); - printf("xinerama screen %i %i %ix%i\n", screen->x, screen->y, screen->w, screen->h); - INF("E INIT: XINERAMA SCREEN: [%i][%i], %ix%i+%i+%i", - i, i, screen->w, screen->h, screen->x, screen->y); - i++; - } - eina_list_free(screens); - // if we have NO screens at all (above - i will be 0) AND we have no - // existing screens set up in xinerama - then just say root window size - // is the entire screen. this should handle the case where you unplug ALL - // screens from an existing setup (unplug external monitors and/or close - // laptop lid), in which case as long as at least one screen is configured - // in xinerama, it will be left-as is until next time we re-eval screen - // setup and have at least one screen - printf("xinerama setup............... %i %p\n", i, e_xinerama_screens_all_get()); - if ((i == 0) && (!e_xinerama_screens_all_get())) - { - screen = E_NEW(E_Screen, 1); - screen->escreen = screen->screen = 0; - screen->x = 0; - screen->y = 0; - screen->w = rw; - screen->h = rh; - all_screens = eina_list_append(all_screens, screen); - } - e_xinerama_screens_set(all_screens); - return EINA_TRUE; -} - static Eina_Bool _e_comp_x_randr_change(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *event_info EINA_UNUSED) { @@ -4678,7 +4545,7 @@ _e_comp_x_randr_change(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev E_Client *ec; ecore_x_netwm_desk_size_set(e_comp->root, e_comp->w, e_comp->h); - _e_comp_x_xinerama_setup(e_comp->w, e_comp->h); + e_randr2_screens_setup(e_comp->w, e_comp->h); e_comp_canvas_update(); E_CLIENT_FOREACH(ec) @@ -4696,7 +4563,7 @@ _e_comp_x_ee_resize(Ecore_Evas *ee EINA_UNUSED) E_Client *ec; ecore_x_netwm_desk_size_set(e_comp->root, e_comp->w, e_comp->h); - _e_comp_x_xinerama_setup(e_comp->w, e_comp->h); + e_randr2_screens_setup(e_comp->w, e_comp->h); e_comp_canvas_update(); E_CLIENT_FOREACH(ec) @@ -5102,6 +4969,8 @@ _e_comp_x_screens_setup(void) Ecore_X_Window *roots; Eina_Bool success = EINA_FALSE; + e_comp_x_randr_screen_iface_set(); + if (!e_randr2_init()) return 0; roots = ecore_x_window_root_list(&n); if ((!roots) || (n <= 0)) { @@ -5116,13 +4985,8 @@ _e_comp_x_screens_setup(void) Ecore_X_Window root = roots[i]; ecore_x_window_size_get(root, &rw, &rh); - if (n == 1) - { - /* more than 1 root window - xinerama wont be active */ - success = _e_comp_x_xinerama_setup(rw, rh); - if (!success) break; - } - if (!success) break; + + e_randr2_screens_setup(rw, rh); success = _e_comp_x_setup(root, rw, rh); if (!success) break; } diff --git a/src/bin/e_randr2.c b/src/bin/e_randr2.c index 1c2e438..d1e86da 100644 --- a/src/bin/e_randr2.c +++ b/src/bin/e_randr2.c @@ -843,6 +843,22 @@ _screen_config_maxsize(void) e_randr2->h = maxy; } +static int +_screen_sort_cb(const void *data1, const void *data2) +{ + const E_Randr2_Screen *s1 = data1, *s2 = data2; + int dif; + + dif = -(s1->config.priority - s2->config.priority); + if (dif == 0) + { + dif = s1->config.geom.x - s2->config.geom.x; + if (dif == 0) + dif = s1->config.geom.y - s2->config.geom.y; + } + return dif; +} + EAPI void e_randr2_screen_refresh_queue(Eina_Bool lid_event) { @@ -870,3 +886,119 @@ e_randr2_config_screen_find(E_Randr2_Screen *s, E_Config_Randr2 *cfg) } return NULL; } + +EAPI void +e_randr2_screens_setup(int rw, int rh) +{ + int i; + E_Screen *screen; + Eina_List *screens = NULL, *screens_rem; + Eina_List *all_screens = NULL; + Eina_List *l, *ll; + E_Randr2_Screen *s, *s2, *s_chosen; + Eina_Bool removed; + + if ((!e_randr2) || (!e_randr2->screens)) goto out; + // put screens in tmp list + EINA_LIST_FOREACH(e_randr2->screens, l, s) + { + if ((s->config.enabled) && + (s->config.geom.w > 0) && + (s->config.geom.h > 0)) + { + screens = eina_list_append(screens, s); + } + } + // remove overlapping screens - if a set of screens overlap, keep the + // smallest/lowest res + do + { + removed = EINA_FALSE; + + EINA_LIST_FOREACH(screens, l, s) + { + screens_rem = NULL; + + EINA_LIST_FOREACH(l->next, ll, s2) + { + if (E_INTERSECTS(s->config.geom.x, s->config.geom.y, + s->config.geom.w, s->config.geom.h, + s2->config.geom.x, s2->config.geom.y, + s2->config.geom.w, s2->config.geom.h)) + { + if (!screens_rem) + screens_rem = eina_list_append(screens_rem, s); + screens_rem = eina_list_append(screens_rem, s2); + } + } + // we have intersecting screens - choose the lowest res one + if (screens_rem) + { + removed = EINA_TRUE; + // find the smallest screen (chosen one) + s_chosen = NULL; + EINA_LIST_FOREACH(screens_rem, ll, s2) + { + if (!s_chosen) s_chosen = s2; + else + { + if ((s_chosen->config.geom.w * + s_chosen->config.geom.h) > + (s2->config.geom.w * + s2->config.geom.h)) + s_chosen = s2; + } + } + // remove all from screens but the chosen one + EINA_LIST_FREE(screens_rem, s2) + { + if (s2 != s_chosen) + screens = eina_list_remove_list(screens, l); + } + // break our list walk and try again + break; + } + } + } + while (removed); + // sort screens by priority etc. + screens = eina_list_sort(screens, 0, _screen_sort_cb); + i = 0; + EINA_LIST_FOREACH(screens, l, s) + { + screen = E_NEW(E_Screen, 1); + screen->escreen = screen->screen = i; + screen->x = s->config.geom.x; + screen->y = s->config.geom.y; + screen->w = s->config.geom.w; + screen->h = s->config.geom.h; + all_screens = eina_list_append(all_screens, screen); + printf("xinerama screen %i %i %ix%i\n", screen->x, screen->y, screen->w, screen->h); + INF("E INIT: XINERAMA SCREEN: [%i][%i], %ix%i+%i+%i", + i, i, screen->w, screen->h, screen->x, screen->y); + i++; + } + eina_list_free(screens); + // if we have NO screens at all (above - i will be 0) AND we have no + // existing screens set up in xinerama - then just say root window size + // is the entire screen. this should handle the case where you unplug ALL + // screens from an existing setup (unplug external monitors and/or close + // laptop lid), in which case as long as at least one screen is configured + // in xinerama, it will be left-as is until next time we re-eval screen + // setup and have at least one screen + printf("xinerama setup............... %i %p\n", i, e_xinerama_screens_all_get()); + if ((i == 0) && (!e_xinerama_screens_all_get())) + { +out: + screen = E_NEW(E_Screen, 1); + screen->escreen = screen->screen = 0; + screen->x = 0; + screen->y = 0; + if ((rw > 0) && (rh > 0)) + screen->w = rw, screen->h = rh; + else + ecore_evas_screen_geometry_get(e_comp->ee, NULL, NULL, &screen->w, &screen->h); + all_screens = eina_list_append(all_screens, screen); + } + e_xinerama_screens_set(all_screens); +} diff --git a/src/bin/e_randr2.h b/src/bin/e_randr2.h index 727b393..870734f 100644 --- a/src/bin/e_randr2.h +++ b/src/bin/e_randr2.h @@ -122,5 +122,6 @@ EAPI void e_randr2_screeninfo_update(void); EAPI void e_randr2_screen_refresh_queue(Eina_Bool lid_event); EAPI E_Config_Randr2_Screen *e_randr2_config_screen_find(E_Randr2_Screen *s, E_Config_Randr2 *cfg); +EAPI void e_randr2_screens_setup(int rw, int rh); #endif #endif --