Hello community, here is the log from the commit of package grim for openSUSE:Factory checked in at 2020-01-16 18:23:24 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/grim (Old) and /work/SRC/openSUSE:Factory/.grim.new.26092 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "grim" Thu Jan 16 18:23:24 2020 rev:3 rq:764984 version:1.3.0 Changes: -------- --- /work/SRC/openSUSE:Factory/grim/grim.changes 2019-06-04 12:14:34.175777970 +0200 +++ /work/SRC/openSUSE:Factory/.grim.new.26092/grim.changes 2020-01-16 18:23:38.153054811 +0100 @@ -1,0 +2,11 @@ +Thu Jan 16 13:39:24 UTC 2020 - Michael Vetter <mvet...@suse.com> + +- Update to 1.3.0: + * Allow to be invoked without a destination file argument. + In which case a timestamped file will be written in + $XDG_PICTURES_DIR. + * Allow user to set default output dir. + * Provide more helpful error message + * Fix maybe-uninitialized warning + +------------------------------------------------------------------- Old: ---- v1.2.0.tar.gz New: ---- v1.3.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ grim.spec ++++++ --- /var/tmp/diff_new_pack.4Vah3q/_old 2020-01-16 18:23:39.701055637 +0100 +++ /var/tmp/diff_new_pack.4Vah3q/_new 2020-01-16 18:23:39.701055637 +0100 @@ -1,7 +1,7 @@ # # spec file for package grim # -# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2020 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -12,12 +12,12 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org/ # Name: grim -Version: 1.2.0 +Version: 1.3.0 Release: 0 Summary: Wayland compositor image grabber License: MIT ++++++ v1.2.0.tar.gz -> v1.3.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/grim-1.2.0/README.md new/grim-1.3.0/README.md --- old/grim-1.2.0/README.md 2019-06-03 20:50:17.000000000 +0200 +++ new/grim-1.3.0/README.md 2020-01-16 12:33:31.000000000 +0100 @@ -1,37 +1,37 @@ # grim -Grab images from a Wayland compositor. Works great with [slurp] and with [sway] >= 1.0. +Grab images from a Wayland compositor. Works great with [slurp] and with [sway]. ## Example usage Screenshoot all outputs: ```sh -grim screenshot.png +grim ``` Screenshoot a specific output: ```sh -grim -o DP-1 screenshot.png +grim -o DP-1 ``` Screenshoot a region: ```sh -grim -g "10,20 300x400" screenshot.png +grim -g "10,20 300x400" ``` Select a region and screenshoot it: ```sh -grim -g "$(slurp)" screenshot.png +grim -g "$(slurp)" ``` -Use a timestamped filename: +Use a custom filename: ```sh -grim $(xdg-user-dir PICTURES)/$(date +'%Y-%m-%d-%H%M%S_grim.png') +grim $(xdg-user-dir PICTURES)/$(date +'%s_grim.png') ``` Screenshoot and copy to clipboard: @@ -40,15 +40,18 @@ grim - | wl-copy ``` -Grab a screenshot from the focused monitor under Sway, using `swaymsg` and `jq`: +Grab a screenshot from the focused monitor under Sway, using `swaymsg` and +`jq`: ```sh -grim -o $(swaymsg -t get_outputs | jq -r '.[] | select(.focused) | .name') screenshot.png +grim -o $(swaymsg -t get_outputs | jq -r '.[] | select(.focused) | .name') ``` -## Package manager installation +Pick a color, using ImageMagick: -* Arch Linux: `pacman -S grim` +```sh +grim -g "$(slurp -p)" -t ppm - | convert - -format '%[pixel:p{0,0}]' txt:- +``` ## Building from source @@ -66,11 +69,15 @@ ninja -C build ``` -To run directly, use `build/grim`, or if you would like to do a system installation (in `/usr/local` by default), run `ninja -C build install`. +To run directly, use `build/grim`, or if you would like to do a system +installation (in `/usr/local` by default), run `ninja -C build install`. ## Contributing -Either [send GitHub pull requests][github] or [send patches on the mailing list][ml]. +Either [send GitHub pull requests][github] or [send patches on the mailing +list][ml]. + +Join the IRC channel: ##emersion on Freenode. ## License diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/grim-1.2.0/cairo_jpg.c new/grim-1.3.0/cairo_jpg.c --- old/grim-1.2.0/cairo_jpg.c 2019-06-03 20:50:17.000000000 +0200 +++ new/grim-1.3.0/cairo_jpg.c 2020-01-16 12:33:31.000000000 +0100 @@ -82,7 +82,7 @@ static cairo_status_t cj_write(void *closure, const unsigned char *data, unsigned int length) { - if (write((long) closure, data, length) < length) { + if (write((long) closure, data, length) < (ssize_t) length) { return CAIRO_STATUS_WRITE_ERROR; } else { return CAIRO_STATUS_SUCCESS; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/grim-1.2.0/cairo_ppm.c new/grim-1.3.0/cairo_ppm.c --- old/grim-1.2.0/cairo_ppm.c 2019-06-03 20:50:17.000000000 +0200 +++ new/grim-1.3.0/cairo_ppm.c 2020-01-16 12:33:31.000000000 +0100 @@ -52,7 +52,7 @@ static cairo_status_t cj_write(void *closure, const unsigned char *data, unsigned int length) { - if (write((long) closure, data, length) < length) { + if (write((long) closure, data, length) < (ssize_t) length) { return CAIRO_STATUS_WRITE_ERROR; } else { return CAIRO_STATUS_SUCCESS; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/grim-1.2.0/grim.1.scd new/grim-1.3.0/grim.1.scd --- old/grim-1.2.0/grim.1.scd 2019-06-03 20:50:17.000000000 +0200 +++ new/grim-1.3.0/grim.1.scd 2020-01-16 12:33:31.000000000 +0100 @@ -6,7 +6,7 @@ # DESCRIPTION -*grim* [options...] <output-file> +*grim* [options...] [output-file] # SYNOPSIS @@ -14,8 +14,10 @@ it requires support for the screencopy protocol to work. Support for the xdg-output protocol is optional, but improves fractional scaling support. -grim will write a PNG file to _output-file_. If _output-file_ is *-*, it will -output the file to the standard output instead. +grim will write an image to _output-file_, or to a timestamped file name in +*$GRIM_DEFAULT_DIR* if not specified. If *$GRIM_DEFAULT_DIR* is not set, it +defaults to *$XDG_PICTURES_DIR*. If _output-file_ is *-*, grim will output the +image to the standard output instead. # OPTIONS @@ -33,7 +35,7 @@ *-t* <type> Set the output image's file format to _type_. By default, the filetype - is set to *png* filetype, valid values are *png* or *jpeg*. + is set to *png*, valid values are *png*, *jpeg* or *ppm*. *-q* <quality> Set the output jpeg's filetype compression rate to _quality_. By default, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/grim-1.2.0/main.c new/grim-1.3.0/main.c --- old/grim-1.2.0/main.c 2019-06-03 20:50:17.000000000 +0200 +++ new/grim-1.3.0/main.c 2020-01-16 12:33:31.000000000 +0100 @@ -2,10 +2,12 @@ #include <assert.h> #include <cairo.h> #include <errno.h> +#include <limits.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <time.h> #include <unistd.h> #include "buffer.h" @@ -192,8 +194,69 @@ return CAIRO_STATUS_SUCCESS; } +bool default_filename(char *filename, size_t n, int filetype) { + time_t time_epoch = time(NULL); + struct tm *time = localtime(&time_epoch); + if (time == NULL) { + perror("localtime"); + return false; + } + + char *format_str; + const char *ext = NULL; + switch (filetype) { + case GRIM_FILETYPE_PNG: + ext = "png"; + break; + case GRIM_FILETYPE_PPM: + ext = "ppm"; + break; + case GRIM_FILETYPE_JPEG: +#if HAVE_JPEG + ext = "jpeg"; + break; +#else + assert(false); +#endif + } + assert(ext != NULL); + char tmpstr[32]; + sprintf(tmpstr, "%%Y%%m%%d_%%Hh%%Mm%%Ss_grim.%s", ext); + format_str = tmpstr; + if (strftime(filename, n, format_str, time) == 0) { + fprintf(stderr, "failed to format datetime with strftime(3)\n"); + return false; + } + return true; +} + +static bool path_exists(const char *path) { + return path && access(path, R_OK) != -1; +} + +char *get_output_dir(void) { + static const char *output_dirs[] = { + "GRIM_DEFAULT_DIR", + "XDG_PICTURES_DIR", + }; + + for (size_t i = 0; i < sizeof(output_dirs) / sizeof(char *); ++i) { + char *path = getenv(output_dirs[i]); + if (path_exists(path)) { + return path; + } + } + + return "."; +} + +void filepath(char *output_path, const char *filename) { + char *output_dir = get_output_dir(); + sprintf(output_path, "%s/%s", output_dir, filename); +} + static const char usage[] = - "Usage: grim [options...] <output-file>\n" + "Usage: grim [options...] [output-file]\n" "\n" " -h Show help message and quit.\n" " -s <factor> Set the output image scale factor. Defaults to the\n" @@ -296,11 +359,20 @@ } } + char output_filepath[PATH_MAX]; + char *output_filename; + char tmp[64]; if (optind >= argc) { - fprintf(stderr, "%s", usage); - return EXIT_FAILURE; + if (default_filename(tmp, sizeof(tmp), output_filetype) != true) { + fprintf(stderr, "failed to generate default filename\n"); + return EXIT_FAILURE; + } + output_filename = tmp; + filepath(output_filepath, output_filename); + } else { + output_filename = argv[optind]; + strcpy(output_filepath, output_filename); } - char *output_filename = argv[optind]; struct grim_state state = {0}; wl_list_init(&state.outputs); @@ -432,15 +504,15 @@ } else { switch (output_filetype) { case GRIM_FILETYPE_PPM: - status = cairo_surface_write_to_ppm(surface, output_filename); + status = cairo_surface_write_to_ppm(surface, output_filepath); break; case GRIM_FILETYPE_PNG: - status = cairo_surface_write_to_png(surface, output_filename); + status = cairo_surface_write_to_png(surface, output_filepath); break; case GRIM_FILETYPE_JPEG: #if HAVE_JPEG status = cairo_surface_write_to_jpeg( - surface, output_filename, jpeg_quality); + surface, output_filepath, jpeg_quality); break; #else assert(false); @@ -448,7 +520,10 @@ } } if (status != CAIRO_STATUS_SUCCESS) { - fprintf(stderr, "failed to write output file\n"); + fprintf(stderr, "%s\n", cairo_status_to_string(status)); + if (status == CAIRO_STATUS_WRITE_ERROR && strlen(output_filepath) > NAME_MAX) { + fprintf(stderr, "Hint: Output filepath length may be too long for your filesystem."); + } return EXIT_FAILURE; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/grim-1.2.0/meson.build new/grim-1.3.0/meson.build --- old/grim-1.2.0/meson.build 2019-06-03 20:50:17.000000000 +0200 +++ new/grim-1.3.0/meson.build 2020-01-16 12:33:31.000000000 +0100 @@ -1,12 +1,12 @@ project( 'grim', 'c', - version: '1.2.0', + version: '1.3.0', license: 'MIT', meson_version: '>=0.48.0', default_options: [ 'c_std=c11', - 'warning_level=2', + 'warning_level=3', 'werror=true', ], )