/** * The x server was changed */ static bool xshm_server_changed(obs_properties_t *props, obs_property_t *p, obs_data_t *settings) { UNUSED_PARAMETER(p); bool advanced = obs_data_get_bool(settings, "advanced"); int_fast32_t old_screen = obs_data_get_int(settings, "screen"); const char *server = obs_data_get_string(settings, "server"); obs_property_t *screens = obs_properties_get(props, "screen"); /* we want a real NULL here in case there is no string here */ server = (advanced && *server) ? server : NULL; obs_property_list_clear(screens); Display *dpy = XOpenDisplay(server); if (!dpy) { obs_property_set_enabled(screens, false); return true; } struct dstr screen_info; dstr_init(&screen_info); bool xinerama = xinerama_is_active(dpy); int_fast32_t count = (xinerama) ? xinerama_screen_count(dpy) : 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); else x11_screen_geo(dpy, i, &w, &h); dstr_printf(&screen_info, "Screen %"PRIuFAST32" (%"PRIuFAST32 "x%"PRIuFAST32" @ %"PRIuFAST32 ",%"PRIuFAST32")", i, w, h, x, y); obs_property_list_add_int(screens, screen_info.array, i); } /* handle missing screen */ if (old_screen + 1 > count) { dstr_printf(&screen_info, "Screen %"PRIuFAST32" (not found)", old_screen); size_t index = obs_property_list_add_int(screens, screen_info.array, old_screen); obs_property_list_item_disable(screens, index, true); } dstr_free(&screen_info); XCloseDisplay(dpy); obs_property_set_enabled(screens, true); return true; }
/** * Update the capture * * @return < 0 on error, 0 when size is unchanged, > 1 on size change */ static int_fast32_t xshm_update_geometry(struct xshm_data *data, obs_data_t settings) { int_fast32_t old_width = data->width; int_fast32_t old_height = data->height; int_fast32_t screen = obs_data_get_int(settings, "screen"); if (data->use_xinerama) { if (xinerama_screen_geo(data->dpy, screen, &data->x_org, &data->y_org, &data->width, &data->height) < 0) { return -1; } data->screen = XDefaultScreenOfDisplay(data->dpy); } else { data->x_org = 0; data->y_org = 0; if (x11_screen_geo(data->dpy, screen, &data->width, &data->height) < 0) { return -1; } data->screen = XScreenOfDisplay(data->dpy, screen); } if (!data->width || !data->height) { blog(LOG_ERROR, "xshm-input: Failed to get geometry"); return -1; } blog(LOG_INFO, "xshm-input: Geometry %"PRIdFAST32"x%"PRIdFAST32 " @ %"PRIdFAST32",%"PRIdFAST32, data->width, data->height, data->x_org, data->y_org); if (old_width == data->width && old_height == data->height) return 0; return 1; }
/** * Update the capture * * @return < 0 on error, 0 when size is unchanged, > 1 on size change */ static int_fast32_t xshm_update_geometry(struct xshm_data *data) { int_fast32_t old_width = data->width; int_fast32_t old_height = data->height; if (data->use_xinerama) { if (xinerama_screen_geo(data->xcb, data->screen_id, &data->x_org, &data->y_org, &data->width, &data->height) < 0) { return -1; } data->xcb_screen = xcb_get_screen(data->xcb, 0); } else { data->x_org = 0; data->y_org = 0; if (x11_screen_geo(data->xcb, data->screen_id, &data->width, &data->height) < 0) { return -1; } data->xcb_screen = xcb_get_screen(data->xcb, data->screen_id); } if (!data->width || !data->height) { blog(LOG_ERROR, "Failed to get geometry"); return -1; } blog(LOG_INFO, "Geometry %"PRIdFAST32"x%"PRIdFAST32 " @ %"PRIdFAST32",%"PRIdFAST32, data->width, data->height, data->x_org, data->y_org); if (old_width == data->width && old_height == data->height) return 0; return 1; }