commit
e7b25a9870
|
@ -30,6 +30,7 @@ sudo apt-get install -y \
|
||||||
libvlc-dev \
|
libvlc-dev \
|
||||||
libx11-dev \
|
libx11-dev \
|
||||||
libx264-dev \
|
libx264-dev \
|
||||||
|
libxcb-randr0-dev \
|
||||||
libxcb-shm0-dev \
|
libxcb-shm0-dev \
|
||||||
libxcb-xinerama0-dev \
|
libxcb-xinerama0-dev \
|
||||||
libxcomposite-dev \
|
libxcomposite-dev \
|
||||||
|
|
|
@ -33,6 +33,7 @@ sudo apt-get install -y \
|
||||||
libvlc-dev \
|
libvlc-dev \
|
||||||
libx11-dev \
|
libx11-dev \
|
||||||
libx264-dev \
|
libx264-dev \
|
||||||
|
libxcb-randr0-dev \
|
||||||
libxcb-shm0-dev \
|
libxcb-shm0-dev \
|
||||||
libxcb-xinerama0-dev \
|
libxcb-xinerama0-dev \
|
||||||
libxcomposite-dev \
|
libxcomposite-dev \
|
||||||
|
|
|
@ -6,7 +6,7 @@ if(NOT X11_Xcomposite_FOUND)
|
||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_package(XCB COMPONENTS XCB SHM XFIXES XINERAMA REQUIRED)
|
find_package(XCB COMPONENTS XCB RANDR SHM XFIXES XINERAMA REQUIRED)
|
||||||
find_package(X11_XCB REQUIRED)
|
find_package(X11_XCB REQUIRED)
|
||||||
|
|
||||||
include_directories(SYSTEM
|
include_directories(SYSTEM
|
||||||
|
|
|
@ -17,6 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/shm.h>
|
#include <sys/shm.h>
|
||||||
|
#include <xcb/randr.h>
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
#include <xcb/xinerama.h>
|
#include <xcb/xinerama.h>
|
||||||
|
|
||||||
|
@ -95,6 +96,78 @@ fail:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool randr_is_active(xcb_connection_t *xcb)
|
||||||
|
{
|
||||||
|
if (!xcb || !xcb_get_extension_data(xcb, &xcb_randr_id)->present)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int randr_screen_count(xcb_connection_t *xcb)
|
||||||
|
{
|
||||||
|
if (!xcb)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
xcb_screen_t *screen;
|
||||||
|
screen = xcb_setup_roots_iterator(xcb_get_setup(xcb)).data;
|
||||||
|
|
||||||
|
xcb_randr_get_screen_resources_cookie_t res_c;
|
||||||
|
xcb_randr_get_screen_resources_reply_t* res_r;
|
||||||
|
|
||||||
|
res_c = xcb_randr_get_screen_resources(xcb, screen->root);
|
||||||
|
res_r = xcb_randr_get_screen_resources_reply(xcb, res_c, 0);
|
||||||
|
if (!res_r)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return xcb_randr_get_screen_resources_crtcs_length(res_r);
|
||||||
|
}
|
||||||
|
|
||||||
|
int randr_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,
|
||||||
|
xcb_screen_t **rscreen)
|
||||||
|
{
|
||||||
|
xcb_screen_t *xscreen;
|
||||||
|
xscreen = xcb_setup_roots_iterator(xcb_get_setup(xcb)).data;
|
||||||
|
|
||||||
|
xcb_randr_get_screen_resources_cookie_t res_c;
|
||||||
|
xcb_randr_get_screen_resources_reply_t* res_r;
|
||||||
|
|
||||||
|
res_c = xcb_randr_get_screen_resources(xcb, xscreen->root);
|
||||||
|
res_r = xcb_randr_get_screen_resources_reply(xcb, res_c, 0);
|
||||||
|
if (!res_r)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
int screens = xcb_randr_get_screen_resources_crtcs_length(res_r);
|
||||||
|
if (screen < 0 || screen >= screens)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
xcb_randr_crtc_t *crtc = xcb_randr_get_screen_resources_crtcs(res_r);
|
||||||
|
|
||||||
|
xcb_randr_get_crtc_info_cookie_t crtc_c;
|
||||||
|
xcb_randr_get_crtc_info_reply_t *crtc_r;
|
||||||
|
|
||||||
|
crtc_c = xcb_randr_get_crtc_info(xcb, *(crtc + screen), 0);
|
||||||
|
crtc_r = xcb_randr_get_crtc_info_reply(xcb, crtc_c, 0);
|
||||||
|
if (!crtc_r)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
*x = crtc_r->x;
|
||||||
|
*y = crtc_r->y;
|
||||||
|
*w = crtc_r->width;
|
||||||
|
*h = crtc_r->height;
|
||||||
|
|
||||||
|
if (rscreen)
|
||||||
|
*rscreen = xscreen;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
*x = *y = *w = *h = 0;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int x11_screen_geo(xcb_connection_t *xcb, int_fast32_t screen,
|
int x11_screen_geo(xcb_connection_t *xcb, int_fast32_t screen,
|
||||||
int_fast32_t *w, int_fast32_t *h)
|
int_fast32_t *w, int_fast32_t *h)
|
||||||
{
|
{
|
||||||
|
|
|
@ -64,6 +64,39 @@ int xinerama_screen_geo(xcb_connection_t *xcb, int_fast32_t screen,
|
||||||
int_fast32_t *x, int_fast32_t *y,
|
int_fast32_t *x, int_fast32_t *y,
|
||||||
int_fast32_t *w, int_fast32_t *h);
|
int_fast32_t *w, int_fast32_t *h);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check for Randr extension
|
||||||
|
*
|
||||||
|
* @return true if randr is available which means it's active.
|
||||||
|
*/
|
||||||
|
bool randr_is_active(xcb_connection_t *xcb);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of Randr screens
|
||||||
|
*
|
||||||
|
* @return number of screens
|
||||||
|
*/
|
||||||
|
int randr_screen_count(xcb_connection_t *xcb);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get screen geometry for a Rand crtc (screen)
|
||||||
|
*
|
||||||
|
* @note On error the passed coordinates/sizes will be set to 0.
|
||||||
|
*
|
||||||
|
* @param xcb xcb connection
|
||||||
|
* @param screen screen number to get geometry for
|
||||||
|
* @param x x-coordinate of the screen
|
||||||
|
* @param y y-coordinate of the screen
|
||||||
|
* @param w width of the screen
|
||||||
|
* @param h height of the screen
|
||||||
|
*
|
||||||
|
* @return < 0 on error
|
||||||
|
*/
|
||||||
|
int randr_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,
|
||||||
|
xcb_screen_t **rscreen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get screen geometry for a X11 screen
|
* Get screen geometry for a X11 screen
|
||||||
*
|
*
|
||||||
|
|
|
@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <xcb/randr.h>
|
||||||
#include <xcb/shm.h>
|
#include <xcb/shm.h>
|
||||||
#include <xcb/xfixes.h>
|
#include <xcb/xfixes.h>
|
||||||
#include <xcb/xinerama.h>
|
#include <xcb/xinerama.h>
|
||||||
|
@ -50,6 +51,7 @@ struct xshm_data {
|
||||||
|
|
||||||
bool show_cursor;
|
bool show_cursor;
|
||||||
bool use_xinerama;
|
bool use_xinerama;
|
||||||
|
bool use_randr;
|
||||||
bool advanced;
|
bool advanced;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -83,6 +85,9 @@ static bool xshm_check_extensions(xcb_connection_t *xcb)
|
||||||
if (!xcb_get_extension_data(xcb, &xcb_xinerama_id)->present)
|
if (!xcb_get_extension_data(xcb, &xcb_xinerama_id)->present)
|
||||||
blog(LOG_INFO, "Missing Xinerama extension !");
|
blog(LOG_INFO, "Missing Xinerama extension !");
|
||||||
|
|
||||||
|
if (!xcb_get_extension_data(xcb, &xcb_randr_id)->present)
|
||||||
|
blog(LOG_INFO, "Missing Randr extension !");
|
||||||
|
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +101,15 @@ static int_fast32_t xshm_update_geometry(struct xshm_data *data)
|
||||||
int_fast32_t old_width = data->width;
|
int_fast32_t old_width = data->width;
|
||||||
int_fast32_t old_height = data->height;
|
int_fast32_t old_height = data->height;
|
||||||
|
|
||||||
if (data->use_xinerama) {
|
if (data->use_randr) {
|
||||||
|
if (randr_screen_geo(data->xcb, data->screen_id,
|
||||||
|
&data->x_org, &data->y_org,
|
||||||
|
&data->width, &data->height,
|
||||||
|
&data->xcb_screen) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (data->use_xinerama) {
|
||||||
if (xinerama_screen_geo(data->xcb, data->screen_id,
|
if (xinerama_screen_geo(data->xcb, data->screen_id,
|
||||||
&data->x_org, &data->y_org,
|
&data->x_org, &data->y_org,
|
||||||
&data->width, &data->height) < 0) {
|
&data->width, &data->height) < 0) {
|
||||||
|
@ -189,6 +202,7 @@ static void xshm_capture_start(struct xshm_data *data)
|
||||||
if (!xshm_check_extensions(data->xcb))
|
if (!xshm_check_extensions(data->xcb))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
data->use_randr = randr_is_active(data->xcb) ? true : false;
|
||||||
data->use_xinerama = xinerama_is_active(data->xcb) ? true : false;
|
data->use_xinerama = xinerama_is_active(data->xcb) ? true : false;
|
||||||
|
|
||||||
if (xshm_update_geometry(data) < 0) {
|
if (xshm_update_geometry(data) < 0) {
|
||||||
|
@ -287,16 +301,21 @@ static bool xshm_server_changed(obs_properties_t *props,
|
||||||
|
|
||||||
struct dstr screen_info;
|
struct dstr screen_info;
|
||||||
dstr_init(&screen_info);
|
dstr_init(&screen_info);
|
||||||
|
bool randr = randr_is_active(xcb);
|
||||||
bool xinerama = xinerama_is_active(xcb);
|
bool xinerama = xinerama_is_active(xcb);
|
||||||
int_fast32_t count = (xinerama) ?
|
int_fast32_t count = (randr) ?
|
||||||
xinerama_screen_count(xcb) :
|
randr_screen_count(xcb) :
|
||||||
xcb_setup_roots_length(xcb_get_setup(xcb));
|
(xinerama) ?
|
||||||
|
xinerama_screen_count(xcb) :
|
||||||
|
xcb_setup_roots_length(xcb_get_setup(xcb));
|
||||||
|
|
||||||
for (int_fast32_t i = 0; i < count; ++i) {
|
for (int_fast32_t i = 0; i < count; ++i) {
|
||||||
int_fast32_t x, y, w, h;
|
int_fast32_t x, y, w, h;
|
||||||
x = y = w = h = 0;
|
x = y = w = h = 0;
|
||||||
|
|
||||||
if (xinerama)
|
if (randr)
|
||||||
|
randr_screen_geo(xcb, i, &x, &y, &w, &h, NULL);
|
||||||
|
else if (xinerama)
|
||||||
xinerama_screen_geo(xcb, i, &x, &y, &w, &h);
|
xinerama_screen_geo(xcb, i, &x, &y, &w, &h);
|
||||||
else
|
else
|
||||||
x11_screen_geo(xcb, i, &w, &h);
|
x11_screen_geo(xcb, i, &w, &h);
|
||||||
|
|
Loading…
Reference in New Issue