add xinerama support

This commit is contained in:
Stanislav Seletskiy 2016-08-31 14:10:30 +07:00
parent 21b35b3e3e
commit 05165a02f2
3 changed files with 63 additions and 1 deletions

View File

@ -94,7 +94,7 @@ dnl ---------------------------------------------------------------------
dnl PKG_CONFIG based dependencies
dnl ---------------------------------------------------------------------
PKG_CHECK_MODULES([glib], [glib-2.0 >= 2.40])
GW_CHECK_XCB([xcb-aux xcb-xkb xkbcommon >= 0.5.0 xkbcommon-x11 xcb-ewmh xcb-icccm xcb-xrm xcb-randr])
GW_CHECK_XCB([xcb-aux xcb-xkb xkbcommon >= 0.5.0 xkbcommon-x11 xcb-ewmh xcb-icccm xcb-xrm xcb-randr xcb-xinerama])
PKG_CHECK_MODULES([pango], [pango pangocairo])
PKG_CHECK_MODULES([cairo], [cairo cairo-xcb])
PKG_CHECK_MODULES([libsn], [libstartup-notification-1.0])

View File

@ -153,6 +153,8 @@ cairo_surface_t * x11_helper_get_bg_surface ( void );
* Creates an internal represenation of the available monitors.
* Used for positioning rofi.
*/
uint8_t x11_is_randr_present ( void );
void x11_build_monitor_layout_xinerama ( void );
void x11_build_monitor_layout ( void );
void x11_dump_monitor_layout ( void );
/*@}*/

View File

@ -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"
@ -213,8 +215,66 @@ static workarea * x11_get_monitor_from_output ( xcb_randr_output_t out )
return retv;
}
uint8_t x11_is_randr_present () {
xcb_query_extension_cookie_t randr_cookie = xcb_query_extension (
xcb->connection,
sizeof("RANDR")-1,
"RANDR"
);
xcb_query_extension_reply_t *randr_reply = xcb_query_extension_reply (
xcb->connection,
randr_cookie,
NULL
);
return randr_reply->present;
}
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 ( !x11_is_randr_present () ) {
fprintf ( stderr, "Using XINERAMA instead of XRANDR\n" );
x11_build_monitor_layout_xinerama ();
}
if ( xcb->monitors ) {
return;
}