Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

screenshot using openGL and/or X11

Tags:

c

x11

opengl

i am trying to get a screenshot of the screen or a window. I tried using functions from X11 and it works fine. The problem is that getting the pixels from XImage takes a lot of time. Than i tried to look for some answers on how to do it using openGL. Here's what i've got:

#include <stdlib.h>
#include <stdio.h>
#include <cstdio>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include <X11/Xlib.h>


int main(int argc, char **argv)
{

int width=1200;
int height=800; 
//_____________________________----
 Display *dpy;
  Window root;
  GLint att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None };
  XVisualInfo *vi;
  GLXContext glc;

  dpy = XOpenDisplay(NULL);

  if ( !dpy ) {
    printf("\n\tcannot connect to X server\n\n");
    exit(0);
  }

  root = DefaultRootWindow(dpy);
  vi = glXChooseVisual(dpy, 0, att);

  if (!vi) {
    printf("\n\tno appropriate visual found\n\n");
    exit(0);
  }

glXMakeCurrent(dpy, root, glc);
  glc = glXCreateContext(dpy, vi, NULL, GL_TRUE);


  printf("vendor: %s\n", (const char*)glGetString(GL_VENDOR));

//____________________________________________
glXMakeCurrent(dpy, root, glc);

glEnable(GL_DEPTH_TEST); 
GLubyte* pixelBuffer = new GLubyte[sizeof(GLubyte)*width*height*3*3];

glReadBuffer(GL_FRONT); 

GLint ReadBuffer;
glGetIntegerv(GL_READ_BUFFER,&ReadBuffer);
glPixelStorei(GL_READ_BUFFER,GL_RGB);

GLint PackAlignment;
glGetIntegerv(GL_PACK_ALIGNMENT,&PackAlignment); 
glPixelStorei(GL_PACK_ALIGNMENT,1);

glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_INT, pixelBuffer);

int i;

for (i=0;i<100;i++) printf("%u\n",((unsigned int *)pixelBuffer)[i]);



return 0;
}

when i run the program it returns an error: X Error of failed request: BadAccess (attempt to access private resource denied) Major opcode of failed request: 199 () Minor opcode of failed request: 26 Serial number of failed request: 20 Current serial number in output stream: 20

if i comment the line with glXMakeCurrent(dpy, root, glc); before glc = glXCreateContext(dpy, vi, NULL, GL_TRUE); it returns no erros, but all the pixels are 0.

How should i go about this problem? I am new to openGL and maybe i am missing something important here. Maybe also another way of getting pixels from the screen or specific window exists?

like image 332
Jaka Avatar asked May 19 '11 18:05

Jaka


2 Answers

I don't think what you are trying to do is possible. You can't use OpenGL to read pixels from window you don't own and which probably don't even use OpenGL. You need to stick to X11.

If you have XImage you can get raw pixels from ximage->data. Just make sure you are reading it in correct format.

http://tronche.com/gui/x/xlib/graphics/images.html

like image 98
Piotr Praszmo Avatar answered Sep 30 '22 11:09

Piotr Praszmo


You can use XShmGetImage, but you have to query the extensions of the X11 server first, to make sure MIT-SHM extension is available. You also need to know how to setup and use a shared memory segment for this.

Querying the Extension:

http://git.videolan.org/?p=ffmpeg.git;a=blob;f=libavdevice/x11grab.c#l224

Getting the image:

http://git.videolan.org/?p=ffmpeg.git;a=blob;f=libavdevice/x11grab.c#l537

like image 41
Christian Avatar answered Sep 30 '22 09:09

Christian