-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 Am 21.07.2010 13:47, awesome wrote: > THIS IS AN AUTOMATED MESSAGE, DO NOT REPLY. > > The following task has a new comment added: > > FS#784 - Nvidia's TwinView is not working on awesome 3.4.5+ (Git) > User who did this - Uli Schlachter (psychon) > > ---------- > I just had an idea. > > The current situation is: > - If Xrandr is available, use it > - Else check if Xinerama is available and use it > - Else assume a single screen > > We could change this into something like this: > - If Xrandr is available and reports more than one screen, use it > - Else check if Xinerama is available and use it (No point in checking if > there is more than one screen here, doesnt make a difference anyway) > - Else assume a single screen > ----------
Hi list, the attached patches should implement this. The first one doesn't actually change anything, but splits the code up into functions. The second patch then actually implements my idea. With it, we fall back to Xinerama if Xrandr only finds one screen. I only tested this on my dual-head laptop with working Xrandr (intel driver), since I don't have anything as broken as nvidia. Testing welcome. CC'ing JD since I want his ACK on this. I won't push this if he doesn't approve it. Of course, everyone else is welcome to post comments as well. Cheers, Uli - -- - - Buck, when, exactly, did you lose your mind? - - Three months ago. I woke up one morning married to a pineapple. An ugly pineapple... But I loved her! -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) iQEcBAEBCAAGBQJMRu10AAoJECLkKOvLj8sGfXkH/jhphhrCH+QVtugMdVuTKg0z GBPWmfNAzSFL/OL5+a6Z1Ue+DPhruV+eCpXTH0MX/9uZCjnrhwJgFaBuKWS3LkCq 9Lqwbew29GbVjEzf3D3Nw9MDC2q/0V91uQt22xGdgqr+l0LJaUE8zEj5VTRQ4enp ULBbu/aPcSb9ZOqUjKFX9e+JFDveZzUHYD/Bb8+T5+pGIHA/diYVk6M+CGfOBGWp Cw3Bq1n1ywYZ/k/CvMRnTCvMGYl6kYKTuqWSZdWBSRJJW/9akuAQszgSzbTmcboO 5zb1R3JUUD8TpOT6Cu+khEYlyY00bjgIpePNURotseKy2uB9WhdGG4JblYK3+7M= =wfG2 -----END PGP SIGNATURE-----
>From 7bf1370502de308a4b807238c6c30631e510423d Mon Sep 17 00:00:00 2001 From: Uli Schlachter <[email protected]> Date: Wed, 21 Jul 2010 14:42:45 +0200 Subject: [PATCH 1/2] Split up screen_scan() This splits up screen_scan() into screen_scan_randr(), screen_scan_xinerama() and screen_scan_x11(). These function try to set up screens via RANDR, Xinerama and the classic core protcol setup. No code in these functions was actually changed, only some indentation was changed (and a "return true/false" added to the first two functions). Signed-off-by: Uli Schlachter <[email protected]> --- screen.c | 148 +++++++++++++++++++++++++++++++++++--------------------------- 1 files changed, 84 insertions(+), 64 deletions(-) diff --git a/screen.c b/screen.c index ab8a18c..fcc3898 100644 --- a/screen.c +++ b/screen.c @@ -72,10 +72,8 @@ screen_default_visual(xcb_screen_t *s) return NULL; } -/** Get screens informations and fill global configuration. - */ -void -screen_scan(void) +static bool +screen_scan_randr(void) { /* Check for extension before checking for XRandR */ if(xcb_get_extension_data(globalconf.connection, &xcb_randr_id)->present) @@ -146,81 +144,103 @@ screen_scan(void) globalconf.xinerama_is_active = true; globalconf.screens.tab[0].visual = screen_default_visual(xutil_screen_get(globalconf.connection, globalconf.default_screen)); + + return true; } } - else - { - /* Check for extension before checking for Xinerama */ - if(xcb_get_extension_data(globalconf.connection, &xcb_xinerama_id)->present) - { - xcb_xinerama_is_active_reply_t *xia; - xia = xcb_xinerama_is_active_reply(globalconf.connection, xcb_xinerama_is_active(globalconf.connection), NULL); - globalconf.xinerama_is_active = xia->state; - p_delete(&xia); - } - if(globalconf.xinerama_is_active) - { - xcb_xinerama_query_screens_reply_t *xsq; - xcb_xinerama_screen_info_t *xsi; - int xinerama_screen_number; + return false; +} - xsq = xcb_xinerama_query_screens_reply(globalconf.connection, - xcb_xinerama_query_screens_unchecked(globalconf.connection), - NULL); +static bool +screen_scan_xinerama(void) +{ + /* Check for extension before checking for Xinerama */ + if(xcb_get_extension_data(globalconf.connection, &xcb_xinerama_id)->present) + { + xcb_xinerama_is_active_reply_t *xia; + xia = xcb_xinerama_is_active_reply(globalconf.connection, xcb_xinerama_is_active(globalconf.connection), NULL); + globalconf.xinerama_is_active = xia->state; + p_delete(&xia); + } - xsi = xcb_xinerama_query_screens_screen_info(xsq); - xinerama_screen_number = xcb_xinerama_query_screens_screen_info_length(xsq); + if(globalconf.xinerama_is_active) + { + xcb_xinerama_query_screens_reply_t *xsq; + xcb_xinerama_screen_info_t *xsi; + int xinerama_screen_number; - /* now check if screens overlaps (same x,y): if so, we take only the biggest one */ - for(int screen = 0; screen < xinerama_screen_number; screen++) - { - bool drop = false; - foreach(screen_to_test, globalconf.screens) - if(xsi[screen].x_org == screen_to_test->geometry.x - && xsi[screen].y_org == screen_to_test->geometry.y) - { - /* we already have a screen for this area, just check if - * it's not bigger and drop it */ - drop = true; - int i = screen_array_indexof(&globalconf.screens, screen_to_test); - screen_to_test->geometry.width = - MAX(xsi[screen].width, xsi[i].width); - screen_to_test->geometry.height = - MAX(xsi[screen].height, xsi[i].height); - } - if(!drop) - { - screen_t s; - p_clear(&s, 1); - s.geometry = screen_xsitoarea(xsi[screen]); - screen_array_append(&globalconf.screens, s); - } - } + xsq = xcb_xinerama_query_screens_reply(globalconf.connection, + xcb_xinerama_query_screens_unchecked(globalconf.connection), + NULL); - p_delete(&xsq); + xsi = xcb_xinerama_query_screens_screen_info(xsq); + xinerama_screen_number = xcb_xinerama_query_screens_screen_info_length(xsq); - xcb_screen_t *s = xutil_screen_get(globalconf.connection, globalconf.default_screen); - globalconf.screens.tab[0].visual = screen_default_visual(s); - } - else - /* One screen only / Zaphod mode */ - for(int screen = 0; - screen < xcb_setup_roots_length(xcb_get_setup(globalconf.connection)); - screen++) + /* now check if screens overlaps (same x,y): if so, we take only the biggest one */ + for(int screen = 0; screen < xinerama_screen_number; screen++) + { + bool drop = false; + foreach(screen_to_test, globalconf.screens) + if(xsi[screen].x_org == screen_to_test->geometry.x + && xsi[screen].y_org == screen_to_test->geometry.y) + { + /* we already have a screen for this area, just check if + * it's not bigger and drop it */ + drop = true; + int i = screen_array_indexof(&globalconf.screens, screen_to_test); + screen_to_test->geometry.width = + MAX(xsi[screen].width, xsi[i].width); + screen_to_test->geometry.height = + MAX(xsi[screen].height, xsi[i].height); + } + if(!drop) { - xcb_screen_t *xcb_screen = xutil_screen_get(globalconf.connection, screen); screen_t s; p_clear(&s, 1); - s.geometry.x = 0; - s.geometry.y = 0; - s.geometry.width = xcb_screen->width_in_pixels; - s.geometry.height = xcb_screen->height_in_pixels; - s.visual = screen_default_visual(xcb_screen); + s.geometry = screen_xsitoarea(xsi[screen]); screen_array_append(&globalconf.screens, s); } + } + + p_delete(&xsq); + + xcb_screen_t *s = xutil_screen_get(globalconf.connection, globalconf.default_screen); + globalconf.screens.tab[0].visual = screen_default_visual(s); + + return true; } + return false; +} + +static void screen_scan_x11(void) +{ + /* One screen only / Zaphod mode */ + for(int screen = 0; + screen < xcb_setup_roots_length(xcb_get_setup(globalconf.connection)); + screen++) + { + xcb_screen_t *xcb_screen = xutil_screen_get(globalconf.connection, screen); + screen_t s; + p_clear(&s, 1); + s.geometry.x = 0; + s.geometry.y = 0; + s.geometry.width = xcb_screen->width_in_pixels; + s.geometry.height = xcb_screen->height_in_pixels; + s.visual = screen_default_visual(xcb_screen); + screen_array_append(&globalconf.screens, s); + } +} + +/** Get screens informations and fill global configuration. + */ +void +screen_scan(void) +{ + if(!screen_scan_randr() && !screen_scan_xinerama()) + screen_scan_x11(); + globalconf.screen_focus = globalconf.screens.tab; } -- 1.7.1
>From e830df60920496670ab29d5307f3ef5c1dab1d97 Mon Sep 17 00:00:00 2001 From: Uli Schlachter <[email protected]> Date: Wed, 21 Jul 2010 14:46:49 +0200 Subject: [PATCH 2/2] Screen: Only use Xrandr if it provides data This commit makes awesome ignore the screen geometry provided by Xrandr if it only defines a single screen. This should work around nvidia's binary driver which only provides useful data via Xinerama. Signed-off-by: Uli Schlachter <[email protected]> --- screen.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/screen.c b/screen.c index fcc3898..1e4fc22 100644 --- a/screen.c +++ b/screen.c @@ -91,6 +91,14 @@ screen_scan_randr(void) xcb_randr_get_screen_resources_cookie_t screen_res_c = xcb_randr_get_screen_resources(globalconf.connection, screen->root); xcb_randr_get_screen_resources_reply_t *screen_res_r = xcb_randr_get_screen_resources_reply(globalconf.connection, screen_res_c, NULL); + /* Only use the data from XRandR if there is more than one screen + * defined. This should work around the broken nvidia driver. */ + if (screen_res_r->num_crtcs <= 1) + { + p_delete(&screen_res_r); + return false; + } + /* We go through CRTC, and build a screen for each one. */ xcb_randr_crtc_t *randr_crtcs = xcb_randr_get_screen_resources_crtcs(screen_res_r); -- 1.7.1
0001-Split-up-screen_scan.patch.sig
Description: Binary data
0002-Screen-Only-use-Xrandr-if-it-provides-data.patch.sig
Description: Binary data
