forked from enlightenment/enlightenment
move comp_x screen setup code into e_randr
this was not x-specific, so move it for use in wl compositors
This commit is contained in:
parent
e64998b042
commit
a452baafca
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue