Răsfoiți Sursa

linux-capture: Port geometry functions to xcb

Replace XLib code with xcb in the geometry helper functions.
fryshorts 10 ani în urmă
părinte
comite
114ccd33ee

+ 73 - 43
plugins/linux-capture/xhelpers.c

@@ -17,75 +17,105 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 #include <stdint.h>
 #include <sys/shm.h>
-#include <X11/Xutil.h>
-#include <X11/extensions/Xinerama.h>
+#include <xcb/xcb.h>
+#include <xcb/xinerama.h>
 
 #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)
+	if (!xcb)
 		goto fail;
-	info = XineramaQueryScreens(dpy, &screens);
-	if (screen < 0 || screen >= screens)
+
+	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;
 
-	*x = info[screen].x_org;
-	*y = info[screen].y_org;
-	*w = info[screen].width;
-	*h = info[screen].height;
+	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;
+
+	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;
+		}
+	}
 
-	*w = XWidthOfScreen(scr);
-	*h = XHeightOfScreen(scr);
+	if (success)
+		return 0;
 
-	return 0;
 fail:
 	*w = *h = 0;
 	return -1;

+ 8 - 8
plugins/linux-capture/xhelpers.h

@@ -21,7 +21,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 extern "C" {
 #endif
 
-#include <X11/Xlib.h>
 #include <xcb/shm.h>
 #include <xcb/xproto.h>
 #include <obs.h>
@@ -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

+ 7 - 9
plugins/linux-capture/xshm-input.c

@@ -18,8 +18,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include <stdio.h>
 #include <stdlib.h>
 #include <inttypes.h>
-//#include <X11/Xlib.h>
-//#include <X11/Xutil.h>
 #include <X11/Xlib-xcb.h>
 #include <xcb/shm.h>
 #include <xcb/xfixes.h>
@@ -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