/* erealloc: realloc and report if error */ void * _gib_erealloc(void *ptr, size_t n) { void *p; p = realloc(ptr, n); if (p == NULL) gib_eprintf("realloc of %p by %u bytes failed:", ptr, n); return p; }
/* emalloc: malloc and report if error */ void * _gib_emalloc(size_t n) { void *p; p = malloc(n); if (p == NULL) gib_eprintf("malloc of %u bytes failed:", n); return p; }
/* estrdup: duplicate a string, report if error */ char * _gib_estrdup(char *s) { char *t; if(!s) return NULL; t = (char *) malloc(strlen(s) + 1); if (t == NULL) gib_eprintf("estrdup(\"%.20s\") failed:", s); strcpy(t, s); return t; }
int main(int argc, char **argv) { Imlib_Image image; Imlib_Image thumbnail; Imlib_Load_Error err; char *filename_im = NULL, *filename_thumb = NULL; time_t t; struct tm *tm; init_parse_options(argc, argv); init_x_and_imlib(NULL, 0); if (!opt.output_file) { opt.output_file = gib_estrdup("%Y-%m-%d-%H%M%S_$wx$h_scrot.png"); opt.thumb_file = gib_estrdup("%Y-%m-%d-%H%M%S_$wx$h_scrot-thumb.png"); } if (opt.focused) image = scrot_grab_focused(); else if (opt.window) image = scrot_grab_window(); else if (opt.select) image = scrot_sel_and_grab_image(); else { scrot_do_delay(); if (opt.multidisp) { image = scrot_grab_shot_multi(); } else { image = scrot_grab_shot(); } } if (!image) gib_eprintf("no image grabbed"); time(&t); /* Get the time directly after the screenshot */ tm = localtime(&t); imlib_context_set_image(image); imlib_image_attach_data_value("quality", NULL, opt.quality, NULL); filename_im = im_printf(opt.output_file, tm, NULL, NULL, image); gib_imlib_save_image_with_error_return(image, filename_im, &err); if (err) gib_eprintf("Saving to file %s failed\n", filename_im); if (opt.thumb) { int cwidth, cheight; int twidth, theight; cwidth = gib_imlib_image_get_width(image); cheight = gib_imlib_image_get_height(image); /* Geometry based thumb size */ if (opt.thumb_width || opt.thumb_height) { if (!opt.thumb_width) { twidth = cwidth * opt.thumb_height / cheight; theight = opt.thumb_height; } else if (!opt.thumb_height) { twidth = opt.thumb_width; theight = cheight * opt.thumb_width / cwidth; } else { twidth = opt.thumb_width; theight = opt.thumb_height; } } else { twidth = cwidth * opt.thumb / 100; theight = cheight * opt.thumb / 100; } thumbnail = gib_imlib_create_cropped_scaled_image(image, 0, 0, cwidth, cheight, twidth, theight, 1); if (thumbnail == NULL) gib_eprintf("Unable to create scaled Image\n"); else { filename_thumb = im_printf(opt.thumb_file, tm, NULL, NULL, thumbnail); gib_imlib_save_image_with_error_return(thumbnail, filename_thumb, &err); if (err) gib_eprintf("Saving thumbnail %s failed\n", filename_thumb); } } if (opt.exec) scrot_exec_app(image, tm, filename_im, filename_thumb); gib_imlib_free_image_and_decache(image); return 0; }
Imlib_Image scrot_sel_and_grab_image(void) { Imlib_Image im = NULL; static int xfd = 0; static int fdsize = 0; XEvent ev; fd_set fdset; int count = 0, done = 0; int rx = 0, ry = 0, rw = 0, rh = 0, btn_pressed = 0; int rect_x = 0, rect_y = 0, rect_w = 0, rect_h = 0; Cursor cursor, cursor_nw, cursor_ne, cursor_se, cursor_sw; Window target = None; GC gc; XGCValues gcval; xfd = ConnectionNumber(disp); fdsize = xfd + 1; cursor = XCreateFontCursor(disp, XC_crosshair); cursor_nw = XCreateFontCursor(disp, XC_ul_angle); cursor_ne = XCreateFontCursor(disp, XC_ur_angle); cursor_se = XCreateFontCursor(disp, XC_lr_angle); cursor_sw = XCreateFontCursor(disp, XC_ll_angle); gcval.foreground = XWhitePixel(disp, 0); gcval.function = GXxor; gcval.background = XBlackPixel(disp, 0); gcval.plane_mask = gcval.background ^ gcval.foreground; gcval.subwindow_mode = IncludeInferiors; gc = XCreateGC(disp, root, GCFunction | GCForeground | GCBackground | GCSubwindowMode, &gcval); if ((XGrabPointer (disp, root, False, ButtonMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, root, cursor, CurrentTime) != GrabSuccess)) gib_eprintf("couldn't grab pointer:"); if ((XGrabKeyboard (disp, root, False, GrabModeAsync, GrabModeAsync, CurrentTime) != GrabSuccess)) gib_eprintf("couldn't grab keyboard:"); while (1) { /* handle events here */ while (!done && XPending(disp)) { XNextEvent(disp, &ev); switch (ev.type) { case MotionNotify: if (btn_pressed) { if (rect_w) { /* re-draw the last rect to clear it */ XDrawRectangle(disp, root, gc, rect_x, rect_y, rect_w, rect_h); } rect_x = rx; rect_y = ry; rect_w = ev.xmotion.x - rect_x; rect_h = ev.xmotion.y - rect_y; /* Change the cursor to show we're selecting a region */ if (rect_w < 0 && rect_h < 0) XChangeActivePointerGrab(disp, ButtonMotionMask | ButtonReleaseMask, cursor_nw, CurrentTime); else if (rect_w < 0 && rect_h > 0) XChangeActivePointerGrab(disp, ButtonMotionMask | ButtonReleaseMask, cursor_sw, CurrentTime); else if (rect_w > 0 && rect_h < 0) XChangeActivePointerGrab(disp, ButtonMotionMask | ButtonReleaseMask, cursor_ne, CurrentTime); else if (rect_w > 0 && rect_h > 0) XChangeActivePointerGrab(disp, ButtonMotionMask | ButtonReleaseMask, cursor_se, CurrentTime); if (rect_w < 0) { rect_x += rect_w; rect_w = 0 - rect_w; } if (rect_h < 0) { rect_y += rect_h; rect_h = 0 - rect_h; } /* draw rectangle */ XDrawRectangle(disp, root, gc, rect_x, rect_y, rect_w, rect_h); XFlush(disp); } break; case ButtonPress: btn_pressed = 1; rx = ev.xbutton.x; ry = ev.xbutton.y; target = scrot_get_window(disp, ev.xbutton.subwindow, ev.xbutton.x, ev.xbutton.y); if (target == None) target = root; break; case ButtonRelease: done = 1; break; case KeyPress: fprintf(stderr, "Key was pressed, aborting shot\n"); done = 2; break; case KeyRelease: /* ignore */ break; default: break; } } if (done) break; /* now block some */ FD_ZERO(&fdset); FD_SET(xfd, &fdset); errno = 0; count = select(fdsize, &fdset, NULL, NULL, NULL); if ((count < 0) && ((errno == ENOMEM) || (errno == EINVAL) || (errno == EBADF))) gib_eprintf("Connection to X display lost"); } if (rect_w) { XDrawRectangle(disp, root, gc, rect_x, rect_y, rect_w, rect_h); XFlush(disp); } XUngrabPointer(disp, CurrentTime); XUngrabKeyboard(disp, CurrentTime); XFreeCursor(disp, cursor); XFreeGC(disp, gc); XSync(disp, True); if (done < 2) { scrot_do_delay(); Window client_window = None; if (rect_w > 5) { /* if a rect has been drawn, it's an area selection */ rw = ev.xbutton.x - rx; rh = ev.xbutton.y - ry; if (rw < 0) { rx += rw; rw = 0 - rw; } if (rh < 0) { ry += rh; rh = 0 - rh; } } else { /* else it's a window click */ if (!scrot_get_geometry(target, &client_window, &rx, &ry, &rw, &rh)) return NULL; } scrot_nice_clip(&rx, &ry, &rw, &rh); XBell(disp, 0); if(opt.alpha) im = scrot_grab_transparent_shot(disp, client_window, rx, ry, rw, rh); else im = gib_imlib_create_image_from_drawable(root, 0, rx, ry, rw, rh, 1); } return im; }
int gib_imlib_load_image(Imlib_Image * im, char *filename) { Imlib_Load_Error err; imlib_context_set_progress_function(NULL); if (!filename) return (0); *im = imlib_load_image_with_error_return(filename, &err); if ((err) || (!im)) { /* Check error code */ switch (err) { case IMLIB_LOAD_ERROR_FILE_DOES_NOT_EXIST: gib_weprintf("%s - File does not exist", filename); break; case IMLIB_LOAD_ERROR_FILE_IS_DIRECTORY: gib_weprintf("%s - Directory specified for image filename", filename); break; case IMLIB_LOAD_ERROR_PERMISSION_DENIED_TO_READ: gib_weprintf("%s - No read access to directory", filename); break; case IMLIB_LOAD_ERROR_NO_LOADER_FOR_FILE_FORMAT: gib_weprintf("%s - No Imlib2 loader for that file format", filename); break; case IMLIB_LOAD_ERROR_PATH_TOO_LONG: gib_weprintf("%s - Path specified is too long", filename); break; case IMLIB_LOAD_ERROR_PATH_COMPONENT_NON_EXISTANT: gib_weprintf("%s - Path component does not exist", filename); break; case IMLIB_LOAD_ERROR_PATH_COMPONENT_NOT_DIRECTORY: gib_weprintf("%s - Path component is not a directory", filename); break; case IMLIB_LOAD_ERROR_PATH_POINTS_OUTSIDE_ADDRESS_SPACE: gib_weprintf("%s - Path points outside address space", filename); break; case IMLIB_LOAD_ERROR_TOO_MANY_SYMBOLIC_LINKS: gib_weprintf("%s - Too many levels of symbolic links", filename); break; case IMLIB_LOAD_ERROR_OUT_OF_MEMORY: gib_eprintf("While loading %s - Out of memory", filename); break; case IMLIB_LOAD_ERROR_OUT_OF_FILE_DESCRIPTORS: gib_eprintf("While loading %s - Out of file descriptors", filename); break; case IMLIB_LOAD_ERROR_PERMISSION_DENIED_TO_WRITE: gib_weprintf("%s - Cannot write to directory", filename); break; case IMLIB_LOAD_ERROR_OUT_OF_DISK_SPACE: gib_weprintf("%s - Cannot write - out of disk space", filename); break; case IMLIB_LOAD_ERROR_UNKNOWN: default: gib_weprintf ("While loading %s - Unknown error. Attempting to continue", filename); break; } return (0); } return (1); }