I've been trying to find a way of grabbing video directly from an X window and got pointed to Xlib and the compositing extension.
So far, I've been able to listen to change events and grab a Pixmap with this code:
#include <X11/Intrinsic.h>
#include <X11/extensions/Xcomposite.h>
#include <X11/extensions/Xdamage.h>
#include <iostream>
#include <fstream>
using namespace std;
int main(int argc, char ** argv) {
int br, base;
Window win = 0x3400003;
Display *dsp = XOpenDisplay(0);
XCompositeQueryExtension(dsp, &base, &br);
XDamageQueryExtension(dsp,&base, &br);
cout << base << endl;
Damage damage = XDamageCreate(dsp, win, XDamageReportRawRectangles);
XCompositeRedirectWindow(dsp, win, CompositeRedirectAutomatic);
XEvent ev;
while(true) {
XNextEvent(dsp, &ev);
if(ev.type == base + XDamageNotify) {
Pixmap pm = XCompositeNameWindowPixmap(dsp, win);
XWindowAttributes attr;
XGetWindowAttributes(dsp, win, &attr);
XWriteBitmapFile(dsp, "test.bmp", pm, attr.width, attr.height, -1, -1);
return 0;
}
}
XCompositeUnredirectWindow(dsp, win, CompositeRedirectAutomatic);
XDamageDestroy(dsp, damage);
return 0;
}
The problem here is that the resulting bmp (created by XWriteBitmapFile) is black&white horribleness. Disregarding the fact that I don't want to write the data to file anyway, I am apparently doing something wrong in reading it. I would love to convert the Pixmap to either a framebuffer in opengl or a binary blob in ram.
Thanks in advance for any help you can give me on this.
Best regards.
"Bitmaps" in X world refer to two-colored images. I guess XWriteBitmapFile does internally GetImage request and transforms server pixmap to a bitmap. Note that file format is it's own 'X11 bitmap', not windows bitmap.
Use XGetImage function If you actually need image's binary blob.