diff --git a/plugins/linux-capture/xhelpers.c b/plugins/linux-capture/xhelpers.c index a6e88842a4f0af01f6f46f7e48c3e8f1162d586e..aa76f047d26ae0c15713b4d9b9ca5a842b1ef29a 100644 --- a/plugins/linux-capture/xhelpers.c +++ b/plugins/linux-capture/xhelpers.c @@ -104,6 +104,22 @@ bool randr_is_active(xcb_connection_t *xcb) return true; } +static bool randr_has_monitors(xcb_connection_t *xcb) +{ + xcb_randr_query_version_cookie_t ver_c; + xcb_randr_query_version_reply_t *ver_r; + + ver_c = xcb_randr_query_version(xcb, XCB_RANDR_MAJOR_VERSION, + XCB_RANDR_MINOR_VERSION); + ver_r = xcb_randr_query_version_reply(xcb, ver_c, 0); + if (!ver_r) + return 0; + + bool ret = ver_r->major_version > 1 || ver_r->minor_version >= 5; + free(ver_r); + return ret; +} + int randr_screen_count(xcb_connection_t *xcb) { if (!xcb) @@ -111,6 +127,19 @@ int randr_screen_count(xcb_connection_t *xcb) xcb_screen_t *screen; screen = xcb_setup_roots_iterator(xcb_get_setup(xcb)).data; + if (randr_has_monitors(xcb)) { + xcb_randr_get_monitors_cookie_t mon_c; + xcb_randr_get_monitors_reply_t *mon_r; + + mon_c = xcb_randr_get_monitors(xcb, screen->root, true); + mon_r = xcb_randr_get_monitors_reply(xcb, mon_c, 0); + if (!mon_r) + return 0; + + int count = xcb_randr_get_monitors_monitors_length(mon_r); + free(mon_r); + return count; + } xcb_randr_get_screen_resources_cookie_t res_c; xcb_randr_get_screen_resources_reply_t *res_r; @@ -124,11 +153,58 @@ int randr_screen_count(xcb_connection_t *xcb) 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) + int_fast32_t *h, xcb_screen_t **rscreen, char **name) { xcb_screen_t *xscreen; xscreen = xcb_setup_roots_iterator(xcb_get_setup(xcb)).data; + if (randr_has_monitors(xcb)) { + xcb_randr_get_monitors_cookie_t mon_c; + xcb_randr_get_monitors_reply_t *mon_r; + + mon_c = xcb_randr_get_monitors(xcb, xscreen->root, true); + mon_r = xcb_randr_get_monitors_reply(xcb, mon_c, 0); + if (!mon_r) + return 0; + + int monitors = xcb_randr_get_monitors_monitors_length(mon_r); + if (screen < 0 || screen >= monitors) { + free(mon_r); + goto fail; + } + + xcb_randr_monitor_info_iterator_t mon_i; + mon_i = xcb_randr_get_monitors_monitors_iterator(mon_r); + + int s; + for (s = 0; s < screen; s++) + xcb_randr_monitor_info_next(&mon_i); + + xcb_randr_monitor_info_t *mon = mon_i.data; + + *x = mon->x; + *y = mon->y; + *w = mon->width; + *h = mon->height; + if (rscreen) + *rscreen = xscreen; + + if (mon->name && name) { + xcb_get_atom_name_cookie_t atom_c; + xcb_get_atom_name_reply_t *atom_r; + + atom_c = xcb_get_atom_name(xcb, mon->name); + atom_r = xcb_get_atom_name_reply(xcb, atom_c, 0); + if (atom_r) { + *name = strndup( + xcb_get_atom_name_name(atom_r), + xcb_get_atom_name_name_length(atom_r)); + free(atom_r); + } + } + free(mon_r); + return 0; + } xcb_randr_get_screen_resources_cookie_t res_c; xcb_randr_get_screen_resources_reply_t *res_r; diff --git a/plugins/linux-capture/xhelpers.h b/plugins/linux-capture/xhelpers.h index ffc3f8b3aa67b41676a080739b24ba908afb9272..7908c5ce265f6a5c115efb7af1b02dc7d70a8d66 100644 --- a/plugins/linux-capture/xhelpers.h +++ b/plugins/linux-capture/xhelpers.h @@ -94,7 +94,7 @@ int randr_screen_count(xcb_connection_t *xcb); */ 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); + int_fast32_t *h, xcb_screen_t **rscreen, char **name); /** * Get screen geometry for a X11 screen diff --git a/plugins/linux-capture/xshm-input.c b/plugins/linux-capture/xshm-input.c index 70c3fc06fd782096ec84927acc670616aae938a6..3f60a15dae3e15533a609a060a6a4d20e09e4736 100644 --- a/plugins/linux-capture/xshm-input.c +++ b/plugins/linux-capture/xshm-input.c @@ -104,7 +104,7 @@ static int_fast32_t xshm_update_geometry(struct xshm_data *data) 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) { + &data->xcb_screen, NULL) < 0) { return -1; } } else if (data->use_xinerama) { @@ -308,21 +308,31 @@ static bool xshm_server_changed(obs_properties_t *props, obs_property_t *p, : xcb_setup_roots_length(xcb_get_setup(xcb)); for (int_fast32_t i = 0; i < count; ++i) { + char *name; + char name_tmp[12]; int_fast32_t x, y, w, h; x = y = w = h = 0; + name = NULL; if (randr) - randr_screen_geo(xcb, i, &x, &y, &w, &h, NULL); + randr_screen_geo(xcb, i, &x, &y, &w, &h, NULL, &name); else if (xinerama) xinerama_screen_geo(xcb, i, &x, &y, &w, &h); else x11_screen_geo(xcb, i, &w, &h); + if (name == NULL) { + sprintf(name_tmp, "%" PRIuFAST32, i); + name = name_tmp; + } + dstr_printf(&screen_info, - "Screen %" PRIuFAST32 " (%" PRIuFAST32 - "x%" PRIuFAST32 " @ %" PRIuFAST32 ",%" PRIuFAST32 - ")", - i, w, h, x, y); + "Screen %s (%" PRIuFAST32 "x%" PRIuFAST32 + " @ %" PRIuFAST32 ",%" PRIuFAST32 ")", + name, w, h, x, y); + + if (name != name_tmp) + free(name); if (h > 0 && w > 0) obs_property_list_add_int(screens, screen_info.array,