/* * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 */ #include "e.h" static void _e_xinerama_clean(void); static void _e_xinerama_update(void); static Evas_List *all_screens = NULL; static Evas_List *chosen_screens = NULL; static Evas_List *fake_screens = NULL; EAPI int e_xinerama_init(void) { _e_xinerama_update(); return 1; } EAPI int e_xinerama_shutdown(void) { _e_xinerama_clean(); return 1; } EAPI void e_xinerama_update(void) { _e_xinerama_clean(); _e_xinerama_update(); } EAPI const Evas_List * e_xinerama_screens_get(void) { if (fake_screens) return fake_screens; return chosen_screens; } EAPI const Evas_List * e_xinerama_screens_all_get(void) { if (fake_screens) return fake_screens; return all_screens; } EAPI void e_xinerama_fake_screen_add(int x, int y, int w, int h) { E_Screen *scr; scr = calloc(1, sizeof(E_Screen)); scr->screen = evas_list_count(fake_screens); scr->x = x; scr->y = y; scr->w = w; scr->h = h; fake_screens = evas_list_append(fake_screens, scr); } /* local subsystem functions */ static void _e_xinerama_clean(void) { while (all_screens) { free(all_screens->data); all_screens = evas_list_remove_list(all_screens, all_screens); } while (chosen_screens) { chosen_screens = evas_list_remove_list(chosen_screens, chosen_screens); } while (fake_screens) { free(fake_screens->data); fake_screens = evas_list_remove_list(fake_screens, fake_screens); } } static void _e_xinerama_update(void) { int n; Ecore_X_Window *roots; Evas_List *l; roots = ecore_x_window_root_list(&n); if (roots) { int i; int rw, rh; Ecore_X_Window root; /* more than 1 root window - xinerama wont be active */ if (n > 1) { free(roots); return; } /* first (and only) root window */ root = roots[0]; free(roots); /* get root size */ ecore_x_window_size_get(root, &rw, &rh); /* get number of xinerama screens */ n = ecore_x_xinerama_screen_count_get(); if (n < 1) { E_Screen *scr; scr = calloc(1, sizeof(E_Screen)); scr->screen = 0; scr->x = 0; scr->y = 0; scr->w = rw; scr->h = rh; all_screens = evas_list_append(all_screens, scr); } else { for (i = 0; i < n; i++) { int x, y, w, h; /* get each xinerama screen geometry */ if (ecore_x_xinerama_screen_geometry_get(i, &x, &y, &w, &h)) { E_Screen *scr; printf("E17 INIT: XINERAMA SCREEN: [%i], %ix%i+%i+%i\n", i, w, h, x, y); /* add it to our list */ scr = calloc(1, sizeof(E_Screen)); scr->screen = i; scr->x = x; scr->y = y; scr->w = w; scr->h = h; all_screens = evas_list_append(all_screens, scr); } } } } /* now go through all_screens... and build a list of chosen screens */ for (l = all_screens; l; l = l->next) { Evas_List *ll; E_Screen *scr; int add = 0; Evas_List *removes; scr = l->data; add = 1; removes = NULL; /* does this screen intersect with any we have chosen? */ for (ll = chosen_screens; ll; ll = ll->next) { E_Screen *scr2; scr2 = ll->data; /* if they intersect */ if (E_INTERSECTS(scr->x, scr->y, scr->w, scr->h, scr2->x, scr2->y, scr2->w, scr2->h)) { int sz, sz2; /* calculate pixel area */ sz = scr->w * scr->h; sz2 = scr2->w * scr2->h; /* if the one we already have is bigger, DONT add the new */ if (sz2 >= sz) add = 0; /* add the old to a list to remove */ else removes = evas_list_append(removes, scr); } } /* if there are screens to remove - remove them */ while (removes) { chosen_screens = evas_list_remove(chosen_screens, removes->data); removes = evas_list_remove_list(removes, removes); } /* if this screen is to be added, add it */ if (add) { printf("E17 INIT: XINERAMA CHOSEN: [%i], %ix%i+%i+%i\n", scr->screen, scr->w, scr->h, scr->x, scr->y); chosen_screens = evas_list_append(chosen_screens, scr); } } }