diff options
| author | Mattias Andrée <maandree@operamail.com> | 2014-10-20 05:08:07 +0200 | 
|---|---|---|
| committer | Mattias Andrée <maandree@operamail.com> | 2014-10-20 05:08:07 +0200 | 
| commit | dba7dfb765a4cfd9834c2e852c5ca235ee06f9be (patch) | |
| tree | 906d5710085ed5020bd61e8bbd00f0c5edca1e2d /src | |
| parent | python version, still too slow (diff) | |
| download | scrotty-dba7dfb765a4cfd9834c2e852c5ca235ee06f9be.tar.gz scrotty-dba7dfb765a4cfd9834c2e852c5ca235ee06f9be.tar.bz2 scrotty-dba7dfb765a4cfd9834c2e852c5ca235ee06f9be.tar.xz | |
c version, fast enought
Signed-off-by: Mattias Andrée <maandree@operamail.com>
Diffstat (limited to '')
| -rwxr-xr-x | src/scrotty | 78 | ||||
| -rw-r--r-- | src/scrotty.c | 187 | 
2 files changed, 187 insertions, 78 deletions
| diff --git a/src/scrotty b/src/scrotty deleted file mode 100755 index b334042..0000000 --- a/src/scrotty +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env python3 -# -*- python -*- -''' -scrotty — Screenshot program for Linux's TTY -Copyright © 2014  Mattias Andrée (maandree@member.fsf.org) - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program.  If not, see <http://www.gnu.org/licenses/>. -''' - -import os, sys - -fbno = 0 - -def write(string): -    os.write(pipe_write, string.encode('utf-8')) - -while os.path.exists('/dev/fb%i' % fbno): -    with open('/dev/fb%i' % fbno, 'rb') as file: -        data = file.read() -     -    pathname = 'fb%i.png' % fbno -    if os.path.exists(pathname): -        i = 2 -        while os.path.exists('%s.%i' % (pathname, i)): -            i += 1 -        pathname = '%s.%i' % (pathname, i) -     -    (pipe_read, pipe_write) = os.pipe() -    pid = os.fork() -     -    if pid == 0: -        os.close(pipe_write) -        if pipe_read != 0: -            os.close(0) -            os.dup2(pipe_read, 0) -            os.close(pipe_read) -        os.execlp('convert', 'convert', '/dev/stdin', pathname) -     -    os.close(pipe_read) -     -    write('P3\n') -    with open('/sys/class/graphics/fb%i/virtual_size' % fbno, 'rb') as file: -        write(file.read().decode('utf-8', 'strict').replace(',', ' ')) -    write('255\n') -     -    j = 0 -    data_length = len(data) -    for i in range(0, data_length, 4): -        r, g, b = data[i + 2], data[i + 1], data[i + 0] -        j += 1 -        if (j == 5) or (i + 4 == data_length): -            j = 0 -            write('%i %i %i\n' % (r, g, b)) -        else: -            write('%i %i %i ' % (r, g, b)) -     -    os.close(pipe_write) -     -    reaped = 0 -    while reaped != pid: -        (reaped, status) = os.waitpid(pid, 0) -    if status == 0: -        print('Saved framebuffer %i to %s' % (fbno, pathname), file = sys.stderr) -    else: -        sys.exit(1) -    fbno += 1 - diff --git a/src/scrotty.c b/src/scrotty.c new file mode 100644 index 0000000..6552abf --- /dev/null +++ b/src/scrotty.c @@ -0,0 +1,187 @@ +/** + * scrotty — Screenshot program for Linux's TTY + * Copyright © 2014  Mattias Andrée (maandree@member.fsf.org) + *  + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *  + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + *  + * You should have received a copy of the GNU General Public License + * along with this program.  If not, see <http://www.gnu.org/licenses/>. + */ +#include <stdio.h> +#include <unistd.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> +#include <stdlib.h> + + +#ifndef PATH_MAX +# define PATH_MAX  4096 +#endif +#ifndef DEVDIR +# define DEVDIR  "/dev" +#endif +#ifndef SYSDIR +# define SYSDIR  "/sys" +#endif + + +#define LIST_0_9(P)  P"0\n", P"1\n", P"2\n", P"3\n", P"4\n", P"5\n", P"6\n", P"7\n", P"8\n", P"9\n" +static const char* inttable[] = +  { +    LIST_0_9(""),  LIST_0_9("1"), LIST_0_9("2"), LIST_0_9("3"), LIST_0_9("4"), +    LIST_0_9("5"), LIST_0_9("6"), LIST_0_9("7"), LIST_0_9("8"), LIST_0_9("9"), +     +    LIST_0_9("10"), LIST_0_9("11"), LIST_0_9("12"), LIST_0_9("13"), LIST_0_9("14"), +    LIST_0_9("15"), LIST_0_9("16"), LIST_0_9("17"), LIST_0_9("18"), LIST_0_9("19"), +     +    LIST_0_9("20"), LIST_0_9("21"), LIST_0_9("22"), LIST_0_9("23"), LIST_0_9("24"), +    "250\n", "251\n", "252\n", "253\n", "254\n", "255\n" +  }; + + +static int save_pnm(const char* fbpath, int fbno, int fd) +{ +  char buf[PATH_MAX]; +  FILE* file; +  int saved_errno, sizefd, fbfd, r, g, b; +  ssize_t got, off; +   +  sprintf(buf, SYSDIR "/class/graphics/fb%i/virtual_size", fbno); +  if (sizefd = open(buf, O_RDONLY), sizefd < 0) +    return -1; +   +  if (got = read(sizefd, buf, sizeof(buf) / sizeof(char) - 1), got < 0) +    return saved_errno = errno, close(sizefd), errno = saved_errno, -1; +  close(sizefd); +  buf[got] = '\0'; +  *strchr(buf, ',') = ' '; +   +  fbfd = open(fbpath, O_RDONLY); +  if (fbfd < 0) +    return -1; +   +  file = fdopen(fd, "w"); +  if (file == NULL) +    return saved_errno = errno, close(fbfd), errno = saved_errno, -1; +  fprintf(file, "P3\n%s255\n", buf); +   +  for (off = 0;;) +    { +      got = read(fbfd, buf + off, sizeof(buf) - off * sizeof(char)); +      if (got < 0) +	return saved_errno = errno, fclose(file), close(fbfd), errno = saved_errno, -1; +      if (got += off, got == 0) +	break; +       +      for (off = 0; off < got; off += 4) +	{ +	  r = buf[off + 2] & 255; +	  g = buf[off + 1] & 255; +	  b = buf[off + 0] & 255; +	  fprintf(file, "%s%s%s", inttable[r], inttable[g], inttable[b]); +	} +      if (off != got) +	{ +	  off -= 4; +	  memcpy(buf, buf + off, (got - off) * sizeof(char)); +	  off = got - off; +	} +      else +	off = 0; +    } +   +  fflush(file); +  fclose(file); +  close(fbfd); +  return 0; +} + + +static int save(const char* fbpath, const char* imgpath, int fbno, const char* execname) +{ +  int pipe_rw[2]; +  pid_t pid, reaped; +  int saved_errno, status; +   +  if (pipe(pipe_rw) < 0) +    return -1; +   +  if (pid = fork(), pid == -1) +    return saved_errno = errno, close(pipe_rw[0]), close(pipe_rw[1]), errno = saved_errno, -1; +   +  if (pid == 0) +    { +      close(pipe_rw[1]); +      if (pipe_rw[0] != STDIN_FILENO) +	{ +	  close(STDIN_FILENO); +	  dup2(pipe_rw[0], STDIN_FILENO); +	  close(pipe_rw[0]); +	} +      execlp("convert", "convert", DEVDIR "/stdin", imgpath, NULL); +      perror(execname); +      exit(1); +    } +   +  close(pipe_rw[0]); +   +  if (save_pnm(fbpath, fbno, pipe_rw[1]) < 0) +    return saved_errno = errno, close(pipe_rw[1]), errno = saved_errno, -1; +   +  close(pipe_rw[1]); +   +  reaped = 0; +  while (reaped != pid) +    { +      reaped = waitpid(pid, &status, 0); +      if (reaped < 0) +	return -1; +    } +   +  return status == 0 ? 0 : -1; +} + + +int main(int argc, char* argv[]) +{ +  char fbpath[PATH_MAX]; +  char imgpath[PATH_MAX]; +  int i, fbno; +   +  (void) argc; +   +  for (fbno = 0;; fbno++) +    { +      sprintf(fbpath, DEVDIR "/fb%i", fbno); +      if (access(fbpath, F_OK)) +	break; +       +      sprintf(imgpath, "fb%i.png", fbno); +      if (access(imgpath, F_OK) == 0) +	for (i = 2;; i++) +	  { +	    sprintf(imgpath, "fb%i.png.%i", fbno, i); +	    if (access(imgpath, F_OK)) +	      break; +	  } +       +      if (save(fbpath, imgpath, fbno, *argv) < 0) +	return perror(*argv), 1; +      fprintf(stderr, "Saved framebuffer %i to %s\n", fbno, imgpath); +    } +   +  return 0; +} + | 
