1

So I've been playing around with XLib a bit, and I tried to make a program in c++ that would simply take a screenshot and display it in a window, thus creating a tunnel effect, kind of. And it works just fine, for a few seconds. And then my computer (running Ubuntu, by the way) starts going at a very, very slow frame rate, with my mouse barely responding, and closing the window fails to stop it and pressing ctrl-c fails to stop it, and then it just freezes completely, and I have no choice to use my power button to manually power it off and restart the computer (after which, it seems to work fine?).

Now, XLib is a very weird library, with not great documentation, so I know that I just am fundamentally doing something wrong, but my code is so simple that I have no idea what it could be. I've tried various things (commenting out certain functions, using usleep to pause it in between frames), but it is disheartening after every new idea when it doesn't work and the computer must be restarted. So perhaps one of you knows what is going on?

Here is my code:

#include <X11/Xlib.h>
int main(){
    //Initializes some values
    Display* display=XOpenDisplay(0);
    Window root=DefaultRootWindow(display);
    XWindowAttributes att;
    XGetWindowAttributes(display, root, &att);
    //att.width and att.height now are the width and height of the screen
    int screen=DefaultScreen(display);
    Window window=XCreateSimpleWindow(display, root, 0, 0,
                         att.width, att.height, 1,
                         BlackPixel(display, screen),
                         WhitePixel(display, screen));
    GC graphics=XCreateGC(display, window, 0, NULL);

    //puts window on screen
    XMapWindow(display, window);
    while(1){
        //This gets the screenshot
        XImage* ximg=XGetImage(display, root, 0, 0,
                           att.width, att.height,
                           AllPlanes, ZPixmap);
        //This puts the screenshot in the window "window"
        XPutImage(display,window, graphics,  ximg,
                  0,0,0,0, att.width, att.height);
        //frees the data allocated to ximg
        XFree(ximg);
    }
}

(This should compile with a simple g++ screentest.cpp -lX11)

For what it's worth, some informative webpages that I haven't gleaned any solutions from are:

The man page for XGetImage and XPutImage

The man page for XFree, although I really don't think this is the problem

This Stack Overflow question seems relevant - but it doesn't have any answers

I've also looked over a fair amount of other Stack Overflow questions, and although a fair amount look like they could be relevant, I didn't see anything directly pertaining to my question.

Thank you for any help you can offer.

Community
  • 1
  • 1
Nolan
  • 49
  • 4

1 Answers1

0

You say that you you added code to sleep in between calls. That would be a good thing to do. Try adding in a longer sleep interval than you already tried.

Also consider using a counter so that you aren't calling it forever. I'm guessing that the problem is either run away memory usage, or just an infinite loop. Either way, put in something so that the program will stop itself instead of relying on you to exit it manually.

hazzey
  • 1,179
  • 25
  • 29
  • I used a counter to exit, it worked more or less fine at 1000 calls and was broken for 4000 and I didn't really try to get a more specific number (I suppose I could actually print out the number and find specifically when it freezes, but I'm not terribly interested). And making the sleep longer seems just to make it last proportionally longer - although admittedly since it takes a few thousand calls to kill the computer, and since it does seem always to kill the computer, I haven't experimented much with sleeping longer than a tenth of a second. – Nolan Dec 31 '14 at 04:23