Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automatically take screenshot of x server if window contents change

Tags:

c

x11

xserver

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.

like image 870
Erik Avatar asked Jan 29 '11 18:01

Erik


2 Answers

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).

like image 121
Havoc P Avatar answered Nov 04 '22 22:11

Havoc P


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.

like image 3
rexroni Avatar answered Nov 04 '22 21:11

rexroni