void glDispyWidget::paintGL() { //http://stackoverflow.com/questions/6512543/obtaining-full-desktop-screenshot-from-the-gpu //http://forum.openframeworks.cc/index.php?topic=3017.0 if(useShm) { XShmGetImage(xDisplay, rootWindow, img, 0, 0, AllPlanes); } else { //XImage *img = XGetImage(display,root,0,0,400,400,XAllPlanes(),ZPixmap); img = XGetImage(xDisplay,rootWindow,0,0,xDisplayWidth,xDisplayHeight,XAllPlanes(),ZPixmap); } if (img == NULL) { qDebug() << "error getting display data"; return; } qDebug() << img->width; /*glClear(GL_COLOR_BUFFER_BIT); glColor3f(1,0,0); glBegin(GL_POLYGON); glVertex2f(0,0); glVertex2f(100,500); glVertex2f(500,100); glEnd(); */ //see http://www.opengl.org/wiki/Programming_OpenGL_in_Linux:_Creating_a_texture_from_a_Pixmap //generate a texture from the Ximage glBindTexture(GL_TEXTURE_2D, texture); /*GL_EXT extension test glXBindTexImageEXT (display, glxpixmap, GLX_FRONT_LEFT_EXT, NULL); */ /*working code */ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, xDisplayWidth,xDisplayHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, (void*)(&(img->data[0]))); glEnable(GL_TEXTURE_2D); //glEnable(GL_MULTISAMPLE); //glEnable(GL_CULL_FACE); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex3f(0.f, 0.f, 0.f); glTexCoord2f(1.0f, 0.0f); glVertex3f(width(), 0.f, 0.f); glTexCoord2f(1.0f, 1.0f); glVertex3f(width(), height()-2, 0); glTexCoord2f(0.0f, 1.0f); glVertex3f(0.f, height(), 0.f); glEnd(); //render_fbo->toImage().save("test.png"); }
void FindPixel (char *windowName, int x, int y, Display *display, Window rootWindow) { Window parent; Window *children; Window *child; XImage *image; XWindowAttributes winAttr; XColor color; XTextProperty wmName; unsigned int noOfChildren; unsigned long pixel; int status; int i, red, green, blue; char **list; status = XGetWMName (display, rootWindow, &wmName); if ((status) && (wmName.value) && (wmName.nitems)) { if (strcmp(windowName, wmName.value) == 0) { XGetWindowAttributes(display, rootWindow, &winAttr); image = XGetImage(display, rootWindow, 0, 0, winAttr.width, winAttr.height, XAllPlanes(), ZPixmap); color.pixel = XGetPixel(image, x, y); XQueryColor(display, XDefaultColormap(display, XDefaultScreen(display)), &color); red = floor(color.red * 0.003891051); green = floor(color.green * 0.003891051); blue = floor(color.blue * 0.003891051); printf("%i %i %i\n", red, green, blue); } } status = XQueryTree (display, rootWindow, &rootWindow, &parent, &children, &noOfChildren); for (i=0; i < noOfChildren; i++) { FindPixel (windowName, x, y, display, children[i]); } XFree ((char*) children); }
void ga_xwin_capture(char *buf, int buflen, struct gaRect *rect) { if(XShmGetImage(display, rootWindow, image, 0, 0, XAllPlanes()) == 0) { ga_error("FATAL: XShmGetImage failed.\n"); exit(-1); } if(rect == NULL) { bcopy(image->data, buf, buflen); } else { int i; char *src, *dst; src = ((char *) image->data); src += image->bytes_per_line * rect->top; src += RGBA_SIZE * rect->left; dst = (char*) buf; // for(i = 0; i < rect->height; i++) { bcopy(src, dst, rect->linesize); src += image->bytes_per_line; dst += rect->linesize; } } return; }
int save_image (FILE *file) { int x_loc,y_loc; #ifdef X11WM Window canvas_root_win, child_win; XImage *ximage; #else void *ximage = NULL; #endif char r[MAX_COLORS],g[MAX_COLORS],b[MAX_COLORS]; unsigned int x_width,y_height,border_width,depth; int width, height; #ifdef X11WM int screen = DefaultScreen(connect_id.display); int scrn_width=DisplayWidth(connect_id.display,screen); int scrn_height=DisplayHeight(connect_id.display,screen); #else int screen; int scrn_width; int scrn_height; #endif int x1,y1; /* * Get allocated memory for the XImage structure and copy the * canvas window to it. */ /* Get the application window's position */ #ifdef X11WM XRaiseWindow(connect_id.display,connect_id.drawable); if ( XGetGeometry( connect_id.display,connect_id.drawable, &canvas_root_win, &x_loc, &y_loc, &x_width, &y_height, &border_width, &depth) == 0 || XTranslateCoordinates(connect_id.display,connect_id.drawable, canvas_root_win,0,0,&x1,&y1,&child_win) == False) { err_warn(1,fperr,"Error - getting raster image.\n"); return 0; } width = x_width; height = y_height; /* Find the new x location and the width, if necessary. */ if ((-x1 > width) || (x1 > scrn_width)) { err_warn(1,fperr,"Error - X for getting raster image.\n"); return 0; } if (x1 < 0) { width=width+x1; x1=0; } else if (x1+width > scrn_width) { width=scrn_width-x1; } if ((-y1 > height) || (y1 > scrn_height)) { err_warn(1,fperr,"Error - Y for getting raster image.\n"); return 0; } if (y1 < 0) { height=height+y1; y1=0; } else if (y1+height > scrn_height) { height=scrn_height-y1; } /* This way is good because the root window will create partially obscure windows. * But this method doesn't work for the Mac which has a rootless window. * ximage = XGetImage(cptr->connect_id.display, RootWindowOfScreen(DefaultScreenOfDisplay(cptr->connect_id.display)), x1, y1, width, height, XAllPlanes(), ZPixmap); */ ximage = XGetImage(connect_id.display, connect_id.drawable, 0, 0, width, height, XAllPlanes(), ZPixmap); #elif defined QTWM vcs_legacy_Qt_window_get_image_by_id(connect_id.wkst_id,&ximage); #else fprintf(stderr,"insert here your WM to get image\n"); #endif if (ximage == NULL) { err_warn(1,fperr,"Error - getting raster image.\n"); return 0; } /* If display has 8 bit color */ #ifdef X11WM if (ximage->depth == 8) { /* Convert X colors to u_char arrays */ convert_gks_color(r, g, b); /* Save the image and its colormap in a Sun Raster file */ ras_write_ximage(file, ximage, r, g, b, MAX_COLORS); } else { /* Save the image with no colormap in a Sun Raster file */ ras_write_ximage(file, ximage, NULL, NULL, NULL, 0); } #elif defined QTWM ras_write_ximage(file, ximage, NULL, NULL, NULL, 0); #else fprintf(stderr,"insert here your write to ras func\n"); #endif /* Print out image information print_image_info(x_loc, y_loc, ximage, MAX_COLORS); */ /* Remove the image from memory */ #ifdef X11WM XDestroyImage(ximage); #elif defined QTWM free(ximage); #else fprintf(stderr,"insert here your destroy ximage func\n"); #endif return 1; }
int main(int argc, char *argv[]) { Display *disp; int scr, prepare, tmp; Window selector, rootwin; XEvent event; cairo_surface_t *canvas; Atom setfull[2]; XWindowAttributes scrattr; XSetWindowAttributes winattr; XVisualInfo vis; ScreenshotLoc initloc, endloc; pngstream pngstr; XImage *ximg; // Get the user's display if (!(disp = XOpenDisplay(NULL))) { printf("Could not get display!\n"); } // Get screen, root scr = DefaultScreen(disp); rootwin = RootWindow(disp, scr); XMatchVisualInfo(disp, scr, 32, TrueColor, &vis); // Get screen stats for width/height XGetWindowAttributes(disp, rootwin, &scrattr); // Set window attributes winattr.colormap = XCreateColormap(disp, rootwin, vis.visual, AllocNone); winattr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | Button1MotionMask; winattr.background_pixmap = None; winattr.border_pixel = 0; // Make the selector window selector = XCreateWindow(disp, rootwin, 0, 0, scrattr.width, scrattr.height, 0, vis.depth, InputOutput, vis.visual, CWColormap | CWEventMask | CWBackPixmap | CWBorderPixel, &winattr); XStoreName(disp, selector, "cloudselect"); // We need key release (any key == cancel), and button for hold/release //XSelectInput(disp, selector, ExposureMask|ButtonPressMask|ButtonReleaseMask|KeyReleaseMask); XMapWindow(disp, selector); // set our window to fullscreen setfull[0] = XInternAtom(disp, "_NET_WM_STATE_FULLSCREEN", False); setfull[1] = None; XChangeProperty(disp, selector, XInternAtom(disp, "_NET_WM_STATE", False), XA_ATOM, 32, PropModeReplace, (unsigned char *)setfull, 1); RemoveDecorations(disp, selector); // make a cairo surface to paint on canvas = cairo_xlib_surface_create(disp, selector, vis.visual, scrattr.width, scrattr.height); initloc.x = initloc.y = -1; prepare = 0; while (get_xevents(disp, &event)) { if (event.type == Expose) { paint(canvas, scrattr.width, scrattr.height); } else if (event.type == ButtonPress) { if (event.xbutton.button == Button1) { initloc.x = event.xbutton.x; initloc.y = event.xbutton.y; } else { printf("[INFO] Operation cancelled.\n"); break; } } else if (event.type == ButtonRelease) { // We have completed selecting! if (event.xbutton.button == Button1) { endloc.x = event.xbutton.x; endloc.y = event.xbutton.y; // Negative resolutions are bad and make no sense anyway if (endloc.x < initloc.x) { tmp = endloc.x; endloc.x = initloc.x; initloc.x = tmp; } if (endloc.y < initloc.y) { tmp = endloc.y; endloc.y = initloc.y; initloc.y = tmp; } // Debug printf()s printf("Initial co-ordinates: (%d, %d)\n", initloc.x, initloc.y); printf("Final co-ordinates: (%d, %d)\n", endloc.x, endloc.y); printf("Dimensions: %dx%d\n", endloc.y-initloc.y, endloc.x-initloc.x); // Get selection as XImage ximg = XGetImage(disp, rootwin, initloc.x, initloc.y, (endloc.x-initloc.x), (endloc.y-initloc.y), XAllPlanes(), ZPixmap); // Pass XImage to mkpngstream pngstr = mkpngstream(disp, DefaultScreen(disp), vis.visual, ximg, initloc, endloc); // Make PNG stream to send to CloudApp if (!pngstr.data) { printf("Making PNG stream failed...\n"); if (ximg) { XFree(ximg); // XFree doesn't like NULL pointers } } else { test_write_file(pngstr, "test.png"); } break; } else { // ... Wrong button! printf("[INFO Operation cancelled.\n"); break; } } else if (event.type == MotionNotify) { // We only track Button1Motion, so... endloc.x = event.xmotion.x; endloc.y = event.xmotion.y; printf("[INFO] endloc.x: %d\nendloc.y: %d\n", endloc.x, endloc.y); printf("[INFO] initloc.x: %d\ninitloc.y: %d\n", initloc.x, initloc.y); paint(canvas, scrattr.width, scrattr.height); setrect(canvas, initloc, endloc); } else if (event.type == KeyRelease) { if (prepare == 1) break; } else if (event.type == KeyPress) { prepare = 1; } } cairo_surface_destroy(canvas); XCloseDisplay(disp); return 0; }