summaryrefslogtreecommitdiffstats
path: root/source/x11-helper.c
diff options
context:
space:
mode:
authorDave Davenport <qball@gmpclient.org>2016-08-31 09:44:43 +0200
committerDave Davenport <qball@gmpclient.org>2016-08-31 09:59:51 +0200
commit4a95285212e89a3b9a63c059ef1df1412c246378 (patch)
tree18ea5dbe6817f495c9fc7cabd403a70a70cbc5bd /source/x11-helper.c
parent56cc94195c26c909d587901af753fc22c919f5cd (diff)
parent3da28675067d895eb5d623bccc23af6126ba33af (diff)
Merge branch 'seletskiy-xinerama'
* Tweak some minor things.
Diffstat (limited to 'source/x11-helper.c')
-rw-r--r--source/x11-helper.c63
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 );