I am searching for a way to automatically take a screenshot of my X server if a window is created or the contents of a windows have changed.
I am currently achieving this by listening to X11 events, but not all changes are reported.
Look at XDamageNotifyEvent, XDamageQueryExtension, XDamageCreate, XDamageSubtract from the Damage extension. This extension is used to track changing window contents. http://www.freedesktop.org/wiki/Software/XDamage
A good source of sample code would be anything that makes thumbnails of windows. Also, any compositing window manager (Compiz, some flavors of metacity, etc.) would contain damage-tracking code.
Without the extension, you basically have to poll (update window contents in a timeout).
I know this post is quite dead. And yet, the documentation of X11 is terrible, and it took me a long time to get XDamage working in any regard. So here is an example that will print a line to the console every time the root X11 window changes, based on the documentation mentioned in Havoc's post, and loosely based on this link:
#include <stdio.h>
#include <stdlib.h>
#include <X11/extensions/Xdamage.h>
#include <X11/Xlib.h>
#include <signal.h>
int endnow = 0;
void cleanup(int SIGNUM){
endnow = 1;
}
int main(){
Display *display;
display = XOpenDisplay(":0");
if(!display){
perror("could not open display");
exit(1);
}
Window root = DefaultRootWindow(display);
int damage_event, damage_error, test;
//this line is necessary to initialize things
test = XDamageQueryExtension(display, &damage_event, &damage_error);
/*The "event" output is apparently the integer that appears in the
Xevent.type field when XNextEvent returns an XDamage event */
printf("test = %d, event = %d, error = %d\n",test,damage_event, damage_error);
//This is the handler for the XDamage interface
//See the XDamage documentation for more damage report levels
// http://www.freedesktop.org/wiki/Software/XDamage
Damage damage = XDamageCreate(display, root, XDamageReportNonEmpty);
signal(SIGINT,cleanup);
// XCloseDisplay(display);
while(endnow == 0){
XEvent event;
XNextEvent(display,&event);
printf("event.type = %d\n",event.type);
//this line resets the XDamage handler
XDamageSubtract(display,damage,None,None);
}
XCloseDisplay(display);
printf("done\n");
exit(0);
}
Naturally, if you run this from a console on the same screen as your display :0
, every line it prints it will activate itself, and be kinda unstable. But it is a good demonstration if you run it from an ssh terminal on another computer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With