initial import - xscreenshot - screen capture tool
 (HTM) git clone git://git.codemadness.org/xscreenshot
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 1cf03c53b280d3fe21dac843504dd54e9b64e4b6
 (HTM) Author: Hiltjo Posthuma <hiltjo@codemadness.org>
       Date:   Sun, 27 Jul 2014 21:22:39 +0000
       
       initial import
       
       Signed-off-by: Hiltjo Posthuma <hiltjo@codemadness.org>
       
       Diffstat:
         A .gitignore                          |       2 ++
         A LICENSE                             |      21 +++++++++++++++++++++
         A Makefile                            |       9 +++++++++
         A README                              |      31 +++++++++++++++++++++++++++++++
         A TODO                                |       5 +++++
         A xscreenshot.c                       |     133 +++++++++++++++++++++++++++++++
       
       6 files changed, 201 insertions(+), 0 deletions(-)
       ---
 (DIR) diff --git a/.gitignore b/.gitignore
       @@ -0,0 +1,2 @@
       +xscreenshot
       +*.o
 (DIR) diff --git a/LICENSE b/LICENSE
       @@ -0,0 +1,21 @@
       +MIT/X Consortium License
       +
       +(c) 2014 Hiltjo Posthuma <hiltjo@codemadness.org>
       +
       +Permission is hereby granted, free of charge, to any person obtaining a
       +copy of this software and associated documentation files (the "Software"),
       +to deal in the Software without restriction, including without limitation
       +the rights to use, copy, modify, merge, publish, distribute, sublicense,
       +and/or sell copies of the Software, and to permit persons to whom the
       +Software is furnished to do so, subject to the following conditions:
       +
       +The above copyright notice and this permission notice shall be included in
       +all copies or substantial portions of the Software.
       +
       +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
       +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
       +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
       +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
       +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
       +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
       +DEALINGS IN THE SOFTWARE.
 (DIR) diff --git a/Makefile b/Makefile
       @@ -0,0 +1,9 @@
       +build: clean
       +        cc xscreenshot.c -o xscreenshot -lX11 -lpng -Wall -Wextra -pedantic -std=c99
       +
       +test: build
       +        ./xscreenshot > screen.png
       +        meh screen.png
       +
       +clean:
       +        rm -f xscreenshot
 (DIR) diff --git a/README b/README
       @@ -0,0 +1,31 @@
       +xscreenshot - make screenshot
       +=============================
       +
       +xscreenshot is a simple screenshot utility. It writes image data to stdout.
       +
       +
       +Dependencies
       +------------
       +
       +- libpng
       +- libX11
       +
       +
       +Compile
       +-------
       +
       +run make or:
       +
       +cc xscreenshot.c -o xscreenshot -lX11 -lpng
       +
       +
       +Usage
       +-----
       +
       +xscreenshot [winid] > file.png
       +
       +
       +Known issues
       +------------
       +
       +A specified windowid has to be visible on the screen.
 (DIR) diff --git a/TODO b/TODO
       @@ -0,0 +1,5 @@
       +- I might have missed a few cases of color conversion (convertrow_*).
       +- write a man page.
       +- write a Makefile (suckless-style).
       +- better multi-monitor support.
       +- write a "if" output:  http://git.2f30.org/imagefile/.
 (DIR) diff --git a/xscreenshot.c b/xscreenshot.c
       @@ -0,0 +1,133 @@
       +/* see LICENSE / README for more info */
       +#include <stdio.h>
       +#include <stdint.h>
       +#include <string.h>
       +#include <stdlib.h>
       +#include <errno.h>
       +
       +/* X11 */
       +#include <X11/X.h>
       +#include <X11/Xlib.h>
       +#include <X11/Xutil.h>
       +
       +/* png */
       +#include <png.h>
       +
       +static void
       +die(const char *s) {
       +        fprintf(stderr, "xscreenshot: %s\n", s);
       +        exit(EXIT_FAILURE);
       +}
       +
       +/* LSBFirst: BGRA -> RGBA */
       +static void
       +convertrow_lsb(unsigned char *drow, unsigned char *srow, XImage *img) {
       +        int sx, dx;
       +
       +        for(sx = 0, dx = 0; dx < img->bytes_per_line - 4; sx += 4) {
       +                drow[dx++] = srow[sx + 2]; /* B -> R */
       +                drow[dx++] = srow[sx + 1]; /* G -> G */
       +                drow[dx++] = srow[sx];     /* R -> B */
       +                if(img->depth == 32)
       +                        drow[dx++] = srow[sx + 3]; /* A -> A */
       +                else
       +                        drow[dx++] = 255;
       +        }
       +}
       +
       +/* MSBFirst: ARGB -> RGBA */
       +static void
       +convertrow_msb(unsigned char *drow, unsigned char *srow, XImage *img) {
       +        int sx, dx;
       +
       +        for(sx = 0, dx = 0; dx < img->bytes_per_line - 4; sx += 4) {
       +                drow[dx++] = srow[sx + 1]; /* G -> R */
       +                drow[dx++] = srow[sx + 2]; /* B -> G */
       +                drow[dx++] = srow[sx + 3]; /* A -> B */
       +                if(img->depth == 32)
       +                        drow[dx++] = srow[sx]; /* R -> A */
       +                else
       +                        drow[dx++] = 255;
       +        }
       +}
       +
       +static void
       +pngstdout(XImage *img)
       +{
       +        png_structp png_struct_p;
       +        png_infop png_info_p;
       +        void (*convert)(unsigned char *, unsigned char *, XImage *);
       +        unsigned char *drow = NULL, *srow;
       +        int h;
       +
       +        png_struct_p = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL,
       +                                               NULL);
       +        png_info_p = png_create_info_struct(png_struct_p);
       +
       +        if(!png_struct_p || !png_info_p || setjmp(png_jmpbuf(png_struct_p)))
       +                die("failed to initialize libpng");
       +
       +        png_init_io(png_struct_p, stdout);
       +        png_set_IHDR(png_struct_p, png_info_p, img->width, img->height, 8,
       +                     PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
       +                     PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
       +        png_write_info(png_struct_p, png_info_p);
       +
       +        srow = (unsigned char *)img->data;
       +        drow = calloc(1, img->width * 4); /* output RGBA */
       +        if(!drow)
       +                die("Can't calloc");
       +
       +        if(img->byte_order == LSBFirst)
       +                convert = convertrow_lsb;
       +        else
       +                convert = convertrow_msb;
       +
       +        for(h = 0; h < img->height; h++) {
       +                convert(drow, srow, img);
       +                srow += img->bytes_per_line;
       +                png_write_row(png_struct_p, drow);
       +        }
       +        png_write_end(png_struct_p, NULL);
       +
       +        free(drow);
       +        png_free_data(png_struct_p, png_info_p, PNG_FREE_ALL, -1);
       +        png_destroy_write_struct(&png_struct_p, NULL);
       +}
       +
       +int
       +main(int argc, char *argv[])
       +{
       +        XImage *img;
       +        Display *dpy;
       +        Window win;
       +        XWindowAttributes attr;
       +
       +        dpy = XOpenDisplay(NULL);
       +        if(!dpy)
       +                die("Can't XOpenDisplay");
       +
       +        /* win */
       +        if(argc > 1) {
       +                errno = 0;
       +                win = (Window)strtol(argv[1], NULL, 0);
       +                if(errno != 0)
       +                        die("input not a number");
       +        } else {
       +                win = RootWindow(dpy, 0);
       +        }
       +
       +        XGrabServer(dpy);
       +        XGetWindowAttributes(dpy, win, &attr);
       +
       +        img = XGetImage(dpy, win, 0, 0, attr.width, attr.height, 0xffffffff,
       +                        ZPixmap);
       +        if(!img)
       +                die("Can't XGetImage");
       +        pngstdout(img);
       +        XDestroyImage(img);
       +        XUngrabServer(dpy);
       +        XCloseDisplay(dpy);
       +
       +        return EXIT_SUCCESS;
       +}