From a79f60c36d38df67431a51a0274df5ea01f5172e Mon Sep 17 00:00:00 2001 From: NRK Date: Thu, 23 Jan 2025 17:57:32 +0000 Subject: [PATCH 01/11] remove --note has been deprecated for a while now. Closes: https://github.com/resurrecting-open-source-projects/scrot/discussions/207 Closes: https://github.com/resurrecting-open-source-projects/scrot/issues/236 --- TODO.md | 2 +- src/Makefile.am | 1 - src/note.c | 281 ------------------------------------------------ src/note.h | 38 ------- src/options.c | 18 +--- src/options.h | 1 - src/scrot.c | 9 -- 7 files changed, 2 insertions(+), 348 deletions(-) delete mode 100644 src/note.c delete mode 100644 src/note.h diff --git a/TODO.md b/TODO.md index efff92a2..17b5492d 100644 --- a/TODO.md +++ b/TODO.md @@ -66,5 +66,5 @@ transition for users and avoid depending on bleeding edge library versions. - [ ] https://github.com/resurrecting-open-source-projects/scrot/issues/246 - [ ] https://github.com/resurrecting-open-source-projects/scrot/issues/226 - [ ] Remove deprecated features - - [ ] --note [#236](https://github.com/resurrecting-open-source-projects/scrot/issues/236) + - [x] --note [#236](https://github.com/resurrecting-open-source-projects/scrot/issues/236) - [ ] --script diff --git a/src/Makefile.am b/src/Makefile.am index a7573112..6cac52b4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -35,7 +35,6 @@ MAINTAINERCLEANFILES = Makefile.in bin_PROGRAMS = scrot scrot_SOURCES = scrot.c scrot.h \ -note.c note.h \ options.c options.h \ scrot_selection.c scrot_selection.h \ selection_classic.c selection_classic.h \ diff --git a/src/note.c b/src/note.c deleted file mode 100644 index e30aae03..00000000 --- a/src/note.c +++ /dev/null @@ -1,281 +0,0 @@ -/* note.c - -Copyright 2019-2022 Daniel T. Borelli -Copyright 2021-2023 Guilherme Janczak -Copyright 2021 IFo Hancroft -Copyright 2021 Peter Wu -Copyright 2023 NRK - -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 of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -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 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. - -*/ - -#include -#include -#include -#include -#include - -#include - -#include "note.h" -#include "options.h" -#include "util.h" - -enum { // default color - DEF_COLOR_RED = 0, - DEF_COLOR_GREEN = 0, - DEF_COLOR_BLUE = 0, - DEF_COLOR_ALPHA = 255 -}; - -/* - * Format: -f 'NAME/SIZE' -x NUM -y NUM -t 'TEXT' -c NUM,NUM,NUM,NUM - * - * -f fontname/size - absolute path - * -x screen position x - * -y screen position y - * -t text note - * -c color(red,green,blue,alpha) range 0..255 - * - * */ - -struct ScrotNote { - char *font; /* font name */ - char *text; /* text of the note */ - Imlib_Font imFont; /* private */ - int x; /* position screen (optional) */ - int y; /* position screen (optional) */ - double angle; /* angle text (optional) */ - struct Color { /* (optional) */ - int r, /* red */ - g, /* green */ - b, /* blue */ - a; /* alpha */ - } color; -}; - -static struct ScrotNote *note; -static void loadFont(void); -static char *parseText(char **, char const *const); - -static void pfree(char **ptr) -{ - free(*ptr); - *ptr = NULL; -} - -static void nextSpace(char **token) -{ - while (*++*token == ' ' && **token != '\0') { } -} - -static void nextNotSpace(char **token) -{ - while (*++*token != ' ' && **token != '\0') { } -} - -void scrotNoteNew(char const *const format) -{ - char const *const end = format + strlen(format); - - char *token = strpbrk(format, "-"); - - if (!token || (strlen(token) == 1)) - errx(EXIT_FAILURE, "Error --note option : Malformed syntax."); - - scrotNoteFree(); - - note = ecalloc(1, sizeof(*note)); - note->color.r = DEF_COLOR_RED; - note->color.g = DEF_COLOR_GREEN; - note->color.b = DEF_COLOR_BLUE; - note->color.a = DEF_COLOR_ALPHA; - - while (token) { - const char type = *++token; - char *savePtr = NULL; - char *c; - const char *errmsg; - - nextSpace(&token); - - switch (type) { - case 'f': - note->font = parseText(&token, end); - - if (!note->font) - errx(EXIT_FAILURE, "Error --note option : Malformed syntax for -f"); - - char *number = strrchr(note->font, '/'); - - if (!number) - errx(EXIT_FAILURE, "Error --note option : Malformed syntax for -f, required number."); - - const int fontSize = optionsParseNum(++number, 1, INT_MAX, &errmsg); - if (errmsg) { - errx(EXIT_FAILURE, "option --note: font size '%s' is %s", - number, errmsg); - } - - if (fontSize < 6) - warnx("Warning: --note option: font size < 6"); - break; - case 'x': - if ((1 != sscanf(token, "%d", ¬e->x) || (note->x < 0))) - errx(EXIT_FAILURE, "Error --note option : Malformed syntax for -x"); - nextNotSpace(&token); - break; - case 'y': - if ((1 != sscanf(token, "%d", ¬e->y)) || (note->y < 0)) - errx(EXIT_FAILURE, "Error --note option : Malformed syntax for -y"); - nextNotSpace(&token); - break; - case 'a': - if ((1 != sscanf(token, "%lf", ¬e->angle))) - errx(EXIT_FAILURE, "Error --note option : Malformed syntax for -a"); - nextNotSpace(&token); - break; - case 't': - note->text = parseText(&token, end); - if (!note->text) - errx(EXIT_FAILURE, "Error --note option : Malformed syntax for -t"); - break; - case 'c': - c = strtok_r(token, ",", &savePtr); - - int numberColors = 0; - - while (c) { - token = c; - char *const space = strchr(c, ' '); - - if (space) - *space = '\0'; - const int color = optionsParseNum(c, 0, 255, &errmsg); - if (errmsg) { - errx(EXIT_FAILURE, "option --note: color '%s' is %s", - c, errmsg); - } - if (space) - *space = ' '; - - switch (++numberColors) { - case 1: - note->color.r = color; - break; - case 2: - note->color.g = color; - break; - case 3: - note->color.b = color; - break; - case 4: - note->color.a = color; - break; - } - - c = strtok_r(NULL, ",", &savePtr); - } - - if (numberColors > 4) - warnx("Warning --note option : Malformed syntax for -c"); - break; - default: - errx(EXIT_FAILURE, "Error --note option : unknown option: '-%c'", type); - } - - token = strpbrk(token, "-"); - } - - if (!note->font || !note->text) - errx(EXIT_FAILURE, "Error --note option : Malformed syntax."); - - loadFont(); -} - -void scrotNoteFree(void) -{ - if (!note) - return; - - if (note->text) - pfree(¬e->text); - - if (note->font) - pfree(¬e->font); - - if (note->imFont) { - imlib_context_set_font(note->imFont); - imlib_free_font(); - } - - free(note); - note = NULL; -} - -void scrotNoteDraw(Imlib_Image im) -{ - if (!im) - return; - - scrotAssert(note->imFont); - - imlib_context_set_image(im); - imlib_context_set_font(note->imFont); - - imlib_context_set_direction(IMLIB_TEXT_TO_ANGLE); - imlib_context_set_angle(note->angle); - - imlib_context_set_color(note->color.r, - note->color.g, - note->color.b, - note->color.a); - - imlib_text_draw(note->x, note->y, note->text); -} - -static void loadFont(void) -{ - note->imFont = imlib_load_font(note->font); - - if (!note->imFont) - errx(EXIT_FAILURE, "Error --note option : Failed to load fontname: %s", note->font); -} - -static char *parseText(char **token, char const *const end) -{ - if (**token != '\'') - return NULL; - - (*token)++; - - char *begin = *token; - - while ((*token != end) && **token != '\'') - (*token)++; - - ptrdiff_t length = (*token - begin); - - if (length == 0) - return NULL; - - return strndup(begin, length); -} diff --git a/src/note.h b/src/note.h deleted file mode 100644 index 68c4d81d..00000000 --- a/src/note.h +++ /dev/null @@ -1,38 +0,0 @@ -/* note.h - -Copyright 2019-2022 Daniel T. Borelli -Copyright 2021 Christopher R. Nelson -Copyright 2021-2023 Guilherme Janczak -Copyright 2021 Peter Wu - -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 of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -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 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. - -*/ - -#ifndef H_NOTE -#define H_NOTE - -#include - -void scrotNoteNew(char const *const); -void scrotNoteFree(void); -void scrotNoteDraw(Imlib_Image); - -#endif /* !defined(H_NOTE) */ diff --git a/src/options.c b/src/options.c index 24ccf855..d5b5eee4 100644 --- a/src/options.c +++ b/src/options.c @@ -51,7 +51,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include -#include "note.h" #include "options.h" #include "scrot.h" #include "scrot_selection.h" @@ -81,7 +80,7 @@ enum { /* long opt only */ OPT_FORMAT = UCHAR_MAX + 1, OPT_LIST_OPTS, }; -static const char stropts[] = "a:bC:cD:d:e:F:fhik::l:M:mn:opq:S:s::t:uvw:Z:z"; +static const char stropts[] = "a:bC:cD:d:e:F:fhik::l:M:mopq:S:s::t:uvw:Z:z"; // NOTE: make sure lopts and opt_description indexes are kept in sync static const struct option lopts[] = { {"autoselect", required_argument, NULL, 'a'}, @@ -99,7 +98,6 @@ static const struct option lopts[] = { {"line", required_argument, NULL, 'l'}, {"monitor", required_argument, NULL, 'M'}, {"multidisp", no_argument, NULL, 'm'}, - {"note", required_argument, NULL, 'n'}, {"overwrite", no_argument, NULL, 'o'}, {"pointer", no_argument, NULL, 'p'}, {"quality", required_argument, NULL, 'q'}, @@ -136,7 +134,6 @@ static const struct option_desc { /* l */ { "specify the style of the selection line", "STYLE" }, /* M */ { "capture monitor", "NUM" }, /* m */ { "capture all monitors", "" }, - /* n */ { OPT_DEPRECATED, OPT_DEPRECATED }, /* o */ { "overwrite the output file if needed", "" }, /* p */ { "capture the mouse pointer as well", "" }, /* q */ { "image quality", "NUM" }, @@ -383,7 +380,6 @@ void optionsParse(int argc, char *argv[]) int optch; const char *errmsg; bool FFlagSet = false; - const char *note = NULL; /* Now to pass some optionarinos */ while ((optch = getopt_long(argc, argv, stropts, lopts, NULL)) != -1) { @@ -449,11 +445,6 @@ void optionsParse(int argc, char *argv[]) case 'm': opt.mode = MODE_MULTIDISP; break; - case 'n': - if (optarg[0] == '\0') - errx(EXIT_FAILURE, "Required arguments for --note."); - note = optarg; - break; case 'o': opt.overwrite = true; break; @@ -551,13 +542,6 @@ void optionsParse(int argc, char *argv[]) if (opt.thumb != THUMB_DISABLED) opt.thumbFile = optionsNameThumbnail(opt.outputFile); - - if (note) { - warnx("--note is deprecated. See: " - "https://github.com/resurrecting-open-source-projects/scrot/discussions/207"); - opt.note = estrdup(note); /* TODO: investigate if dup is needed */ - scrotNoteNew(opt.note); - } } static void showUsage(void) diff --git a/src/options.h b/src/options.h index e69673a1..9f292bbb 100644 --- a/src/options.h +++ b/src/options.h @@ -82,7 +82,6 @@ struct ScrotOptions { char *thumbFile; const char *exec; const char *display; - char *note; Window windowId; const char *windowClassName; const char *script; diff --git a/src/scrot.c b/src/scrot.c index c7d67890..2c0f10b2 100644 --- a/src/scrot.c +++ b/src/scrot.c @@ -62,7 +62,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include -#include "note.h" #include "options.h" #include "scrot.h" #include "util.h" @@ -151,9 +150,6 @@ int main(int argc, char *argv[]) } tm = localtime(&timeStamp.tv_sec); - if (opt.note) - scrotNoteDraw(image); - imlib_context_set_image(image); imlib_image_set_format(opt.format); imlib_image_attach_data_value("quality", NULL, opt.quality, NULL); @@ -255,11 +251,6 @@ static void initXAndImlib(const char *dispStr, int screenNumber) /* atexit register func. */ static void uninitXAndImlib(void) { - if (opt.note) { - scrotNoteFree(); - free(opt.note); - } - if (disp) { XCloseDisplay(disp); disp = NULL; From cac520a0df333a0cfc0f868fecfb1b26bab2cd62 Mon Sep 17 00:00:00 2001 From: NRK Date: Thu, 23 Jan 2025 18:02:27 +0000 Subject: [PATCH 02/11] remove --script been deprecated for a while now. Ref: https://github.com/resurrecting-open-source-projects/scrot/pull/231 --- TODO.md | 4 ++-- src/options.c | 7 +------ src/options.h | 1 - src/scrot.c | 13 ------------- 4 files changed, 3 insertions(+), 22 deletions(-) diff --git a/TODO.md b/TODO.md index 17b5492d..fd6fecd3 100644 --- a/TODO.md +++ b/TODO.md @@ -65,6 +65,6 @@ transition for users and avoid depending on bleeding edge library versions. - [ ] https://github.com/resurrecting-open-source-projects/scrot/issues/244 - [ ] https://github.com/resurrecting-open-source-projects/scrot/issues/246 - [ ] https://github.com/resurrecting-open-source-projects/scrot/issues/226 -- [ ] Remove deprecated features +- [x] Remove deprecated features - [x] --note [#236](https://github.com/resurrecting-open-source-projects/scrot/issues/236) - - [ ] --script + - [x] --script diff --git a/src/options.c b/src/options.c index d5b5eee4..d9e40726 100644 --- a/src/options.c +++ b/src/options.c @@ -80,7 +80,7 @@ enum { /* long opt only */ OPT_FORMAT = UCHAR_MAX + 1, OPT_LIST_OPTS, }; -static const char stropts[] = "a:bC:cD:d:e:F:fhik::l:M:mopq:S:s::t:uvw:Z:z"; +static const char stropts[] = "a:bC:cD:d:e:F:fhik::l:M:mopq:s::t:uvw:Z:z"; // NOTE: make sure lopts and opt_description indexes are kept in sync static const struct option lopts[] = { {"autoselect", required_argument, NULL, 'a'}, @@ -101,7 +101,6 @@ static const struct option lopts[] = { {"overwrite", no_argument, NULL, 'o'}, {"pointer", no_argument, NULL, 'p'}, {"quality", required_argument, NULL, 'q'}, - {"script", required_argument, NULL, 'S'}, {"select", optional_argument, NULL, 's'}, {"thumb", required_argument, NULL, 't'}, {"focused", no_argument, NULL, 'u'}, @@ -137,7 +136,6 @@ static const struct option_desc { /* o */ { "overwrite the output file if needed", "" }, /* p */ { "capture the mouse pointer as well", "" }, /* q */ { "image quality", "NUM" }, - /* S */ { OPT_DEPRECATED, OPT_DEPRECATED }, /* s */ { "interactively select a region to capture", "OPTS" }, /* t */ { "also generate a thumbnail", "% | WxH" }, /* u */ { "capture the currently focused window", "" }, @@ -458,9 +456,6 @@ void optionsParse(int argc, char *argv[]) errmsg); } break; - case 'S': - opt.script = optarg; - break; case 's': opt.mode = MODE_SELECT; optionsParseSelection(optarg); diff --git a/src/options.h b/src/options.h index 9f292bbb..bef21e63 100644 --- a/src/options.h +++ b/src/options.h @@ -84,7 +84,6 @@ struct ScrotOptions { const char *display; Window windowId; const char *windowClassName; - const char *script; int autoselectX; int autoselectY; int autoselectH; diff --git a/src/scrot.c b/src/scrot.c index 2c0f10b2..bfac50c0 100644 --- a/src/scrot.c +++ b/src/scrot.c @@ -70,7 +70,6 @@ static void initXAndImlib(const char *, int); static void uninitXAndImlib(void); static void scrotSaveImage(const char *); static Imlib_Image scrotGrabFocused(void); -static void applyFilterIfRequired(void); static Imlib_Image scrotGrabAutoselect(void); static long miliToNanoSec(int); static Imlib_Image scrotGrabShotMulti(void); @@ -158,8 +157,6 @@ int main(int argc, char *argv[]) filenameIM = imPrintf(opt.outputFile, tm, NULL, NULL, image); scrotCheckIfOverwriteFile(&filenameIM); - applyFilterIfRequired(); - scrotSaveImage(filenameIM); if (opt.thumb != THUMB_DISABLED) { @@ -546,16 +543,6 @@ static void scrotGrabMousePointer(Imlib_Image image, const int xOffset, XFree(xcim); } -// It assumes that the local variable 'scrot.c:Imlib_Image image' is in context -static void applyFilterIfRequired(void) -{ - if (opt.script) { - warnx("--script is deprecated. See: " - "https://github.com/resurrecting-open-source-projects/scrot/pull/231"); - imlib_apply_filter(opt.script); - } -} - static void scrotCheckIfOverwriteFile(char **filename) { if (opt.overwrite) From 3df2c5ef9716d038585ea82d020d07cfdb53dd02 Mon Sep 17 00:00:00 2001 From: NRK Date: Wed, 30 Aug 2023 05:19:01 +0600 Subject: [PATCH 03/11] add minimum version requirement for some libraries It seems that the lowest confirmed imlib2 version `scrot` can build with is `v1.4.7` which was released in 2015-04-04. (Imlib2 `v1.4.6` wouldn't build for me, though I didn't really troubleshoot the build error at all). Going by the [git history](https://gitlab.freedesktop.org/xorg/lib/libxcomposite/-/blob/7098e81fd4d933ca922431280579049396466d23/src/Xcomposite.c) of XComposite, `v0.2.0` from 2005 seem to have the functions that we use. So let's just go with that. (I didn't do any runtime testing, though). Whether XFixes uses semantic versioning is not clear. But in any case, there was a CVE fix in 5.0.1 related to XFixesGetCursorImage() (which is the only function from XFixes scrot uses). And it doesn't seem like version 6.0.0 broke anything regarding XFixesGetCursorImage() so go ahead and settle on `v5.0.1` for XFixes. Xinerama v1.1.3 was released 10 years ago and seems to contain a CVE fix. So let's go for that. Closes: https://github.com/resurrecting-open-source-projects/scrot/issues/307 --- README.md | 3 +++ TODO.md | 2 +- deps.pc | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 23474a1f..2bd3dfcc 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,9 @@ scrot requires a few projects and libraries: - libXfixes [(can be found in X.Org)](https://gitlab.freedesktop.org/xorg/lib/libxfixes) - libXinerama [(can be found in X.Org)](https://gitlab.freedesktop.org/xorg/lib/libxinerama) +The [deps.pc](./deps.pc) file documents minimum version requirement for some of +the libraries. + ### Generic installation instructions ### If you are building from a git checkout, or if you have applied additional diff --git a/TODO.md b/TODO.md index fd6fecd3..f2bd2a2f 100644 --- a/TODO.md +++ b/TODO.md @@ -60,7 +60,7 @@ It will be released when Imlib2 v1.11 is available on Debian stable to ease the transition for users and avoid depending on bleeding edge library versions. - [ ] Require Imlib2 v1.11.0 -- [ ] Document minimum version of other dependencies [#307](https://github.com/resurrecting-open-source-projects/scrot/issues/307) +- [x] Document minimum version of other dependencies [#307](https://github.com/resurrecting-open-source-projects/scrot/issues/307) - [ ] Use file descriptors when saving images - [ ] https://github.com/resurrecting-open-source-projects/scrot/issues/244 - [ ] https://github.com/resurrecting-open-source-projects/scrot/issues/246 diff --git a/deps.pc b/deps.pc index bc117607..e5def5c6 100644 --- a/deps.pc +++ b/deps.pc @@ -2,4 +2,4 @@ Name: scrot's mandatory dependencies Description: ditto Version: infinite Cflags: -D_XOPEN_SOURCE=700L -Requires: x11 imlib2 xcomposite xext xfixes xinerama +Requires: x11 imlib2 >= 1.4.7 xcomposite >= 0.2.0 xext xfixes >= 5.0.1 xinerama >= 1.1.3 From df1fca79fdf0dd359ea559677afcf681817d28b9 Mon Sep 17 00:00:00 2001 From: NRK Date: Thu, 23 Jan 2025 18:19:29 +0000 Subject: [PATCH 04/11] start requiring Imlib2 v1.11.0 --- TODO.md | 2 +- deps.pc | 2 +- src/scrot.c | 16 +++++----------- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/TODO.md b/TODO.md index f2bd2a2f..db99d18e 100644 --- a/TODO.md +++ b/TODO.md @@ -59,7 +59,7 @@ Work for it happens on the `v2` branch. It will be released when Imlib2 v1.11 is available on Debian stable to ease the transition for users and avoid depending on bleeding edge library versions. -- [ ] Require Imlib2 v1.11.0 +- [x] Require Imlib2 v1.11.0 - [x] Document minimum version of other dependencies [#307](https://github.com/resurrecting-open-source-projects/scrot/issues/307) - [ ] Use file descriptors when saving images - [ ] https://github.com/resurrecting-open-source-projects/scrot/issues/244 diff --git a/deps.pc b/deps.pc index e5def5c6..d4189b05 100644 --- a/deps.pc +++ b/deps.pc @@ -2,4 +2,4 @@ Name: scrot's mandatory dependencies Description: ditto Version: infinite Cflags: -D_XOPEN_SOURCE=700L -Requires: x11 imlib2 >= 1.4.7 xcomposite >= 0.2.0 xext xfixes >= 5.0.1 xinerama >= 1.1.3 +Requires: x11 imlib2 >= 1.11.0 xcomposite >= 0.2.0 xext xfixes >= 5.0.1 xinerama >= 1.1.3 diff --git a/src/scrot.c b/src/scrot.c index bfac50c0..e322b6c4 100644 --- a/src/scrot.c +++ b/src/scrot.c @@ -256,21 +256,15 @@ static void uninitXAndImlib(void) static void scrotSaveImage(const char *filename) { - Imlib_Load_Error imErr; - imlib_save_image_with_error_return(filename, &imErr); + imlib_save_image(filename); + int imErr = imlib_get_error(); if (imErr) { - const char *colon = "", *errmsg = ""; // NOLINT(*DeadStores) + const char *errmsg = imlib_strerror(imErr); const char imlibPrefix[] = "Imlib2: "; -#if defined(IMLIB2_VERSION) -#if IMLIB2_VERSION >= IMLIB2_VERSION_(1, 10, 0) - colon = ": "; - errmsg = imlib_strerror(imlib_get_error()); -#endif -#endif if (strncmp(errmsg, imlibPrefix, sizeof(imlibPrefix) - 1) == 0) errmsg += sizeof(imlibPrefix) - 1; - errx(EXIT_FAILURE, "failed to save image: %s%s%s", - filename, colon, errmsg); + errx(EXIT_FAILURE, "failed to save image: %s: %s", + filename, errmsg); } } From 288fb7b5b339b1920c7b78d95f0accb6db7c00ec Mon Sep 17 00:00:00 2001 From: NRK Date: Thu, 23 Jan 2025 19:35:20 +0000 Subject: [PATCH 05/11] ci: upgrade cygwin-install-action version --- .github/workflows/full-check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/full-check.yml b/.github/workflows/full-check.yml index 9e4c2943..0251e05d 100644 --- a/.github/workflows/full-check.yml +++ b/.github/workflows/full-check.yml @@ -64,7 +64,7 @@ jobs: # newlines to DOS newlines. shell: bash - uses: actions/checkout@v4 - - uses: cygwin/cygwin-install-action@v1 + - uses: cygwin/cygwin-install-action@v5 with: packages: autoconf autoconf-archive automake gcc-core libImlib2-devel \ libXcomposite-devel libXext-devel libXfixes-devel libXinerama-devel \ From 95ae608ad529839a1617f6867ef48007e795ee94 Mon Sep 17 00:00:00 2001 From: NRK Date: Sun, 26 Jan 2025 22:02:01 +0000 Subject: [PATCH 06/11] ci: remove cygwin the imlib2 version on it is way too old. --- .github/workflows/full-check.yml | 33 -------------------------------- 1 file changed, 33 deletions(-) diff --git a/.github/workflows/full-check.yml b/.github/workflows/full-check.yml index 0251e05d..683c2f58 100644 --- a/.github/workflows/full-check.yml +++ b/.github/workflows/full-check.yml @@ -49,36 +49,3 @@ jobs: clang-tidy --version find src -name '*.c' -print | xargs -P$(nproc) -I{} \ clang-tidy --quiet {} -- $(pkg-config --cflags ./deps.pc) - cygwin: - runs-on: windows-latest - env: - CYGWIN_NOWINPATH: 1 # Removes non-Cygwin dirs from PATH. - CHERE_INVOKING: '' # Makes Cygwin's `bash.exe --login` not cd. - defaults: - run: - shell: C:\cygwin\bin\bash.exe --login -o igncr {0} - steps: - - run: git config --global core.autocrlf input - # This is NOT the Cygwin bash, it's the Git for Windows bash from the - # default Github Actions Windows VM. This step tells git to translate Unix - # newlines to DOS newlines. - shell: bash - - uses: actions/checkout@v4 - - uses: cygwin/cygwin-install-action@v5 - with: - packages: autoconf autoconf-archive automake gcc-core libImlib2-devel \ - libXcomposite-devel libXext-devel libXfixes-devel libXinerama-devel \ - make - - name: distcheck - # NOTE: cygwin's imlib2 version is too old, and it's imlib_apply_filter - # lacks `const` qualifier. so use `-Wno-error=discarded-qualifiers`. - run: | - cd ${GITHUB_WORKSPACE} - ./autogen.sh - ./configure SCROT_PRIVATE_FLAGS="-Werror -Wno-error=cpp -Wno-error=pedantic -Wno-error=discarded-qualifiers" - make distcheck - - name: run_program - run: | - cd ${GITHUB_WORKSPACE} - make - src/scrot -v From c6f91383c798bd5184d10bf81930959dcc751873 Mon Sep 17 00:00:00 2001 From: NRK Date: Sun, 26 Jan 2025 22:19:29 +0000 Subject: [PATCH 07/11] use fd for saving images Closes: https://github.com/resurrecting-open-source-projects/scrot/issues/244 Closes: https://github.com/resurrecting-open-source-projects/scrot/issues/246 --- TODO.md | 6 ++-- src/options.c | 13 ------- src/scrot.c | 96 ++++++++++++++++++++++++++++----------------------- 3 files changed, 56 insertions(+), 59 deletions(-) diff --git a/TODO.md b/TODO.md index db99d18e..1e34907c 100644 --- a/TODO.md +++ b/TODO.md @@ -61,9 +61,9 @@ transition for users and avoid depending on bleeding edge library versions. - [x] Require Imlib2 v1.11.0 - [x] Document minimum version of other dependencies [#307](https://github.com/resurrecting-open-source-projects/scrot/issues/307) -- [ ] Use file descriptors when saving images - - [ ] https://github.com/resurrecting-open-source-projects/scrot/issues/244 - - [ ] https://github.com/resurrecting-open-source-projects/scrot/issues/246 +- [x] Use file descriptors when saving images + - [x] https://github.com/resurrecting-open-source-projects/scrot/issues/244 + - [x] https://github.com/resurrecting-open-source-projects/scrot/issues/246 - [ ] https://github.com/resurrecting-open-source-projects/scrot/issues/226 - [x] Remove deprecated features - [x] --note [#236](https://github.com/resurrecting-open-source-projects/scrot/issues/236) diff --git a/src/options.c b/src/options.c index d9e40726..70099c26 100644 --- a/src/options.c +++ b/src/options.c @@ -361,18 +361,6 @@ static void optionsParseLine(char *optarg) } /* while */ } -static const char *getPathOfStdout(void) -{ - const char *paths[] = { "/dev/stdout", "/dev/fd/1", "/proc/self/fd/1" }; - - for (size_t i = 0; i < ARRAY_COUNT(paths); ++i) { - if (access(paths[i], W_OK) == 0) - return paths[i]; - } - err(EXIT_FAILURE, "access to stdout failed"); - return 0; /* silence tcc warning */ -} - void optionsParse(int argc, char *argv[]) { int optch; @@ -526,7 +514,6 @@ void optionsParse(int argc, char *argv[]) if (strcmp(opt.outputFile, "-") == 0) { opt.overwrite = true; opt.thumb = THUMB_DISABLED; - opt.outputFile = getPathOfStdout(); } size_t outputFileLen = strlen(opt.outputFile); diff --git a/src/scrot.c b/src/scrot.c index e322b6c4..e4eed785 100644 --- a/src/scrot.c +++ b/src/scrot.c @@ -48,8 +48,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include -#include +#include #include +#include #include #include #include @@ -68,7 +69,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. static void initXAndImlib(const char *, int); static void uninitXAndImlib(void); -static void scrotSaveImage(const char *); +static void scrotSaveImage(int, const char *); static Imlib_Image scrotGrabFocused(void); static Imlib_Image scrotGrabAutoselect(void); static long miliToNanoSec(int); @@ -76,7 +77,7 @@ static Imlib_Image scrotGrabShotMulti(void); static Imlib_Image scrotGrabShotMonitor(void); static Imlib_Image scrotGrabStackWindows(void); static Imlib_Image scrotGrabShot(void); -static void scrotCheckIfOverwriteFile(char **); +static int scrotCheckIfOverwriteFile(char **); static void scrotExecApp(Imlib_Image, struct tm *, char *, char *); static char *imPrintf(const char *, struct tm *, const char *, const char *, Imlib_Image); @@ -102,6 +103,7 @@ int main(int argc, char *argv[]) char *filenameThumb = NULL; struct timespec timeStamp; struct tm *tm; + int fd; /* Get the time ASAP to reduce the timing error in case --delay is used. */ opt.delayStart = clockNow(); @@ -155,9 +157,8 @@ int main(int argc, char *argv[]) imlib_image_attach_data_value("compression", NULL, opt.compression, NULL); filenameIM = imPrintf(opt.outputFile, tm, NULL, NULL, image); - scrotCheckIfOverwriteFile(&filenameIM); - - scrotSaveImage(filenameIM); + fd = scrotCheckIfOverwriteFile(&filenameIM); + scrotSaveImage(fd, filenameIM); if (opt.thumb != THUMB_DISABLED) { int cwidth, cheight; @@ -195,8 +196,8 @@ int main(int argc, char *argv[]) imlib_image_set_format(opt.format); filenameThumb = imPrintf(opt.thumbFile, tm, NULL, NULL, thumbnail); - scrotCheckIfOverwriteFile(&filenameThumb); - scrotSaveImage(filenameThumb); + fd = scrotCheckIfOverwriteFile(&filenameThumb); + scrotSaveImage(fd, filenameThumb); imlib_free_image_and_decache(); } } @@ -254,9 +255,11 @@ static void uninitXAndImlib(void) } } -static void scrotSaveImage(const char *filename) +// save image to fd, filename only used for logging +// fd will be closed after calling this function +static void scrotSaveImage(int fd, const char *filename) { - imlib_save_image(filename); + imlib_save_image_fd(fd, filename); int imErr = imlib_get_error(); if (imErr) { const char *errmsg = imlib_strerror(imErr); @@ -537,43 +540,50 @@ static void scrotGrabMousePointer(Imlib_Image image, const int xOffset, XFree(xcim); } -static void scrotCheckIfOverwriteFile(char **filename) +static int scrotCheckIfOverwriteFile(char **filename) { - if (opt.overwrite) - return; - - if (access(*filename, F_OK) == -1) - return; - - const size_t maxCounter = 999; - char fmt[5]; // _000 + NUL byte - const size_t slen = strlen(*filename); - const size_t nalloc = slen + sizeof(fmt); - - char *ext; - size_t extLength = scrotHaveFileExtension(*filename, &ext); - - char *newName = ecalloc(nalloc, sizeof(*newName)); - memcpy(newName, *filename, slen - extLength); - char *ptr = newName + (slen - extLength); - - size_t counter = 0; - do { - snprintf(fmt, sizeof(fmt), "_%03zu", counter++); - memcpy(ptr, fmt, sizeof(fmt)); - memcpy(ptr + sizeof(fmt) - 1, ext, extLength); - } while ((counter < maxCounter) && !access(newName, F_OK)); - - scrotAssert(newName[nalloc - 1] == '\0'); + if (strcmp(*filename, "-") == 0) + return 1; + + int flags = O_RDWR | O_CREAT | (opt.overwrite ? O_TRUNC : O_EXCL); + int fd = open(*filename, flags, 0644); + if (!opt.overwrite && fd < 0 && errno == EEXIST) { + const size_t maxCounter = 999; + char fmt[5]; // _000 + NUL byte + const size_t slen = strlen(*filename); + const size_t nalloc = slen + sizeof(fmt); + + char *ext; + size_t extLength = scrotHaveFileExtension(*filename, &ext); + + char *newName = ecalloc(nalloc, sizeof(*newName)); + memcpy(newName, *filename, slen - extLength); + char *ptr = newName + (slen - extLength); + + size_t counter = 0; + do { + snprintf(fmt, sizeof(fmt), "_%03zu", counter++); + memcpy(ptr, fmt, sizeof(fmt)); + memcpy(ptr + sizeof(fmt) - 1, ext, extLength); + fd = open(newName, flags, 0644); + } while ((counter < maxCounter) && fd < 0 && errno == EEXIST); + scrotAssert(newName[nalloc - 1] == '\0'); + + if (counter == maxCounter) { + errx(EXIT_FAILURE, "scrot can no longer generate new file names.\n" + "The last attempt is %s", newName); + } - if (counter == maxCounter) { - errx(EXIT_FAILURE, "scrot can no longer generate new file names.\n" - "The last attempt is %s", newName); + int saved_errno = errno; // avoid errno getting potentially clobbered + warnx("`%s` already exists, attempting `%s` instead", *filename, newName); + free(*filename); + *filename = newName; + errno = saved_errno; } - warnx("`%s` already exists, attempting `%s` instead", *filename, newName); - free(*filename); - *filename = newName; + if (fd < 0) + err(EXIT_FAILURE, "couldn't open file %s", *filename); + return fd; } static int scrotMatchWindowClassName(Window target) From 53b5edfac2a1a49048254415c7c1f44609b8ce54 Mon Sep 17 00:00:00 2001 From: NRK Date: Thu, 30 Jan 2025 20:38:28 +0000 Subject: [PATCH 08/11] don't close standard out --- src/scrot.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/scrot.c b/src/scrot.c index e4eed785..80062aac 100644 --- a/src/scrot.c +++ b/src/scrot.c @@ -542,8 +542,13 @@ static void scrotGrabMousePointer(Imlib_Image image, const int xOffset, static int scrotCheckIfOverwriteFile(char **filename) { - if (strcmp(*filename, "-") == 0) - return 1; + if (strcmp(*filename, "-") == 0) { + // scrotSaveImage will close the fd, so dup it + int fd = fcntl(1, F_DUPFD_CLOEXEC, 3); + if (fd < 0) + err(EXIT_FAILURE, "dup failed"); + return fd; + } int flags = O_RDWR | O_CREAT | (opt.overwrite ? O_TRUNC : O_EXCL); int fd = open(*filename, flags, 0644); From bd0ffe6d043ca0cbc432c50d9d97d2fde3c844ac Mon Sep 17 00:00:00 2001 From: NRK Date: Thu, 30 Jan 2025 06:01:42 +0000 Subject: [PATCH 09/11] derive default line width from display dpi allows better default on high dpi displays where the previous default of 1 pixel would've been too small. Closes: https://github.com/resurrecting-open-source-projects/scrot/issues/285 --- configure.ac | 2 +- deps.pc | 1 + man/scrot.txt | 2 +- src/options.c | 1 - src/scrot_selection.c | 9 +++++++++ 5 files changed, 12 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 8e00785c..48887e01 100644 --- a/configure.ac +++ b/configure.ac @@ -28,7 +28,7 @@ AS_IF([test "x$orig_CFLAGS" = "x"], [ AX_APPEND_LINK_FLAGS(["-flto"]) ]) m4_foreach([SCROT_FLAG], - [["-O3"], ["-Wall"], ["-Wextra"], ["-Wpedantic"]], [ + [["-O3"], ["-Wall"], ["-Wextra"], ["-Wpedantic"], ["-fno-math-errno"]], [ AX_APPEND_COMPILE_FLAGS(["SCROT_FLAG"]) AS_IF([test "x$LTO_ENABLED" = "xyes"], [ AX_APPEND_LINK_FLAGS(["SCROT_FLAG"]) diff --git a/deps.pc b/deps.pc index d4189b05..6cd37969 100644 --- a/deps.pc +++ b/deps.pc @@ -2,4 +2,5 @@ Name: scrot's mandatory dependencies Description: ditto Version: infinite Cflags: -D_XOPEN_SOURCE=700L +Libs: -lm Requires: x11 imlib2 >= 1.11.0 xcomposite >= 0.2.0 xext xfixes >= 5.0.1 xinerama >= 1.1.3 diff --git a/man/scrot.txt b/man/scrot.txt index f78e9ae7..fb0ad3fa 100644 --- a/man/scrot.txt +++ b/man/scrot.txt @@ -175,7 +175,7 @@ SELECTION STYLE Without the -l option, a default style is used: - mode=auto,style=solid,width=1,opacity=100 + mode=auto,style=solid,width=$dpi/75,opacity=100 Example: diff --git a/src/options.c b/src/options.c index 70099c26..1ed5bf82 100644 --- a/src/options.c +++ b/src/options.c @@ -68,7 +68,6 @@ struct ScrotOptions opt = { .quality = 75, .compression = 7, .lineStyle = LineSolid, - .lineWidth = 1, .lineOpacity = SELECTION_OPACITY_DEFAULT, .stackDirection = HORIZONTAL, .outputFile = defaultOutputFile, diff --git a/src/scrot_selection.c b/src/scrot_selection.c index 1bb55db3..e3d2690b 100644 --- a/src/scrot_selection.c +++ b/src/scrot_selection.c @@ -35,6 +35,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#include #include #include #include @@ -423,6 +424,14 @@ Imlib_Image scrotSelectionSelectMode(void) opt.lineMode = LINE_MODE_CLASSIC; } + if (opt.lineWidth == 0) { + double mmToInches = 1 / 25.4; + double inchesDiag = hypot(scr->mwidth, scr->mheight) * mmToInches; + double pixelsDiag = hypot(scr->width, scr->height); + double dpi = round(pixelsDiag / inchesDiag); + opt.lineWidth = fmin(fmax(round(dpi / 75.0), 1), 8); + } + if (opt.delaySelection) scrotDoDelay(); From 2ea7a12d74d7f8e44c583b6d9e25ccfdf5f48b12 Mon Sep 17 00:00:00 2001 From: NRK Date: Thu, 6 Feb 2025 11:24:48 +0000 Subject: [PATCH 10/11] simpler line width calculation --- configure.ac | 2 +- deps.pc | 1 - man/scrot.txt | 2 +- src/scrot_selection.c | 8 ++------ src/util.h | 1 + 5 files changed, 5 insertions(+), 9 deletions(-) diff --git a/configure.ac b/configure.ac index 48887e01..8e00785c 100644 --- a/configure.ac +++ b/configure.ac @@ -28,7 +28,7 @@ AS_IF([test "x$orig_CFLAGS" = "x"], [ AX_APPEND_LINK_FLAGS(["-flto"]) ]) m4_foreach([SCROT_FLAG], - [["-O3"], ["-Wall"], ["-Wextra"], ["-Wpedantic"], ["-fno-math-errno"]], [ + [["-O3"], ["-Wall"], ["-Wextra"], ["-Wpedantic"]], [ AX_APPEND_COMPILE_FLAGS(["SCROT_FLAG"]) AS_IF([test "x$LTO_ENABLED" = "xyes"], [ AX_APPEND_LINK_FLAGS(["SCROT_FLAG"]) diff --git a/deps.pc b/deps.pc index 6cd37969..d4189b05 100644 --- a/deps.pc +++ b/deps.pc @@ -2,5 +2,4 @@ Name: scrot's mandatory dependencies Description: ditto Version: infinite Cflags: -D_XOPEN_SOURCE=700L -Libs: -lm Requires: x11 imlib2 >= 1.11.0 xcomposite >= 0.2.0 xext xfixes >= 5.0.1 xinerama >= 1.1.3 diff --git a/man/scrot.txt b/man/scrot.txt index fb0ad3fa..c84a7341 100644 --- a/man/scrot.txt +++ b/man/scrot.txt @@ -175,7 +175,7 @@ SELECTION STYLE Without the -l option, a default style is used: - mode=auto,style=solid,width=$dpi/75,opacity=100 + mode=auto,style=solid,width=...,opacity=100 # FIXME: width Example: diff --git a/src/scrot_selection.c b/src/scrot_selection.c index e3d2690b..fd386a3f 100644 --- a/src/scrot_selection.c +++ b/src/scrot_selection.c @@ -35,7 +35,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include -#include #include #include #include @@ -425,11 +424,8 @@ Imlib_Image scrotSelectionSelectMode(void) } if (opt.lineWidth == 0) { - double mmToInches = 1 / 25.4; - double inchesDiag = hypot(scr->mwidth, scr->mheight) * mmToInches; - double pixelsDiag = hypot(scr->width, scr->height); - double dpi = round(pixelsDiag / inchesDiag); - opt.lineWidth = fmin(fmax(round(dpi / 75.0), 1), 8); + int width = (scr->height + scr->width) / (scr->mheight + scr->mwidth); + opt.lineWidth = MIN(MAX(width/4, 1), 8); } if (opt.delaySelection) diff --git a/src/util.h b/src/util.h index 6a350aab..56a1bc5b 100644 --- a/src/util.h +++ b/src/util.h @@ -43,6 +43,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define ARRAY_COUNT(X) (sizeof(X) / sizeof(0[X])) #define MAX(A, B) ((A) > (B) ? (A) : (B)) +#define MIN(A, B) ((A) < (B) ? (A) : (B)) typedef struct { char *buf; From 737df1176be21283d205e876a19fc49b646c80a0 Mon Sep 17 00:00:00 2001 From: Guilherme Janczak Date: Sun, 9 Feb 2025 14:42:12 +0000 Subject: [PATCH 11/11] document selection line width DPI scaling --- man/scrot.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/man/scrot.txt b/man/scrot.txt index c84a7341..aaf01ee2 100644 --- a/man/scrot.txt +++ b/man/scrot.txt @@ -175,7 +175,9 @@ SELECTION STYLE Without the -l option, a default style is used: - mode=auto,style=solid,width=...,opacity=100 # FIXME: width + mode=auto,style=solid,width=...,opacity=100 + + The default width automatically scales with DPI. Example: