From 114ccd33ee24d73b2576bd289150d4799bc43670 Mon Sep 17 00:00:00 2001 From: fryshorts Date: Mon, 22 Dec 2014 00:12:37 +0100 Subject: [PATCH] linux-capture: Port geometry functions to xcb Replace XLib code with xcb in the geometry helper functions. --- plugins/linux-capture/xhelpers.c | 118 ++++++++++++++++++----------- plugins/linux-capture/xhelpers.h | 16 ++-- plugins/linux-capture/xshm-input.c | 16 ++-- 3 files changed, 89 insertions(+), 61 deletions(-) diff --git a/plugins/linux-capture/xhelpers.c b/plugins/linux-capture/xhelpers.c index 2bd769067..1eeda7c22 100644 --- a/plugins/linux-capture/xhelpers.c +++ b/plugins/linux-capture/xhelpers.c @@ -17,75 +17,105 @@ along with this program. If not, see . #include #include -#include -#include +#include +#include #include "xhelpers.h" -int_fast32_t xinerama_is_active(Display *dpy) +bool xinerama_is_active(xcb_connection_t *xcb) { - int minor, major; - if (!dpy) - return 0; - if (!XineramaQueryVersion(dpy, &minor, &major)) - return 0; - if (!XineramaIsActive(dpy)) - return 0; - return 1; + if (!xcb || !xcb_get_extension_data(xcb, &xcb_xinerama_id)->present) + return false; + + bool active = true; + xcb_xinerama_is_active_cookie_t xnr_c; + xcb_xinerama_is_active_reply_t *xnr_r; + + xnr_c = xcb_xinerama_is_active_unchecked(xcb); + xnr_r = xcb_xinerama_is_active_reply(xcb, xnr_c, NULL); + if (!xnr_r || xnr_r->state == 0) + active = false; + free(xnr_r); + + return active; } -int_fast32_t xinerama_screen_count(Display *dpy) +int xinerama_screen_count(xcb_connection_t *xcb) { - int screens; - if (!dpy) + if (!xcb) return 0; - XFree(XineramaQueryScreens(dpy, &screens)); + + int screens = 0; + xcb_xinerama_query_screens_cookie_t scr_c; + xcb_xinerama_query_screens_reply_t *scr_r; + + scr_c = xcb_xinerama_query_screens_unchecked(xcb); + scr_r = xcb_xinerama_query_screens_reply(xcb, scr_c, NULL); + if (scr_r) + screens = scr_r->number; + free(scr_r); + return screens; } -int_fast32_t xinerama_screen_geo(Display *dpy, const int_fast32_t screen, - int_fast32_t *x, int_fast32_t *y, int_fast32_t *w, int_fast32_t *h) +int xinerama_screen_geo(xcb_connection_t *xcb, int_fast32_t screen, + int_fast32_t *x, int_fast32_t *y, + int_fast32_t *w, int_fast32_t *h) { - int screens; - XineramaScreenInfo *info = NULL; - - if (!dpy) - goto fail; - info = XineramaQueryScreens(dpy, &screens); - if (screen < 0 || screen >= screens) + if (!xcb) goto fail; - *x = info[screen].x_org; - *y = info[screen].y_org; - *w = info[screen].width; - *h = info[screen].height; + bool success = false; + xcb_xinerama_query_screens_cookie_t scr_c; + xcb_xinerama_query_screens_reply_t *scr_r; + xcb_xinerama_screen_info_iterator_t iter; + + scr_c = xcb_xinerama_query_screens_unchecked(xcb); + scr_r = xcb_xinerama_query_screens_reply(xcb, scr_c, NULL); + if (!scr_r) + goto fail; + + iter = xcb_xinerama_query_screens_screen_info_iterator(scr_r); + for (; iter.rem; --screen, xcb_xinerama_screen_info_next(&iter)) { + if (!screen) { + *x = iter.data->x_org; + *y = iter.data->y_org; + *w = iter.data->width; + *h = iter.data->height; + success = true; + } + } + free(scr_r); + + if (success) + return 0; - XFree(info); - return 0; fail: - if (info) - XFree(info); - *x = *y = *w = *h = 0; return -1; } -int_fast32_t x11_screen_geo(Display *dpy, const int_fast32_t screen, - int_fast32_t *w, int_fast32_t *h) +int x11_screen_geo(xcb_connection_t *xcb, int_fast32_t screen, + int_fast32_t *w, int_fast32_t *h) { - Screen *scr; - - if (!dpy || screen < 0 || screen >= XScreenCount(dpy)) + if (!xcb) goto fail; - scr = XScreenOfDisplay(dpy, screen); - if (!scr) - goto fail; + bool success = false; + xcb_screen_iterator_t iter; - *w = XWidthOfScreen(scr); - *h = XHeightOfScreen(scr); + iter = xcb_setup_roots_iterator(xcb_get_setup(xcb)); + for (; iter.rem; --screen, xcb_screen_next(&iter)) { + if (!screen) { + *w = iter.data->width_in_pixels; + *h = iter.data->height_in_pixels; + success = true; + } + } + + if (success) + return 0; - return 0; fail: *w = *h = 0; return -1; diff --git a/plugins/linux-capture/xhelpers.h b/plugins/linux-capture/xhelpers.h index 50b1e4986..7aa12f227 100644 --- a/plugins/linux-capture/xhelpers.h +++ b/plugins/linux-capture/xhelpers.h @@ -21,7 +21,6 @@ along with this program. If not, see . extern "C" { #endif -#include #include #include #include @@ -36,16 +35,16 @@ typedef struct { /** * Check for Xinerama extension * - * @return > 0 if Xinerama is available and active + * @return true if xinerama is available and active */ -int_fast32_t xinerama_is_active(Display *dpy); +bool xinerama_is_active(xcb_connection_t *xcb); /** * Get the number of Xinerama screens * * @return number of screens */ -int_fast32_t xinerama_screen_count(Display *dpy); +int xinerama_screen_count(xcb_connection_t *xcb); /** * Get screen geometry for a Xinerama screen @@ -61,8 +60,9 @@ int_fast32_t xinerama_screen_count(Display *dpy); * * @return < 0 on error */ -int_fast32_t xinerama_screen_geo(Display *dpy, const int_fast32_t screen, - int_fast32_t *x, int_fast32_t *y, int_fast32_t *w, int_fast32_t *h); +int xinerama_screen_geo(xcb_connection_t *xcb, int_fast32_t screen, + int_fast32_t *x, int_fast32_t *y, + int_fast32_t *w, int_fast32_t *h); /** * Get screen geometry for a X11 screen @@ -76,8 +76,8 @@ int_fast32_t xinerama_screen_geo(Display *dpy, const int_fast32_t screen, * * @return < 0 on error */ -int_fast32_t x11_screen_geo(Display *dpy, const int_fast32_t screen, - int_fast32_t *w, int_fast32_t *h); +int x11_screen_geo(xcb_connection_t *xcb, int_fast32_t screen, + int_fast32_t *w, int_fast32_t *h); /** * Attach a shared memory segment to the X-Server diff --git a/plugins/linux-capture/xshm-input.c b/plugins/linux-capture/xshm-input.c index dd290e5b7..1b48f5b6e 100644 --- a/plugins/linux-capture/xshm-input.c +++ b/plugins/linux-capture/xshm-input.c @@ -18,8 +18,6 @@ along with this program. If not, see . #include #include #include -//#include -//#include #include #include #include @@ -111,7 +109,7 @@ static int_fast32_t xshm_update_geometry(struct xshm_data *data) int_fast32_t old_height = data->height; if (data->use_xinerama) { - if (xinerama_screen_geo(data->dpy, data->screen_id, + if (xinerama_screen_geo(data->xcb, data->screen_id, &data->x_org, &data->y_org, &data->width, &data->height) < 0) { return -1; @@ -122,7 +120,7 @@ static int_fast32_t xshm_update_geometry(struct xshm_data *data) else { data->x_org = 0; data->y_org = 0; - if (x11_screen_geo(data->dpy, data->screen_id, + if (x11_screen_geo(data->xcb, data->screen_id, &data->width, &data->height) < 0) { return -1; } @@ -208,7 +206,7 @@ static void xshm_capture_start(struct xshm_data *data) if (!xshm_check_extensions(data->xcb)) goto fail; - data->use_xinerama = xinerama_is_active(data->dpy) ? true : false; + data->use_xinerama = xinerama_is_active(data->xcb) ? true : false; if (xshm_update_geometry(data) < 0) { blog(LOG_ERROR, "failed to update geometry !"); @@ -309,18 +307,18 @@ static bool xshm_server_changed(obs_properties_t *props, struct dstr screen_info; dstr_init(&screen_info); - bool xinerama = xinerama_is_active(dpy); + bool xinerama = xinerama_is_active(xcb); int_fast32_t count = (xinerama) ? - xinerama_screen_count(dpy) : XScreenCount(dpy); + xinerama_screen_count(xcb) : XScreenCount(dpy); for (int_fast32_t i = 0; i < count; ++i) { int_fast32_t x, y, w, h; x = y = w = h = 0; if (xinerama) - xinerama_screen_geo(dpy, i, &x, &y, &w, &h); + xinerama_screen_geo(xcb, i, &x, &y, &w, &h); else - x11_screen_geo(dpy, i, &w, &h); + x11_screen_geo(xcb, i, &w, &h); dstr_printf(&screen_info, "Screen %"PRIuFAST32" (%"PRIuFAST32 "x%"PRIuFAST32" @ %"PRIuFAST32