From 731200111990fa8270781ffad2f060f9c214a12a Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Sun, 13 Dec 2015 16:53:51 +0100 Subject: support margins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- DEPENDENCIES | 1 + TODO | 2 -- po/sv.po | 33 +++++++++++--------- src/kern-linux.c | 91 +++++++++++++++++++++++++++++++++----------------------- src/kern.h | 5 ++-- src/png.c | 1 + src/scrotty.c | 31 +++++++++---------- 7 files changed, 92 insertions(+), 72 deletions(-) diff --git a/DEPENDENCIES b/DEPENDENCIES index 491cdf4..99ee910 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -7,6 +7,7 @@ RUNTIME DEPENDENCIES: BUILD DEPENDENCIES: + linux-api-headers make coreutils glibc (any libc with getopt_long) diff --git a/TODO b/TODO index 42d3998..70fddbe 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,5 @@ Take the screenshot of the framebuffers more simultaneously. (async) -Support framebuffers with other depths. - Investigate Hurd support. Make a release-test script that validates that the diff --git a/po/sv.po b/po/sv.po index 7f1e7bb..92191be 100644 --- a/po/sv.po +++ b/po/sv.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: scrotty 1.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-12-12 09:08+0100\n" +"POT-Creation-Date: 2015-12-13 16:52+0100\n" "PO-Revision-Date: 2015-12-07 18:50+0100\n" "Last-Translator: Mattias Andrée \n" "Language-Team: none\n" @@ -17,61 +17,66 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: src/scrotty.c:224 +#: src/scrotty.c:223 #, c-format msgid "Saved framebuffer %i to %s.\n" msgstr "Bildrutebuffert %i sparad till %s.\n" -#: src/scrotty.c:358 src/scrotty.c:361 src/scrotty.c:367 src/scrotty.c:373 -#: src/scrotty.c:377 src/scrotty.c:383 src/scrotty.c:391 +#: src/scrotty.c:359 src/scrotty.c:362 src/scrotty.c:368 src/scrotty.c:374 +#: src/scrotty.c:378 src/scrotty.c:384 src/scrotty.c:392 #, c-format msgid "%s: %s. Type '%s --help' for help.\n" msgstr "%s: %s. Kör '%s --help' för hjälp.\n" -#: src/scrotty.c:358 +#: src/scrotty.c:359 msgid "--device is used twice" msgstr "--device förkommer mer än en gång" -#: src/scrotty.c:361 src/scrotty.c:367 +#: src/scrotty.c:362 src/scrotty.c:368 msgid "Invalid device number, not a non-negative integer" msgstr "Ogiltigt enhetsnummer, måste vara ett ickenegativt heltal" -#: src/scrotty.c:373 +#: src/scrotty.c:374 msgid "--exec is used twice" msgstr "--exec förkommer mer än en gång" -#: src/scrotty.c:377 +#: src/scrotty.c:378 msgid "Invalid input" msgstr "Ogiltig indata" -#: src/scrotty.c:383 +#: src/scrotty.c:384 msgid "FILENAME-PATTERN is used twice" msgstr "FILNAMNSMÖNSTER förekommer mer än en gång" -#: src/scrotty.c:391 +#: src/scrotty.c:392 msgid "--exec cannot be combined with piping" msgstr "--exec kan inte kombineras med rördragning" -#: src/scrotty.c:403 +#: src/scrotty.c:404 #, c-format msgid "%s: It looks like you are inside a display server. If this is correct, what you see is probably not what you get.\n" msgstr "%s: Det ser ut som att du är innan för en grafikserver. Om detta är korrect, vad de ser är troligtvis inte vad du får.\n" -#: src/scrotty.c:413 +#: src/scrotty.c:412 #, c-format msgid "%s: %s: %s\n" msgstr "%s: %s: %s\n" -#: src/scrotty.c:421 +#: src/scrotty.c:422 #, c-format msgid "%s: The selected device does not exist.\n" msgstr "%s: Vald enhet existerar inte.\n" -#: src/kern-linux.c:41 +#: src/kern-linux.c:52 #, c-format msgid "%s: Unable to find a framebuffer. If you have a file named %s/MAKEDEV, run it with '-d /dev/fb' as root, or try running '%s'.\n" msgstr "%s: Kunde inte hitta någon bildrutebuffert. Om filen %s/MAKEDEV finns ditt system, kör den med '-d /dev/fb' som root, eller testa att köra '%s'.\n" +#: src/kern-linux.c:106 +#, c-format +msgid "%s: Unsupported framebuffer configurations: pixels are not encoded in whole bytes.\n" +msgstr "%s: Ickestödd bildrutebuffertsinställningar: pixlar är inte kodade i hela byte:ar.\n" + #: src/info.c:32 #, fuzzy, c-format msgid "" diff --git a/src/kern-linux.c b/src/kern-linux.c index e6ca1a2..071d3fc 100644 --- a/src/kern-linux.c +++ b/src/kern-linux.c @@ -20,6 +20,9 @@ #include "kern.h" #include "png.h" +#include +#include + /** @@ -27,6 +30,14 @@ */ const int alt_fbpath_limit = 2; +struct data +{ + unsigned long start; + unsigned long end; + long hblank; + unsigned long position; +}; + /** @@ -67,53 +78,49 @@ get_fbpath (int altpath, int fbno) * Get the dimensions of a framebuffer. * * @param fbno The number of the framebuffer. - * @param fbpath The path to the framebuffer device.. + * @param fbfd File descriptor for framebuffer device. * @param width Output parameter for the width of the image. * @param height Output parameter for the height of the image. * @parma data Additional data to pass to `convert_fb_to_png`. * @return Zero on success, -1 on error. */ int -measure (int fbno, char *restrict fbpath, long *restrict width, - long *restrict height, void **restrict data) +measure (int fbno, int fbfd, long *restrict width, long *restrict height, void **restrict data) { - static char buf[sizeof (SYSDIR "/class/graphics/fb/virtual_size") + 3 * sizeof(int)]; - /* The string "/class/graphics/fb/virtual_size" is large enought for the call (*) "*/ - char *delim; - int sizefd = -1; - ssize_t got; - int saved_errno; + static struct data d; + struct fb_fix_screeninfo fixinfo; + struct fb_var_screeninfo varinfo; + unsigned long int linelength; - /* Open the file with the framebuffer's dimensions. */ - sprintf (buf, "%s/class/graphics/fb%i/virtual_size", SYSDIR, fbno); - sizefd = open (buf, O_RDONLY); - if (sizefd == -1) - FILE_FAILURE (buf); + if (ioctl (fbfd, FBIOGET_FSCREENINFO, &fixinfo)) + goto fail; - /* Get the dimensions of the framebuffer. */ - got = read (sizefd, buf, sizeof (buf) / sizeof (char) - 1); /* (*) */ - if (got < 0) + if (ioctl (fbfd, FBIOGET_VSCREENINFO, &varinfo)) goto fail; - close (sizefd); - /* The read content is formated as `%{width},%{height}\n`, - convert it to `%{width}\0%{height}\0` and parse it. */ - buf[got] = '\0'; - delim = strchr (buf, ','); - *delim++ = '\0'; - *width = atol (buf); - *height = atol (delim); + *width = varinfo.xres; + *height = varinfo.yres; - return 0; + if (varinfo.bits_per_pixel & 7) + { + fprintf(stderr, _("%s: Unsupported framebuffer configurations: " + "pixels are not encoded in whole bytes.\n"), execname); + exit(1); + } + linelength = fixinfo.line_length / (varinfo.bits_per_pixel / 8); + d.start = varinfo.yoffset * linelength; + d.start += varinfo.xoffset; + d.end = d.start + linelength * varinfo.yres; + d.hblank = linelength - *width; + d.position = 0; + + /* TODO depth support */ + + *data = &d; + return 0; fail: - saved_errno = errno; - if (sizefd >= 0) - close (sizefd); - errno = saved_errno; return -1; - - (void) fbpath; } @@ -133,16 +140,19 @@ measure (int fbno, char *restrict fbpath, long *restrict width, * @param data Data from `measure`. * @return Zero on success, -1 on error. */ -int convert_fb_to_png (png_struct *pngbuf, png_byte *restrict pixbuf, const char *restrict buf, - size_t n, long width3, size_t *restrict adjustment, long *restrict state, - void *restrict data) +int +convert_fb_to_png (png_struct *pngbuf, png_byte *restrict pixbuf, const char *restrict buf, size_t n, + long width3, size_t *restrict adjustment, long *restrict state, void *restrict data) { const uint32_t *restrict pixel; int r, g, b; size_t off; long x3 = *state; + struct data d = *(struct data *)data; + unsigned long pos = d.position; + long lineend = width3 + d.hblank * 3; - for (off = 0; off < n; off += 4) + for (off = 0; off < n; off += 4, pos++) { /* A pixel in the framebuffer is formatted as `%{blue}%{green}%{red}%{x}` in big-endian binary, or `%{x}%{red}%{green}%{blue}` in little-endian binary. */ @@ -151,9 +161,13 @@ int convert_fb_to_png (png_struct *pngbuf, png_byte *restrict pixbuf, const char g = (*pixel >> 8) & 255; b = (*pixel >> 0) & 255; - SAVE_PNG_PIXEL (pixbuf, x3, r, g, b); + if ((pos < d.start) || (pos >= d.end)) + continue; + + if (x3 < width3) + SAVE_PNG_PIXEL (pixbuf, x3, r, g, b); x3 += 3; - if (x3 == width3) + if (x3 == lineend) { SAVE_PNG_ROW (pngbuf, pixbuf); x3 = 0; @@ -162,6 +176,7 @@ int convert_fb_to_png (png_struct *pngbuf, png_byte *restrict pixbuf, const char *adjustment = (off != n ? 4 : 0); *state = x3; + ((struct data *)data)->position = pos; return 0; } diff --git a/src/kern.h b/src/kern.h index 5bd191c..3810c5f 100644 --- a/src/kern.h +++ b/src/kern.h @@ -55,14 +55,13 @@ char *get_fbpath (int altpath, int fbno); * Get the dimensions of a framebuffer. * * @param fbno The number of the framebuffer. - * @param fbpath The path to the framebuffer device.. + * @param fbfd File descriptor for framebuffer device. * @param width Output parameter for the width of the image. * @param height Output parameter for the height of the image. * @parma data Additional data to pass to `convert_fb_to_png`. * @return Zero on success, -1 on error. */ -int measure (int fbno, char *restrict fbpath, long *restrict width, - long *restrict height, void **restrict data); +int measure (int fbno, int fbfd, long *restrict width, long *restrict height, void **restrict data); /** * Convert read data from a framebuffer to PNG pixel data. diff --git a/src/png.c b/src/png.c index ad889e1..504cdf0 100644 --- a/src/png.c +++ b/src/png.c @@ -71,6 +71,7 @@ save_png (int fbfd, long width, long height, int imgfd, void *restrict data) goto fail; /* Initialise PNG write, and write head. */ + errno = 0; if (setjmp (png_jmpbuf(pngbuf))) /* Failing libpng calls jump here. */ goto fail; png_init_io (pngbuf, file); diff --git a/src/scrotty.c b/src/scrotty.c index bce7036..5ab39fe 100644 --- a/src/scrotty.c +++ b/src/scrotty.c @@ -66,7 +66,7 @@ static int try_alt_fbpath = 0; /** * Create an image of a framebuffer. * - * @param fbname The framebuffer device. + * @param fbfd File descriptor for framebuffer device. * @param imgname The pathname of the output image, `NULL` for piping. * @param width The width of the image. * @param height The height of the image. @@ -74,10 +74,10 @@ static int try_alt_fbpath = 0; * @return Zero on success, -1 on error. */ static int -save (const char *fbpath, const char *imgpath, long width, +save (int fbfd, const char *imgpath, long width, long height, void *restrict data) { - int imgfd = STDOUT_FILENO, fbfd = -1, piping = (imgpath == NULL); + int imgfd = STDOUT_FILENO, piping = (imgpath == NULL); int saved_errno; /* Open output file. */ @@ -89,11 +89,6 @@ save (const char *fbpath, const char *imgpath, long width, FILE_FAILURE (imgpath); } - /* Open the framebuffer device for reading. */ - fbfd = open (fbpath, O_RDONLY); - if (fbfd == -1) - FILE_FAILURE (fbpath); - /* Save image. */ if (save_png (fbfd, width, height, imgfd, data) < 0) goto fail; @@ -105,8 +100,6 @@ save (const char *fbpath, const char *imgpath, long width, fail: saved_errno = errno; - if (fbfd >= 0) - close (fbfd); if ((imgfd >= 0) && !piping) close (imgfd); errno = saved_errno; @@ -198,6 +191,7 @@ save_fb (int fbno, const char *filepattern, const char *execpattern) char *execargs = NULL; long width, height; void *data = NULL; + int fbfd = -1; int rc = 0, saved_errno = 0; /* Get pathname for framebuffer, and stop if we have read all existing ones. */ @@ -205,8 +199,13 @@ save_fb (int fbno, const char *filepattern, const char *execpattern) if (access (fbpath, F_OK)) return 1; + /* Open the framebuffer device for reading. */ + fbfd = open (fbpath, O_RDONLY); + if (fbfd == -1) + FILE_FAILURE (fbpath); + /* Get the size of the framebuffer. */ - if (measure (fbno, fbpath, &width, &height, &data) < 0) + if (measure (fbno, fbfd, &width, &height, &data) < 0) goto fail; /* Get output pathname. */ @@ -218,7 +217,7 @@ save_fb (int fbno, const char *filepattern, const char *execpattern) } /* Take a screenshot of the current framebuffer. */ - if (save (fbpath, imgpath, width, height, data) < 0) + if (save (fbfd, imgpath, width, height, data) < 0) goto fail; if (imgpath) fprintf (stderr, _("Saved framebuffer %i to %s.\n"), fbno, imgpath); @@ -242,6 +241,8 @@ save_fb (int fbno, const char *filepattern, const char *execpattern) saved_errno = errno; rc = -1; done: + if (fbfd >= 0) + close (fbfd); free (execargs); free (imgpath); return errno = saved_errno, rc; @@ -407,11 +408,11 @@ main (int argc, char *argv[]) return 0; fail: - if (failure_file == NULL) - perror (execname); - else + if (failure_file != NULL) fprintf (stderr, _("%s: %s: %s\n"), execname, strerror (errno), failure_file); + else if (errno) + perror (execname); return 1; no_fb: -- cgit v1.2.3-70-g09d2