diff options
author | Dave Davenport <qball@gmpclient.org> | 2016-08-31 09:44:43 +0200 |
---|---|---|
committer | Dave Davenport <qball@gmpclient.org> | 2016-08-31 09:59:51 +0200 |
commit | 4a95285212e89a3b9a63c059ef1df1412c246378 (patch) | |
tree | 18ea5dbe6817f495c9fc7cabd403a70a70cbc5bd /source/x11-helper.c | |
parent | 56cc94195c26c909d587901af753fc22c919f5cd (diff) | |
parent | 3da28675067d895eb5d623bccc23af6126ba33af (diff) |
Merge branch 'seletskiy-xinerama'
* Tweak some minor things.
Diffstat (limited to 'source/x11-helper.c')
-rw-r--r-- | source/x11-helper.c | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/source/x11-helper.c b/source/x11-helper.c index 560ce39f..684f9855 100644 --- a/source/x11-helper.c +++ b/source/x11-helper.c @@ -37,7 +37,9 @@ #include <xcb/xcb.h> #include <xcb/randr.h> +#include <xcb/xinerama.h> #include <xcb/xcb_ewmh.h> +#include <xcb/xproto.h> #include "xcb-internal.h" #include "xcb.h" #include "settings.h" @@ -54,6 +56,8 @@ #include "x11-helper.h" #include "xkb-internal.h" +#define LOG_DOMAIN "X11Helper" + struct _xcb_stuff xcb_int = { .connection = NULL, .screen = NULL, @@ -213,11 +217,70 @@ static workarea * x11_get_monitor_from_output ( xcb_randr_output_t out ) return retv; } +static int x11_is_extension_present (const char *extension) { + xcb_query_extension_cookie_t randr_cookie = xcb_query_extension ( xcb->connection, strlen(extension), extension); + + xcb_query_extension_reply_t *randr_reply = xcb_query_extension_reply ( xcb->connection, randr_cookie, NULL); + + int present = randr_reply->present; + + free ( randr_reply ); + + return present; +} + +static void x11_build_monitor_layout_xinerama () { + xcb_xinerama_query_screens_cookie_t screens_cookie = xcb_xinerama_query_screens_unchecked ( + xcb->connection + ); + + xcb_xinerama_query_screens_reply_t *screens_reply = xcb_xinerama_query_screens_reply ( + xcb->connection, + screens_cookie, + NULL + ); + + xcb_xinerama_screen_info_iterator_t screens_iterator = xcb_xinerama_query_screens_screen_info_iterator ( + screens_reply + ); + + for ( ; screens_iterator.rem > 0; xcb_xinerama_screen_info_next (&screens_iterator) ) { + workarea *w = g_malloc0 ( sizeof ( workarea ) ); + + w->x = screens_iterator.data->x_org; + w->y = screens_iterator.data->y_org; + w->w = screens_iterator.data->width; + w->h = screens_iterator.data->height; + + if ( w ) { + w->next = xcb->monitors; + xcb->monitors = w; + } + } + + int index = 0; + for ( workarea *iter = xcb->monitors; iter; iter = iter->next ) { + iter->monitor_id = index++; + } + + free ( screens_reply ); +} + void x11_build_monitor_layout () { if ( xcb->monitors ) { return; } + // If RANDR is not available, try Xinerama + if ( !x11_is_extension_present ( "RANDR" ) ) { + // Check if xinerama is available. + if ( x11_is_extension_present ( "XINERAMA" ) ) { + g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Using XINERAMA instead of XRANDR\n" ); + x11_build_monitor_layout_xinerama (); + } + return; + } + xcb_randr_get_screen_resources_current_reply_t *res_reply; xcb_randr_get_screen_resources_current_cookie_t src; src = xcb_randr_get_screen_resources_current ( xcb->connection, xcb->screen->root ); |