New upstream version 23.2.1+dfsg1

This commit is contained in:
Simon Chopin 2019-07-27 14:47:10 +02:00
parent cdc9a9fc87
commit b14f9eae6d
1017 changed files with 37232 additions and 11111 deletions

View file

@ -6,7 +6,7 @@ if(NOT X11_Xcomposite_FOUND)
return()
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)
include_directories(SYSTEM

View file

@ -11,6 +11,6 @@ CropRight="Beskær højre (pixels)"
CropBottom="Beskær bund (pixels)"
SwapRedBlue="Ombyt rød og blå"
LockX="Lås X server under optagelse"
IncludeXBorder="Inkluder X-kant"
IncludeXBorder="Inkludér X-kant"
ExcludeAlpha="Benyt alpha-fri teksturformat (Mesa løsning)"

View file

@ -2,7 +2,7 @@ X11SharedMemoryScreenInput="Bildschirmaufnahme (XSHM)"
Screen="Bildschirm"
CaptureCursor="Mauszeiger aufnehmen"
AdvancedSettings="Erweiterte Einstellungen"
XServer="X Server"
XServer="X-Server"
XCCapture="Fensteraufnahme (Xcomposite)"
Window="Fenster"
CropTop="Oben abschneiden (Pixel)"
@ -10,7 +10,7 @@ CropLeft="Links abschneiden (Pixel)"
CropRight="Rechts abschneiden (Pixel)"
CropBottom="Unten abschneiden (Pixel)"
SwapRedBlue="Rot und Blau tauschen"
LockX="X Server sperren während der Aufnahme"
IncludeXBorder="X Rahmen anzeigen"
ExcludeAlpha="Verwenden von alphalosem Texturformat (Mesa Problemumgehung)"
LockX="X-Server während der Aufnahme sperren"
IncludeXBorder="X-Rahmen anzeigen"
ExcludeAlpha="Alphaloses Texturformat verwenden (Mesa-Problemumgehung)"

View file

@ -0,0 +1,15 @@
X11SharedMemoryScreenInput="صفحه نمایش ضبط (XSHM)"
Screen="صفحه نمایش"
CaptureCursor="گرفتن مکان نما"
AdvancedSettings="تنظیمات پیشرفته"
XServer="سرویس دهنده"
XCCapture="ضبط پنجره (Xcomposite)"
Window="ویندوز"
CropTop="برش بالا (پیکسل)"
CropLeft="برش چپ (پیکسل)"
CropRight="برش راست (پیکسل)"
CropBottom="برش پایین (پیکسل)"
LockX="سرور اکس قفل هنگام گرفتن"
IncludeXBorder="شامل X مرز"
ExcludeAlpha="استفاده از فرمت های بافت آلفا کمتر (مسا حلی)"

View file

@ -11,6 +11,6 @@ CropRight="Rogner à droite (pixels)"
CropBottom="Rogner en bas (pixels)"
SwapRedBlue="Intervertir le rouge et le bleu"
LockX="Verrouiller le serveur X lors de la capture"
IncludeXBorder="Inclure la bordure de X"
ExcludeAlpha="Utiliser un format de texture sans alpha (contournement pour Mesa)"
IncludeXBorder="Inclure la bordure de la fenêtre X"
ExcludeAlpha="Utiliser un format de texture sans alpha (palliatif pour Mesa)"

View file

@ -1,16 +1,16 @@
X11SharedMemoryScreenInput="Cattura schermo (XSHM)"
X11SharedMemoryScreenInput="Cattura dello schermo (XSHM)"
Screen="Schermo"
CaptureCursor="Cattura il cursore"
AdvancedSettings="Configurazioni Avanzate"
AdvancedSettings="Impostazioni avanzate"
XServer="X Server"
XCCapture="Cattura la finestra (xcomposite)"
XCCapture="Cattura la finestra (Xcomposite)"
Window="Finestra"
CropTop="Crop Superiore (pixels)"
CropLeft="Crop Sinistro (pixels)"
CropRight="Crop Destro (pixels)"
CropBottom="Crop Inferiore (pixels)"
SwapRedBlue="Inverti rosso e blu"
LockX="Blocca l' X Server durante l'acquisizione"
IncludeXBorder="Includi X bordi"
ExcludeAlpha="Usa formato texture alfa-less (soluzione di Mesa)"
CropTop="Ritaglia dall'alto (in pixel)"
CropLeft="Ritaglia da sinistra (in pixel)"
CropRight="Ritaglia da destra (in pixel)"
CropBottom="Ritaglia dal basso (in pixel)"
SwapRedBlue="Inverti i colori rosso e blu"
LockX="Blocca X Server durante la cattura"
IncludeXBorder="Includi i bordi della finestra X"
ExcludeAlpha="Utilizza il formato alfa-less per le texture (soluzione di Mesa)"

View file

@ -12,5 +12,5 @@ CropBottom="Trunchiază partea inferioară (pixeli)"
SwapRedBlue="Schimbă roșu cu albastru"
LockX="Blochează serverul X atunci când se capturează"
IncludeXBorder="Include marginea cu X"
ExcludeAlpha="Folosește formatul de texturi fără alpha (soluție de evitare Mesa)"
ExcludeAlpha="Folosește formatul de texturi fără alpha (soluție de evitare pentru Mesa)"

View file

@ -1,6 +1,6 @@
X11SharedMemoryScreenInput="Ekranski ulaz (XSHM)"
Screen="Ekran"
CaptureCursor="Snimaj kursor"
X11SharedMemoryScreenInput="Snimak ekrana (XSHM)"
Screen="Екран"
CaptureCursor="Снимај курсор"
AdvancedSettings="Napredna podešavanja"
XServer="X server"
XCCapture="Улаз са прозора (Xcomposite)"

View file

@ -1,6 +1,6 @@
X11SharedMemoryScreenInput="Екрански улаз (XSHM)"
Screen="Екран"
CaptureCursor="Снимај курсор"
X11SharedMemoryScreenInput="Снимак екрана (XSHM)"
Screen="Ekran"
CaptureCursor="Snimaj kursor"
AdvancedSettings="Напредна подешавања"
XServer="X сервер"
XCCapture="Ulaz sa prozora (Xcomposite)"

View file

@ -1,7 +1,7 @@
X11SharedMemoryScreenInput="Bildskärmskälla (XSHM)"
Screen="Skärm"
CaptureCursor="Visa muspekare"
AdvancedSettings="Avancerade Inställningar"
AdvancedSettings="Avancerade inställningar"
XServer="X-servern"
XCCapture="Fönsterkälla (Xcomposite)"
Window="Fönster"

View file

@ -18,6 +18,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
OBS_DECLARE_MODULE()
OBS_MODULE_USE_DEFAULT_LOCALE("linux-xshm", "en-US")
MODULE_EXPORT const char *obs_module_description(void)
{
return "xcomposite/xshm based window/screen capture for X11";
}
extern struct obs_source_info xshm_input;

View file

@ -148,6 +148,7 @@ struct XCompcapMain_private
bool lockX;
bool include_border;
bool exclude_alpha;
bool draw_opaque;
double window_check_time = 0.0;
@ -251,6 +252,9 @@ static void xcc_cleanup(XCompcapMain_private *p)
XDisplayLock xlock;
if (p->gltex) {
GLuint gltex = *(GLuint*)gs_texture_get_obj(p->gltex);
glBindTexture(GL_TEXTURE_2D, gltex);
glXReleaseTexImageEXT(xdisp, p->glxpixmap, GLX_FRONT_LEFT_EXT);
gs_texture_destroy(p->gltex);
p->gltex = 0;
}
@ -301,6 +305,7 @@ void XCompcapMain::updateSettings(obs_data_t *settings)
p->show_cursor = obs_data_get_bool(settings, "show_cursor");
p->include_border = obs_data_get_bool(settings, "include_border");
p->exclude_alpha = obs_data_get_bool(settings, "exclude_alpha");
p->draw_opaque = false;
} else {
p->win = prevWin;
}
@ -347,6 +352,90 @@ void XCompcapMain::updateSettings(obs_data_t *settings)
cf = GS_BGRX;
}
bool has_alpha = true;
const int attrs[] =
{
GLX_BIND_TO_TEXTURE_RGBA_EXT, GL_TRUE,
GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT,
GLX_ALPHA_SIZE, 8,
GLX_DOUBLEBUFFER, GL_FALSE,
None
};
int nelem = 0;
GLXFBConfig *configs = glXGetFBConfigs(xdisp,
XCompcap::getRootWindowScreen(attr.root),
&nelem);
if (nelem <= 0) {
blog(LOG_ERROR, "no fb configs available");
p->win = 0;
p->height = 0;
p->width = 0;
return;
}
GLXFBConfig config;
for (int i = 0; i < nelem; i++) {
config = configs[i];
XVisualInfo *visual = glXGetVisualFromFBConfig(xdisp, config);
if (!visual)
continue;
if (attr.visual->visualid != visual->visualid) {
XFree(visual);
continue;
}
XFree(visual);
int value;
glXGetFBConfigAttrib(xdisp, config, GLX_ALPHA_SIZE, &value);
if (value != 8)
has_alpha = false;
break;
}
XFree(configs);
configs = glXChooseFBConfig(xdisp,
XCompcap::getRootWindowScreen(attr.root),
attrs, &nelem);
if (nelem <= 0) {
blog(LOG_ERROR, "no matching fb config found");
p->win = 0;
p->height = 0;
p->width = 0;
return;
}
bool found = false;
for (int i = 0; i < nelem; i++) {
config = configs[i];
XVisualInfo *visual = glXGetVisualFromFBConfig(xdisp, config);
if (!visual)
continue;
if (attr.depth != visual->depth) {
XFree(visual);
continue;
}
XFree(visual);
found = true;
break;
}
if (!found)
config = configs[0];
if (cf == GS_BGRX || !has_alpha) {
p->draw_opaque = true;
}
int inverted;
glXGetFBConfigAttrib(xdisp, config, GLX_Y_INVERTED_EXT, &inverted);
p->inverted = inverted != 0;
p->border = attr.border_width;
if (p->include_border) {
@ -395,32 +484,6 @@ void XCompcapMain::updateSettings(obs_data_t *settings)
glBindTexture(GL_TEXTURE_2D, 0);
}
const int attrs[] =
{
GLX_BIND_TO_TEXTURE_RGBA_EXT, GL_TRUE,
GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT,
GLX_ALPHA_SIZE, 8,
GLX_DOUBLEBUFFER, GL_FALSE,
None
};
int nelem = 0;
GLXFBConfig* configs = glXChooseFBConfig(xdisp,
XCompcap::getRootWindowScreen(attr.root),
attrs, &nelem);
if (nelem <= 0) {
blog(LOG_ERROR, "no matching fb config found");
p->win = 0;
p->height = 0;
p->width = 0;
return;
}
glXGetFBConfigAttrib(xdisp, configs[0], GLX_Y_INVERTED_EXT, &nelem);
p->inverted = nelem != 0;
xlock.resetError();
p->pixmap = XCompositeNameWindowPixmap(xdisp, p->win);
@ -433,14 +496,23 @@ void XCompcapMain::updateSettings(obs_data_t *settings)
return;
}
const int attribs[] =
const int attribs_alpha[] =
{
GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGBA_EXT,
None
};
p->glxpixmap = glXCreatePixmap(xdisp, configs[0], p->pixmap, attribs);
const int attribs_no_alpha[] =
{
GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT,
None
};
const int *attribs = cf == GS_RGBA ? attribs_alpha : attribs_no_alpha;
p->glxpixmap = glXCreatePixmap(xdisp, config, p->pixmap, attribs);
if (xlock.gotError()) {
blog(LOG_ERROR, "glXCreatePixmap failed: %s",
@ -466,10 +538,14 @@ void XCompcapMain::updateSettings(obs_data_t *settings)
if (!p->windowName.empty()) {
blog(LOG_INFO, "[window-capture: '%s'] update settings:\n"
"\ttitle: %s\n"
"\tclass: %s",
"\tclass: %s\n"
"\tHas alpha: %s\n"
"\tFound proper GLXFBConfig: %s\n",
obs_source_get_name(p->source),
XCompcap::getWindowName(p->win).c_str(),
XCompcap::getWindowClass(p->win).c_str());
XCompcap::getWindowClass(p->win).c_str(),
has_alpha ? "yes" : "no",
found ? "yes" : "no");
blog(LOG_DEBUG, "\n"
"\tid: %s",
std::to_string((long long)p->win).c_str());
@ -563,7 +639,10 @@ void XCompcapMain::render(gs_effect_t *effect)
PLock lock(&p->lock, true);
effect = obs_get_base_effect(OBS_EFFECT_OPAQUE);
if (p->draw_opaque)
effect = obs_get_base_effect(OBS_EFFECT_OPAQUE);
else
effect = obs_get_base_effect(OBS_EFFECT_DEFAULT);
if (!lock.isLocked() || !p->tex)
return;

View file

@ -17,6 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <stdint.h>
#include <sys/shm.h>
#include <xcb/randr.h>
#include <xcb/xcb.h>
#include <xcb/xinerama.h>
@ -95,6 +96,78 @@ fail:
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_fast32_t *w, int_fast32_t *h)
{

View file

@ -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 *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
*

View file

@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <xcb/randr.h>
#include <xcb/shm.h>
#include <xcb/xfixes.h>
#include <xcb/xinerama.h>
@ -50,6 +51,7 @@ struct xshm_data {
bool show_cursor;
bool use_xinerama;
bool use_randr;
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)
blog(LOG_INFO, "Missing Xinerama extension !");
if (!xcb_get_extension_data(xcb, &xcb_randr_id)->present)
blog(LOG_INFO, "Missing Randr extension !");
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_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,
&data->x_org, &data->y_org,
&data->width, &data->height) < 0) {
@ -189,6 +202,7 @@ static void xshm_capture_start(struct xshm_data *data)
if (!xshm_check_extensions(data->xcb))
goto fail;
data->use_randr = randr_is_active(data->xcb) ? true : false;
data->use_xinerama = xinerama_is_active(data->xcb) ? true : false;
if (xshm_update_geometry(data) < 0) {
@ -287,16 +301,21 @@ static bool xshm_server_changed(obs_properties_t *props,
struct dstr screen_info;
dstr_init(&screen_info);
bool randr = randr_is_active(xcb);
bool xinerama = xinerama_is_active(xcb);
int_fast32_t count = (xinerama) ?
xinerama_screen_count(xcb) :
xcb_setup_roots_length(xcb_get_setup(xcb));
int_fast32_t count = (randr) ?
randr_screen_count(xcb) :
(xinerama) ?
xinerama_screen_count(xcb) :
xcb_setup_roots_length(xcb_get_setup(xcb));
for (int_fast32_t i = 0; i < count; ++i) {
int_fast32_t x, y, w, h;
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);
else
x11_screen_geo(xcb, i, &w, &h);