summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile2
-rw-r--r--src/debug.h2
-rw-r--r--src/events.c35
-rw-r--r--src/exif.c577
-rw-r--r--src/exif.h17
-rw-r--r--src/exif_canon.c30
-rw-r--r--src/exif_canon.h3
-rw-r--r--src/exif_cfg.h85
-rw-r--r--src/exif_nikon.c796
-rw-r--r--src/exif_nikon.h3
-rw-r--r--src/feh.h20
-rw-r--r--src/feh_png.c5
-rw-r--r--src/filelist.c60
-rw-r--r--src/filelist.h3
-rw-r--r--src/getopt.c949
-rw-r--r--src/getopt.h130
-rw-r--r--src/getopt1.c173
-rw-r--r--src/gib_hash.c4
-rw-r--r--src/gib_hash.h2
-rw-r--r--src/gib_imlib.c5
-rw-r--r--src/gib_imlib.h2
-rw-r--r--src/gib_list.c2
-rw-r--r--src/help.raw7
-rw-r--r--src/imlib.c318
-rw-r--r--src/index.c6
-rw-r--r--src/index.h2
-rw-r--r--src/keyevents.c16
-rw-r--r--src/list.c2
-rw-r--r--src/main.c59
-rw-r--r--src/menu.c20
-rw-r--r--src/menu.h2
-rw-r--r--src/options.c445
-rw-r--r--src/options.h111
-rw-r--r--src/signals.c26
-rw-r--r--src/signals.h5
-rw-r--r--src/slideshow.c29
-rw-r--r--src/structs.h2
-rw-r--r--src/strverscmp.c6
-rw-r--r--src/thumbnail.c15
-rw-r--r--src/thumbnail.h6
-rw-r--r--src/timers.c2
-rw-r--r--src/utils.c2
-rw-r--r--src/wallpaper.c194
-rw-r--r--src/wallpaper.h5
-rw-r--r--src/winwidget.c61
-rw-r--r--src/winwidget.h2
46 files changed, 1757 insertions, 2491 deletions
diff --git a/src/Makefile b/src/Makefile
index 10e33eb..2968671 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -4,8 +4,6 @@ TARGETS = \
events.c \
feh_png.c \
filelist.c \
- getopt.c \
- getopt1.c \
gib_hash.c \
gib_imlib.c \
gib_list.c \
diff --git a/src/debug.h b/src/debug.h
index 569637e..0ff1447 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -1,7 +1,7 @@
/* debug.h
Copyright (C) 1999-2003 Tom Gilbert.
-Copyright (C) 2010-2020 Daniel Friesel.
+Copyright (C) 2010-2020 Birte Kristina Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
diff --git a/src/events.c b/src/events.c
index c44ebf4..de9e7b3 100644
--- a/src/events.c
+++ b/src/events.c
@@ -1,7 +1,7 @@
/* events.c
Copyright (C) 1999-2003 Tom Gilbert.
-Copyright (C) 2010-2020 Daniel Friesel.
+Copyright (C) 2010-2020 Birte Kristina Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -85,6 +85,15 @@ static void feh_set_parse_bb_partial(fehkey *button, char *binding)
button->button = atoi(cur);
button->state = mod;
+
+ if (button->button == 0) {
+ /*
+ * Mod3 is unused on today's keyboards. If Mod3 is unset and button==0,
+ * we are dealing with an uninitialized or unset binding. If Mod3 is set
+ * and button==0, it refers to mouse movement.
+ */
+ button->state |= Mod3Mask;
+ }
}
/*
@@ -255,7 +264,7 @@ static void feh_event_handle_ButtonPress(XEvent * ev)
- winwid->im_y) / winwid->old_zoom;
/* copied from zoom_in, keyevents.c */
- winwid->zoom = winwid->zoom * 1.25;
+ winwid->zoom = winwid->zoom * opt.zoom_rate;
if (winwid->zoom > ZOOM_MAX)
winwid->zoom = ZOOM_MAX;
@@ -283,7 +292,7 @@ static void feh_event_handle_ButtonPress(XEvent * ev)
- winwid->im_y) / winwid->old_zoom;
/* copied from zoom_out, keyevents.c */
- winwid->zoom = winwid->zoom * 0.80;
+ winwid->zoom = winwid->zoom / opt.zoom_rate;
if (winwid->zoom < ZOOM_MIN)
winwid->zoom = ZOOM_MIN;
@@ -672,14 +681,18 @@ static void feh_event_handle_MotionNotify(XEvent * ev)
} else {
while (XCheckTypedWindowEvent(disp, ev->xmotion.window, MotionNotify, ev));
winwid = winwidget_get_from_window(ev->xmotion.window);
- if ((winwid != NULL) && (winwid->type == WIN_TYPE_THUMBNAIL)) {
- feh_thumbnail *thumbnail;
- int x, y;
-
- x = (ev->xbutton.x - winwid->im_x) / winwid->zoom;
- y = (ev->xbutton.y - winwid->im_y) / winwid->zoom;
- thumbnail = feh_thumbnail_get_thumbnail_from_coords(x, y);
- feh_thumbnail_select(winwid, thumbnail);
+ if (winwid != NULL) {
+ if (winwid->type == WIN_TYPE_THUMBNAIL) {
+ feh_thumbnail *thumbnail;
+ int x, y;
+
+ x = (ev->xbutton.x - winwid->im_x) / winwid->zoom;
+ y = (ev->xbutton.y - winwid->im_y) / winwid->zoom;
+ thumbnail = feh_thumbnail_get_thumbnail_from_coords(x, y);
+ feh_thumbnail_select(winwid, thumbnail);
+ } else {
+ feh_event_handle_generic(winwid, ev->xmotion.state | Mod3Mask, NoSymbol, 0);
+ }
}
}
return;
diff --git a/src/exif.c b/src/exif.c
index 9ad9dae..6b0719d 100644
--- a/src/exif.c
+++ b/src/exif.c
@@ -1,6 +1,7 @@
/* exif.c
Copyright (C) 2012 Dennis Real.
+Copyright (C) 2021 Birte Kristina Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -42,199 +43,302 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/* remove all spaces on the right end of a string */
void exif_trim_spaces(char *str)
{
- char *end;
-
- for (end = str; *str!='\0'; str++)
- {
- if (*str != ' ')
- {
- end = str + 1;
- }
- }
- *end = '\0';
+ char *end;
+
+ for (end = str; *str != '\0'; str++) {
+ if (*str != ' ') {
+ end = str + 1;
+ }
+ }
+ *end = '\0';
}
/* show given exif tag content with tag name */
-void exif_get_tag(ExifData *d, ExifIfd ifd, ExifTag tag, char* buffer, unsigned int maxsize)
+void exif_get_tag(ExifData * d, ExifIfd ifd, ExifTag tag, char *buffer,
+ unsigned int maxsize)
{
- char s[EXIF_MAX_DATA];
- ExifEntry *entry = NULL;
-
- if ( (d != NULL) && (buffer != NULL) && (maxsize > 0) )
- {
- entry = exif_content_get_entry(d->ifd[ifd], tag);
- if (entry != NULL)
- {
- /* Get the contents of the tag in human-readable form */
- exif_entry_get_value(entry, s, EXIF_MAX_DATA);
-
- /* Don't bother printing it if it's entirely blank */
- exif_trim_spaces(s);
- if (*s != '\0')
- {
- D(("%s: %s\n", exif_tag_get_name_in_ifd(tag,ifd), s));
- snprintf(buffer, (size_t)maxsize, "%s: %s\n", exif_tag_get_name_in_ifd(tag,ifd), s);
- }
- }
- }
+ char s[EXIF_MAX_DATA];
+ ExifEntry *entry = NULL;
+
+ if ((d != NULL) && (buffer != NULL) && (maxsize > 0)) {
+ entry = exif_content_get_entry(d->ifd[ifd], tag);
+ if (entry != NULL) {
+ /* Get the contents of the tag in human-readable form */
+ exif_entry_get_value(entry, s, EXIF_MAX_DATA);
+
+ /* Don't bother printing it if it's entirely blank */
+ exif_trim_spaces(s);
+ if (*s != '\0') {
+ D(("%s: %s\n",
+ exif_tag_get_name_in_ifd(tag, ifd), s));
+ snprintf(buffer, (size_t) maxsize,
+ "%s: %s\n",
+ exif_tag_get_name_in_ifd(tag,
+ ifd), s);
+ }
+ }
+ }
}
/* show given exif tag content without tag name */
-void exif_get_tag_content(ExifData *d, ExifIfd ifd, ExifTag tag, char* buffer, unsigned int maxsize)
+void exif_get_tag_content(ExifData * d, ExifIfd ifd, ExifTag tag,
+ char *buffer, unsigned int maxsize)
{
- char s[EXIF_MAX_DATA];
- ExifEntry *entry = NULL;
-
- if ( (d != NULL) && (buffer != NULL) && (maxsize > 0) )
- {
- entry = exif_content_get_entry(d->ifd[ifd], tag);
- if (entry != NULL)
- {
- /* Get the contents of the tag in human-readable form */
- exif_entry_get_value(entry, s, EXIF_MAX_DATA);
-
- /* Don't bother printing it if it's entirely blank */
- exif_trim_spaces(s);
- if (*s != '\0')
- {
- D(("%s - %s\n", exif_tag_get_name_in_ifd(tag,ifd), s));
- snprintf(buffer, (size_t)maxsize, "%s", s);
- }
- }
- }
+ char s[EXIF_MAX_DATA];
+ ExifEntry *entry = NULL;
+
+ if ((d != NULL) && (buffer != NULL) && (maxsize > 0)) {
+ entry = exif_content_get_entry(d->ifd[ifd], tag);
+ if (entry != NULL) {
+ /* Get the contents of the tag in human-readable form */
+ exif_entry_get_value(entry, s, EXIF_MAX_DATA);
+
+ /* Don't bother printing it if it's entirely blank */
+ exif_trim_spaces(s);
+ if (*s != '\0') {
+ D(("%s - %s\n",
+ exif_tag_get_name_in_ifd(tag, ifd), s));
+ snprintf(buffer, (size_t) maxsize, "%s",
+ s);
+ }
+ }
+ }
}
/* Show the given MakerNote tag if it exists */
-void exif_get_mnote_tag(ExifData *d, unsigned int tag, char* buffer, unsigned int maxsize)
+void exif_get_mnote_tag(ExifData * d, unsigned int tag, char *buffer,
+ unsigned int maxsize)
{
- ExifMnoteData *mn = NULL;
- int i, num;
- char buf[1024];
-
- if ( (d!=NULL) && (buffer!=NULL) && (maxsize > 0) )
- {
- mn = exif_data_get_mnote_data(d);
- }
- else
- {
- return;
- }
-
- if ( mn != NULL )
- {
- num = exif_mnote_data_count(mn);
-
- /* Loop through all MakerNote tags, searching for the desired one */
- for (i=0; i < num; ++i)
- {
- D(("%d/%d %d 0x%2x %s; %s\n", i, num, exif_mnote_data_get_id(mn, i),
- exif_mnote_data_get_id(mn, i),
- exif_mnote_data_get_name(mn,i),
- exif_mnote_data_get_title(mn, i) ));
-
- if (exif_mnote_data_get_id(mn, i) == tag)
- {
- if (exif_mnote_data_get_value(mn, i, buf, sizeof(buf)))
- {
- /* Don't bother printing it if it's entirely blank */
- exif_trim_spaces(buf);
- if (*buf != '\0')
- {
- D(("%s\n", buf));
- snprintf(buffer, (size_t)maxsize, "%s: %s\n", exif_mnote_data_get_title(mn, i), buf);
- }
- }
- }
- }
- }
+ ExifMnoteData *mn = NULL;
+ int i, num;
+ char buf[1024];
+
+ if ((d != NULL) && (buffer != NULL) && (maxsize > 0)) {
+ mn = exif_data_get_mnote_data(d);
+ } else {
+ return;
+ }
+
+ if (mn != NULL) {
+ num = exif_mnote_data_count(mn);
+
+ /* Loop through all MakerNote tags, searching for the desired one */
+ for (i = 0; i < num; ++i) {
+ D(("%d/%d %d 0x%2x %s; %s\n", i, num,
+ exif_mnote_data_get_id(mn, i),
+ exif_mnote_data_get_id(mn, i),
+ exif_mnote_data_get_name(mn, i),
+ exif_mnote_data_get_title(mn, i)));
+
+ if (exif_mnote_data_get_id(mn, i) == tag) {
+ if (exif_mnote_data_get_value
+ (mn, i, buf, sizeof(buf))) {
+ /* Don't bother printing it if it's entirely blank */
+ exif_trim_spaces(buf);
+ if (*buf != '\0') {
+ D(("%s\n", buf));
+ snprintf(buffer,
+ (size_t) maxsize,
+ "%s: %s\n",
+ exif_mnote_data_get_title
+ (mn, i), buf);
+ }
+ }
+ }
+ }
+ }
}
+void exif_get_make_model_lens(ExifData * ed, char *buffer, unsigned int maxsize)
+{
+ char make[EXIF_STD_BUF_LEN];
+ char model[EXIF_STD_BUF_LEN];
+ char lens[EXIF_STD_BUF_LEN];
+ unsigned int offset = 0;
+
+ make[0] = model[0] = lens[0] = '\0';
+
+ exif_get_tag_content(ed, EXIF_IFD_0, EXIF_TAG_MAKE, make, sizeof(make));
+ exif_get_tag_content(ed, EXIF_IFD_0, EXIF_TAG_MODEL, model, sizeof(model));
+ exif_get_tag_content(ed, EXIF_IFD_EXIF, 0xa434, lens, sizeof(lens));
+
+ if (make[0] && strncmp(make, model, strlen(make)) != 0) {
+ offset += snprintf(buffer, maxsize, "%s ", make);
+ }
+ if (model[0]) {
+ offset += snprintf(buffer + offset, maxsize - offset, "%s", model);
+ }
+ if (lens[0]) {
+ offset += snprintf(buffer + offset, maxsize - offset, " + %s", lens);
+ }
+ snprintf(buffer + offset, maxsize - offset, "\n");
+}
+
+void exif_get_exposure(ExifData * ed, char *buffer, unsigned int maxsize)
+{
+ char fnumber[EXIF_STD_BUF_LEN];
+ char exposure[EXIF_STD_BUF_LEN];
+ char iso[EXIF_STD_BUF_LEN];
+ char focus[EXIF_STD_BUF_LEN];
+ char focus35[EXIF_STD_BUF_LEN];
+ unsigned int offset = 0;
+
+ fnumber[0] = exposure[0] = iso[0] = '\0';
+ focus[0] = focus35[0] = '\0';
+
+ exif_get_tag_content(ed, EXIF_IFD_EXIF, EXIF_TAG_FNUMBER, fnumber, sizeof(fnumber));
+ exif_get_tag_content(ed, EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_TIME, exposure, sizeof(exposure));
+ exif_get_tag_content(ed, EXIF_IFD_EXIF, EXIF_TAG_ISO_SPEED_RATINGS, iso, sizeof(iso));
+ exif_get_tag_content(ed, EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH, focus, sizeof(focus));
+ exif_get_tag_content(ed, EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM, focus35, sizeof(focus35));
+
+ if (fnumber[0] || exposure[0]) {
+ offset += snprintf(buffer, maxsize, "%s %s ", fnumber, exposure);
+ }
+ if (iso[0]) {
+ offset += snprintf(buffer + offset, maxsize - offset, "ISO%s ", iso);
+ }
+ if (focus[0] && focus35[0]) {
+ snprintf(buffer + offset, maxsize - offset, "%s (%s mm)\n", focus, focus35);
+ } else if (focus[0]) {
+ snprintf(buffer + offset, maxsize - offset, "%s\n", focus);
+ }
+}
+
+void exif_get_flash(ExifData * ed, char *buffer, unsigned int maxsize)
+{
+ char flash[EXIF_STD_BUF_LEN];
+
+ flash[0] = '\0';
+
+ exif_get_tag_content(ed, EXIF_IFD_EXIF, EXIF_TAG_FLASH, flash, sizeof(flash));
+
+ if (flash[0]) {
+ snprintf(buffer, maxsize, "%s\n", flash);
+ }
+}
+
+void exif_get_mode(ExifData * ed, char *buffer, unsigned int maxsize)
+{
+ char mode[EXIF_STD_BUF_LEN];
+ char program[EXIF_STD_BUF_LEN];
+
+ mode[0] = program[0] = '\0';
+
+ exif_get_tag_content(ed, EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_MODE, mode, sizeof(mode));
+ exif_get_tag_content(ed, EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_PROGRAM, program, sizeof(program));
+
+ if (mode[0] || program[0]) {
+ snprintf(buffer, maxsize, "%s (%s)\n", mode, program);
+ }
+}
+
+void exif_get_datetime(ExifData * ed, char *buffer, unsigned int maxsize)
+{
+ char datetime[EXIF_STD_BUF_LEN];
+
+ datetime[0] = '\0';
+
+ exif_get_tag_content(ed, EXIF_IFD_EXIF, EXIF_TAG_DATE_TIME_ORIGINAL, datetime, sizeof(datetime));
+
+ if (datetime[0]) {
+ snprintf(buffer, maxsize, "%s\n", datetime);
+ }
+}
+
+void exif_get_description(ExifData * ed, char *buffer, unsigned int maxsize)
+{
+ char description[EXIF_STD_BUF_LEN];
+
+ description[0] = '\0';
+
+ exif_get_tag_content(ed, EXIF_IFD_0, EXIF_TAG_IMAGE_DESCRIPTION, description, sizeof(description));
+
+ if (description[0]) {
+ snprintf(buffer, maxsize, "\"%s\"\n", description);
+ }
+}
/* get gps coordinates if available */
void exif_get_gps_coords(ExifData * ed, char *buffer, unsigned int maxsize)
{
- char buf[EXIF_STD_BUF_LEN];
-
- buf[0] = '\0';
- exif_get_tag_content(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_LATITUDE_REF, buf, sizeof(buf));
- if ( buf[0] != '\0' )
- {
- snprintf(buffer + strlen(buffer), maxsize - strlen(buffer), "GPS: %s ", buf);
- }
- else
- {
- return;
- }
-
- buf[0] = '\0';
- exif_get_tag_content(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_LATITUDE, buf, sizeof(buf));
- if ( buf[0] != '\0' )
- {
- snprintf(buffer + strlen(buffer), maxsize - strlen(buffer), "%s ", buf);
- }
- else
- {
- return;
- }
-
- buf[0] = '\0';
- exif_get_tag_content(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_LONGITUDE_REF, buf, sizeof(buf));
- if ( buf[0] != '\0' )
- {
- snprintf(buffer + strlen(buffer), maxsize - strlen(buffer), ", %s ", buf);
- }
- else
- {
- return;
- }
-
- buf[0] = '\0';
- exif_get_tag_content(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_LONGITUDE, buf, sizeof(buf));
- if ( buf[0] != '\0' )
- {
- snprintf(buffer + strlen(buffer), maxsize - strlen(buffer), "%s ", buf);
- }
- else
- {
- return;
- }
-
- buf[0] = '\0';
- exif_get_tag_content(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_MAP_DATUM, buf, sizeof(buf));
- if ( buf[0] != '\0' )
- {
- snprintf(buffer + strlen(buffer), maxsize - strlen(buffer), "(%s)\n", buf);
- }
- else
- {
- return;
- }
+ char buf[EXIF_STD_BUF_LEN];
+
+ buf[0] = '\0';
+ exif_get_tag_content(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_LATITUDE_REF,
+ buf, sizeof(buf));
+ if (buf[0] != '\0') {
+ snprintf(buffer + strlen(buffer), maxsize - strlen(buffer),
+ "GPS: %s ", buf);
+ } else {
+ return;
+ }
+
+ buf[0] = '\0';
+ exif_get_tag_content(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_LATITUDE, buf,
+ sizeof(buf));
+ if (buf[0] != '\0') {
+ snprintf(buffer + strlen(buffer), maxsize - strlen(buffer),
+ "%s ", buf);
+ } else {
+ return;
+ }
+
+ buf[0] = '\0';
+ exif_get_tag_content(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_LONGITUDE_REF,
+ buf, sizeof(buf));
+ if (buf[0] != '\0') {
+ snprintf(buffer + strlen(buffer), maxsize - strlen(buffer),
+ ", %s ", buf);
+ } else {
+ return;
+ }
+
+ buf[0] = '\0';
+ exif_get_tag_content(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_LONGITUDE, buf,
+ sizeof(buf));
+ if (buf[0] != '\0') {
+ snprintf(buffer + strlen(buffer), maxsize - strlen(buffer),
+ "%s ", buf);
+ } else {
+ return;
+ }
+
+ buf[0] = '\0';
+ exif_get_tag_content(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_MAP_DATUM, buf,
+ sizeof(buf));
+ if (buf[0] != '\0') {
+ snprintf(buffer + strlen(buffer), maxsize - strlen(buffer),
+ "(%s)\n", buf);
+ } else {
+ return;
+ }
}
/* return data structure with exif data if available */
-ExifData * exif_get_data(char *path)
+ExifData *exif_get_data(char *path)
{
- ExifData *ed = NULL;
+ ExifData *ed = NULL;
- /* Load an ExifData object from an EXIF file */
- ed = exif_data_new_from_file(path);
- if (ed == NULL)
- {
- D(("File not readable or no Exif data present in %s\n", path));
- }
+ /* Load an ExifData object from an EXIF file */
+ ed = exif_data_new_from_file(path);
+ if (ed == NULL) {
+ D(("File not readable or no Exif data present in %s\n",
+ path));
+ }
- return(ed);
+ return (ed);
}
@@ -243,76 +347,93 @@ ExifData * exif_get_data(char *path)
/* get all exif data in readable form */
void exif_get_info(ExifData * ed, char *buffer, unsigned int maxsize)
{
- ExifEntry *entry = NULL;
- char buf[EXIF_STD_BUF_LEN];
- unsigned short int i = 0;
-
- if ( (buffer == NULL) || (maxsize == 0) )
- {
- return;
- }
- else if (ed == NULL)
- {
- snprintf(buffer, (size_t)maxsize, "%s\n", "No Exif data in file.");
- return;
- }
- else
- {
- /* show normal exif tags. list must be defined in exif_cfg.h */
- while ( (i < USHRT_MAX) && (Exif_tag_list[i].ifd != EXIF_IFD_COUNT) )
- {
- exif_get_tag(ed, Exif_tag_list[i].ifd, Exif_tag_list[i].tag, buffer + strlen(buffer), maxsize - strlen(buffer));
- i++;
- }
-
- /* show vendor specific makernote tags */
- entry = exif_content_get_entry(ed->ifd[EXIF_IFD_0], EXIF_TAG_MAKE);
- if (entry != NULL)
- {
-
- if (exif_entry_get_value(entry, buf, sizeof(buf)))
- {
- exif_trim_spaces(buf);
-
- if ( (strcmp(buf, "NIKON CORPORATION") == 0)
- || (strcmp(buf, "Nikon") == 0)
- || (strcmp(buf, "NIKON") == 0)
- )
- {
- /* show nikon makernote exif tags. list must be defined in exif_cfg.h */
- i=0;
- while ( (i < USHRT_MAX) && (Exif_makernote_nikon_tag_list[i] != EXIF_NIKON_MAKERNOTE_END) )
- {
- exn_get_mnote_nikon_tags(ed, Exif_makernote_nikon_tag_list[i],
- buffer + strlen(buffer), maxsize - strlen(buffer));
- i++;
- }
-
- }
- else if ( (strcmp(buf, "Canon") == 0) )
- {
- /* show canon makernote exif tags. list must be defined in exif_cfg.h */
- i=0;
- while ( (i < USHRT_MAX) && (Exif_makernote_canon_tag_list[i] != EXIF_CANON_MAKERNOTE_END) )
- {
- exc_get_mnote_canon_tags(ed, Exif_makernote_canon_tag_list[i],
- buffer + strlen(buffer), maxsize - strlen(buffer));
- i++;
- }
-
- }
- else
- {
- }
- }
-
- }
-
- /* show gps coordinates */
- exif_get_gps_coords(ed, buffer + strlen(buffer), maxsize - strlen(buffer));
-
- }
-
+ ExifEntry *entry = NULL;
+ char buf[EXIF_STD_BUF_LEN];
+ unsigned short int i = 0;
+
+ if ((buffer == NULL) || (maxsize == 0)) {
+ return;
+ } else if (ed == NULL) {
+ snprintf(buffer, (size_t) maxsize, "%s\n",
+ "No Exif data in file.");
+ return;
+ }
+
+ exif_get_description(ed, buffer + strlen(buffer),
+ maxsize - strlen(buffer));
+ exif_get_make_model_lens(ed, buffer + strlen(buffer),
+ maxsize - strlen(buffer));
+ exif_get_exposure(ed, buffer + strlen(buffer),
+ maxsize - strlen(buffer));
+ exif_get_mode(ed, buffer + strlen(buffer),
+ maxsize - strlen(buffer));
+ exif_get_flash(ed, buffer + strlen(buffer),
+ maxsize - strlen(buffer));
+ exif_get_datetime(ed, buffer + strlen(buffer),
+ maxsize - strlen(buffer));
+
+ /* show vendor specific makernote tags */
+ entry =
+ exif_content_get_entry(ed->ifd[EXIF_IFD_0],
+ EXIF_TAG_MAKE);
+ if (entry != NULL) {
+
+ if (exif_entry_get_value(entry, buf, sizeof(buf))) {
+ exif_trim_spaces(buf);
+
+ if ((strcmp(buf, "NIKON CORPORATION") == 0)
+ || (strcmp(buf, "Nikon") == 0)
+ || (strcmp(buf, "NIKON") == 0)
+ ) {
+ /* show nikon makernote exif tags. list must be defined in exif_cfg.h */
+ i = 0;
+ while ((i < USHRT_MAX)
+ &&
+ (Exif_makernote_nikon_tag_list
+ [i] !=
+ EXIF_NIKON_MAKERNOTE_END))
+ {
+ exn_get_mnote_nikon_tags
+ (ed,
+ Exif_makernote_nikon_tag_list
+ [i],
+ buffer +
+ strlen(buffer),
+ maxsize -
+ strlen(buffer));
+ i++;
+ }
+
+ } else if ((strcmp(buf, "Canon") == 0)) {
+ /* show canon makernote exif tags. list must be defined in exif_cfg.h */
+ i = 0;
+ while ((i < USHRT_MAX)
+ &&
+ (Exif_makernote_canon_tag_list
+ [i] !=
+ EXIF_CANON_MAKERNOTE_END))
+ {
+ exc_get_mnote_canon_tags
+ (ed,
+ Exif_makernote_canon_tag_list
+ [i],
+ buffer +
+ strlen(buffer),
+ maxsize -
+ strlen(buffer));
+ i++;
+ }
+
+ } else {
+ }
+ }
+
+ }
+
+ /* show gps coordinates */
+ exif_get_gps_coords(ed, buffer + strlen(buffer),
+ maxsize - strlen(buffer));
+
}
#endif
diff --git a/src/exif.h b/src/exif.h
index 79187f4..41769c0 100644
--- a/src/exif.h
+++ b/src/exif.h
@@ -32,11 +32,16 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define EXIF_STD_BUF_LEN 128
extern void exif_trim_spaces(char *str);
-extern void exif_get_tag(ExifData *d, ExifIfd ifd, ExifTag tag, char* buffer, unsigned int maxsize);
-extern void exif_get_tag_content(ExifData *d, ExifIfd ifd, ExifTag tag, char* buffer, unsigned int maxsize);
-extern void exif_get_mnote_tag(ExifData *d, unsigned int tag, char* buffer, unsigned int maxsize);
-extern void exif_get_gps_coords(ExifData * ed, char *buffer, unsigned int maxsize);
-extern ExifData * exif_get_data(char *path);
-extern void exif_get_info(ExifData * ed, char *buffer, unsigned int maxsize);
+extern void exif_get_tag(ExifData * d, ExifIfd ifd, ExifTag tag,
+ char *buffer, unsigned int maxsize);
+extern void exif_get_tag_content(ExifData * d, ExifIfd ifd, ExifTag tag,
+ char *buffer, unsigned int maxsize);
+extern void exif_get_mnote_tag(ExifData * d, unsigned int tag,
+ char *buffer, unsigned int maxsize);
+extern void exif_get_gps_coords(ExifData * ed, char *buffer,
+ unsigned int maxsize);
+extern ExifData *exif_get_data(char *path);
+extern void exif_get_info(ExifData * ed, char *buffer,
+ unsigned int maxsize);
#endif
diff --git a/src/exif_canon.c b/src/exif_canon.c
index 8801899..ee72164 100644
--- a/src/exif_canon.c
+++ b/src/exif_canon.c
@@ -36,26 +36,26 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/* get interesting canon maker note tags in readable form */
-void exc_get_mnote_canon_tags(ExifData *ed, unsigned int tag, char * buffer, unsigned int maxsize)
+void exc_get_mnote_canon_tags(ExifData * ed, unsigned int tag,
+ char *buffer, unsigned int maxsize)
{
- /* char buf[EXIF_STD_BUF_LEN];
+ /* char buf[EXIF_STD_BUF_LEN];
- buf[0] = '\0';
- exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_FLASH, buf, sizeof(buf));
- exif_trim_spaces(buf); */
+ buf[0] = '\0';
+ exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_FLASH, buf, sizeof(buf));
+ exif_trim_spaces(buf); */
- switch(tag)
- {
- default:
- {
- /* normal makernote tags without special treatment */
- exif_get_mnote_tag(ed, tag, buffer, maxsize);
- }
- break;
- }
+ switch (tag) {
+ default:
+ {
+ /* normal makernote tags without special treatment */
+ exif_get_mnote_tag(ed, tag, buffer, maxsize);
+ }
+ break;
+ }
- return;
+ return;
}
#endif
diff --git a/src/exif_canon.h b/src/exif_canon.h
index d8682c3..58ecc0e 100644
--- a/src/exif_canon.h
+++ b/src/exif_canon.h
@@ -28,6 +28,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <libexif/exif-data.h>
-extern void exc_get_mnote_canon_tags(ExifData *ed, unsigned int tag, char * buffer, unsigned int maxsize);
+extern void exc_get_mnote_canon_tags(ExifData * ed, unsigned int tag,
+ char *buffer, unsigned int maxsize);
#endif
diff --git a/src/exif_cfg.h b/src/exif_cfg.h
index a961147..0a13fa3 100644
--- a/src/exif_cfg.h
+++ b/src/exif_cfg.h
@@ -28,78 +28,43 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <libexif/exif-data.h>
-typedef struct
-{
- ExifIfd ifd; /* section */
- ExifTag tag; /* tag */
-} t_EXIF_INFO;
-
-
-/* show these standard tags. section must be given first, than the tag itself */
-/* definition: http://libexif.sourceforge.net/api/exif-tag_8h.html */
-const t_EXIF_INFO Exif_tag_list [] =
-{
- {EXIF_IFD_0, EXIF_TAG_MAKE},
- {EXIF_IFD_0, EXIF_TAG_MODEL},
- {EXIF_IFD_0, EXIF_TAG_IMAGE_DESCRIPTION},
- {EXIF_IFD_EXIF, EXIF_TAG_DATE_TIME_ORIGINAL},
- {EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_TIME},
- {EXIF_IFD_EXIF, EXIF_TAG_SHUTTER_SPEED_VALUE},
- {EXIF_IFD_EXIF, EXIF_TAG_FNUMBER},
- {EXIF_IFD_EXIF, EXIF_TAG_APERTURE_VALUE},
- {EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_BIAS_VALUE},
- {EXIF_IFD_EXIF, EXIF_TAG_ISO_SPEED_RATINGS},
- {EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH},
- {EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM},
- {EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_MODE},
- {EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_PROGRAM},
- {EXIF_IFD_EXIF, EXIF_TAG_SCENE_CAPTURE_TYPE},
- {EXIF_IFD_EXIF, EXIF_TAG_FLASH},
-
- {EXIF_IFD_COUNT, 0} /* end marker */
-};
+/* Nikon */
+#define EXIF_NIKON_MAKERNOTE_END 0 /* end marker: if 0 used as a tag we must find something else */
+/* show these nikon makernote tags */
+const unsigned int Exif_makernote_nikon_tag_list[] = {
-/* Nikon */
+ 6,
+ 8, /* Flash Setting */
+ 9, /* Flash Mode */
+ 135, /* Flash used */
+ 18, /* Flash Exposure Comp */
+ 168, /* Flash info: control mode */
-#define EXIF_NIKON_MAKERNOTE_END 0 /* end marker: if 0 used as a tag we must find something else */
+ 2, /* ISO. Has some more info than EXIF_TAG_ISO_SPEED_RATINGS but also fails on Lo.1 */
+ 5, /* White Balance */
+ 132, /* Lens */
+ 171, /* Digital Vari-Program */
+ 34, /* Active D-Lighting */
-/* show these nikon makernote tags */
-const unsigned int Exif_makernote_nikon_tag_list [] =
-{
-
- 6,
- 8, /* Flash Setting */
- 9, /* Flash Mode */
- 135, /* Flash used */
- 18, /* Flash Exposure Comp */
- 168, /* Flash info: control mode */
-
- 2, /* ISO. Has some more info than EXIF_TAG_ISO_SPEED_RATINGS but also fails on Lo.1 */
- 5, /* White Balance */
- 132, /* Lens */
- 171, /* Digital Vari-Program */
- 34, /* Active D-Lighting */
-
- 35, /* PictureControlData */
- 183, /* AFInfo2 */
-
- EXIF_NIKON_MAKERNOTE_END /* end marker */
+ 35, /* PictureControlData */
+ 183, /* AFInfo2 */
+
+ EXIF_NIKON_MAKERNOTE_END /* end marker */
};
/* Canon */
-#define EXIF_CANON_MAKERNOTE_END 0xFFFF /* end marker: if this is used as a tag we must find something else */
+#define EXIF_CANON_MAKERNOTE_END 0xFFFF /* end marker: if this is used as a tag we must find something else */
/* show these canon makernote tags */
-const unsigned int Exif_makernote_canon_tag_list [] =
-{
- 8, /* Image Number */
- 9, /* Owner Name */
-
- EXIF_CANON_MAKERNOTE_END /* end marker */
+const unsigned int Exif_makernote_canon_tag_list[] = {
+ 8, /* Image Number */
+ 9, /* Owner Name */
+
+ EXIF_CANON_MAKERNOTE_END /* end marker */
};
diff --git a/src/exif_nikon.c b/src/exif_nikon.c
index c058d8c..a81f290 100644
--- a/src/exif_nikon.c
+++ b/src/exif_nikon.c
@@ -37,12 +37,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/* Flash control mode */
/* http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html#FlashControlMode */
#define EXN_FLASH_CONTROL_MODES_MAX 9
-char *EXN_NikonFlashControlModeValues[EXN_FLASH_CONTROL_MODES_MAX] = {"Off",
- "iTTL-BL", "iTTL", "Auto Aperture",
- "Automatic", "GN (distance priority)",
- "Manual", "Repeating Flash",
- "N/A" /* "N/A" is not a nikon setting */
- };
+char *EXN_NikonFlashControlModeValues[EXN_FLASH_CONTROL_MODES_MAX] =
+ { "Off",
+ "iTTL-BL", "iTTL", "Auto Aperture",
+ "Automatic", "GN (distance priority)",
+ "Manual", "Repeating Flash",
+ "N/A" /* "N/A" is not a nikon setting */
+};
#define EXN_FLASH_CONTROL_MODE_MASK 0x7F
@@ -50,280 +51,302 @@ char *EXN_NikonFlashControlModeValues[EXN_FLASH_CONTROL_MODES_MAX] = {"Off",
/* AFInfo2 */
/* http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html#AFInfo2 */
#define EXN_CONTRAST_DETECT_AF_MAX 2
-char *EXN_NikonContrastDetectAF[EXN_CONTRAST_DETECT_AF_MAX] = {"Off", "On"};
+char *EXN_NikonContrastDetectAF[EXN_CONTRAST_DETECT_AF_MAX] =
+ { "Off", "On" };
/* AFArea Mode for ContrastDetectAF Off */
#define EXN_AF_AREA_MODE_P_MAX 13
char *EXN_NikonAFAreaModePhase[EXN_AF_AREA_MODE_P_MAX] = {
- "Single Area", "Dynamic Area", "Dynamic Area (closest subject)",
- "Group Dynamic ", "Dynamic Area (9 points) ", "Dynamic Area (21 points)",
- "Dynamic Area (51 points) ", "Dynamic Area (51 points, 3D-tracking)",
- "Auto-area", "Dynamic Area (3D-tracking)", "Single Area (wide)",
- "Dynamic Area (wide)", "Dynamic Area (wide, 3D-tracking)"};
+ "Single Area", "Dynamic Area", "Dynamic Area (closest subject)",
+ "Group Dynamic ", "Dynamic Area (9 points) ",
+ "Dynamic Area (21 points)",
+ "Dynamic Area (51 points) ",
+ "Dynamic Area (51 points, 3D-tracking)",
+ "Auto-area", "Dynamic Area (3D-tracking)", "Single Area (wide)",
+ "Dynamic Area (wide)", "Dynamic Area (wide, 3D-tracking)"
+};
/* AFArea Mode for ContrastDetectAF On */
#define EXN_AF_AREA_MODE_C_MAX 5
char *EXN_NikonAFAreaModeContr[EXN_AF_AREA_MODE_C_MAX] = {
- "Contrast-detect",
- "Contrast-detect (normal area)",
- "Contrast-detect (wide area)",
- "Contrast-detect (face priority)",
- "Contrast-detect (subject tracking)"};
+ "Contrast-detect",
+ "Contrast-detect (normal area)",
+ "Contrast-detect (wide area)",
+ "Contrast-detect (face priority)",
+ "Contrast-detect (subject tracking)"
+};
#define EXN_PHASE_DETECT_AF_MAX 4
-char *EXN_NikonPhaseDetectAF[EXN_PHASE_DETECT_AF_MAX] = {"Off", "On (51-point)",
- "On (11-point)", "On (39-point)"};
+char *EXN_NikonPhaseDetectAF[EXN_PHASE_DETECT_AF_MAX] =
+ { "Off", "On (51-point)",
+ "On (11-point)", "On (39-point)"
+};
/* PrimaryAFPoint and AFPointsUsed only valid with PhaseDetectAF == On */
#define EXN_PRIM_AF_PT_51_MAX 52
-char * EXN_Prim_AF_Pt_51[EXN_PRIM_AF_PT_51_MAX] = {"(none)", "C6 (Center)", "B6", "A5",
- "D6", "E5", "C7", "B7", "A6", "D7", "E6", "C5", "B5", "A4", "D5", "E4", "C8", "B8",
- "A7", "D8", "E7", "C9", "B9", "A8", "D9", "E8", "C10", "B10", "A9", "D10", "E9",
- "C11", "B11", "D11", "C4", "B4", "A3", "D4", "E3", "C3", "B3", "A2", "D3", "E2",
- "C2", "B2", "A1", "D2", "E1", "C1", "B1", "D1"};
-
+char *EXN_Prim_AF_Pt_51[EXN_PRIM_AF_PT_51_MAX] =
+ { "(none)", "C6 (Center)", "B6", "A5",
+ "D6", "E5", "C7", "B7", "A6", "D7", "E6", "C5", "B5", "A4", "D5",
+ "E4", "C8", "B8",
+ "A7", "D8", "E7", "C9", "B9", "A8", "D9", "E8", "C10", "B10", "A9",
+ "D10", "E9",
+ "C11", "B11", "D11", "C4", "B4", "A3", "D4", "E3", "C3", "B3",
+ "A2", "D3", "E2",
+ "C2", "B2", "A1", "D2", "E1", "C1", "B1", "D1"
+};
+
#define EXN_PRIM_AF_PT_11_MAX 12
-char * EXN_Prim_AF_Pt_11[EXN_PRIM_AF_PT_11_MAX] = {"(none)", "Center", "Top", "Bottom",
- "Mid-left", "Upper-left", "Lower-left", "Far Left", "Mid-right", "Upper-right",
- "Lower-right", "Far Right"};
+char *EXN_Prim_AF_Pt_11[EXN_PRIM_AF_PT_11_MAX] =
+ { "(none)", "Center", "Top", "Bottom",
+ "Mid-left", "Upper-left", "Lower-left", "Far Left", "Mid-right",
+ "Upper-right",
+ "Lower-right", "Far Right"
+};
#define EXN_PRIM_AF_PT_39_MAX 40
-char * EXN_Prim_AF_Pt_39[EXN_PRIM_AF_PT_39_MAX] = {"(none)", "C6 (Center)", "B6", "A2",
- "D6", "E2", "C7", "B7", "A3", "D7", "E3", "C5", "B5", "A1", "D5", "E1", "C8", "B8",
- "D8", "C9", "B9", "D9", "C10", "B10", "D10", "C11", "B11", "D11", "C4", "B4", "D4",
- "C3", "B3", "D3", "C2", "B2", "D2", "C1", "B1", "D1"};
+char *EXN_Prim_AF_Pt_39[EXN_PRIM_AF_PT_39_MAX] =
+ { "(none)", "C6 (Center)", "B6", "A2",
+ "D6", "E2", "C7", "B7", "A3", "D7", "E3", "C5", "B5", "A1", "D5",
+ "E1", "C8", "B8",
+ "D8", "C9", "B9", "D9", "C10", "B10", "D10", "C11", "B11", "D11",
+ "C4", "B4", "D4",
+ "C3", "B3", "D3", "C2", "B2", "D2", "C1", "B1", "D1"
+};
#define EXN_PIC_CTRL_ADJ_MAX 3
-char * EXN_Pic_Ctrl_Adj[EXN_PIC_CTRL_ADJ_MAX] = {"Default Settings",
- "Quick Adjust",
- "Full Control"};
+char *EXN_Pic_Ctrl_Adj[EXN_PIC_CTRL_ADJ_MAX] = { "Default Settings",
+ "Quick Adjust",
+ "Full Control"
+};
static void exn_get_prim_af_pt(unsigned int phasedetectaf,
- unsigned int primafpt,
- char * buffer,
- unsigned int maxsize);
-static void exn_get_flash_output(unsigned int flashoutput, char * buffer, unsigned int maxsize);
-static void exn_get_mnote_nikon_18(ExifData *ed, char * buffer, unsigned int maxsize);
-static void exn_get_mnote_nikon_34(ExifData *ed, char * buffer, unsigned int maxsize);
-static void exn_get_mnote_nikon_35(ExifData *ed, char * buffer, unsigned int maxsize);
-static void exn_get_mnote_nikon_168(ExifData *ed, char * buffer, unsigned int maxsize);
-static void exn_get_mnote_nikon_183(ExifData *ed, char * buffer, unsigned int maxsize);
+ unsigned int primafpt,
+ char *buffer, unsigned int maxsize);
+static void exn_get_flash_output(unsigned int flashoutput, char *buffer,
+ unsigned int maxsize);
+static void exn_get_mnote_nikon_18(ExifData * ed, char *buffer,
+ unsigned int maxsize);
+static void exn_get_mnote_nikon_34(ExifData * ed, char *buffer,
+ unsigned int maxsize);
+static void exn_get_mnote_nikon_35(ExifData * ed, char *buffer,
+ unsigned int maxsize);
+static void exn_get_mnote_nikon_168(ExifData * ed, char *buffer,
+ unsigned int maxsize);
+static void exn_get_mnote_nikon_183(ExifData * ed, char *buffer,
+ unsigned int maxsize);
/* get primary AF point */
static void exn_get_prim_af_pt(unsigned int phasedetectaf,
- unsigned int primafpt,
- char * buffer,
- unsigned int maxsize)
+ unsigned int primafpt,
+ char *buffer, unsigned int maxsize)
{
-
- switch(phasedetectaf)
- {
- case 0:
- {
- /* phasedetect not used. should not happen */
- snprintf(buffer, maxsize, "FAIL");
- return;
- }
- break;
- case 1:
- {
- /* 51 pt */
- if ( primafpt < EXN_PRIM_AF_PT_51_MAX )
- {
- snprintf(buffer, maxsize, "%s", EXN_Prim_AF_Pt_51[primafpt]);
- }
- return;
- }
- break;
- case 2:
- {
- /* 11 pt */
- if ( primafpt < EXN_PRIM_AF_PT_11_MAX )
- {
- snprintf(buffer, maxsize, "%s", EXN_Prim_AF_Pt_11[primafpt]);
- }
- return;
- }
- break;
- case 3:
- {
- /* 39 pt */
- if ( primafpt < EXN_PRIM_AF_PT_39_MAX )
- {
- snprintf(buffer, maxsize, "%s", EXN_Prim_AF_Pt_39[primafpt]);
- }
- return;
- }
- break;
- default:
- {
- snprintf(buffer, maxsize, "?");
- return;
- }
- break;
-
- }
-
+
+ switch (phasedetectaf) {
+ case 0:
+ {
+ /* phasedetect not used. should not happen */
+ snprintf(buffer, maxsize, "FAIL");
+ return;
+ }
+ break;
+ case 1:
+ {
+ /* 51 pt */
+ if (primafpt < EXN_PRIM_AF_PT_51_MAX) {
+ snprintf(buffer, maxsize, "%s",
+ EXN_Prim_AF_Pt_51[primafpt]);
+ }
+ return;
+ }
+ break;
+ case 2:
+ {
+ /* 11 pt */
+ if (primafpt < EXN_PRIM_AF_PT_11_MAX) {
+ snprintf(buffer, maxsize, "%s",
+ EXN_Prim_AF_Pt_11[primafpt]);
+ }
+ return;
+ }
+ break;
+ case 3:
+ {
+ /* 39 pt */
+ if (primafpt < EXN_PRIM_AF_PT_39_MAX) {
+ snprintf(buffer, maxsize, "%s",
+ EXN_Prim_AF_Pt_39[primafpt]);
+ }
+ return;
+ }
+ break;
+ default:
+ {
+ snprintf(buffer, maxsize, "?");
+ return;
+ }
+ break;
+
+ }
+
}
/* get flash output power (for FlashInfo010x) */
-static void exn_get_flash_output(unsigned int flashoutput, char * buffer, unsigned int maxsize)
+static void exn_get_flash_output(unsigned int flashoutput, char *buffer,
+ unsigned int maxsize)
{
-
- if ( flashoutput == 0 )
- {
- /* full power */
- snprintf(buffer, maxsize, "Full");
- }
- else
- {
- if ( (flashoutput % 6) == 0 )
- {
- /* value is a power of 2 */
- snprintf(buffer, maxsize, "1/%d", 1<<(flashoutput/6));
- }
- else
- {
- /* something uneven...ugly. maybe introduce pow() function from libm later */
- snprintf(buffer, maxsize, "1/2^(%f)", ((float)flashoutput)/6.0);
- }
- }
+
+ if (flashoutput == 0) {
+ /* full power */
+ snprintf(buffer, maxsize, "Full");
+ } else {
+ if ((flashoutput % 6) == 0) {
+ /* value is a power of 2 */
+ snprintf(buffer, maxsize, "1/%d",
+ 1 << (flashoutput / 6));
+ } else {
+ /* something uneven...ugly. maybe introduce pow() function from libm later */
+ snprintf(buffer, maxsize, "1/2^(%f)",
+ ((float) flashoutput) / 6.0);
+ }
+ }
}
/* get ActiveD-Lighting (18) info */
-static void exn_get_mnote_nikon_18(ExifData *ed, char * buffer, unsigned int maxsize)
+static void exn_get_mnote_nikon_18(ExifData * ed, char *buffer,
+ unsigned int maxsize)
{
- char buf[EXIF_STD_BUF_LEN];
- float data = 0;
+ char buf[EXIF_STD_BUF_LEN];
+ float data = 0;
- buf[0] = '\0';
- exif_get_mnote_tag(ed, 18, buf, sizeof(buf));
+ buf[0] = '\0';
+ exif_get_mnote_tag(ed, 18, buf, sizeof(buf));
- sscanf(buf, "Flash Exposure Compensation: %f", &data); /* libexif buggy here. fix conversion */
+ sscanf(buf, "Flash Exposure Compensation: %f", &data); /* libexif buggy here. fix conversion */
- snprintf(buffer, maxsize, "FlashExposureCompensation: %+.1f EV\n", ((float)((signed char)round(data*6.0))) / 6.0 );
+ snprintf(buffer, maxsize, "FlashExposureCompensation: %+.1f EV\n",
+ ((float) ((signed char) round(data * 6.0))) / 6.0);
}
/* get ActiveD-Lighting (34) info */
-static void exn_get_mnote_nikon_34(ExifData *ed, char * buffer, unsigned int maxsize)
+static void exn_get_mnote_nikon_34(ExifData * ed, char *buffer,
+ unsigned int maxsize)
{
- char buf[EXIF_STD_BUF_LEN];
- unsigned int data = 0;
- char *answer;
-
- buf[0] = '\0';
- exif_get_mnote_tag(ed, 34, buf, sizeof(buf));
- sscanf(buf, "(null): %u", &data); /* not directly supported by libexif yet */
-
- switch(data)
- {
- case 0:
- {
- answer = "Off";
- }
- break;
- case 1:
- {
- answer = "Low";
- }
- break;
- case 3:
- {
- answer = "Normal";
- }
- break;
- case 5:
- {
- answer = "High";
- }
- break;
- case 7:
- {
- answer = "Extra High";
- }
- break;
- case 65535:
- {
- answer = "Auto";
- }
- break;
- default:
- {
- answer = "N/A"; /* this is not a nikon value */
- }
-
- }
-
- snprintf(buffer, maxsize, "Active D-Lightning: %s\n", answer);
-
+ char buf[EXIF_STD_BUF_LEN];
+ unsigned int data = 0;
+ char *answer;
+
+ buf[0] = '\0';
+ exif_get_mnote_tag(ed, 34, buf, sizeof(buf));
+ sscanf(buf, "(null): %u", &data); /* not directly supported by libexif yet */
+
+ switch (data) {
+ case 0:
+ {
+ answer = "Off";
+ }
+ break;
+ case 1:
+ {
+ answer = "Low";
+ }
+ break;
+ case 3:
+ {
+ answer = "Normal";
+ }
+ break;
+ case 5:
+ {
+ answer = "High";
+ }
+ break;
+ case 7:
+ {
+ answer = "Extra High";
+ }
+ break;
+ case 65535:
+ {
+ answer = "Auto";
+ }
+ break;
+ default:
+ {
+ answer = "N/A"; /* this is not a nikon value */
+ }
+
+ }
+
+ snprintf(buffer, maxsize, "Active D-Lightning: %s\n", answer);
+
}
/* get nikon PictureControlData (35) info */
-static void exn_get_mnote_nikon_35(ExifData *ed, char * buffer, unsigned int maxsize)
+static void exn_get_mnote_nikon_35(ExifData * ed, char *buffer,
+ unsigned int maxsize)
{
- char buf[EXIF_STD_BUF_LEN];
- char picturecontrolname[EXIF_STD_BUF_LEN];
- char picturecontrolbase[EXIF_STD_BUF_LEN];
- unsigned int version = 0;
- unsigned int length = 0;
- unsigned int piccontroladj = 0;
- unsigned int piccontrolquickadj = 0;
- unsigned int sharpness = 0;
- unsigned int contrast = 0;
- unsigned int brightness = 0;
- unsigned int saturation = 0;
- unsigned int hueadjustment = 0;
- unsigned int i, j;
-
- /* libexif does not support PictureControlData 35 yet. so we have to parse the debug data :-( */
- buf[0] = '\0';
- exif_get_mnote_tag(ed, 35, buf, sizeof(buf));
-
- sscanf(buf, "(null): %u bytes unknown data: 303130%02X%40s%40s%*8s%02X%02X%02X%02X%02X%02X%02X",
- &length, &version, &picturecontrolname[0], &picturecontrolbase[0],
- &piccontroladj, &piccontrolquickadj,
- &sharpness, &contrast, &brightness, &saturation, &hueadjustment
- );
-
- /* printf("--%s %d-%d-\n", buf, version, piccontroladj); */
-
- for ( i=0; i<40; i++ )
- {
- sscanf(&picturecontrolname[2*i], "%2X", &j);
- picturecontrolname[i] = j;
- sscanf(&picturecontrolbase[2*i], "%2X", &j);
- picturecontrolbase[i] = j;
-
- }
- exif_trim_spaces(picturecontrolname);
- exif_trim_spaces(picturecontrolbase);
-
- if ( ((length == 58) && (version == '0'))
- && (piccontroladj < EXN_PIC_CTRL_ADJ_MAX)
-
- )
- {
- snprintf(buffer, maxsize,
- "PictCtrlData: Name: %s; Base: %s; CtrlAdj: %s; Quick: %d; Shrp: %d; Contr: %d; Brght: %d; Sat: %d; Hue: %d\n",
- picturecontrolname, picturecontrolbase,
- EXN_Pic_Ctrl_Adj[piccontroladj], piccontrolquickadj,
- sharpness, contrast, brightness, saturation, hueadjustment);
- }
+ char buf[EXIF_STD_BUF_LEN];
+ char picturecontrolname[EXIF_STD_BUF_LEN];
+ char picturecontrolbase[EXIF_STD_BUF_LEN];
+ unsigned int version = 0;
+ unsigned int length = 0;
+ unsigned int piccontroladj = 0;
+ unsigned int piccontrolquickadj = 0;
+ unsigned int sharpness = 0;
+ unsigned int contrast = 0;
+ unsigned int brightness = 0;
+ unsigned int saturation = 0;
+ unsigned int hueadjustment = 0;
+ unsigned int i, j;
+
+ /* libexif does not support PictureControlData 35 yet. so we have to parse the debug data :-( */
+ buf[0] = '\0';
+ exif_get_mnote_tag(ed, 35, buf, sizeof(buf));
+
+ sscanf(buf,
+ "(null): %u bytes unknown data: 303130%02X%40s%40s%*8s%02X%02X%02X%02X%02X%02X%02X",
+ &length, &version, &picturecontrolname[0],
+ &picturecontrolbase[0], &piccontroladj, &piccontrolquickadj,
+ &sharpness, &contrast, &brightness, &saturation,
+ &hueadjustment);
+
+ /* printf("--%s %d-%d-\n", buf, version, piccontroladj); */
+
+ for (i = 0; i < 40; i++) {
+ sscanf(&picturecontrolname[2 * i], "%2X", &j);
+ picturecontrolname[i] = j;
+ sscanf(&picturecontrolbase[2 * i], "%2X", &j);
+ picturecontrolbase[i] = j;
+
+ }
+ exif_trim_spaces(picturecontrolname);
+ exif_trim_spaces(picturecontrolbase);
+
+ if (((length == 58) && (version == '0'))
+ && (piccontroladj < EXN_PIC_CTRL_ADJ_MAX)
+ ) {
+ snprintf(buffer, maxsize,
+ "PictCtrlData: Name: %s; Base: %s; CtrlAdj: %s; Quick: %d; Shrp: %d; Contr: %d; Brght: %d; Sat: %d; Hue: %d\n",
+ picturecontrolname, picturecontrolbase,
+ EXN_Pic_Ctrl_Adj[piccontroladj],
+ piccontrolquickadj, sharpness, contrast,
+ brightness, saturation, hueadjustment);
+ }
}
@@ -331,180 +354,189 @@ static void exn_get_mnote_nikon_35(ExifData *ed, char * buffer, unsigned int max
/* get nikon Flash info: control mode (168) info */
-static void exn_get_mnote_nikon_168(ExifData *ed, char * buffer, unsigned int maxsize)
+static void exn_get_mnote_nikon_168(ExifData * ed, char *buffer,
+ unsigned int maxsize)
{
- char buf[EXIF_STD_BUF_LEN];
- unsigned int version = 0;
- unsigned int length = 0;
- unsigned int exn_fcm = (EXN_FLASH_CONTROL_MODES_MAX-1); /* default to N/A */
- unsigned int flashoutput = 0;
- unsigned int externalflashflags = 0;
- unsigned int flashcompensation = 0;
-
- /* libexif does not support flash info 168 yet. so we have to parse the debug data :-( */
- buf[0] = '\0';
- exif_get_mnote_tag(ed, 168, buf, sizeof(buf));
- sscanf(buf, "(null): %u bytes unknown data: 303130%02X%*8s%02X%02X%02X%02X", &length, &version, &externalflashflags, &exn_fcm, &flashoutput, &flashcompensation);
- exn_fcm = exn_fcm & EXN_FLASH_CONTROL_MODE_MASK;
-
- /* printf("%s - %d %d %d %d\n", buf, externalflashflags, exn_fcm, flashoutput, (signed char)flashcompensation); */
-
- if ( (exn_fcm < EXN_FLASH_CONTROL_MODES_MAX)
- && ( ((length == 22) && (version == '3')) /* Nikon FlashInfo0103 */
- || ((length == 22) && (version == '4')) /* Nikon FlashInfo0104 */
- || ((length == 21) && (version == '2')) /* Nikon FlashInfo0102 */
- || ((length == 19) && (version == '0')) /* Nikon FlashInfo0100 */
- )
- )
- {
-
- buf[0] = '\0';
- exn_get_flash_output(flashoutput, buf, EXIF_STD_BUF_LEN);
- snprintf(buffer, maxsize, "NikonFlashControlMode: %s (Power: %s)\n", EXN_NikonFlashControlModeValues[exn_fcm], buf);
-
- /* External Flash Flags. Not as useful as expected. Not used (yet). */
- /* if ( (externalflashflags & (1<<2)) ) -> Bounce Flash */
- /* if ( (externalflashflags & (1<<4)) ) -> Wide Flash Adapter */
- /* if ( (externalflashflags & (1<<5)) ) -> Dome Diffusor */
-
- }
+ char buf[EXIF_STD_BUF_LEN];
+ unsigned int version = 0;
+ unsigned int length = 0;
+ unsigned int exn_fcm = (EXN_FLASH_CONTROL_MODES_MAX - 1); /* default to N/A */
+ unsigned int flashoutput = 0;
+ unsigned int externalflashflags = 0;
+ unsigned int flashcompensation = 0;
+
+ /* libexif does not support flash info 168 yet. so we have to parse the debug data :-( */
+ buf[0] = '\0';
+ exif_get_mnote_tag(ed, 168, buf, sizeof(buf));
+ sscanf(buf,
+ "(null): %u bytes unknown data: 303130%02X%*8s%02X%02X%02X%02X",
+ &length, &version, &externalflashflags, &exn_fcm,
+ &flashoutput, &flashcompensation);
+ exn_fcm = exn_fcm & EXN_FLASH_CONTROL_MODE_MASK;
+
+ /* printf("%s - %d %d %d %d\n", buf, externalflashflags, exn_fcm, flashoutput, (signed char)flashcompensation); */
+
+ if ((exn_fcm < EXN_FLASH_CONTROL_MODES_MAX)
+ && (((length == 22) && (version == '3')) /* Nikon FlashInfo0103 */
+ ||((length == 22) && (version == '4')) /* Nikon FlashInfo0104 */
+ ||((length == 21) && (version == '2')) /* Nikon FlashInfo0102 */
+ ||((length == 19) && (version == '0')) /* Nikon FlashInfo0100 */
+ )
+ ) {
+
+ buf[0] = '\0';
+ exn_get_flash_output(flashoutput, buf, EXIF_STD_BUF_LEN);
+ snprintf(buffer, maxsize,
+ "NikonFlashControlMode: %s (Power: %s)\n",
+ EXN_NikonFlashControlModeValues[exn_fcm], buf);
+
+ /* External Flash Flags. Not as useful as expected. Not used (yet). */
+ /* if ( (externalflashflags & (1<<2)) ) -> Bounce Flash */
+ /* if ( (externalflashflags & (1<<4)) ) -> Wide Flash Adapter */
+ /* if ( (externalflashflags & (1<<5)) ) -> Dome Diffusor */
+
+ }
}
/* get nikon AFInfo2 (183) info */
-static void exn_get_mnote_nikon_183(ExifData *ed, char * buffer, unsigned int maxsize)
+static void exn_get_mnote_nikon_183(ExifData * ed, char *buffer,
+ unsigned int maxsize)
{
- char buf[EXIF_STD_BUF_LEN];
- unsigned int contrastdetectaf = 0;
- unsigned int afareamode = 0;
- unsigned int phasedetectaf = 0;
- unsigned int primaryafpoint = 0;
- unsigned int version = 0;
- unsigned int length = 0;
-
- /* AFInfo2 */
- /* libexif does not support AFInfo2 183 yet. so we have to parse the debug data :-( */
- buf[0] = '\0';
- exif_get_mnote_tag(ed, 183, buf, sizeof(buf));
- sscanf(buf, "(null): %u bytes unknown data: 303130%02X%02X%02X%02X%02X", &length, &version,
- &contrastdetectaf,
- &afareamode,
- &phasedetectaf,
- &primaryafpoint
- );
-
-
- if ( ((length == 30) && (version == '0'))
- && (contrastdetectaf < EXN_CONTRAST_DETECT_AF_MAX)
- && (phasedetectaf < EXN_PHASE_DETECT_AF_MAX)
- )
- {
- if ( (contrastdetectaf != 0) && (afareamode < EXN_AF_AREA_MODE_C_MAX) )
- {
- /* Contrast AF (live view) */
- snprintf(buffer, maxsize,
- "ContrastDetectAF: %s; AFAreaMode: %s\n",
- EXN_NikonContrastDetectAF[contrastdetectaf],
- EXN_NikonAFAreaModeContr[afareamode]);
-
- }
- else if ( (phasedetectaf != 0) && (afareamode < EXN_AF_AREA_MODE_P_MAX) )
- {
- /* Phase AF */
- buf[0] = '\0';
- exn_get_prim_af_pt(phasedetectaf, primaryafpoint, buf, EXIF_STD_BUF_LEN);
-
- snprintf(buffer, maxsize,
- "PhaseDetectAF: %s; AreaMode: %s; PrimaryAFPoint: %s\n",
- EXN_NikonPhaseDetectAF[phasedetectaf],
- EXN_NikonAFAreaModePhase[afareamode],
- buf
- );
- }
-
- }
+ char buf[EXIF_STD_BUF_LEN];
+ unsigned int contrastdetectaf = 0;
+ unsigned int afareamode = 0;
+ unsigned int phasedetectaf = 0;
+ unsigned int primaryafpoint = 0;
+ unsigned int version = 0;
+ unsigned int length = 0;
+
+ /* AFInfo2 */
+ /* libexif does not support AFInfo2 183 yet. so we have to parse the debug data :-( */
+ buf[0] = '\0';
+ exif_get_mnote_tag(ed, 183, buf, sizeof(buf));
+ sscanf(buf,
+ "(null): %u bytes unknown data: 303130%02X%02X%02X%02X%02X",
+ &length, &version, &contrastdetectaf, &afareamode,
+ &phasedetectaf, &primaryafpoint);
+
+
+ if (((length == 30) && (version == '0'))
+ && (contrastdetectaf < EXN_CONTRAST_DETECT_AF_MAX)
+ && (phasedetectaf < EXN_PHASE_DETECT_AF_MAX)
+ ) {
+ if ((contrastdetectaf != 0)
+ && (afareamode < EXN_AF_AREA_MODE_C_MAX)) {
+ /* Contrast AF (live view) */
+ snprintf(buffer, maxsize,
+ "ContrastDetectAF: %s; AFAreaMode: %s\n",
+ EXN_NikonContrastDetectAF
+ [contrastdetectaf],
+ EXN_NikonAFAreaModeContr[afareamode]);
+
+ } else if ((phasedetectaf != 0)
+ && (afareamode < EXN_AF_AREA_MODE_P_MAX)) {
+ /* Phase AF */
+ buf[0] = '\0';
+ exn_get_prim_af_pt(phasedetectaf, primaryafpoint,
+ buf, EXIF_STD_BUF_LEN);
+
+ snprintf(buffer, maxsize,
+ "PhaseDetectAF: %s; AreaMode: %s; PrimaryAFPoint: %s\n",
+ EXN_NikonPhaseDetectAF[phasedetectaf],
+ EXN_NikonAFAreaModePhase[afareamode],
+ buf);
+ }
+
+ }
}
/* get interesting nikon maker note tags in readable form */
-void exn_get_mnote_nikon_tags(ExifData *ed, unsigned int tag, char * buffer, unsigned int maxsize)
+void exn_get_mnote_nikon_tags(ExifData * ed, unsigned int tag,
+ char *buffer, unsigned int maxsize)
{
- char buf[EXIF_STD_BUF_LEN];
-
- buf[0] = '\0';
- exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_FLASH, buf, sizeof(buf));
- exif_trim_spaces(buf);
-
- switch(tag)
- {
- /* show only if flash was used */
- case 8: /* Flash Setting */
- case 9: /* Flash Mode */
- case 135: /* Flash used */
- {
- if ( !(strcmp("Flash: Flash did not fire\n", buf) == 0) )
- {
- /* show extended flash info only if flash was fired */
- exif_get_mnote_tag(ed, tag, buffer, maxsize);
- }
- }
- break;
-
- case 18: /* FlashExposureComp */
- {
- if ( !(strcmp("Flash: Flash did not fire\n", buf) == 0) )
- {
- /* show only if flash was fired */
- exn_get_mnote_nikon_18(ed, buffer, maxsize);
- }
- }
- break;
-
- case 34:
- {
- /* ActiveD-Lighting */
- exn_get_mnote_nikon_34(ed, buffer, maxsize);
- }
- break;
-
- case 35:
- {
- /* PictureControlData */
- exn_get_mnote_nikon_35(ed, buffer, maxsize);
- }
- break;
-
- case 168:
- {
- /* Flash info: control mode */
- if ( !(strcmp("Flash: Flash did not fire\n", buf) == 0) )
- {
- /* show extended flash info only if flash was fired */
- exn_get_mnote_nikon_168(ed, buffer, maxsize);
- }
- }
- break;
-
- case 183:
- {
- /* AFInfo 2 */
- exn_get_mnote_nikon_183(ed, buffer, maxsize);
- }
- break;
-
- default:
- {
- /* normal makernote tags without special treatment */
- exif_get_mnote_tag(ed, tag, buffer, maxsize);
- }
- break;
- }
-
-
- return;
+ char buf[EXIF_STD_BUF_LEN];
+
+ buf[0] = '\0';
+ exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_FLASH, buf, sizeof(buf));
+ exif_trim_spaces(buf);
+
+ switch (tag) {
+ /* show only if flash was used */
+ case 8: /* Flash Setting */
+ case 9: /* Flash Mode */
+ case 135: /* Flash used */
+ {
+ if (!
+ (strcmp("Flash: Flash did not fire\n", buf) ==
+ 0)) {
+ /* show extended flash info only if flash was fired */
+ exif_get_mnote_tag(ed, tag, buffer,
+ maxsize);
+ }
+ }
+ break;
+
+ case 18: /* FlashExposureComp */
+ {
+ if (!
+ (strcmp("Flash: Flash did not fire\n", buf) ==
+ 0)) {
+ /* show only if flash was fired */
+ exn_get_mnote_nikon_18(ed, buffer,
+ maxsize);
+ }
+ }
+ break;
+
+ case 34:
+ {
+ /* ActiveD-Lighting */
+ exn_get_mnote_nikon_34(ed, buffer, maxsize);
+ }
+ break;
+
+ case 35:
+ {
+ /* PictureControlData */
+ exn_get_mnote_nikon_35(ed, buffer, maxsize);
+ }
+ break;
+
+ case 168:
+ {
+ /* Flash info: control mode */
+ if (!
+ (strcmp("Flash: Flash did not fire\n", buf) ==
+ 0)) {
+ /* show extended flash info only if flash was fired */
+ exn_get_mnote_nikon_168(ed, buffer,
+ maxsize);
+ }
+ }
+ break;
+
+ case 183:
+ {
+ /* AFInfo 2 */
+ exn_get_mnote_nikon_183(ed, buffer, maxsize);
+ }
+ break;
+
+ default:
+ {
+ /* normal makernote tags without special treatment */
+ exif_get_mnote_tag(ed, tag, buffer, maxsize);
+ }
+ break;
+ }
+
+
+ return;
}
#endif
diff --git a/src/exif_nikon.h b/src/exif_nikon.h
index 16e8fb9..49d14b6 100644
--- a/src/exif_nikon.h
+++ b/src/exif_nikon.h
@@ -28,6 +28,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <libexif/exif-data.h>
-extern void exn_get_mnote_nikon_tags(ExifData *ed, unsigned int tag, char * buffer, unsigned int maxsize);
+extern void exn_get_mnote_nikon_tags(ExifData * ed, unsigned int tag,
+ char *buffer, unsigned int maxsize);
#endif
diff --git a/src/feh.h b/src/feh.h
index e735871..54e78ea 100644
--- a/src/feh.h
+++ b/src/feh.h
@@ -1,7 +1,7 @@
/* feh.h
Copyright (C) 1999-2003 Tom Gilbert.
-Copyright (C) 2010-2020 Daniel Friesel.
+Copyright (C) 2010-2020 Birte Kristina Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -63,6 +63,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <signal.h>
#include <sys/wait.h>
#include <math.h>
+#include <getopt.h>
#include <Imlib2.h>
#include "gib_hash.h"
@@ -74,7 +75,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "menu.h"
#include "utils.h"
-#include "getopt.h"
#include "debug.h"
@@ -115,6 +115,14 @@ enum slide_change { SLIDE_NEXT, SLIDE_PREV, SLIDE_RAND, SLIDE_FIRST, SLIDE_LAST,
SLIDE_JUMP_PREV_DIR
};
+enum feh_load_error {
+ LOAD_ERROR_IMLIB = 0,
+ LOAD_ERROR_IMAGEMAGICK,
+ LOAD_ERROR_CURL,
+ LOAD_ERROR_DCRAW,
+ LOAD_ERROR_MAGICBYTES
+};
+
#define INPLACE_EDIT_FLIP -1
#define INPLACE_EDIT_MIRROR -2
@@ -137,6 +145,10 @@ void init_slideshow_mode(void);
void init_list_mode(void);
void init_loadables_mode(void);
void init_unloadables_mode(void);
+#ifdef HAVE_LIBMAGIC
+void uninit_magic(void);
+void init_magic(void);
+#endif
void feh_clean_exit(void);
int feh_should_ignore_image(Imlib_Image * im);
int feh_load_image(Imlib_Image * im, feh_file * file);
@@ -148,7 +160,7 @@ void init_buttonbindings(void);
void setup_stdin(void);
void restore_stdin(void);
void feh_event_handle_keypress(XEvent * ev);
-void feh_event_handle_stdin();
+void feh_event_handle_stdin(void);
void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysym, unsigned int button);
fehkey *feh_str_to_kb(char * action);
void feh_action_run(feh_file * file, char *action, winwidget winwid);
@@ -172,7 +184,7 @@ void feh_display_status(char stat);
void real_loadables_mode(int loadable);
void feh_reload_image(winwidget w, int resize, int force_new);
void feh_filelist_image_remove(winwidget winwid, char do_delete);
-void feh_imlib_print_load_error(char *file, winwidget w, Imlib_Load_Error err);
+void feh_print_load_error(char *file, winwidget w, Imlib_Load_Error err, enum feh_load_error feh_err);
void slideshow_save_image(winwidget win);
void feh_edit_inplace(winwidget w, int orientation);
void feh_edit_inplace_lossless(winwidget w, int orientation);
diff --git a/src/feh_png.c b/src/feh_png.c
index d0c1c8a..8f5b94d 100644
--- a/src/feh_png.c
+++ b/src/feh_png.c
@@ -197,7 +197,10 @@ int feh_png_file_is_png(FILE * fp)
{
unsigned char buf[8];
- fread(buf, 1, 8, fp);
+ if (fread(buf, 1, 8, fp) != 8) {
+ return 0;
+ }
+
if (png_sig_cmp(buf, 0, 8)) {
return 0;
}
diff --git a/src/filelist.c b/src/filelist.c
index 361ac19..f1e820c 100644
--- a/src/filelist.c
+++ b/src/filelist.c
@@ -1,7 +1,7 @@
/* filelist.c
Copyright (C) 1999-2003 Tom Gilbert.
-Copyright (C) 2010-2020 Daniel Friesel.
+Copyright (C) 2010-2020 Birte Kristina Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -24,20 +24,19 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#ifdef HAVE_LIBEXIF
-#include <libexif/exif-data.h>
-#endif
-
#include "feh.h"
#include "filelist.h"
#include "signals.h"
#include "options.h"
+#ifdef HAVE_LIBCURL
+#include <curl/curl.h>
+#endif
+
gib_list *filelist = NULL;
gib_list *original_file_items = NULL; /* original file items from argv */
int filelist_len = 0;
gib_list *current_file = NULL;
-extern int errno;
static gib_list *rm_filelist = NULL;
@@ -156,7 +155,7 @@ static void feh_print_stat_error(char *path)
}
}
-static void add_stdin_to_filelist()
+static void add_stdin_to_filelist(void)
{
char buf[1024];
size_t readsize;
@@ -181,6 +180,7 @@ static void add_stdin_to_filelist()
while ((readsize = fread(buf, sizeof(char), sizeof(buf), stdin)) > 0) {
if (fwrite(buf, sizeof(char), readsize, outfile) < readsize) {
free(sfn);
+ fclose(outfile);
return;
}
}
@@ -198,7 +198,7 @@ void add_file_to_filelist_recursively(char *origpath, unsigned char level)
struct stat st;
char *path;
- if (!origpath)
+ if (!origpath || *origpath == '\0')
return;
path = estrdup(origpath);
@@ -398,7 +398,7 @@ void feh_file_dirname(char *dst, feh_file * f, int maxlen)
return;
}
- strncpy(dst, f->filename, n);
+ memcpy(dst, f->filename, n);
dst[n] = '\0';
}
@@ -641,12 +641,13 @@ char *feh_absolute_path(char *path)
filelist file can be saved anywhere and feh will still find the
images */
D(("Need to convert %s to an absolute form\n", path));
- /* I SHOULD be able to just use a simple realpath() here, but dumb *
+ /* I SHOULD be able to just use a simple realpath() here, but dumb *
old Solaris's realpath doesn't return an absolute path if the
path you give it is relative. Linux and BSD get this right... */
if (getcwd(cwd, sizeof(cwd)) == NULL)
eprintf("Cannot determine working directory:");
- snprintf(temp, sizeof(temp), "%s/%s", cwd, path);
+ if ((size_t) snprintf(temp, sizeof(temp), "%s/%s", cwd, path) >= sizeof(temp))
+ eprintf("Absolute path for working directory was truncated");
if (realpath(temp, fullpath) != NULL) {
ret = estrdup(fullpath);
} else {
@@ -656,11 +657,20 @@ char *feh_absolute_path(char *path)
return(ret);
}
-void feh_save_filelist()
+void feh_save_filelist(void)
{
char *tmpname;
+ char *base_dir = "";
- tmpname = feh_unique_filename("", "filelist");
+ if (opt.output_dir) {
+ base_dir = estrjoin("", opt.output_dir, "/", NULL);
+ }
+
+ tmpname = feh_unique_filename(base_dir, "filelist");
+
+ if (opt.output_dir) {
+ free(base_dir);
+ }
if (opt.verbose)
fprintf(stderr, "saving filelist to filename '%s'\n", tmpname);
@@ -669,3 +679,27 @@ void feh_save_filelist()
free(tmpname);
return;
}
+
+#ifdef HAVE_LIBCURL
+
+char *feh_http_unescape(char *url)
+{
+ CURL *curl = curl_easy_init();
+ if (!curl) {
+ return NULL;
+ }
+ char *tmp_url = curl_easy_unescape(curl, url, 0, NULL);
+ char *new_url = estrdup(tmp_url);
+ curl_free(tmp_url);
+ curl_easy_cleanup(curl);
+ return new_url;
+}
+
+#else
+
+char *feh_http_unescape(char *url)
+{
+ return NULL;
+}
+
+#endif
diff --git a/src/filelist.h b/src/filelist.h
index e24a6a6..7f263dc 100644
--- a/src/filelist.h
+++ b/src/filelist.h
@@ -96,7 +96,8 @@ int feh_write_filelist(gib_list * list, char *filename);
gib_list *feh_read_filelist(char *filename);
char *feh_absolute_path(char *path);
gib_list *feh_file_remove_from_list(gib_list * list, gib_list * l);
-void feh_save_filelist();
+void feh_save_filelist(void);
+char *feh_http_unescape(char * url);
int feh_cmp_name(void *file1, void *file2);
int feh_cmp_dirname(void *file1, void *file2);
diff --git a/src/getopt.c b/src/getopt.c
deleted file mode 100644
index d212b3a..0000000
--- a/src/getopt.c
+++ /dev/null
@@ -1,949 +0,0 @@
-/* Getopt for GNU.
- NOTE: getopt is now part of the C library, so if you don't know what
- "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
- before changing it!
-
- Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97
- Free Software Foundation, Inc.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The GNU C Library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
- Ditto for AIX 3.2 and <stdlib.h>. */
-#ifndef _NO_PROTO
-#define _NO_PROTO
-#endif
-
-#if !defined (__STDC__) || !__STDC__
-/* This is a separate conditional since some stdc systems
- reject `defined (const)'. */
-#ifndef const
-#define const
-#endif
-#endif
-
-#include <stdio.h>
-
-/* Comment out all this code if we are using the GNU C Library, and are not
- actually compiling the library itself. This code is part of the GNU C
- Library, but also included in many other GNU distributions. Compiling
- and linking in this code is a waste when using the GNU C library
- (especially if it is a shared library). Rather than having every GNU
- program understand `configure --with-gnu-libc' and omit the object files,
- it is simpler to just do this in the source for each such file. */
-
-#define GETOPT_INTERFACE_VERSION 2
-#if !defined (_LIBC) && defined (__GLIBC__) && __GLIBC__ >= 2
-#include <gnu-versions.h>
-#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
-#define ELIDE_CODE
-#endif
-#endif
-
-#ifndef ELIDE_CODE
-
-/* This needs to come after some library #include
- to get __GNU_LIBRARY__ defined. */
-#ifdef __GNU_LIBRARY__
-/* Don't include stdlib.h for non-GNU C libraries because some of them
- contain conflicting prototypes for getopt. */
-#include <stdlib.h>
-#include <unistd.h>
-#endif /* GNU C library. */
-
-#ifdef VMS
-#include <unixlib.h>
-#if HAVE_STRING_H - 0
-#include <string.h>
-#endif
-#endif
-
-#ifndef _
-/* This is for other GNU distributions with internationalized messages.
- When compiling libc, the _ macro is predefined. */
-#ifdef HAVE_LIBINTL_H
-# include <libintl.h>
-# define _(msgid) gettext (msgid)
-#else
-# define _(msgid) (msgid)
-#endif
-#endif
-
-/* This version of `getopt' appears to the caller like standard Unix `getopt'
- but it behaves differently for the user, since it allows the user
- to intersperse the options with the other arguments.
-
- As `getopt' works, it permutes the elements of ARGV so that,
- when it is done, all the options precede everything else. Thus
- all application programs are extended to handle flexible argument order.
-
- Setting the environment variable POSIXLY_CORRECT disables permutation.
- Then the behavior is completely standard.
-
- GNU application programs can use a third alternative mode in which
- they can distinguish the relative order of options and other arguments. */
-
-#include "getopt.h"
-
-/* For communication from `getopt' to the caller.
- When `getopt' finds an option that takes an argument,
- the argument value is returned here.
- Also, when `ordering' is RETURN_IN_ORDER,
- each non-option ARGV-element is returned here. */
-
-char *optarg = NULL;
-
-/* Index in ARGV of the next element to be scanned.
- This is used for communication to and from the caller
- and for communication between successive calls to `getopt'.
-
- On entry to `getopt', zero means this is the first call; initialize.
-
- When `getopt' returns -1, this is the index of the first of the
- non-option elements that the caller should itself scan.
-
- Otherwise, `optind' communicates from one call to the next
- how much of ARGV has been scanned so far. */
-
-/* 1003.2 says this must be 1 before any call. */
-int optind = 1;
-
-/* Formerly, initialization of getopt depended on optind==0, which
- causes problems with re-calling getopt as programs generally don't
- know that. */
-
-int __getopt_initialized = 0;
-
-/* The next char to be scanned in the option-element
- in which the last option character we returned was found.
- This allows us to pick up the scan where we left off.
-
- If this is zero, or a null string, it means resume the scan
- by advancing to the next ARGV-element. */
-
-static char *nextchar;
-
-/* Callers store zero here to inhibit the error message
- for unrecognized options. */
-
-int opterr = 1;
-
-/* Set to an option character which was unrecognized.
- This must be initialized on some systems to avoid linking in the
- system's own getopt implementation. */
-
-int optopt = '?';
-
-/* Describe how to deal with options that follow non-option ARGV-elements.
-
- If the caller did not specify anything,
- the default is REQUIRE_ORDER if the environment variable
- POSIXLY_CORRECT is defined, PERMUTE otherwise.
-
- REQUIRE_ORDER means don't recognize them as options;
- stop option processing when the first non-option is seen.
- This is what Unix does.
- This mode of operation is selected by either setting the environment
- variable POSIXLY_CORRECT, or using `+' as the first character
- of the list of option characters.
-
- PERMUTE is the default. We permute the contents of ARGV as we scan,
- so that eventually all the non-options are at the end. This allows options
- to be given in any order, even with programs that were not written to
- expect this.
-
- RETURN_IN_ORDER is an option available to programs that were written
- to expect options and other ARGV-elements in any order and that care about
- the ordering of the two. We describe each non-option ARGV-element
- as if it were the argument of an option with character code 1.
- Using `-' as the first character of the list of option characters
- selects this mode of operation.
-
- The special argument `--' forces an end of option-scanning regardless
- of the value of `ordering'. In the case of RETURN_IN_ORDER, only
- `--' can cause `getopt' to return -1 with `optind' != ARGC. */
-
-static enum {
- REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
-} ordering;
-
-/* Value of POSIXLY_CORRECT environment variable. */
-static char *posixly_correct;
-
-#ifdef __GNU_LIBRARY__
-/* We want to avoid inclusion of string.h with non-GNU libraries
- because there are many ways it can cause trouble.
- On some systems, it contains special magic macros that don't work
- in GCC. */
-#include <string.h>
-#define my_index strchr
-#else
-
-/* Avoid depending on library functions or files
- whose names are inconsistent. */
-
-char *getenv();
-
-static char *my_index(str, chr)
-const char *str;
-int chr;
-{
- while (*str) {
- if (*str == chr)
- return (char *) str;
- str++;
- }
- return 0;
-}
-
-/* If using GCC, we can safely declare strlen this way.
- If not using GCC, it is ok not to declare it. */
-#ifdef __GNUC__
-/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
- That was relevant to code that was here before. */
-#if !defined (__STDC__) || !__STDC__
-/* gcc with -traditional declares the built-in strlen to return int,
- and has done so at least since version 2.4.5. -- rms. */
-extern int strlen(const char *);
-#endif /* not __STDC__ */
-#endif /* __GNUC__ */
-
-#endif /* not __GNU_LIBRARY__ */
-
-/* Handle permutation of arguments. */
-
-/* Describe the part of ARGV that contains non-options that have
- been skipped. `first_nonopt' is the index in ARGV of the first of them;
- `last_nonopt' is the index after the last of them. */
-
-static int first_nonopt;
-static int last_nonopt;
-
-#ifdef _LIBC
-/* Bash 2.0 gives us an environment variable containing flags
- indicating ARGV elements that should not be considered arguments. */
-
-/* Defined in getopt_init.c */
-extern char *__getopt_nonoption_flags;
-
-static int nonoption_flags_max_len;
-static int nonoption_flags_len;
-
-static int original_argc;
-static char *const *original_argv;
-
-/* Make sure the environment variable bash 2.0 puts in the environment
- is valid for the getopt call we must make sure that the ARGV passed
- to getopt is that one passed to the process. */
-static void
- __attribute__ ((unused)) store_args_and_env(int argc, char *const *argv)
-{
- /* XXX This is no good solution. We should rather copy the args so that
- we can compare them later. But we must not use malloc(3). */
- original_argc = argc;
- original_argv = argv;
-}
-
-# ifdef text_set_element
-text_set_element(__libc_subinit, store_args_and_env);
-# endif /* text_set_element */
-
-# define SWAP_FLAGS(ch1, ch2) \
- if (nonoption_flags_len > 0) \
- { \
- char __tmp = __getopt_nonoption_flags[ch1]; \
- __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
- __getopt_nonoption_flags[ch2] = __tmp; \
- }
-#else /* !_LIBC */
-# define SWAP_FLAGS(ch1, ch2)
-#endif /* _LIBC */
-
-/* Exchange two adjacent subsequences of ARGV.
- One subsequence is elements [first_nonopt,last_nonopt)
- which contains all the non-options that have been skipped so far.
- The other is elements [last_nonopt,optind), which contains all
- the options processed since those non-options were skipped.
-
- `first_nonopt' and `last_nonopt' are relocated so that they describe
- the new indices of the non-options in ARGV after they are moved. */
-
-#if defined (__STDC__) && __STDC__
-static void exchange(char **);
-#endif
-
-static void exchange(argv)
-char **argv;
-{
- int bottom = first_nonopt;
- int middle = last_nonopt;
- int top = optind;
- char *tem;
-
- /* Exchange the shorter segment with the far end of the longer segment.
- That puts the shorter segment into the right place. It leaves the
- longer segment in the right place overall, but it consists of two parts
- that need to be swapped next. */
-
-#ifdef _LIBC
- /* First make sure the handling of the `__getopt_nonoption_flags' string
- can work normally. Our top argument must be in the range of the
- string. */
- if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) {
- /* We must extend the array. The user plays games with us and presents
- new arguments. */
- char *new_str = malloc(top + 1);
-
- if (new_str == NULL)
- nonoption_flags_len = nonoption_flags_max_len = 0;
- else {
- memset(__mempcpy
- (new_str, __getopt_nonoption_flags,
- nonoption_flags_max_len), '\0', top + 1 - nonoption_flags_max_len);
- nonoption_flags_max_len = top + 1;
- __getopt_nonoption_flags = new_str;
- }
- }
-#endif
-
- while (top > middle && middle > bottom) {
- if (top - middle > middle - bottom) {
- /* Bottom segment is the short one. */
- int len = middle - bottom;
- register int i;
-
- /* Swap it with the top part of the top segment. */
- for (i = 0; i < len; i++) {
- tem = argv[bottom + i];
- argv[bottom + i] = argv[top - (middle - bottom) + i];
- argv[top - (middle - bottom) + i] = tem;
- SWAP_FLAGS(bottom + i, top - (middle - bottom) + i);
- }
- /* Exclude the moved bottom segment from further swapping. */
- top -= len;
- } else {
- /* Top segment is the short one. */
- int len = top - middle;
- register int i;
-
- /* Swap it with the bottom part of the bottom segment. */
- for (i = 0; i < len; i++) {
- tem = argv[bottom + i];
- argv[bottom + i] = argv[middle + i];
- argv[middle + i] = tem;
- SWAP_FLAGS(bottom + i, middle + i);
- }
- /* Exclude the moved top segment from further swapping. */
- bottom += len;
- }
- }
-
- /* Update records for the slots the non-options now occupy. */
-
- first_nonopt += (optind - last_nonopt);
- last_nonopt = optind;
-}
-
-/* Initialize the internal data when the first call is made. */
-
-#if defined (__STDC__) && __STDC__
-static const char *_getopt_initialize(int, char *const *, const char *);
-#endif
-static const char *_getopt_initialize(argc, argv, optstring)
-int argc;
-char *const *argv;
-const char *optstring;
-{
- /* Start processing options with ARGV-element 1 (since ARGV-element 0 is
- the program name); the sequence of previously skipped non-option
- ARGV-elements is empty. */
-
- first_nonopt = last_nonopt = optind;
-
- nextchar = NULL;
-
- posixly_correct = getenv("POSIXLY_CORRECT");
-
- /* Determine how to handle the ordering of options and nonoptions. */
-
- if (optstring[0] == '-') {
- ordering = RETURN_IN_ORDER;
- ++optstring;
- } else if (optstring[0] == '+') {
- ordering = REQUIRE_ORDER;
- ++optstring;
- } else if (posixly_correct != NULL)
- ordering = REQUIRE_ORDER;
- else
- ordering = PERMUTE;
-
-#ifdef _LIBC
- if (posixly_correct == NULL && argc == original_argc && argv == original_argv) {
- if (nonoption_flags_max_len == 0) {
- if (__getopt_nonoption_flags == NULL || __getopt_nonoption_flags[0] == '\0')
- nonoption_flags_max_len = -1;
- else {
- const char *orig_str = __getopt_nonoption_flags;
- int len = nonoption_flags_max_len = strlen(orig_str);
-
- if (nonoption_flags_max_len < argc)
- nonoption_flags_max_len = argc;
- __getopt_nonoption_flags = (char *)
- malloc(nonoption_flags_max_len);
- if (__getopt_nonoption_flags == NULL)
- nonoption_flags_max_len = -1;
- else
- memset(__mempcpy
- (__getopt_nonoption_flags,
- orig_str, len), '\0', nonoption_flags_max_len - len);
- }
- }
- nonoption_flags_len = nonoption_flags_max_len;
- } else
- nonoption_flags_len = 0;
-#endif
-
- return optstring;
-}
-
-/* Scan elements of ARGV (whose length is ARGC) for option characters
- given in OPTSTRING.
-
- If an element of ARGV starts with '-', and is not exactly "-" or "--",
- then it is an option element. The characters of this element
- (aside from the initial '-') are option characters. If `getopt'
- is called repeatedly, it returns successively each of the option characters
- from each of the option elements.
-
- If `getopt' finds another option character, it returns that character,
- updating `optind' and `nextchar' so that the next call to `getopt' can
- resume the scan with the following option character or ARGV-element.
-
- If there are no more option characters, `getopt' returns -1.
- Then `optind' is the index in ARGV of the first ARGV-element
- that is not an option. (The ARGV-elements have been permuted
- so that those that are not options now come last.)
-
- OPTSTRING is a string containing the legitimate option characters.
- If an option character is seen that is not listed in OPTSTRING,
- return '?' after printing an error message. If you set `opterr' to
- zero, the error message is suppressed but we still return '?'.
-
- If a char in OPTSTRING is followed by a colon, that means it wants an arg,
- so the following text in the same ARGV-element, or the text of the following
- ARGV-element, is returned in `optarg'. Two colons mean an option that
- wants an optional arg; if there is text in the current ARGV-element,
- it is returned in `optarg', otherwise `optarg' is set to zero.
-
- If OPTSTRING starts with `-' or `+', it requests different methods of
- handling the non-option ARGV-elements.
- See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
-
- Long-named options begin with `--' instead of `-'.
- Their names may be abbreviated as long as the abbreviation is unique
- or is an exact match for some defined option. If they have an
- argument, it follows the option name in the same ARGV-element, separated
- from the option name by a `=', or else the in next ARGV-element.
- When `getopt' finds a long-named option, it returns 0 if that option's
- `flag' field is nonzero, the value of the option's `val' field
- if the `flag' field is zero.
-
- The elements of ARGV aren't really const, because we permute them.
- But we pretend they're const in the prototype to be compatible
- with other systems.
-
- LONGOPTS is a vector of `struct option' terminated by an
- element containing a name which is zero.
-
- LONGIND returns the index in LONGOPT of the long-named option found.
- It is only valid when a long-named option has been found by the most
- recent call.
-
- If LONG_ONLY is nonzero, '-' as well as '--' can introduce
- long-named options. */
-
-int _getopt_internal(argc, argv, optstring, longopts, longind, long_only)
-int argc;
-char *const *argv;
-const char *optstring;
-const struct option *longopts;
-int *longind;
-int long_only;
-{
- optarg = NULL;
-
- if (optind == 0 || !__getopt_initialized) {
- if (optind == 0)
- optind = 1; /* Don't scan ARGV[0], the
- program name. */
- optstring = _getopt_initialize(argc, argv, optstring);
- __getopt_initialized = 1;
- }
-
- /* Test whether ARGV[optind] points to a non-option argument. Either it
- does not have option syntax, or there is an environment flag from the
- shell indicating it is not an option. The later information is only
- used when the used in the GNU libc. */
-#ifdef _LIBC
-#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
- || (optind < nonoption_flags_len \
- && __getopt_nonoption_flags[optind] == '1'))
-#else
-#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
-#endif
-
- if (nextchar == NULL || *nextchar == '\0') {
- /* Advance to the next ARGV-element. */
-
- /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
- moved back by the user (who may also have changed the arguments). */
- if (last_nonopt > optind)
- last_nonopt = optind;
- if (first_nonopt > optind)
- first_nonopt = optind;
-
- if (ordering == PERMUTE) {
- /* If we have just processed some options following some
- non-options, exchange them so that the options come first. */
-
- if (first_nonopt != last_nonopt && last_nonopt != optind)
- exchange((char **) argv);
- else if (last_nonopt != optind)
- first_nonopt = optind;
-
- /* Skip any additional non-options and extend the range of
- non-options previously skipped. */
-
- while (optind < argc && NONOPTION_P)
- optind++;
- last_nonopt = optind;
- }
-
- /* The special ARGV-element `--' means premature end of options. Skip
- it like a null option, then exchange with previous non-options as if
- it were an option, then skip everything else like a non-option. */
-
- if (optind != argc && !strcmp(argv[optind], "--")) {
- optind++;
-
- if (first_nonopt != last_nonopt && last_nonopt != optind)
- exchange((char **) argv);
- else if (first_nonopt == last_nonopt)
- first_nonopt = optind;
- last_nonopt = argc;
-
- optind = argc;
- }
-
- /* If we have done all the ARGV-elements, stop the scan and back over
- any non-options that we skipped and permuted. */
-
- if (optind == argc) {
- /* Set the next-arg-index to point at the non-options that we
- previously skipped, so the caller will digest them. */
- if (first_nonopt != last_nonopt)
- optind = first_nonopt;
- return -1;
- }
-
- /* If we have come to a non-option and did not permute it, either stop
- the scan or describe it to the caller and pass it by. */
-
- if (NONOPTION_P) {
- if (ordering == REQUIRE_ORDER)
- return -1;
- optarg = argv[optind++];
- return 1;
- }
-
- /* We have found another option-ARGV-element. Skip the initial
- punctuation. */
-
- nextchar = (argv[optind] + 1 + (longopts != NULL && argv[optind][1] == '-'));
- }
-
- /* Decode the current option-ARGV-element. */
-
- /* Check whether the ARGV-element is a long option.
-
- If long_only and the ARGV-element has the form "-f", where f is a valid
- short option, don't consider it an abbreviated form of a long option
- that starts with f. Otherwise there would be no way to give the -f
- short option.
-
- On the other hand, if there's a long option "fubar" and the
- ARGV-element is "-fu", do consider that an abbreviation of the long
- option, just like "--fu", and not "-f" with arg "u".
-
- This distinction seems to be the most useful approach. */
-
- if (longopts != NULL && (argv[optind][1] == '-' || (long_only && (argv[optind][2]
- || !my_index(optstring, argv[optind]
- [1]))))) {
- char *nameend;
- const struct option *p;
- const struct option *pfound = NULL;
- int exact = 0;
- int ambig = 0;
- int indfound = -1;
- int option_index;
-
- for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
- /* Do nothing. */ ;
-
- /* Test all long options for either exact match or abbreviated matches.
- */
- for (p = longopts, option_index = 0; p->name; p++, option_index++)
- if (!strncmp(p->name, nextchar, nameend - nextchar)) {
- if ((unsigned int) (nameend - nextchar) == (unsigned int) strlen(p->name)) {
- /* Exact match found. */
- pfound = p;
- indfound = option_index;
- exact = 1;
- break;
- } else if (pfound == NULL) {
- /* First nonexact match found. */
- pfound = p;
- indfound = option_index;
- } else
- /* Second or later nonexact match found. */
- ambig = 1;
- }
-
- if (ambig && !exact) {
- if (opterr)
- fprintf(stderr, _("%s: option `%s' is ambiguous\n"), argv[0], argv[optind]);
- nextchar += strlen(nextchar);
- optind++;
- optopt = 0;
- return '?';
- }
-
- if (pfound != NULL) {
- option_index = indfound;
- optind++;
- if (*nameend) {
- /* Don't test has_arg with >, because some C compilers don't
- allow it to be used on enums. */
- if (pfound->has_arg)
- optarg = nameend + 1;
- else {
- if (opterr) {
- if (argv[optind - 1][1] == '-')
- /* --option */
- fprintf(stderr,
- _
- ("%s: option `--%s' doesn't allow an argument\n"),
- argv[0], pfound->name);
- else
- /* +option or -option */
- fprintf(stderr,
- _
- ("%s: option `%c%s' doesn't allow an argument\n"),
- argv[0], argv[optind - 1][0], pfound->name);
- }
-
- nextchar += strlen(nextchar);
-
- optopt = pfound->val;
- return '?';
- }
- } else if (pfound->has_arg == 1) {
- if (optind < argc)
- optarg = argv[optind++];
- else {
- if (opterr)
- fprintf(stderr,
- _
- ("%s: option `%s' requires an argument\n"),
- argv[0], argv[optind - 1]);
- nextchar += strlen(nextchar);
- optopt = pfound->val;
- return optstring[0] == ':' ? ':' : '?';
- }
- }
- nextchar += strlen(nextchar);
- if (longind != NULL)
- *longind = option_index;
- if (pfound->flag) {
- *(pfound->flag) = pfound->val;
- return 0;
- }
- return pfound->val;
- }
-
- /* Can't find it as a long option. If this is not getopt_long_only, or
- the option starts with '--' or is not a valid short option, then
- it's an error. Otherwise interpret it as a short option. */
- if (!long_only || argv[optind][1] == '-' || my_index(optstring, *nextchar) == NULL) {
- if (opterr) {
- if (argv[optind][1] == '-')
- /* --option */
- fprintf(stderr, _("%s: unrecognized option `--%s'\n"), argv[0], nextchar);
- else
- /* +option or -option */
- fprintf(stderr,
- _
- ("%s: unrecognized option `%c%s'\n"),
- argv[0], argv[optind][0], nextchar);
- }
- nextchar = (char *) "";
- optind++;
- optopt = 0;
- return '?';
- }
- }
-
- /* Look at and handle the next short option-character. */
-
- {
- char c = *nextchar++;
- char *temp = my_index(optstring, c);
-
- /* Increment `optind' when we start to process its last character. */
- if (*nextchar == '\0')
- ++optind;
-
- if (temp == NULL || c == ':') {
- if (opterr) {
- if (posixly_correct)
- /* 1003.2 specifies the format of this message. */
- fprintf(stderr, _("%s: illegal option -- %c\n"), argv[0], c);
- else
- fprintf(stderr, _("%s: invalid option -- %c\n"), argv[0], c);
- }
- optopt = c;
- return '?';
- }
- /* Convenience. Treat POSIX -W foo same as long option --foo */
- if (temp[0] == 'W' && temp[1] == ';') {
- char *nameend;
- const struct option *p;
- const struct option *pfound = NULL;
- int exact = 0;
- int ambig = 0;
- int indfound = 0;
- int option_index;
-
- /* This is an option that requires an argument. */
- if (*nextchar != '\0') {
- optarg = nextchar;
- /* If we end this ARGV-element by taking the rest as an arg, we
- must advance to the next element now. */
- optind++;
- } else if (optind == argc) {
- if (opterr) {
- /* 1003.2 specifies the format of this message. */
- fprintf(stderr, _("%s: option requires an argument -- %c\n"), argv[0], c);
- }
- optopt = c;
- if (optstring[0] == ':')
- c = ':';
- else
- c = '?';
- return c;
- } else
- /* We already incremented `optind' once; increment it again when
- taking next ARGV-elt as argument. */
- optarg = argv[optind++];
-
- /* optarg is now the argument, see if it's in the table of longopts.
- */
-
- for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
- /* Do nothing. */ ;
-
- /* Test all long options for either exact match or abbreviated
- matches. */
- for (p = longopts, option_index = 0; p->name; p++, option_index++)
- if (!strncmp(p->name, nextchar, nameend - nextchar)) {
- if ((unsigned int) (nameend - nextchar) == strlen(p->name)) {
- /* Exact match found. */
- pfound = p;
- indfound = option_index;
- exact = 1;
- break;
- } else if (pfound == NULL) {
- /* First nonexact match found. */
- pfound = p;
- indfound = option_index;
- } else
- /* Second or later nonexact match found. */
- ambig = 1;
- }
- if (ambig && !exact) {
- if (opterr)
- fprintf(stderr, _("%s: option `-W %s' is ambiguous\n"), argv[0], argv[optind]);
- nextchar += strlen(nextchar);
- optind++;
- return '?';
- }
- if (pfound != NULL) {
- option_index = indfound;
- if (*nameend) {
- /* Don't test has_arg with >, because some C compilers don't
- allow it to be used on enums. */
- if (pfound->has_arg)
- optarg = nameend + 1;
- else {
- if (opterr)
- fprintf(stderr, _("\
-%s: option `-W %s' doesn't allow an argument\n"), argv[0], pfound->name);
-
- nextchar += strlen(nextchar);
- return '?';
- }
- } else if (pfound->has_arg == 1) {
- if (optind < argc)
- optarg = argv[optind++];
- else {
- if (opterr)
- fprintf(stderr,
- _
- ("%s: option `%s' requires an argument\n"),
- argv[0], argv[optind - 1]);
- nextchar += strlen(nextchar);
- return optstring[0] == ':' ? ':' : '?';
- }
- }
- nextchar += strlen(nextchar);
- if (longind != NULL)
- *longind = option_index;
- if (pfound->flag) {
- *(pfound->flag) = pfound->val;
- return 0;
- }
- return pfound->val;
- }
- nextchar = NULL;
- return 'W'; /* Let the application handle it.
- */
- }
- if (temp[1] == ':') {
- if (temp[2] == ':') {
- /* This is an option that accepts an argument optionally. */
- if (*nextchar != '\0') {
- optarg = nextchar;
- optind++;
- } else
- optarg = NULL;
- nextchar = NULL;
- } else {
- /* This is an option that requires an argument. */
- if (*nextchar != '\0') {
- optarg = nextchar;
- /* If we end this ARGV-element by taking the rest as an arg,
- we must advance to the next element now. */
- optind++;
- } else if (optind == argc) {
- if (opterr) {
- /* 1003.2 specifies the format of this message. */
- fprintf(stderr,
- _("%s: option requires an argument -- %c\n"), argv[0], c);
- }
- optopt = c;
- if (optstring[0] == ':')
- c = ':';
- else
- c = '?';
- } else
- /* We already incremented `optind' once; increment it again
- when taking next ARGV-elt as argument. */
- optarg = argv[optind++];
- nextchar = NULL;
- }
- }
- return c;
- }
-}
-
-int getopt(argc, argv, optstring)
-int argc;
-char *const *argv;
-const char *optstring;
-{
- return _getopt_internal(argc, argv, optstring, (const struct option *) 0, (int *) 0, 0);
-}
-
-#endif /* Not ELIDE_CODE. */
-
-#ifdef TEST
-
-/* Compile with -DTEST to make an executable for use in testing
- the above definition of `getopt'. */
-
-int main(argc, argv)
-int argc;
-char **argv;
-{
- int c;
- int digit_optind = 0;
-
- while (1) {
- int this_option_optind = optind ? optind : 1;
-
- c = getopt(argc, argv, "abc:d:0123456789");
- if (c == -1)
- break;
-
- switch (c) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- if (digit_optind != 0 && digit_optind != this_option_optind)
- printf("digits occur in two different argv-elements.\n");
- digit_optind = this_option_optind;
- printf("option %c\n", c);
- break;
-
- case 'a':
- printf("option a\n");
- break;
-
- case 'b':
- printf("option b\n");
- break;
-
- case 'c':
- printf("option c with value `%s'\n", optarg);
- break;
-
- case '?':
- break;
-
- default:
- printf("?? getopt returned character code 0%o ??\n", c);
- }
- }
-
- if (optind < argc) {
- printf("non-option ARGV-elements: ");
- while (optind < argc)
- printf("%s ", argv[optind++]);
- printf("\n");
- }
-
- exit(0);
-}
-
-#endif /* TEST */
diff --git a/src/getopt.h b/src/getopt.h
deleted file mode 100644
index 0a985b0..0000000
--- a/src/getopt.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/* Declarations for getopt.
- Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The GNU C Library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
-
-#ifndef _GETOPT_H
-#define _GETOPT_H 1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* For communication from `getopt' to the caller.
- When `getopt' finds an option that takes an argument,
- the argument value is returned here.
- Also, when `ordering' is RETURN_IN_ORDER,
- each non-option ARGV-element is returned here. */
-
- extern char *optarg;
-
-/* Index in ARGV of the next element to be scanned.
- This is used for communication to and from the caller
- and for communication between successive calls to `getopt'.
-
- On entry to `getopt', zero means this is the first call; initialize.
-
- When `getopt' returns -1, this is the index of the first of the
- non-option elements that the caller should itself scan.
-
- Otherwise, `optind' communicates from one call to the next
- how much of ARGV has been scanned so far. */
-
- extern int optind;
-
-/* Callers store zero here to inhibit the error message `getopt' prints
- for unrecognized options. */
-
- extern int opterr;
-
-/* Set to an option character which was unrecognized. */
-
- extern int optopt;
-
-/* Describe the long-named options requested by the application.
- The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
- of `struct option' terminated by an element containing a name which is
- zero.
-
- The field `has_arg' is:
- no_argument (or 0) if the option does not take an argument,
- required_argument (or 1) if the option requires an argument,
- optional_argument (or 2) if the option takes an optional argument.
-
- If the field `flag' is not NULL, it points to a variable that is set
- to the value given in the field `val' when the option is found, but
- left unchanged if the option is not found.
-
- To have a long-named option do something other than set an `int' to
- a compiled-in constant, such as set a value from `optarg', set the
- option's `flag' field to zero and its `val' field to a nonzero
- value (the equivalent single-letter option character, if there is
- one). For long options that have a zero `flag' field, `getopt'
- returns the contents of the `val' field. */
-
- struct option {
-#if defined (__STDC__) && __STDC__
- const char *name;
-#else
- char *name;
-#endif
- /* has_arg can't be an enum because some compilers complain about type
- mismatches in all the code that assumes it is an int. */
- int has_arg;
- int *flag;
- int val;
- };
-
-/* Names for the values of the `has_arg' field of `struct option'. */
-
-#define no_argument 0
-#define required_argument 1
-#define optional_argument 2
-
-#if defined (__STDC__) && __STDC__
-#ifdef __GNU_LIBRARY__
-/* Many other libraries have conflicting prototypes for getopt, with
- differences in the consts, in stdlib.h. To avoid compilation
- errors, only prototype getopt for the GNU C library. */
- extern int getopt(int argc, char *const *argv, const char *shortopts);
-#else /* not __GNU_LIBRARY__ */
-#ifndef __cplusplus
-/* C++ is more pedantic, and demands a full prototype, not this.
- Hope that stdlib.h has a prototype for `getopt'. */
- extern int getopt();
-#endif /* __cplusplus */
-#endif /* __GNU_LIBRARY__ */
- extern int getopt_long(int argc, char *const *argv,
- const char *shortopts, const struct option *longopts, int *longind);
- extern int getopt_long_only(int argc, char *const *argv,
- const char *shortopts, const struct option *longopts, int *longind);
-
-/* Internal only. Users should not call this directly. */
- extern int _getopt_internal(int argc, char *const *argv,
- const char *shortopts, const struct option *longopts, int *longind, int long_only);
-#else /* not __STDC__ */
- extern int getopt();
- extern int getopt_long();
- extern int getopt_long_only();
-
- extern int _getopt_internal();
-#endif /* __STDC__ */
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* getopt.h */
diff --git a/src/getopt1.c b/src/getopt1.c
deleted file mode 100644
index 5a5c483..0000000
--- a/src/getopt1.c
+++ /dev/null
@@ -1,173 +0,0 @@
-/* getopt_long and getopt_long_only entry points for GNU getopt.
- Copyright (C) 1987,88,89,90,91,92,93,94,96,97 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The GNU C Library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-#include "getopt.h"
-
-#if !defined (__STDC__) || !__STDC__
-/* This is a separate conditional since some stdc systems
- reject `defined (const)'. */
-#ifndef const
-#define const
-#endif
-#endif
-
-#include <stdio.h>
-
-/* Comment out all this code if we are using the GNU C Library, and are not
- actually compiling the library itself. This code is part of the GNU C
- Library, but also included in many other GNU distributions. Compiling
- and linking in this code is a waste when using the GNU C library
- (especially if it is a shared library). Rather than having every GNU
- program understand `configure --with-gnu-libc' and omit the object files,
- it is simpler to just do this in the source for each such file. */
-
-#define GETOPT_INTERFACE_VERSION 2
-#if !defined (_LIBC) && defined (__GLIBC__) && __GLIBC__ >= 2
-#include <gnu-versions.h>
-#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
-#define ELIDE_CODE
-#endif
-#endif
-
-#ifndef ELIDE_CODE
-
-/* This needs to come after some library #include
- to get __GNU_LIBRARY__ defined. */
-#ifdef __GNU_LIBRARY__
-#include <stdlib.h>
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-int getopt_long(argc, argv, options, long_options, opt_index)
-int argc;
-char *const *argv;
-const char *options;
-const struct option *long_options;
-int *opt_index;
-{
- return _getopt_internal(argc, argv, options, long_options, opt_index, 0);
-}
-
-/* Like getopt_long, but '-' as well as '--' can indicate a long option.
- If an option that starts with '-' (not '--') doesn't match a long option,
- but does match a short option, it is parsed as a short option
- instead. */
-
-int getopt_long_only(argc, argv, options, long_options, opt_index)
-int argc;
-char *const *argv;
-const char *options;
-const struct option *long_options;
-int *opt_index;
-{
- return _getopt_internal(argc, argv, options, long_options, opt_index, 1);
-}
-
-#endif /* Not ELIDE_CODE. */
-
-#ifdef TEST
-
-#include <stdio.h>
-
-int main(argc, argv)
-int argc;
-char **argv;
-{
- int c;
- int digit_optind = 0;
-
- while (1) {
- int this_option_optind = optind ? optind : 1;
- int option_index = 0;
- static struct option long_options[] = {
- {"add", 1, 0, 0},
- {"append", 0, 0, 0},
- {"delete", 1, 0, 0},
- {"verbose", 0, 0, 0},
- {"create", 0, 0, 0},
- {"file", 1, 0, 0},
- {0, 0, 0, 0}
- };
-
- c = getopt_long(argc, argv, "abc:d:0123456789", long_options, &option_index);
- if (c == -1)
- break;
-
- switch (c) {
- case 0:
- printf("option %s", long_options[option_index].name);
- if (optarg)
- printf(" with arg %s", optarg);
- printf("\n");
- break;
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- if (digit_optind != 0 && digit_optind != this_option_optind)
- printf("digits occur in two different argv-elements.\n");
- digit_optind = this_option_optind;
- printf("option %c\n", c);
- break;
-
- case 'a':
- printf("option a\n");
- break;
-
- case 'b':
- printf("option b\n");
- break;
-
- case 'c':
- printf("option c with value `%s'\n", optarg);
- break;
-
- case 'd':
- printf("option d with value `%s'\n", optarg);
- break;
-
- case '?':
- break;
-
- default:
- printf("?? getopt returned character code 0%o ??\n", c);
- }
- }
-
- if (optind < argc) {
- printf("non-option ARGV-elements: ");
- while (optind < argc)
- printf("%s ", argv[optind++]);
- printf("\n");
- }
-
- exit(0);
-}
-
-#endif /* TEST */
diff --git a/src/gib_hash.c b/src/gib_hash.c
index 0d6a226..9497d04 100644
--- a/src/gib_hash.c
+++ b/src/gib_hash.c
@@ -53,7 +53,7 @@ void gib_hash_node_free_and_data(gib_hash_node *node)
return;
}
-gib_hash *gib_hash_new()
+gib_hash *gib_hash_new(void)
{
gib_hash *hash = emalloc(sizeof(gib_hash));
hash->base = gib_hash_node_new("__gib_hash_new",NULL);
@@ -89,7 +89,7 @@ static unsigned char gib_hash_find_callback(gib_list *list, void *data)
gib_hash_node *node = GIB_HASH_NODE(list);
char *key = (char*) data;
- /* strncasecmp causes simliar keys like key1 and key11 clobber eachother */
+ /* strncasecmp causes similar keys like key1 and key11 clobber each other */
return !strcasecmp(node->key, key);
}
diff --git a/src/gib_hash.h b/src/gib_hash.h
index 58506c8..125e280 100644
--- a/src/gib_hash.h
+++ b/src/gib_hash.h
@@ -55,7 +55,7 @@ gib_hash_node *gib_hash_node_new(char *key, void *data);
void gib_hash_node_free(gib_hash_node *node);
void gib_hash_node_free_and_data(gib_hash_node *node);
-gib_hash *gib_hash_new();
+gib_hash *gib_hash_new(void);
void gib_hash_free(gib_hash *hash);
void gib_hash_free_and_data(gib_hash *hash);
diff --git a/src/gib_imlib.c b/src/gib_imlib.c
index 7858cb7..39d0081 100644
--- a/src/gib_imlib.c
+++ b/src/gib_imlib.c
@@ -27,6 +27,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "utils.h"
#include "debug.h"
+/*
int
gib_imlib_load_image(Imlib_Image * im, char *filename)
{
@@ -38,7 +39,6 @@ gib_imlib_load_image(Imlib_Image * im, char *filename)
*im = imlib_load_image_with_error_return(filename, &err);
if ((err) || (!im))
{
- /* Check error code */
switch (err)
{
case IMLIB_LOAD_ERROR_FILE_DOES_NOT_EXIST:
@@ -91,6 +91,7 @@ gib_imlib_load_image(Imlib_Image * im, char *filename)
}
return (1);
}
+*/
int
gib_imlib_image_get_width(Imlib_Image im)
@@ -322,7 +323,7 @@ gib_imlib_text_draw(Imlib_Image im, Imlib_Font fn, gib_style * s, int x,
gib_style_bit *bb;
gib_list *l;
- /* here we shift the draw to accomodate bits with negative offsets,
+ /* here we shift the draw to accommodate bits with negative offsets,
* which would be drawn at negative coords otherwise */
l = s->bits;
while (l)
diff --git a/src/gib_imlib.h b/src/gib_imlib.h
index 07daabe..6a35e7e 100644
--- a/src/gib_imlib.h
+++ b/src/gib_imlib.h
@@ -47,7 +47,9 @@ extern "C"
{
#endif
+/*
int gib_imlib_load_image(Imlib_Image * im, char *filename);
+*/
int gib_imlib_image_get_width(Imlib_Image im);
int gib_imlib_image_get_height(Imlib_Image im);
int gib_imlib_image_has_alpha(Imlib_Image im);
diff --git a/src/gib_list.c b/src/gib_list.c
index a8ba1dd..e7710bc 100644
--- a/src/gib_list.c
+++ b/src/gib_list.c
@@ -520,7 +520,7 @@ gib_list_find(gib_list *root, unsigned char (*find_func)(gib_list *node, void *d
for (i=root; i; i=i->next)
if (find_func(i,data))
return i;
-
+
return NULL;
}
diff --git a/src/help.raw b/src/help.raw
index e0fb62a..e218e78 100644
--- a/src/help.raw
+++ b/src/help.raw
@@ -29,6 +29,8 @@ OPTIONS
mode or when window geometry is fixed. If combined
with --auto-zoom, zooming will be limited to the
the size. Also support \"max\" and \"fill\"
+ --zoom-step PERCENT Zoom images in and out by PERCENT (default: 25)
+ when using the zoom keys / buttons
--keep-zoom-vp Keep viewport zoom and settings while changing images
-w, --multiwindow Open all files at once, one window per image
-x, --borderless Create borderless windows
@@ -39,7 +41,7 @@ OPTIONS
--auto-rotate Rotate images according to Exif info (if compiled with exif=1)
-^, --title TITLE Set window title (see FORMAT SPECIFIERS)
-D, --slideshow-delay NUM Set delay between automatically changing slides
- --on-last-slide quit Exit after one loop through the slide show
+ --on-last-slide quit Exit after one loop through the slide show (old --cycle-once)
--on-last-slide hold Stop at both ends of the filelist
-R, --reload NUM Reload images after NUM seconds
-k, --keep-http Keep local copies when viewing HTTP/FTP files
@@ -100,6 +102,7 @@ OPTIONS
--scroll-step COUNT scroll COUNT pixels when movement key is pressed
--cache-size NUM imlib cache size in mebibytes (0 .. 2048)
--auto-reload automatically reload shown image if file was changed
+ --window-id ID Draw to an existing X11 window by its ID
MONTAGE MODE OPTIONS
-X, --ignore-aspect Set thumbnail to specified width/height without
@@ -201,7 +204,7 @@ DEFAULT KEYS
This program is free software, see the file COPYING for licensing info.
Copyright Tom Gilbert (and various contributors) 1999-2003.
-Copyright Daniel Friesel (and various contributors) 2010-2020.
+Copyright Birte Kristina Friesel (and various contributors) 2010-2020.
Homepage: http://feh.finalrewind.org
Report bugs to <derf+feh@finalrewind.org> or #feh on irc.oftc.net.
diff --git a/src/imlib.c b/src/imlib.c
index 4e8e790..143807d 100644
--- a/src/imlib.c
+++ b/src/imlib.c
@@ -1,7 +1,7 @@
/* imlib.c
Copyright (C) 1999-2003 Tom Gilbert.
-Copyright (C) 2010-2020 Daniel Friesel.
+Copyright (C) 2010-2020 Birte Kristina Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -44,6 +44,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "exif.h"
#endif
+#ifdef HAVE_LIBMAGIC
+#include <magic.h>
+
+magic_t magic = NULL;
+#endif
+
Display *disp = NULL;
Visual *vis = NULL;
Screen *scr = NULL;
@@ -164,11 +170,31 @@ int feh_load_image_char(Imlib_Image * im, char *filename)
return(i);
}
-void feh_imlib_print_load_error(char *file, winwidget w, Imlib_Load_Error err)
+void feh_print_load_error(char *file, winwidget w, Imlib_Load_Error err, enum feh_load_error feh_err)
{
if (err == IMLIB_LOAD_ERROR_OUT_OF_FILE_DESCRIPTORS)
eprintf("%s - Out of file descriptors while loading", file);
else if (!opt.quiet || w) {
+ switch (feh_err) {
+ case LOAD_ERROR_IMLIB:
+ // handled in the next switch/case statement
+ break;
+ case LOAD_ERROR_IMAGEMAGICK:
+ im_weprintf(w, "%s - No ImageMagick loader for that file format", file);
+ break;
+ case LOAD_ERROR_CURL:
+ im_weprintf(w, "%s - libcurl was unable to retrieve the file", file);
+ break;
+ case LOAD_ERROR_DCRAW:
+ im_weprintf(w, "%s - Unable to open preview via dcraw", file);
+ break;
+ case LOAD_ERROR_MAGICBYTES:
+ im_weprintf(w, "%s - Does not look like an image (magic bytes missing)", file);
+ break;
+ }
+ if (feh_err != LOAD_ERROR_IMLIB) {
+ return;
+ }
switch (err) {
case IMLIB_LOAD_ERROR_FILE_DOES_NOT_EXIST:
im_weprintf(w, "%s - File does not exist", file);
@@ -181,11 +207,7 @@ void feh_imlib_print_load_error(char *file, winwidget w, Imlib_Load_Error err)
break;
case IMLIB_LOAD_ERROR_UNKNOWN:
case IMLIB_LOAD_ERROR_NO_LOADER_FOR_FILE_FORMAT:
- if (getenv("FEH_SKIP_MAGIC")) {
- im_weprintf(w, "%s - No Imlib2 loader for that file format", file);
- } else {
- im_weprintf(w, "%s - Does not look like an image (magic bytes missing)", file);
- }
+ im_weprintf(w, "%s - No Imlib2 loader for that file format", file);
break;
case IMLIB_LOAD_ERROR_PATH_TOO_LONG:
im_weprintf(w, "%s - Path specified is too long", file);
@@ -211,6 +233,14 @@ void feh_imlib_print_load_error(char *file, winwidget w, Imlib_Load_Error err)
case IMLIB_LOAD_ERROR_OUT_OF_DISK_SPACE:
im_weprintf(w, "%s - Cannot write - out of disk space", file);
break;
+#if defined(IMLIB2_VERSION_MAJOR) && defined(IMLIB2_VERSION_MINOR) && (IMLIB2_VERSION_MAJOR > 1 || IMLIB2_VERSION_MINOR > 7)
+ case IMLIB_LOAD_ERROR_IMAGE_READ:
+ im_weprintf(w, "%s - Invalid image file", file);
+ break;
+ case IMLIB_LOAD_ERROR_IMAGE_FRAME:
+ im_weprintf(w, "%s - Requested frame not in image", file);
+ break;
+#endif
default:
im_weprintf(w, "While loading %s - Unknown error (%d)",
file, err);
@@ -219,6 +249,33 @@ void feh_imlib_print_load_error(char *file, winwidget w, Imlib_Load_Error err)
}
}
+#ifdef HAVE_LIBMAGIC
+void uninit_magic(void)
+{
+ if (!magic) {
+ return;
+ }
+
+ magic_close(magic);
+ magic = NULL;
+}
+void init_magic(void)
+{
+ if (getenv("FEH_SKIP_MAGIC")) {
+ return;
+ }
+
+ if (!(magic = magic_open(MAGIC_NONE))) {
+ weprintf("unable to initialize magic library\n");
+ return;
+ }
+
+ if (magic_load(magic, NULL) != 0) {
+ weprintf("cannot load magic database: %s\n", magic_error(magic));
+ uninit_magic();
+ }
+}
+
/*
* This is a workaround for an Imlib2 regression, causing unloadable image
* detection to be excessively slow (and, thus, causing feh to hang for a while
@@ -226,90 +283,53 @@ void feh_imlib_print_load_error(char *file, winwidget w, Imlib_Load_Error err)
* avoid calling Imlib2 for files it probably cannot handle. See
* <https://phab.enlightenment.org/T8739> and
* <https://github.com/derf/feh/issues/505>.
- *
- * Note that this drops support for bz2-compressed files, unless
- * FEH_SKIP_MAGIC is set
*/
-int feh_is_image(feh_file * file)
+int feh_is_image(feh_file * file, int magic_flags)
{
- unsigned char buf[16];
- FILE *fh = fopen(file->filename, "r");
- if (!fh) {
- return 0;
- }
- if (fread(buf, 1, 16, fh) != 16) {
- return 0;
- }
- fclose(fh);
+ const char * mime_type = NULL;
- if (buf[0] == 0xff && buf[1] == 0xd8) {
- // JPEG
- return 1;
- }
- if (!memcmp(buf, "\x89PNG\x0d\x0a\x1a\x0a", 8)) {
- // PNG
- return 1;
- }
- if (buf[0] == 'A' && buf[1] == 'R' && buf[2] == 'G' && buf[3] == 'B') {
- // ARGB
- return 1;
- }
- if (buf[0] == 'B' && buf[1] == 'M') {
- // BMP
- return 1;
- }
- if (!memcmp(buf, "farbfeld", 8)) {
- // farbfeld
- return 1;
- }
- if (buf[0] == 'G' && buf[1] == 'I' && buf[2] == 'F') {
- // GIF
+ if (!magic) {
return 1;
}
- if (buf[0] == 0x00 && buf[1] == 0x00 && buf[2] <= 0x02 && buf[3] == 0x00) {
- // ICO
- return 1;
- }
- if (!memcmp(buf, "FORM", 4)) {
- // Amiga IFF ILBM
- return 1;
- }
- if (buf[0] == 'P' && buf[1] >= '1' && buf[1] <= '7') {
- // PNM et al.
- return 1;
- }
- if (strstr(file->filename, ".tga")) {
- // TGA
- return 1;
- }
- if (!memcmp(buf, "II\x2a\x00", 4) || !memcmp(buf, "MM\x00\x2a", 4)) {
- // TIFF
- return 1;
- }
- if (!memcmp(buf, "RIFF", 4)) {
- // might be webp
- return 1;
+
+ magic_setflags(magic, MAGIC_MIME_TYPE | MAGIC_SYMLINK | magic_flags);
+ mime_type = magic_file(magic, file->filename);
+
+ if (!mime_type) {
+ return 0;
}
- buf[15] = 0;
- if (strstr((char *)buf, "XPM")) {
- // XPM
+
+ D(("file %s has mime type: %s\n", file->filename, mime_type));
+
+ if (strncmp(mime_type, "image/", 6) == 0) {
return 1;
}
- if (strstr(file->filename, ".bz2") || strstr(file->filename, ".gz")) {
- // Imlib2 supports compressed images. It relies on the filename to
- // determine the appropriate loader and does not use magic bytes here.
- return 1;
+
+ /* no infinite loop on compressed content, please */
+ if (magic_flags) {
+ return 0;
}
- // moved to the end as this variable won't be set in most cases
- if (getenv("FEH_SKIP_MAGIC")) {
- return 1;
+
+ /* imlib2 supports loading compressed images, let's have a look inside */
+ if (strcmp(mime_type, "application/gzip") == 0 ||
+ strcmp(mime_type, "application/x-bzip2") == 0 ||
+ strcmp(mime_type, "application/x-xz") == 0) {
+ return feh_is_image(file, MAGIC_COMPRESS);
}
+
return 0;
}
+#else
+int feh_is_image(__attribute__((unused)) feh_file * file, __attribute__((unused)) int magic_flags)
+{
+ return 1;
+}
+#endif
int feh_load_image(Imlib_Image * im, feh_file * file)
{
Imlib_Load_Error err = IMLIB_LOAD_ERROR_NONE;
+ enum feh_load_error feh_err = LOAD_ERROR_IMLIB;
enum { SRC_IMLIB, SRC_HTTP, SRC_MAGICK, SRC_DCRAW } image_source = SRC_IMLIB;
char *tmpname = NULL;
char *real_filename = NULL;
@@ -322,19 +342,16 @@ int feh_load_image(Imlib_Image * im, feh_file * file)
if (path_is_url(file->filename)) {
image_source = SRC_HTTP;
- if ((tmpname = feh_http_load_image(file->filename)) == NULL)
+ if ((tmpname = feh_http_load_image(file->filename)) == NULL) {
+ feh_err = LOAD_ERROR_CURL;
err = IMLIB_LOAD_ERROR_FILE_DOES_NOT_EXIST;
- }
- else if (opt.conversion_timeout >= 0 && feh_file_is_raw(file->filename)) {
- image_source = SRC_DCRAW;
- tmpname = feh_dcraw_load_image(file->filename);
- if (!tmpname)
- err = IMLIB_LOAD_ERROR_NO_LOADER_FOR_FILE_FORMAT;
+ }
}
else {
- if (feh_is_image(file)) {
+ if (feh_is_image(file, 0)) {
*im = imlib_load_image_with_error_return(file->filename, &err);
} else {
+ feh_err = LOAD_ERROR_MAGICBYTES;
err = IMLIB_LOAD_ERROR_NO_LOADER_FOR_FILE_FORMAT;
}
}
@@ -342,8 +359,20 @@ int feh_load_image(Imlib_Image * im, feh_file * file)
if (opt.conversion_timeout >= 0 && (
(err == IMLIB_LOAD_ERROR_UNKNOWN) ||
(err == IMLIB_LOAD_ERROR_NO_LOADER_FOR_FILE_FORMAT))) {
- image_source = SRC_MAGICK;
- tmpname = feh_magick_load_image(file->filename);
+ if (feh_file_is_raw(file->filename)) {
+ image_source = SRC_DCRAW;
+ tmpname = feh_dcraw_load_image(file->filename);
+ if (!tmpname) {
+ feh_err = LOAD_ERROR_DCRAW;
+ }
+ } else {
+ image_source = SRC_MAGICK;
+ feh_err = LOAD_ERROR_IMLIB;
+ tmpname = feh_magick_load_image(file->filename);
+ if (!tmpname) {
+ feh_err = LOAD_ERROR_IMAGEMAGICK;
+ }
+ }
}
if (tmpname) {
@@ -366,7 +395,14 @@ int feh_load_image(Imlib_Image * im, feh_file * file)
file->filename = real_filename;
#ifdef HAVE_LIBEXIF
- file->ed = exif_get_data(tmpname);
+ /*
+ * if we're called from within feh_reload_image, file->ed is already
+ * populated.
+ */
+ if (file->ed) {
+ exif_data_unref(file->ed);
+ }
+ file->ed = exif_data_new_from_file(tmpname);
#endif
}
if (!opt.use_conversion_cache && ((image_source != SRC_HTTP) || !opt.keep_http))
@@ -376,8 +412,19 @@ int feh_load_image(Imlib_Image * im, feh_file * file)
// add_file_to_rm_filelist duplicates tmpname
add_file_to_rm_filelist(tmpname);
- if (image_source != SRC_HTTP && !opt.use_conversion_cache)
+ if (!opt.use_conversion_cache)
free(tmpname);
+ } else if (im) {
+#ifdef HAVE_LIBEXIF
+ /*
+ * if we're called from within feh_reload_image, file->ed is already
+ * populated.
+ */
+ if (file->ed) {
+ exif_data_unref(file->ed);
+ }
+ file->ed = exif_data_new_from_file(file->filename);
+#endif
}
if ((err) || (!im)) {
@@ -385,7 +432,7 @@ int feh_load_image(Imlib_Image * im, feh_file * file)
fputs("\n", stderr);
reset_output = 1;
}
- feh_imlib_print_load_error(file->filename, NULL, err);
+ feh_print_load_error(file->filename, NULL, err, feh_err);
D(("Load *failed*\n"));
return(0);
}
@@ -402,14 +449,13 @@ int feh_load_image(Imlib_Image * im, feh_file * file)
#ifdef HAVE_LIBEXIF
int orientation = 0;
- ExifData *exifData = exif_data_new_from_file(file->filename);
- if (exifData) {
- ExifByteOrder byteOrder = exif_data_get_byte_order(exifData);
- ExifEntry *exifEntry = exif_data_get_entry(exifData, EXIF_TAG_ORIENTATION);
- if (exifEntry && opt.auto_rotate)
+ if (file->ed) {
+ ExifByteOrder byteOrder = exif_data_get_byte_order(file->ed);
+ ExifEntry *exifEntry = exif_data_get_entry(file->ed, EXIF_TAG_ORIENTATION);
+ if (exifEntry && opt.auto_rotate) {
orientation = exif_get_short(exifEntry->data, byteOrder);
+ }
}
- file->ed = exifData;
if (orientation == 2)
gib_imlib_image_flip_horizontal(*im);
@@ -527,11 +573,9 @@ static int feh_file_is_raw(char *filename)
}
if (childpid == 0) {
- if (opt.quiet) {
- int devnull = open("/dev/null", O_WRONLY);
- dup2(devnull, 1);
- dup2(devnull, 2);
- }
+ int devnull = open("/dev/null", O_WRONLY);
+ dup2(devnull, 1);
+ dup2(devnull, 2);
execlp("dcraw", "dcraw", "-i", filename, NULL);
_exit(1);
} else {
@@ -591,9 +635,7 @@ static char *feh_dcraw_load_image(char *filename)
close(fd);
return NULL;
} else if (childpid == 0) {
-
- close(1);
- dup(fd);
+ dup2(fd, STDOUT_FILENO);
close(fd);
alarm(opt.conversion_timeout);
@@ -818,15 +860,32 @@ static char *feh_http_load_image(char *url)
}
basename = strrchr(url, '/') + 1;
- tmpname = feh_unique_filename(path, basename);
- if (strlen(tmpname) > (NAME_MAX-6))
- tmpname[NAME_MAX-7] = '\0';
+#ifdef HAVE_MKSTEMPS
+ tmpname = estrjoin("_", "feh_curl_XXXXXX", basename, NULL);
- sfn = estrjoin("_", tmpname, "XXXXXX", NULL);
+ if (strlen(tmpname) > NAME_MAX) {
+ tmpname[NAME_MAX] = '\0';
+ }
+#else
+ if (strlen(basename) > NAME_MAX-7) {
+ tmpname = estrdup("feh_curl_XXXXXX");
+ } else {
+ tmpname = estrjoin("_", "feh_curl", basename, "XXXXXX", NULL);
+ }
+#endif
+
+ sfn = estrjoin("", path, tmpname, NULL);
free(tmpname);
+ D(("sfn is %s\n", sfn))
+
+#ifdef HAVE_MKSTEMPS
+ fd = mkstemps(sfn, strlen(basename) + 1);
+#else
fd = mkstemp(sfn);
+#endif
+
if (fd != -1) {
sfp = fdopen(fd, "w+");
if (sfp != NULL) {
@@ -835,8 +894,8 @@ static char *feh_http_load_image(char *url)
#endif
/*
* Do not allow requests to take longer than 30 minutes.
- * This should be sufficiently high to accomodate use cases with
- * unusually high latencies, while at the sime time avoiding
+ * This should be sufficiently high to accommodate use cases with
+ * unusually high latencies, while at the same time avoiding
* feh hanging indefinitely in unattended slideshows.
*/
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 1800);
@@ -844,6 +903,7 @@ static char *feh_http_load_image(char *url)
curl_easy_setopt(curl, CURLOPT_WRITEDATA, sfp);
ebuff = emalloc(CURL_ERROR_SIZE);
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, ebuff);
+ curl_easy_setopt(curl, CURLOPT_USERAGENT, PACKAGE "/" VERSION);
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
#if LIBCURL_VERSION_NUM >= 0x072000 /* 07.32.0 */
@@ -885,7 +945,11 @@ static char *feh_http_load_image(char *url)
close(fd);
}
} else {
+#ifdef HAVE_MKSTEMPS
+ weprintf("open url: mkstemps failed:");
+#else
weprintf("open url: mkstemp failed:");
+#endif
free(sfn);
}
curl_easy_cleanup(curl);
@@ -1115,7 +1179,7 @@ void feh_draw_exif(winwidget w)
if (buffer[0] == '\0')
{
- snprintf(buffer, EXIF_MAX_DATA, "%s", estrdup("Failed to run exif command"));
+ snprintf(buffer, EXIF_MAX_DATA, "%s", "Failed to run exif command");
gib_imlib_get_text_size(fn, buffer, NULL, &width, &height, IMLIB_TEXT_TO_RIGHT);
info_buf[no_lines] = estrdup(buffer);
no_lines++;
@@ -1127,29 +1191,28 @@ void feh_draw_exif(winwidget w)
{
/* max 128 lines */
pos2 = 0;
- while ( pos2 < 256 ) /* max 256 chars per line */
+ while ( pos2 < 255 ) /* max 255 chars + 1 null byte per line */
{
if ( (buffer[pos] != '\n')
&& (buffer[pos] != '\0') )
{
- info_line[pos2] = buffer[pos];
- }
- else if ( buffer[pos] == '\0' )
- {
- pos = EXIF_MAX_DATA; /* all data seen */
- info_line[pos2] = '\0';
+ info_line[pos2] = buffer[pos];
+ }
+ else if ( buffer[pos] == '\0' )
+ {
+ pos = EXIF_MAX_DATA; /* all data seen */
+ break;
+ }
+ else
+ {
+ pos++; /* line finished, continue with next line*/
+ break;
}
- else
- {
- info_line[pos2] = '\0'; /* line finished, continue with next line*/
-
- pos++;
- break;
- }
- pos++;
- pos2++;
+ pos++;
+ pos2++;
}
+ info_line[pos2] = '\0';
gib_imlib_get_text_size(fn, info_line, NULL, &line_width,
&line_height, IMLIB_TEXT_TO_RIGHT);
@@ -1184,6 +1247,7 @@ void feh_draw_exif(winwidget w)
info_buf[i], IMLIB_TEXT_TO_RIGHT, 0, 0, 0, 255);
gib_imlib_text_draw(im, fn, NULL, 1, (i * line_height) + 1,
info_buf[i], IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255);
+ free(info_buf[i]);
}
@@ -1514,8 +1578,8 @@ void feh_edit_inplace(winwidget w, int op)
FEH_FILE(w->file->data)->filename, &err);
gib_imlib_free_image(old);
if (err)
- feh_imlib_print_load_error(FEH_FILE(w->file->data)->filename,
- w, err);
+ feh_print_load_error(FEH_FILE(w->file->data)->filename,
+ w, err, LOAD_ERROR_IMLIB);
feh_reload_image(w, 1, 1);
} else {
/*
diff --git a/src/index.c b/src/index.c
index 3633c96..b0b6923 100644
--- a/src/index.c
+++ b/src/index.c
@@ -1,7 +1,7 @@
/* index.c
Copyright (C) 1999-2003 Tom Gilbert.
-Copyright (C) 2010-2020 Daniel Friesel.
+Copyright (C) 2010-2020 Birte Kristina Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -131,7 +131,7 @@ void init_index_mode(void)
weprintf(
"The image size you specified (%dx%d) is not large\n"
"enough to hold all %d thumbnails. To fit all the thumbnails,\n"
- "either decrease their size, choos e asmaller font,\n"
+ "either decrease their size, choose a smaller font,\n"
"or use a larger image (like %dx%d)",
opt.limit_w, opt.limit_h, filelist_len, w, h);
h = opt.limit_h;
@@ -332,7 +332,7 @@ void init_index_mode(void)
gib_imlib_save_image_with_error_return(im_main, output_buf, &err);
if (err) {
- feh_imlib_print_load_error(output_buf, im_main, err);
+ feh_print_load_error(output_buf, im_main, err, LOAD_ERROR_IMLIB);
}
else if (opt.verbose) {
int tw, th;
diff --git a/src/index.h b/src/index.h
index b022f1a..b805cc0 100644
--- a/src/index.h
+++ b/src/index.h
@@ -1,6 +1,6 @@
/* index.h
-Copyright (C) 2018 Daniel Friesel.
+Copyright (C) 2018 Birte Kristina Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
diff --git a/src/keyevents.c b/src/keyevents.c
index a5526a2..2f9b1d6 100644
--- a/src/keyevents.c
+++ b/src/keyevents.c
@@ -1,7 +1,7 @@
/* keyevents.c
Copyright (C) 1999-2003 Tom Gilbert.
-Copyright (C) 2010-2020 Daniel Friesel.
+Copyright (C) 2010-2020 Birte Kristina Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -35,7 +35,7 @@ struct __fehkey keys[EVENT_LIST_END];
struct termios old_term_settings;
unsigned char control_via_stdin = 0;
-void setup_stdin() {
+void setup_stdin(void) {
struct termios ctrl;
control_via_stdin = 1;
@@ -55,7 +55,7 @@ void setup_stdin() {
eprintf("tcsetattr failed");
}
-void restore_stdin() {
+void restore_stdin(void) {
if (tcsetattr(STDIN_FILENO, TCSANOW, &old_term_settings) == -1)
eprintf("tcsetattr failed");
}
@@ -314,12 +314,12 @@ void feh_event_invoke_action(winwidget winwid, unsigned char action)
return;
}
-void feh_event_handle_stdin()
+void feh_event_handle_stdin(void)
{
char stdin_buf[2];
static char is_esc = 0;
KeySym keysym = NoSymbol;
- if (read(STDIN_FILENO, &stdin_buf, 1) == -1) {
+ if (read(STDIN_FILENO, &stdin_buf, 1) <= 0) {
control_via_stdin = 0;
if (isatty(STDIN_FILENO) && getpgrp() == (tcgetpgrp(STDIN_FILENO))) {
weprintf("reading a command from stdin failed - disabling control via stdin");
@@ -359,7 +359,7 @@ void feh_event_handle_stdin()
else
keysym = XStringToKeysym(stdin_buf);
- if (window_num)
+ if (window_num && keysym)
feh_event_handle_generic(windows[0], is_esc * Mod1Mask, keysym, 0);
is_esc = 0;
@@ -603,7 +603,7 @@ void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysy
}
else if (feh_is_kp(EVENT_zoom_in, state, keysym, button)) {
winwid->old_zoom = winwid->zoom;
- winwid->zoom = winwid->zoom * 1.25;
+ winwid->zoom = winwid->zoom * opt.zoom_rate;
if (winwid->zoom > ZOOM_MAX)
winwid->zoom = ZOOM_MAX;
@@ -617,7 +617,7 @@ void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysy
}
else if (feh_is_kp(EVENT_zoom_out, state, keysym, button)) {
winwid->old_zoom = winwid->zoom;
- winwid->zoom = winwid->zoom * 0.80;
+ winwid->zoom = winwid->zoom / opt.zoom_rate;
if (winwid->zoom < ZOOM_MIN)
winwid->zoom = ZOOM_MIN;
diff --git a/src/list.c b/src/list.c
index 83df407..f293af3 100644
--- a/src/list.c
+++ b/src/list.c
@@ -1,7 +1,7 @@
/* list.c
Copyright (C) 1999-2003 Tom Gilbert.
-Copyright (C) 2010-2020 Daniel Friesel.
+Copyright (C) 2010-2020 Birte Kristina Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
diff --git a/src/main.c b/src/main.c
index 1497be2..78ee616 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,7 +1,7 @@
/* main.c
Copyright (C) 1999-2003 Tom Gilbert.
-Copyright (C) 2010-2020 Daniel Friesel.
+Copyright (C) 2010-2020 Birte Kristina Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -49,6 +49,11 @@ int main(int argc, char **argv)
srandom(getpid() * time(NULL) % ((unsigned int) -1));
setup_signal_handlers();
+
+#ifdef HAVE_LIBMAGIC
+ init_magic();
+#endif
+
init_parse_options(argc, argv);
init_imlib_fonts();
@@ -102,6 +107,28 @@ int main(int argc, char **argv)
return(sig_exit);
}
+static void feh_process_signal(void)
+{
+ winwidget winwid = winwidget_get_first_window_of_type(WIN_TYPE_SLIDESHOW);
+ int i;
+ int signo = sig_received;
+ sig_received = 0;
+
+ if (winwid) {
+ if (filelist_len > 1) {
+ if (signo == SIGUSR1)
+ slideshow_change_image(winwid, SLIDE_NEXT, 1);
+ else if (signo == SIGUSR2)
+ slideshow_change_image(winwid, SLIDE_PREV, 1);
+ } else {
+ feh_reload_image(winwid, 0, 0);
+ }
+ } else if (opt.multiwindow) {
+ for (i = window_num - 1; i >= 0; i--)
+ feh_reload_image(windows[i], 0, 0);
+ }
+}
+
/* Return 0 to stop iterating, 1 if ok to continue. */
int feh_main_iteration(int block)
{
@@ -119,6 +146,10 @@ int feh_main_iteration(int block)
if (window_num == 0 || sig_exit != 0)
return(0);
+ if (sig_received) {
+ feh_process_signal();
+ }
+
if (first) {
/* Only need to set these up the first time */
xfd = ConnectionNumber(disp);
@@ -151,6 +182,10 @@ int feh_main_iteration(int block)
if (window_num == 0 || sig_exit != 0)
return(0);
+
+ if (sig_received) {
+ feh_process_signal();
+ }
}
XFlush(disp);
@@ -158,8 +193,9 @@ int feh_main_iteration(int block)
FD_ZERO(&fdset);
FD_SET(xfd, &fdset);
- if (control_via_stdin)
+ if (control_via_stdin) {
FD_SET(STDIN_FILENO, &fdset);
+ }
#ifdef HAVE_INOTIFY
if (opt.auto_reload) {
FD_SET(opt.inotify_fd, &fdset);
@@ -210,7 +246,12 @@ int feh_main_iteration(int block)
in that */
feh_handle_timer();
}
- else if ((count > 0) && (FD_ISSET(0, &fdset)))
+ /*
+ * Beware: If stdin is not connected, we may end up with xfd == 0.
+ * However, STDIN_FILENO == 0 holds as well in most cases. So we must
+ * check control_via_stdin to avoid mistaking an X11 event for stdin.
+ */
+ else if ((count > 0) && control_via_stdin && (FD_ISSET(STDIN_FILENO, &fdset)))
feh_event_handle_stdin();
#ifdef HAVE_INOTIFY
else if ((count > 0) && (FD_ISSET(opt.inotify_fd, &fdset)))
@@ -227,7 +268,7 @@ int feh_main_iteration(int block)
&& ((errno == ENOMEM) || (errno == EINVAL)
|| (errno == EBADF)))
eprintf("Connection to X display lost");
- else if ((count > 0) && (FD_ISSET(0, &fdset)))
+ else if ((count > 0) && control_via_stdin && (FD_ISSET(STDIN_FILENO, &fdset)))
feh_event_handle_stdin();
#ifdef HAVE_INOTIFY
else if ((count > 0) && (FD_ISSET(opt.inotify_fd, &fdset)))
@@ -237,7 +278,11 @@ int feh_main_iteration(int block)
}
if (window_num == 0 || sig_exit != 0)
return(0);
-
+
+ if (sig_received) {
+ feh_process_signal();
+ }
+
return(1);
}
@@ -256,6 +301,10 @@ void feh_clean_exit(void)
if(disp)
XCloseDisplay(disp);
+#ifdef HAVE_LIBMAGIC
+ uninit_magic();
+#endif
+
/*
* Only restore the old terminal settings if
* - we changed them in the first place
diff --git a/src/menu.c b/src/menu.c
index b1deedb..b1ef61d 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -1,7 +1,7 @@
/* menu.c
Copyright (C) 1999-2003 Tom Gilbert.
-Copyright (C) 2010-2020 Daniel Friesel.
+Copyright (C) 2010-2020 Birte Kristina Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -825,21 +825,17 @@ void feh_menu_draw_toggle_at(int x, int y, int w, int h, Imlib_Image dst, int ox
void feh_menu_draw_submenu_at(int x, int y, Imlib_Image dst, int ox, int oy)
{
- ImlibPolygon poly;
-
- x -= ox;
+ // Draw filled triangle
+ x -= ox;
y -= oy;
imlib_context_set_image(dst);
-
- poly = imlib_polygon_new();
- imlib_polygon_add_point(poly, x, y + 3);
- imlib_polygon_add_point(poly, x + 3, y + 6);
- imlib_polygon_add_point(poly, x, y + 9);
imlib_context_set_color(0, 0, 0, 255);
- imlib_image_fill_polygon(poly);
- imlib_polygon_free(poly);
+ for (int i= 0; i <= 3; i++) {
+ imlib_image_draw_line(x+i, y+3+i, x+i, y+9-i, 0);
+ }
+
return;
}
@@ -936,7 +932,7 @@ void feh_menu_init_main(void)
return;
}
-void feh_menu_init_common()
+void feh_menu_init_common(void)
{
int num_desks, i;
char buf[30];
diff --git a/src/menu.h b/src/menu.h
index 3ab29bc..5bad00c 100644
--- a/src/menu.h
+++ b/src/menu.h
@@ -1,7 +1,7 @@
/* menu.h
Copyright (C) 1999-2003 Tom Gilbert.
-Copyright (C) 2010-2020 Daniel Friesel.
+Copyright (C) 2010-2020 Birte Kristina Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
diff --git a/src/options.c b/src/options.c
index 04f02c5..0fc656d 100644
--- a/src/options.c
+++ b/src/options.c
@@ -1,7 +1,7 @@
/* options.c
Copyright (C) 1999-2003 Tom Gilbert.
-Copyright (C) 2010-2020 Daniel Friesel.
+Copyright (C) 2010-2020 Birte Kristina Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -63,6 +63,8 @@ void init_parse_options(int argc, char **argv)
opt.font = NULL;
opt.max_height = opt.max_width = UINT_MAX;
+ opt.zoom_rate = 1.25;
+
opt.start_list_at = NULL;
opt.jump_on_resort = 1;
@@ -330,109 +332,111 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)
/* (*name, has_arg, *flag, val) See: struct option in getopts.h */
static struct option lopts[] = {
- {"debug" , 0, 0, '+'},
- {"scale-down" , 0, 0, '.'},
- {"max-dimension" , 1, 0, '<'},
- {"min-dimension" , 1, 0, '>'},
- {"title-font" , 1, 0, '@'},
- {"action" , 1, 0, 'A'},
- {"image-bg" , 1, 0, 'B'},
- {"fontpath" , 1, 0, 'C'},
- {"slideshow-delay",1, 0, 'D'},
- {"thumb-height" , 1, 0, 'E'},
- {"full-screen" , 0, 0, 'F'}, /* deprecated */
- {"fullscreen" , 0, 0, 'F'},
- {"draw-actions" , 0, 0, 'G'},
- {"limit-height" , 1, 0, 'H'},
- {"fullindex" , 0, 0, 'I'},
- {"thumb-redraw" , 1, 0, 'J'},
- {"caption-path" , 1, 0, 'K'},
- {"customlist" , 1, 0, 'L'},
- {"menu-font" , 1, 0, 'M'},
- {"no-menus" , 0, 0, 'N'},
- {"output-only" , 1, 0, 'O'},
- {"cache-thumbnails", 0, 0, 'P'},
- {"reload" , 1, 0, 'R'},
- {"sort" , 1, 0, 'S'},
- {"theme" , 1, 0, 'T'},
- {"loadable" , 0, 0, 'U'},
- {"verbose" , 0, 0, 'V'},
- {"limit-width" , 1, 0, 'W'},
- {"ignore-aspect" , 0, 0, 'X'},
- {"hide-pointer" , 0, 0, 'Y'},
- {"auto-zoom" , 0, 0, 'Z'},
- {"title" , 1, 0, '^'},
- {"alpha" , 1, 0, 'a'},
- {"bg" , 1, 0, 'b'},
- {"draw-filename" , 0, 0, 'd'},
- {"font" , 1, 0, 'e'},
- {"filelist" , 1, 0, 'f'},
- {"geometry" , 1, 0, 'g'},
- {"help" , 0, 0, 'h'},
- {"index" , 0, 0, 'i'},
- {"output-dir" , 1, 0, 'j'},
- {"keep-http" , 0, 0, 'k'},
- {"list" , 0, 0, 'l'},
- {"montage" , 0, 0, 'm'},
- {"reverse" , 0, 0, 'n'},
- {"output" , 1, 0, 'o'},
- {"preload" , 0, 0, 'p'},
- {"quiet" , 0, 0, 'q'},
- {"recursive" , 0, 0, 'r'},
- {"stretch" , 0, 0, 's'},
- {"thumbnails" , 0, 0, 't'},
- {"unloadable" , 0, 0, 'u'},
- {"version" , 0, 0, 'v'},
- {"multiwindow" , 0, 0, 'w'},
- {"borderless" , 0, 0, 'x'},
- {"thumb-width" , 1, 0, 'y'},
- {"randomize" , 0, 0, 'z'},
- {"start-at" , 1, 0, '|'},
- {"thumb-title" , 1, 0, '~'},
- {"bg-tile" , 0, 0, 200},
- {"bg-center" , 0, 0, 201},
- {"bg-scale" , 0, 0, 202},
- {"zoom" , 1, 0, 205},
- {"no-screen-clip", 0, 0, 206},
- {"index-info" , 1, 0, 207},
- {"magick-timeout", 1, 0, 208},
- {"action1" , 1, 0, 209},
- {"action2" , 1, 0, 210},
- {"action3" , 1, 0, 211},
- {"action4" , 1, 0, 212},
- {"action5" , 1, 0, 213},
- {"action6" , 1, 0, 214},
- {"action7" , 1, 0, 215},
- {"action8" , 1, 0, 216},
- {"action9" , 1, 0, 217},
- {"bg-fill" , 0, 0, 218},
- {"bg-max" , 0, 0, 219},
- {"no-jump-on-resort", 0, 0, 220},
- {"edit" , 0, 0, 221},
+ {"debug" , 0, 0, OPTION_debug},
+ {"scale-down" , 0, 0, OPTION_scale_down},
+ {"max-dimension" , 1, 0, OPTION_max_dimension},
+ {"min-dimension" , 1, 0, OPTION_min_dimension},
+ {"title-font" , 1, 0, OPTION_title_font},
+ {"action" , 1, 0, OPTION_action},
+ {"image-bg" , 1, 0, OPTION_image_bg},
+ {"fontpath" , 1, 0, OPTION_fontpath},
+ {"slideshow-delay",1, 0, OPTION_slideshow_delay},
+ {"thumb-height" , 1, 0, OPTION_thumb_height},
+ {"full-screen" , 0, 0, OPTION_fullscreen}, /* deprecated */
+ {"fullscreen" , 0, 0, OPTION_fullscreen},
+ {"draw-actions" , 0, 0, OPTION_draw_actions},
+ {"limit-height" , 1, 0, OPTION_limit_height},
+ {"fullindex" , 0, 0, OPTION_fullindex},
+ {"thumb-redraw" , 1, 0, OPTION_thumb_redraw},
+ {"caption-path" , 1, 0, OPTION_caption_path},
+ {"customlist" , 1, 0, OPTION_customlist},
+ {"menu-font" , 1, 0, OPTION_menu_font},
+ {"no-menus" , 0, 0, OPTION_no_menus},
+ {"output-only" , 1, 0, OPTION_output_only},
+ {"cache-thumbnails", 0, 0, OPTION_cache_thumbnails},
+ {"reload" , 1, 0, OPTION_reload},
+ {"sort" , 1, 0, OPTION_sort},
+ {"theme" , 1, 0, OPTION_theme},
+ {"loadable" , 0, 0, OPTION_loadable},
+ {"verbose" , 0, 0, OPTION_verbose},
+ {"limit-width" , 1, 0, OPTION_limit_width},
+ {"ignore-aspect" , 0, 0, OPTION_ignore_aspect},
+ {"hide-pointer" , 0, 0, OPTION_hide_pointer},
+ {"auto-zoom" , 0, 0, OPTION_auto_zoom},
+ {"title" , 1, 0, OPTION_title},
+ {"alpha" , 1, 0, OPTION_alpha},
+ {"bg" , 1, 0, OPTION_bg},
+ {"draw-filename" , 0, 0, OPTION_draw_filename},
+ {"font" , 1, 0, OPTION_font},
+ {"filelist" , 1, 0, OPTION_filelist},
+ {"geometry" , 1, 0, OPTION_geometry},
+ {"help" , 0, 0, OPTION_help},
+ {"index" , 0, 0, OPTION_index},
+ {"output-dir" , 1, 0, OPTION_output_dir},
+ {"keep-http" , 0, 0, OPTION_keep_http},
+ {"list" , 0, 0, OPTION_list},
+ {"montage" , 0, 0, OPTION_montage},
+ {"reverse" , 0, 0, OPTION_reverse},
+ {"output" , 1, 0, OPTION_output},
+ {"preload" , 0, 0, OPTION_preload},
+ {"quiet" , 0, 0, OPTION_quiet},
+ {"recursive" , 0, 0, OPTION_recursive},
+ {"stretch" , 0, 0, OPTION_stretch},
+ {"thumbnails" , 0, 0, OPTION_thumbnails},
+ {"unloadable" , 0, 0, OPTION_unloadable},
+ {"version" , 0, 0, OPTION_version},
+ {"multiwindow" , 0, 0, OPTION_multiwindow},
+ {"borderless" , 0, 0, OPTION_borderless},
+ {"thumb-width" , 1, 0, OPTION_thumb_width},
+ {"randomize" , 0, 0, OPTION_randomize},
+ {"start-at" , 1, 0, OPTION_start_at},
+ {"thumb-title" , 1, 0, OPTION_thumb_title},
+ {"bg-tile" , 0, 0, OPTION_bg_title},
+ {"bg-center" , 0, 0, OPTION_bg_center},
+ {"bg-scale" , 0, 0, OPTION_bg_scale},
+ {"zoom" , 1, 0, OPTION_zoom},
+ {"zoom-step" , 1, 0, OPTION_zoom_step},
+ {"no-screen-clip", 0, 0, OPTION_no_screen_clip},
+ {"index-info" , 1, 0, OPTION_index_info},
+ {"magick-timeout", 1, 0, OPTION_magick_timeout},
+ {"action1" , 1, 0, OPTION_action1},
+ {"action2" , 1, 0, OPTION_action2},
+ {"action3" , 1, 0, OPTION_action3},
+ {"action4" , 1, 0, OPTION_action4},
+ {"action5" , 1, 0, OPTION_action5},
+ {"action6" , 1, 0, OPTION_action6},
+ {"action7" , 1, 0, OPTION_action7},
+ {"action8" , 1, 0, OPTION_action8},
+ {"action9" , 1, 0, OPTION_action9},
+ {"bg-fill" , 0, 0, OPTION_bg_fill},
+ {"bg-max" , 0, 0, OPTION_bg_max},
+ {"no-jump-on-resort", 0, 0, OPTION_no_jump_on_resort},
+ {"edit" , 0, 0, OPTION_edit},
#ifdef HAVE_LIBEXIF
- {"draw-exif" , 0, 0, 223},
- {"auto-rotate" , 0, 0, 242},
+ {"draw-exif" , 0, 0, OPTION_draw_exif},
+ {"auto-rotate" , 0, 0, OPTION_auto_rotate},
#endif
- {"no-xinerama" , 0, 0, 225},
- {"draw-tinted" , 0, 0, 229},
- {"info" , 1, 0, 234},
- {"force-aliasing", 0, 0, 235},
- {"no-fehbg" , 0, 0, 236},
- {"keep-zoom-vp" , 0, 0, 237},
- {"scroll-step" , 1, 0, 238},
- {"xinerama-index", 1, 0, 239},
- {"insecure" , 0, 0, 240},
- {"no-recursive" , 0, 0, 241},
- {"cache-size" , 1, 0, 243},
- {"on-last-slide" , 1, 0, 244},
- {"conversion-timeout" , 1, 0, 245},
- {"version-sort" , 0, 0, 246},
- {"offset" , 1, 0, 247},
+ {"no-xinerama" , 0, 0, OPTION_no_xinerama},
+ {"draw-tinted" , 0, 0, OPTION_draw_tinted},
+ {"info" , 1, 0, OPTION_info},
+ {"force-aliasing", 0, 0, OPTION_force_aliasing},
+ {"no-fehbg" , 0, 0, OPTION_no_fehbg},
+ {"keep-zoom-vp" , 0, 0, OPTION_keep_zoom_vp},
+ {"scroll-step" , 1, 0, OPTION_scroll_step},
+ {"xinerama-index", 1, 0, OPTION_xinerama_index},
+ {"insecure" , 0, 0, OPTION_insecure},
+ {"no-recursive" , 0, 0, OPTION_recursive},
+ {"cache-size" , 1, 0, OPTION_cache_size},
+ {"on-last-slide" , 1, 0, OPTION_on_last_slide},
+ {"conversion-timeout" , 1, 0, OPTION_conversion_timeout},
+ {"version-sort" , 0, 0, OPTION_version_sort},
+ {"offset" , 1, 0, OPTION_offset},
#ifdef HAVE_INOTIFY
- {"auto-reload" , 0, 0, 248},
+ {"auto-reload" , 0, 0, OPTION_auto_reload},
#endif
- {"class" , 1, 0, 249},
- {"no-conversion-cache", 0, 0, 250},
+ {"class" , 1, 0, OPTION_class},
+ {"no-conversion-cache", 0, 0, OPTION_no_conversion_cache},
+ {"window-id", 1, 0, OPTION_window_id},
{0, 0, 0, 0}
};
int optch = 0, cmdx = 0;
@@ -442,10 +446,10 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)
switch (optch) {
case 0:
break;
- case '+':
+ case OPTION_debug:
opt.debug = 1;
break;
- case '<':
+ case OPTION_max_dimension:
opt.filter_by_dimensions = 1;
XParseGeometry(optarg, &discard, &discard, &opt.max_width, &opt.max_height);
if (opt.max_width == 0)
@@ -453,27 +457,27 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)
if (opt.max_height == 0)
opt.max_height = UINT_MAX;
break;
- case '>':
+ case OPTION_min_dimension:
opt.filter_by_dimensions = 1;
XParseGeometry(optarg, &discard, &discard, &opt.min_width, &opt.min_height);
break;
- case '.':
+ case OPTION_scale_down:
opt.scale_down = 1;
break;
- case '@':
+ case OPTION_title_font:
opt.title_font = estrdup(optarg);
break;
- case 'A':
+ case OPTION_action:
opt.actions[0] = estrdup(optarg);
break;
- case 'B':
+ case OPTION_image_bg:
opt.image_bg = estrdup(optarg);
break;
- case 'C':
+ case OPTION_fontpath:
D(("adding fontpath %s\n", optarg));
imlib_add_path_to_font_path(optarg);
break;
- case 'D':
+ case OPTION_slideshow_delay:
opt.slideshow_delay = atof(optarg);
if (opt.slideshow_delay < 0.0) {
opt.slideshow_delay *= (-1);
@@ -482,57 +486,59 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)
opt.paused = 0;
}
break;
- case 'E':
+ case OPTION_thumb_height:
opt.thumb_h = atoi(optarg);
break;
- case 'F':
+ case OPTION_fullscreen:
opt.full_screen = 1;
break;
- case 'G':
+ case OPTION_draw_actions:
opt.draw_actions = 1;
break;
- case 'H':
+ case OPTION_limit_height:
opt.limit_h = atoi(optarg);
break;
- case 'I':
+ case OPTION_fullindex:
opt.index = 1;
opt.index_info = estrdup("%n\n%S\n%wx%h");
break;
- case 'J':
+ case OPTION_thumb_redraw:
opt.thumb_redraw = atoi(optarg);
break;
- case 'K':
+ case OPTION_caption_path:
opt.caption_path = estrdup(optarg);
break;
- case 'L':
+ case OPTION_customlist:
opt.customlist = estrdup(optarg);
opt.display = 0;
break;
- case 'M':
+ case OPTION_menu_font:
free(opt.menu_font);
opt.menu_font = estrdup(optarg);
break;
- case 'N':
+ case OPTION_no_menus:
opt.no_menus = 1;
break;
- case 'O':
+ case OPTION_output_only:
opt.output = 1;
opt.output_file = estrdup(optarg);
opt.display = 0;
break;
- case 'P':
+ case OPTION_cache_thumbnails:
opt.cache_thumbnails = 1;
break;
- case 'R':
+ case OPTION_reload:
opt.reload = atof(optarg);
opt.use_conversion_cache = 0;
#ifdef HAVE_INOTIFY
opt.auto_reload = 0;
#endif
break;
- case 'S':
+ case OPTION_sort:
if (!strcasecmp(optarg, "name"))
opt.sort = SORT_NAME;
+ else if (!strcasecmp(optarg, "none"))
+ opt.sort = SORT_NONE;
else if (!strcasecmp(optarg, "filename"))
opt.sort = SORT_FILENAME;
else if (!strcasecmp(optarg, "dirname"))
@@ -560,116 +566,116 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)
opt.randomize = 0;
}
break;
- case 'T':
+ case OPTION_theme:
theme = estrdup(optarg);
break;
- case 'U':
+ case OPTION_loadable:
opt.loadables = 1;
opt.display = 0;
break;
- case 'V':
+ case OPTION_verbose:
opt.verbose = 1;
break;
- case 'W':
+ case OPTION_limit_width:
opt.limit_w = atoi(optarg);
break;
- case 'X':
+ case OPTION_ignore_aspect:
opt.aspect = 0;
break;
- case 'Y':
+ case OPTION_hide_pointer:
opt.hide_pointer = 1;
break;
- case 'Z':
+ case OPTION_auto_zoom:
opt.zoom_mode = ZOOM_MODE_MAX;
break;
- case '^':
+ case OPTION_title:
opt.title = estrdup(optarg);
break;
- case 'a':
+ case OPTION_alpha:
opt.alpha = 1;
opt.alpha_level = 255 - atoi(optarg);
break;
- case 'b':
+ case OPTION_bg:
opt.bg = 1;
opt.bg_file = estrdup(optarg);
break;
- case 'd':
+ case OPTION_draw_filename:
opt.draw_filename = 1;
break;
- case 'e':
+ case OPTION_font:
opt.font = estrdup(optarg);
break;
- case 'f':
+ case OPTION_filelist:
if (!strcmp(optarg, "-"))
opt.filelistfile = estrdup("/dev/stdin");
else
opt.filelistfile = estrdup(optarg);
break;
- case 'g':
+ case OPTION_geometry:
opt.geom_enabled = 1;
opt.geom_flags = XParseGeometry(optarg, &opt.geom_x,
&opt.geom_y, &opt.geom_w, &opt.geom_h);
break;
- case 'h':
+ case OPTION_help:
show_usage();
break;
- case 'i':
+ case OPTION_index:
opt.index = 1;
opt.index_info = estrdup("%n");
break;
- case 'j':
+ case OPTION_output_dir:
opt.output_dir = estrdup(optarg);
break;
- case 'k':
+ case OPTION_keep_http:
opt.keep_http = 1;
break;
- case 'l':
+ case OPTION_list:
opt.list = 1;
opt.display = 0;
break;
- case 'm':
+ case OPTION_montage:
opt.index = 1;
break;
- case 'n':
+ case OPTION_reverse:
opt.reverse = 1;
break;
- case 'o':
+ case OPTION_output:
opt.output = 1;
opt.output_file = estrdup(optarg);
break;
- case 'p':
+ case OPTION_preload:
opt.preload = 1;
break;
- case 'q':
+ case OPTION_quiet:
opt.quiet = 1;
break;
- case 'r':
+ case OPTION_recursive:
opt.recursive = 1;
break;
- case 's':
+ case OPTION_stretch:
opt.stretch = 1;
break;
- case 't':
+ case OPTION_thumbnails:
opt.thumbs = 1;
opt.index_info = estrdup("%n");
break;
- case 'u':
+ case OPTION_unloadable:
opt.unloadables = 1;
opt.display = 0;
break;
- case 'v':
+ case OPTION_version:
show_version();
break;
- case 'w':
+ case OPTION_multiwindow:
opt.multiwindow = 1;
break;
- case 'x':
+ case OPTION_borderless:
opt.borderless = 1;
break;
- case 'y':
+ case OPTION_thumb_width:
opt.thumb_w = atoi(optarg);
break;
- case 'z':
+ case OPTION_randomize:
opt.randomize = 1;
if (opt.sort != SORT_NONE) {
weprintf("commandline contains --sort and --randomize. "
@@ -677,22 +683,22 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)
opt.sort = SORT_NONE;
}
break;
- case '|':
+ case OPTION_start_at:
opt.start_list_at = estrdup(optarg);
break;
- case '~':
+ case OPTION_thumb_title:
opt.thumb_title = estrdup(optarg);
break;
- case 200:
+ case OPTION_bg_title:
opt.bgmode = BG_MODE_TILE;
break;
- case 201:
+ case OPTION_bg_center:
opt.bgmode = BG_MODE_CENTER;
break;
- case 202:
+ case OPTION_bg_scale:
opt.bgmode = BG_MODE_SCALE;
break;
- case 205:
+ case OPTION_zoom:
if (!strcmp("fill", optarg))
opt.zoom_mode = ZOOM_MODE_FILL;
else if (!strcmp("max", optarg))
@@ -700,70 +706,75 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)
else
opt.default_zoom = atoi(optarg);
break;
- case 206:
+ case OPTION_no_screen_clip:
opt.screen_clip = 0;
break;
- case 207:
+ case OPTION_index_info:
opt.index_info = estrdup(optarg);
break;
- case 208:
+ case OPTION_magick_timeout:
weprintf("--magick-timeout is deprecated, please use --conversion-timeout instead");
opt.conversion_timeout = atoi(optarg);
break;
- case 209:
+ case OPTION_action1:
opt.actions[1] = estrdup(optarg);
break;
- case 210:
+ case OPTION_action2:
opt.actions[2] = estrdup(optarg);
break;
- case 211:
+ case OPTION_action3:
opt.actions[3] = estrdup(optarg);
break;
- case 212:
+ case OPTION_action4:
opt.actions[4] = estrdup(optarg);
break;
- case 213:
+ case OPTION_action5:
opt.actions[5] = estrdup(optarg);
break;
- case 214:
+ case OPTION_action6:
opt.actions[6] = estrdup(optarg);
break;
- case 215:
+ case OPTION_action7:
opt.actions[7] = estrdup(optarg);
break;
- case 216:
+ case OPTION_action8:
opt.actions[8] = estrdup(optarg);
break;
- case 217:
+ case OPTION_action9:
opt.actions[9] = estrdup(optarg);
break;
- case 218:
+ case OPTION_bg_fill:
opt.bgmode = BG_MODE_FILL;
break;
- case 219:
+ case OPTION_bg_max:
opt.bgmode = BG_MODE_MAX;
break;
- case 220:
+ case OPTION_no_jump_on_resort:
opt.jump_on_resort = 0;
break;
- case 221:
+ case OPTION_edit:
opt.edit = 1;
break;
#ifdef HAVE_LIBEXIF
- case 223:
+ case OPTION_draw_exif:
opt.draw_exif = 1;
break;
- case 242:
+ case OPTION_auto_rotate:
+#if defined(IMLIB2_VERSION_MAJOR) && defined(IMLIB2_VERSION_MINOR) && defined(IMLIB2_VERSION_MICRO) && (IMLIB2_VERSION_MAJOR > 1 || IMLIB2_VERSION_MINOR > 7 || IMLIB2_VERSION_MICRO >= 5)
+ weprintf("This feh release was built with Imlib2 version %d.%d.%d, which transparently adjusts for image orientation according to EXIF data.", IMLIB2_VERSION_MAJOR, IMLIB2_VERSION_MINOR, IMLIB2_VERSION_MICRO);
+ weprintf("--auto-rotate would rotate an already correctly oriented image, resulting in incorrect orientation. It has been disabled in this build. Rebuild feh with Imlib2 <1.7.5 to enable --auto-rotate.");
+#else
opt.auto_rotate = 1;
+#endif
break;
#endif
- case 225:
+ case OPTION_no_xinerama:
opt.xinerama = 0;
break;
- case 229:
+ case OPTION_draw_tinted:
opt.text_bg = TEXT_BG_TINTED;
break;
- case 234:
+ case OPTION_info:
opt.info_cmd = estrdup(optarg);
if (opt.info_cmd[0] == ';') {
opt.draw_info = 0;
@@ -772,35 +783,35 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)
opt.draw_info = 1;
}
break;
- case 235:
+ case OPTION_force_aliasing:
opt.force_aliasing = 1;
break;
- case 236:
+ case OPTION_no_fehbg:
opt.no_fehbg = 1;
break;
- case 237:
+ case OPTION_keep_zoom_vp:
opt.keep_zoom_vp = 1;
break;
- case 238:
+ case OPTION_scroll_step:
opt.scroll_step = atoi(optarg);
break;
- case 239:
+ case OPTION_xinerama_index:
opt.xinerama_index = atoi(optarg);
break;
- case 240:
+ case OPTION_insecure:
opt.insecure_ssl = 1;
break;
- case 241:
+ case OPTION_no_recursive:
opt.recursive = 0;
break;
- case 243:
+ case OPTION_cache_size:
opt.cache_size = atoi(optarg);
if (opt.cache_size < 0)
opt.cache_size = 0;
if (opt.cache_size > 2048)
opt.cache_size = 2048;
break;
- case 244:
+ case OPTION_on_last_slide:
if (!strcmp(optarg, "quit")) {
opt.on_last_slide = ON_LAST_SLIDE_QUIT;
} else if (!strcmp(optarg, "hold")) {
@@ -812,27 +823,39 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)
"Supported actions: hold, resume, quit\n", optarg);
}
break;
- case 245:
+ case OPTION_conversion_timeout:
opt.conversion_timeout = atoi(optarg);
break;
- case 246:
+ case OPTION_version_sort:
opt.version_sort = 1;
break;
- case 247:
+ case OPTION_offset:
opt.offset_flags = XParseGeometry(optarg, &opt.offset_x,
&opt.offset_y, (unsigned int *)&discard, (unsigned int *)&discard);
break;
#ifdef HAVE_INOTIFY
- case 248:
+ case OPTION_auto_reload:
opt.auto_reload = 1;
break;
#endif
- case 249:
+ case OPTION_class:
opt.x11_class = estrdup(optarg);
break;
- case 250:
+ case OPTION_no_conversion_cache:
opt.use_conversion_cache = 0;
break;
+ case OPTION_window_id:
+ opt.x11_windowid = strtol(optarg, NULL, 0);
+ break;
+ case OPTION_zoom_step:
+ opt.zoom_rate = atof(optarg);
+ if ((opt.zoom_rate <= 0)) {
+ weprintf("Zooming disabled due to --zoom-step=%f", opt.zoom_rate);
+ opt.zoom_rate = 1.0;
+ } else {
+ opt.zoom_rate = 1 + ((float)opt.zoom_rate / 100);
+ }
+ break;
default:
break;
}
@@ -855,11 +878,26 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)
*/
if (opt.start_list_at && path_is_url(opt.start_list_at) && (strlen(opt.start_list_at) <= 8 || strncmp(opt.start_list_at, "file:///", 8) != 0)) {
add_file_to_filelist_recursively(opt.start_list_at, FILELIST_FIRST);
+ /*
+ * Otherwise, make "feh --start-at dir/file.jpg" behave like
+ * "feh --start-at dir/file.jpg dir".
+ */
} else if (opt.start_list_at && strrchr(opt.start_list_at, '/')) {
+ /*
+ * feh can't candle urlencoded path components ("some%20dir" etc).
+ * Use libcurl to unescape them if --start-at is file://...
+ */
if (strlen(opt.start_list_at) > 8 && strncmp(opt.start_list_at, "file:///", 8) == 0) {
- char *start_at_path = estrdup(opt.start_list_at + 7);
- free(opt.start_list_at);
- opt.start_list_at = start_at_path;
+ char *unescaped_path = feh_http_unescape(opt.start_list_at);
+ if (unescaped_path != NULL) {
+ free(opt.start_list_at);
+ opt.start_list_at = estrdup(unescaped_path + 7);
+ free(unescaped_path);
+ } else {
+ char *new_path = estrdup(opt.start_list_at + 7);
+ free(opt.start_list_at);
+ opt.start_list_at = new_path;
+ }
}
char *target_directory = estrdup(opt.start_list_at);
char *filename_start = strrchr(target_directory, '/');
@@ -867,6 +905,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)
*filename_start = '\0';
}
add_file_to_filelist_recursively(target_directory, FILELIST_FIRST);
+ original_file_items = gib_list_add_front(original_file_items, estrdup(target_directory));
free(target_directory);
} else {
add_file_to_filelist_recursively(".", FILELIST_FIRST);
@@ -939,6 +978,10 @@ static void show_version(void)
"help "
#endif
+#ifdef HAVE_LIBMAGIC
+ "magic "
+#endif
+
#if _FILE_OFFSET_BITS == 64
"stat64 "
#endif
diff --git a/src/options.h b/src/options.h
index 4906004..aa3cd91 100644
--- a/src/options.h
+++ b/src/options.h
@@ -1,7 +1,7 @@
/* options.h
Copyright (C) 1999-2003 Tom Gilbert.
-Copyright (C) 2010-2020 Daniel Friesel.
+Copyright (C) 2010-2020 Birte Kristina Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -127,9 +127,11 @@ struct __fehoptions {
int offset_y;
int default_zoom;
int zoom_mode;
+ double zoom_rate;
unsigned char adjust_reload;
int xinerama_index;
char *x11_class;
+ unsigned long int x11_windowid;
/* signed in case someone wants to invert scrolling real quick */
int scroll_step;
@@ -149,6 +151,113 @@ struct __fehoptions {
Imlib_Font menu_fn;
};
+enum __feh_option {
+OPTION_debug = '+',
+OPTION_scale_down = '.',
+OPTION_max_dimension = '<',
+OPTION_min_dimension = '>',
+OPTION_title_font = '@',
+OPTION_action = 'A',
+OPTION_image_bg = 'B',
+OPTION_fontpath = 'C',
+OPTION_slideshow_delay = 'D',
+OPTION_thumb_height = 'E',
+OPTION_fullscreen = 'F',
+OPTION_draw_actions = 'G',
+OPTION_limit_height = 'H',
+OPTION_fullindex = 'I',
+OPTION_thumb_redraw = 'J',
+OPTION_caption_path = 'K',
+OPTION_customlist = 'L',
+OPTION_menu_font = 'M',
+OPTION_no_menus = 'N',
+OPTION_output_only = 'O',
+OPTION_cache_thumbnails = 'P',
+OPTION_reload = 'R',
+OPTION_sort = 'S',
+OPTION_theme = 'T',
+OPTION_loadable = 'U',
+OPTION_verbose = 'V',
+OPTION_limit_width = 'W',
+OPTION_ignore_aspect = 'X',
+OPTION_hide_pointer = 'Y',
+OPTION_auto_zoom = 'Z',
+OPTION_title = '^',
+OPTION_alpha = 'a',
+OPTION_bg = 'b',
+OPTION_draw_filename = 'd',
+OPTION_font = 'e',
+OPTION_filelist = 'f',
+OPTION_geometry = 'g',
+OPTION_help = 'h',
+OPTION_index = 'i',
+OPTION_output_dir = 'j',
+OPTION_keep_http = 'k',
+OPTION_list = 'l',
+OPTION_montage = 'm',
+OPTION_reverse = 'n',
+OPTION_output = 'o',
+OPTION_preload = 'p',
+OPTION_quiet = 'q',
+OPTION_recursive = 'r',
+OPTION_stretch = 's',
+OPTION_thumbnails = 't',
+OPTION_unloadable = 'u',
+OPTION_version = 'v',
+OPTION_multiwindow = 'w',
+OPTION_borderless = 'x',
+OPTION_thumb_width = 'y',
+OPTION_randomize = 'z',
+OPTION_start_at = '|',
+OPTION_thumb_title = '~',
+OPTION_bg_title,
+OPTION_bg_center,
+OPTION_bg_scale,
+OPTION_bg_fill,
+OPTION_bg_max,
+OPTION_zoom,
+OPTION_zoom_step,
+OPTION_zoom_in_rate,
+OPTION_zoom_out_rate,
+OPTION_keep_zoom_vp,
+OPTION_no_screen_clip,
+OPTION_index_info,
+OPTION_magick_timeout,
+OPTION_action1,
+OPTION_action2,
+OPTION_action3,
+OPTION_action4,
+OPTION_action5,
+OPTION_action6,
+OPTION_action7,
+OPTION_action8,
+OPTION_action9,
+OPTION_no_jump_on_resort,
+OPTION_edit,
+OPTION_draw_exif,
+OPTION_auto_rotate,
+OPTION_no_xinerama,
+OPTION_draw_tinted,
+OPTION_info,
+OPTION_force_aliasing,
+OPTION_no_fehbg,
+OPTION_scroll_step,
+OPTION_xinerama_index,
+OPTION_insecure,
+OPTION_no_recursive,
+OPTION_cache_size,
+OPTION_on_last_slide,
+OPTION_conversion_timeout,
+OPTION_version_sort,
+OPTION_offset,
+OPTION_auto_reload,
+OPTION_class,
+OPTION_no_conversion_cache,
+OPTION_window_id,
+};
+
+//typedef enum __fehoption fehoption;
+
struct __fehkey {
unsigned int keysyms[3];
unsigned int keystates[3];
diff --git a/src/signals.c b/src/signals.c
index a64f935..5a64883 100644
--- a/src/signals.c
+++ b/src/signals.c
@@ -1,6 +1,6 @@
/* signals.c
-Copyright (C) 2010-2020 by Daniel Friesel
+Copyright (C) 2010-2020 by Birte Kristina Friesel
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -29,9 +29,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "options.h"
void feh_handle_signal(int);
+volatile int sig_received = 0;
volatile int sig_exit = 0;
-void setup_signal_handlers()
+void setup_signal_handlers(void)
{
struct sigaction feh_sh;
sigset_t feh_ss;
@@ -71,9 +72,6 @@ void setup_signal_handlers()
void feh_handle_signal(int signo)
{
- winwidget winwid;
- int i;
-
switch (signo) {
case SIGALRM:
if (childpid)
@@ -92,21 +90,5 @@ void feh_handle_signal(int signo)
return;
}
- winwid = winwidget_get_first_window_of_type(WIN_TYPE_SLIDESHOW);
-
- if (winwid) {
- if (filelist_len > 1) {
- if (signo == SIGUSR1)
- slideshow_change_image(winwid, SLIDE_NEXT, 1);
- else if (signo == SIGUSR2)
- slideshow_change_image(winwid, SLIDE_PREV, 1);
- } else {
- feh_reload_image(winwid, 0, 0);
- }
- } else if (opt.multiwindow) {
- for (i = window_num - 1; i >= 0; i--)
- feh_reload_image(windows[i], 0, 0);
- }
-
- return;
+ sig_received = signo;
}
diff --git a/src/signals.h b/src/signals.h
index bff737e..505a071 100644
--- a/src/signals.h
+++ b/src/signals.h
@@ -1,6 +1,6 @@
/* signals.h
-Copyright (C) 2010 by Daniel Friesel
+Copyright (C) 2010 by Birte Kristina Friesel
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -26,6 +26,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SIGNALS_H
#define SIGNALS_H
-void setup_signal_handlers();
+void setup_signal_handlers(void);
extern volatile int sig_exit;
+extern volatile int sig_received;
#endif
diff --git a/src/slideshow.c b/src/slideshow.c
index 07a1e94..a53749e 100644
--- a/src/slideshow.c
+++ b/src/slideshow.c
@@ -1,7 +1,7 @@
/* slideshow.c
Copyright (C) 1999-2003 Tom Gilbert.
-Copyright (C) 2010-2020 Daniel Friesel.
+Copyright (C) 2010-2020 Birte Kristina Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -57,6 +57,7 @@ void init_slideshow_mode(void)
// Try finding an exact filename match first
for (; l && opt.start_list_at; l = l->next) {
if (!strcmp(opt.start_list_at, FEH_FILE(l->data)->filename)) {
+ free(opt.start_list_at);
opt.start_list_at = NULL;
break;
}
@@ -83,6 +84,7 @@ void init_slideshow_mode(void)
current_filename = FEH_FILE(l->data)->filename;
}
if (!strcmp(start_at_filename, current_filename)) {
+ free(opt.start_list_at);
opt.start_list_at = NULL;
break;
}
@@ -163,7 +165,7 @@ void cb_reload_timer(void *data)
if (opt.filelistfile) {
filelist = gib_list_cat(filelist, feh_read_filelist(opt.filelistfile));
}
-
+
if (!(filelist_len = gib_list_length(filelist))) {
eprintf("No files found to reload.");
}
@@ -225,6 +227,18 @@ void slideshow_change_image(winwidget winwid, int change, int render)
/* The for loop prevents us looping infinitely */
for (i = 0; i < our_filelist_len; i++) {
winwidget_free_image(winwid);
+#ifdef HAVE_LIBEXIF
+ /*
+ * An EXIF data chunk requires up to 50 kB of space. For large and
+ * long-running slideshows, this would acculumate gigabytes of
+ * EXIF data after a few days. We therefore do not cache EXIF data
+ * in slideshows.
+ */
+ if (FEH_FILE(winwid->file->data)->ed) {
+ exif_data_unref(FEH_FILE(winwid->file->data)->ed);
+ FEH_FILE(winwid->file->data)->ed = NULL;
+ }
+#endif
switch (change) {
case SLIDE_NEXT:
current_file = feh_list_jump(filelist, current_file, FORWARD, 1);
@@ -371,7 +385,8 @@ void feh_action_run(feh_file * file, char *action, winwidget winwid)
if (opt.verbose && !opt.list && !opt.customlist)
fprintf(stderr, "Running action -->%s<--\n", sys);
- system(sys);
+ if (system(sys) == -1)
+ perror("running action via system() failed");
}
return;
}
@@ -514,6 +529,12 @@ char *feh_printf(char *str, feh_file * file, winwidget winwid)
strncat(ret, buf, sizeof(ret) - strlen(ret) - 1);
}
break;
+ case 'W':
+ if (winwid) {
+ snprintf(buf, sizeof(buf), "%dx%d+%d+%d", winwid->w, winwid->h, winwid->x, winwid->y);
+ strncat(ret, buf, sizeof(ret) - strlen(ret) - 1);
+ }
+ break;
case 'z':
if (winwid) {
snprintf(buf, sizeof(buf), "%.2f", winwid->zoom);
@@ -626,7 +647,7 @@ void slideshow_save_image(winwidget win)
gib_imlib_save_image_with_error_return(win->im, tmpname, &err);
if (err)
- feh_imlib_print_load_error(tmpname, win, err);
+ feh_print_load_error(tmpname, win, err, LOAD_ERROR_IMLIB);
free(tmpname);
return;
diff --git a/src/structs.h b/src/structs.h
index 3e2a1aa..8438930 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -1,7 +1,7 @@
/* structs.h
Copyright (C) 1999-2003 Tom Gilbert.
-Copyright (C) 2010-2020 Daniel Friesel.
+Copyright (C) 2010-2020 Birte Kristina Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
diff --git a/src/strverscmp.c b/src/strverscmp.c
index 92cd877..ddc6b6d 100644
--- a/src/strverscmp.c
+++ b/src/strverscmp.c
@@ -41,9 +41,9 @@ int strverscmp(const char *l0, const char *r0)
else if (c!='0') z=0;
}
- if (l[dp]!='0' && r[dp]!='0') {
- /* If we're not looking at a digit sequence that began
- * with a zero, longest digit string is greater. */
+ if (l[dp]-'1'<9U && r[dp]-'1'<9U) {
+ /* If we're looking at non-degenerate digit sequences starting
+ * with nonzero digits, longest digit string is greater. */
for (j=i; isdigit(l[j]); j++)
if (!isdigit(r[j])) return 1;
if (isdigit(r[j])) return -1;
diff --git a/src/thumbnail.c b/src/thumbnail.c
index 41bd1a0..77c0acd 100644
--- a/src/thumbnail.c
+++ b/src/thumbnail.c
@@ -1,7 +1,7 @@
/* thumbnail.c
Copyright (C) 1999-2003 Tom Gilbert.
-Copyright (C) 2010-2020 Daniel Friesel.
+Copyright (C) 2010-2020 Birte Kristina Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -392,7 +392,7 @@ void init_thumbnail_mode(void)
}
gib_imlib_save_image_with_error_return(td.im_main, output_buf, &err);
if (err) {
- feh_imlib_print_load_error(output_buf, td.im_main, err);
+ feh_print_load_error(output_buf, td.im_main, err, LOAD_ERROR_IMLIB);
}
else if (opt.verbose) {
int tw, th;
@@ -411,6 +411,7 @@ void init_thumbnail_mode(void)
else if (opt.start_list_at) {
for (l = thumbnails; l; l = l->next) {
if (!strcmp(opt.start_list_at, FEH_THUMB(l->data)->file->filename)) {
+ free(opt.start_list_at);
opt.start_list_at = NULL;
feh_thumbnail_select(winwid, FEH_THUMB(l->data));
break;
@@ -592,7 +593,7 @@ int feh_thumbnail_get_thumbnail(Imlib_Image * image, feh_file * file,
return status;
}
-static char *feh_thumbnail_get_prefix()
+static char *feh_thumbnail_get_prefix(void)
{
char *dir = NULL, *home, *xdg_cache_home;
@@ -635,9 +636,9 @@ char *feh_thumbnail_get_name_uri(char *name)
/* FIXME: what happens with http, https, and ftp? MTime etc */
if (!path_is_url(name)) {
- /* make sure it's an absoulte path */
+ /* make sure it's an absolute path */
/* FIXME: add support for ~, need to investigate if it's expanded
- somewhere else before adding (unecessary) code */
+ somewhere else before adding (unnecessary) code */
if (name[0] != '/') {
/* work around /some/path/./image.ext */
if ((strncmp(name, "./", 2)) == 0)
@@ -881,13 +882,13 @@ void feh_thumbnail_select_prev(winwidget winwid, int jump)
}
}
-void feh_thumbnail_show_selected()
+void feh_thumbnail_show_selected(void)
{
if (td.selected && td.selected->file)
feh_thumbnail_show_fullsize(td.selected->file);
}
-feh_file* feh_thumbnail_get_selected_file()
+feh_file* feh_thumbnail_get_selected_file(void)
{
if (td.selected)
return td.selected->file;
diff --git a/src/thumbnail.h b/src/thumbnail.h
index 61d3053..e69759f 100644
--- a/src/thumbnail.h
+++ b/src/thumbnail.h
@@ -1,7 +1,7 @@
/* thumbnail.h
Copyright (C) 1999-2003 Tom Gilbert.
-Copyright (C) 2010-2020 Daniel Friesel.
+Copyright (C) 2010-2020 Birte Kristina Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -83,8 +83,8 @@ void feh_thumbnail_show_fullsize(feh_file *thumbfile);
void feh_thumbnail_select(winwidget winwid, feh_thumbnail *thumbnail);
void feh_thumbnail_select_next(winwidget winwid, int jump);
void feh_thumbnail_select_prev(winwidget winwid, int jump);
-void feh_thumbnail_show_selected();
-feh_file *feh_thumbnail_get_selected_file();
+void feh_thumbnail_show_selected(void);
+feh_file *feh_thumbnail_get_selected_file(void);
int feh_thumbnail_setup_thumbnail_dir(void);
diff --git a/src/timers.c b/src/timers.c
index b2cdbc7..8e42050 100644
--- a/src/timers.c
+++ b/src/timers.c
@@ -1,7 +1,7 @@
/* timers.c
Copyright (C) 1999-2003 Tom Gilbert.
-Copyright (C) 2010-2020 Daniel Friesel.
+Copyright (C) 2010-2020 Birte Kristina Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
diff --git a/src/utils.c b/src/utils.c
index 087e7f6..eb128a2 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -146,6 +146,8 @@ char *estrjoin(const char *separator, ...)
char path_is_url(char *path) {
if ((!strncmp(path, "http://", 7))
|| (!strncmp(path, "https://", 8))
+ || (!strncmp(path, "gopher://", 9))
+ || (!strncmp(path, "gophers://", 10))
|| (!strncmp(path, "ftp://", 6))
|| (!strncmp(path, "file://", 7)))
return 1;
diff --git a/src/wallpaper.c b/src/wallpaper.c
index 37b5a1d..e2fa67e 100644
--- a/src/wallpaper.c
+++ b/src/wallpaper.c
@@ -1,7 +1,7 @@
/* wallpaper.c
Copyright (C) 1999-2003 Tom Gilbert.
-Copyright (C) 2010-2020 Daniel Friesel.
+Copyright (C) 2010-2020 Birte Kristina Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -245,6 +245,106 @@ static void feh_wm_set_bg_maxed(Pixmap pmap, Imlib_Image im, int use_filelist,
return;
}
+/*
+** Creates a script that can be used to create the same background
+** as the last time the program was called.
+*/
+void feh_wm_gen_bg_script(char* fil, int centered, int scaled, int filled, int use_filelist) {
+ char * home = getenv("HOME");
+
+ if (!home)
+ return;
+
+ FILE *fp;
+ int fd;
+ char *path;
+ char *exec_method;
+ char *absolute_path;
+ struct stat s;
+ gib_list *filelist_pos = filelist;
+
+ if (strchr(cmdargv[0], '/'))
+ exec_method = feh_absolute_path(cmdargv[0]);
+ else
+ exec_method = cmdargv[0];
+
+ path = estrjoin("/", home, ".fehbg", NULL);
+
+ if ((fp = fopen(path, "w")) == NULL) {
+ weprintf("Can't write to %s", path);
+ } else {
+ fputs("#!/bin/sh\n", fp);
+ fputs(exec_method, fp);
+ fputs(" --no-fehbg --bg-", fp);
+ if (centered)
+ fputs("center", fp);
+ else if (scaled)
+ fputs("scale", fp);
+ else if (filled == 1)
+ fputs("fill", fp);
+ else if (filled == 2)
+ fputs("max", fp);
+ else
+ fputs("tile", fp);
+ if (opt.image_bg) {
+ fputs(" --image-bg ", fp);
+ fputs(shell_escape(opt.image_bg), fp);
+ }
+#ifdef HAVE_LIBXINERAMA
+ if (opt.xinerama) {
+ if (opt.xinerama_index >= 0) {
+ fprintf(fp, " --xinerama-index %d", opt.xinerama_index);
+ }
+ }
+ else {
+ fputs(" --no-xinerama", fp);
+ }
+#endif /* HAVE_LIBXINERAMA */
+ if (opt.geom_flags & XValue) {
+ fprintf(fp, " --geometry %c%d",
+ opt.geom_flags & XNegative ? '-' : '+',
+ opt.geom_flags & XNegative ? abs(opt.geom_x) : opt.geom_x);
+ if (opt.geom_flags & YValue) {
+ fprintf(fp, "%c%d",
+ opt.geom_flags & YNegative ? '-' : '+',
+ opt.geom_flags & YNegative ? abs(opt.geom_y) : opt.geom_y);
+ }
+ }
+ if (opt.force_aliasing) {
+ fputs(" --force-aliasing", fp);
+ }
+ fputc(' ', fp);
+ if (use_filelist) {
+#ifdef HAVE_LIBXINERAMA
+ for (int i = 0; (i < opt.xinerama ? num_xinerama_screens : 1) && filelist_pos; i++)
+#else
+ for (int i = 0; (i < 1 ) && filelist_pos; i++)
+#endif
+ {
+ absolute_path = feh_absolute_path(FEH_FILE(filelist_pos->data)->filename);
+ fputs(shell_escape(absolute_path), fp);
+ filelist_pos = filelist_pos->next;
+ free(absolute_path);
+ fputc(' ', fp);
+ }
+ } else if (fil) {
+ absolute_path = feh_absolute_path(fil);
+ fputs(shell_escape(absolute_path), fp);
+ free(absolute_path);
+ }
+ fputc('\n', fp);
+ fd = fileno(fp);
+ if (fstat(fd, &s) != 0 || fchmod(fd, s.st_mode | S_IXUSR | S_IXGRP) != 0) {
+ weprintf("Can't set %s as executable", path);
+ }
+ fclose(fp);
+ }
+ free(path);
+
+ if(exec_method != cmdargv[0])
+ free(exec_method);
+}
+
void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled,
int filled, int desktop, int use_filelist)
{
@@ -282,7 +382,10 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled,
feh_wm_load_next(&im);
fil = FEH_FILE(filelist->data)->filename;
}
- snprintf(sendbuf, sizeof(sendbuf), "background %s bg.file %s", bgname, fil);
+ if ((size_t) snprintf(sendbuf, sizeof(sendbuf), "background %s bg.file %s", bgname, fil) >= sizeof(sendbuf)) {
+ weprintf("Writing to IPC send buffer was truncated");
+ return;
+ }
enl_ipc_send(sendbuf);
if (scaled) {
@@ -322,8 +425,6 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled,
unsigned char *data_root = NULL, *data_esetroot = NULL;
Pixmap pmap_d1, pmap_d2;
- char *home;
-
/* local display to set closedownmode on */
Display *disp2;
Window root2;
@@ -448,87 +549,8 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled,
gib_imlib_render_image_on_drawable(pmap_d1, im, 0, 0, 1, 1, 0);
}
- if (!opt.no_fehbg) {
- home = getenv("HOME");
- if (home) {
- FILE *fp;
- int fd;
- char *path;
- char *absolute_path;
- struct stat s;
- gib_list *filelist_pos = filelist;
- path = estrjoin("/", home, ".fehbg", NULL);
- if ((fp = fopen(path, "w")) == NULL) {
- weprintf("Can't write to %s", path);
- } else {
- fputs("#!/bin/sh\n", fp);
- fputs(cmdargv[0], fp);
- fputs(" --no-fehbg --bg-", fp);
- if (centered)
- fputs("center", fp);
- else if (scaled)
- fputs("scale", fp);
- else if (filled == 1)
- fputs("fill", fp);
- else if (filled == 2)
- fputs("max", fp);
- else
- fputs("tile", fp);
- if (opt.image_bg) {
- fputs(" --image-bg ", fp);
- fputs(shell_escape(opt.image_bg), fp);
- }
-#ifdef HAVE_LIBXINERAMA
- if (opt.xinerama) {
- if (opt.xinerama_index >= 0) {
- fprintf(fp, " --xinerama-index %d", opt.xinerama_index);
- }
- }
- else {
- fputs(" --no-xinerama", fp);
- }
-#endif /* HAVE_LIBXINERAMA */
- if (opt.geom_flags & XValue) {
- fprintf(fp, " --geometry %c%d",
- opt.geom_flags & XNegative ? '-' : '+',
- opt.geom_flags & XNegative ? abs(opt.geom_x) : opt.geom_x);
- if (opt.geom_flags & YValue) {
- fprintf(fp, "%c%d",
- opt.geom_flags & YNegative ? '-' : '+',
- opt.geom_flags & YNegative ? abs(opt.geom_y) : opt.geom_y);
- }
- }
- if (opt.force_aliasing) {
- fputs(" --force-aliasing", fp);
- }
- fputc(' ', fp);
- if (use_filelist) {
-#ifdef HAVE_LIBXINERAMA
- for (int i = 0; (i < opt.xinerama ? num_xinerama_screens : 1) && filelist_pos; i++) {
-#else
- for (int i = 0; (i < 1 ) && filelist_pos; i++) {
-#endif
- absolute_path = feh_absolute_path(FEH_FILE(filelist_pos->data)->filename);
- fputs(shell_escape(absolute_path), fp);
- filelist_pos = filelist_pos->next;
- free(absolute_path);
- fputc(' ', fp);
- }
- } else if (fil) {
- absolute_path = feh_absolute_path(fil);
- fputs(shell_escape(absolute_path), fp);
- free(absolute_path);
- }
- fputc('\n', fp);
- fd = fileno(fp);
- if (fstat(fd, &s) != 0 || fchmod(fd, s.st_mode | S_IXUSR | S_IXGRP) != 0) {
- weprintf("Can't set %s as executable", path);
- }
- fclose(fp);
- }
- free(path);
- }
- }
+ if (!opt.no_fehbg)
+ feh_wm_gen_bg_script(fil, centered, scaled, filled, use_filelist);
/* create new display, copy pixmap to new display */
disp2 = XOpenDisplay(NULL);
@@ -569,7 +591,7 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled,
if (data_root)
XFree(data_root);
-
+
if (data_esetroot)
XFree(data_esetroot);
diff --git a/src/wallpaper.h b/src/wallpaper.h
index cf52d2d..c836c0f 100644
--- a/src/wallpaper.h
+++ b/src/wallpaper.h
@@ -1,7 +1,7 @@
/* wallpaper.h
Copyright (C) 1999-2003 Tom Gilbert.
-Copyright (C) 2010-2020 Daniel Friesel.
+Copyright (C) 2010-2020 Birte Kristina Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -42,7 +42,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
extern Window ipc_win;
extern Atom ipc_atom;
-_XFUNCPROTOBEGIN extern Window enl_ipc_get_win(void);
+extern Window enl_ipc_get_win(void);
extern void enl_ipc_send(char *);
extern char *enl_wait_for_reply(void);
extern char *enl_ipc_get(const char *);
@@ -53,5 +53,4 @@ extern int feh_wm_get_num_desks(void);
extern signed char feh_wm_get_wm_is_e(void);
void feh_wm_set_bg_filelist(unsigned char bgmode);
-_XFUNCPROTOEND
#endif
diff --git a/src/winwidget.c b/src/winwidget.c
index bfd987d..b98cbef 100644
--- a/src/winwidget.c
+++ b/src/winwidget.c
@@ -1,7 +1,7 @@
/* winwidget.c
Copyright (C) 1999-2003 Tom Gilbert.
-Copyright (C) 2010-2020 Daniel Friesel.
+Copyright (C) 2010-2020 Birte Kristina Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -104,8 +104,13 @@ winwidget winwidget_create_from_image(Imlib_Image im, char type)
ret->w = ret->im_w = gib_imlib_image_get_width(ret->im);
ret->h = ret->im_h = gib_imlib_image_get_height(ret->im);
- if (opt.full_screen && (type != WIN_TYPE_THUMBNAIL))
+ if (opt.full_screen && (type != WIN_TYPE_THUMBNAIL)) {
ret->full_screen = True;
+ } else if (opt.default_zoom) {
+ ret->zoom = 0.01 * opt.default_zoom;
+ ret->w *= ret->zoom;
+ ret->h *= ret->zoom;
+ }
winwidget_create_window(ret, ret->w, ret->h);
winwidget_render_image(ret, 1, 0);
@@ -133,8 +138,13 @@ winwidget winwidget_create_from_file(gib_list * list, char type)
ret->w = ret->im_w = gib_imlib_image_get_width(ret->im);
ret->h = ret->im_h = gib_imlib_image_get_height(ret->im);
D(("image is %dx%d pixels, format %s\n", ret->w, ret->h, gib_imlib_image_format(ret->im)));
- if (opt.full_screen)
+ if (opt.full_screen) {
ret->full_screen = True;
+ } else if (opt.default_zoom) {
+ ret->zoom = 0.01 * opt.default_zoom;
+ ret->w *= ret->zoom;
+ ret->h *= ret->zoom;
+ }
winwidget_create_window(ret, ret->w, ret->h);
winwidget_render_image(ret, 1, 0);
}
@@ -144,6 +154,7 @@ winwidget winwidget_create_from_file(gib_list * list, char type)
void winwidget_create_window(winwidget ret, int w, int h)
{
+ XWindowAttributes window_attr;
XSetWindowAttributes attr;
XEvent ev;
XClassHint *xch;
@@ -250,11 +261,31 @@ void winwidget_create_window(winwidget ret, int w, int h)
}
}
- ret->win =
- XCreateWindow(disp, DefaultRootWindow(disp), x, y, w, h, 0,
- depth, InputOutput, vis,
- CWOverrideRedirect | CWSaveUnder | CWBackingStore
- | CWColormap | CWBackPixel | CWBorderPixel | CWEventMask, &attr);
+ if (opt.x11_windowid == 0) {
+ ret->win =
+ XCreateWindow(disp, DefaultRootWindow(disp), x, y, w, h, 0,
+ depth, InputOutput, vis,
+ CWOverrideRedirect | CWSaveUnder | CWBackingStore
+ | CWColormap | CWBackPixel | CWBorderPixel | CWEventMask,
+ &attr);
+ } else {
+ /* x11_windowid is a pointer to the window */
+ ret->win = (Window) opt.x11_windowid;
+
+ /* set our attributes on the window */
+ XChangeWindowAttributes(disp, ret->win,
+ CWOverrideRedirect | CWSaveUnder | CWBackingStore
+ | CWColormap | CWBackPixel | CWBorderPixel
+ | CWEventMask, &attr);
+
+ /* determine the size and visibility of the window */
+ XGetWindowAttributes(disp, ret->win, &window_attr);
+ ret->visible = (window_attr.map_state == IsViewable);
+ ret->x = window_attr.x;
+ ret->y = window_attr.y;
+ ret->w = window_attr.width;
+ ret->h = window_attr.height;
+ }
if (mwmhints.flags) {
XChangeProperty(disp, ret->win, prop, prop, 32,
@@ -433,7 +464,12 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias)
int antialias = 0;
if (!winwid->full_screen && resize) {
- winwidget_resize(winwid, winwid->im_w, winwid->im_h, 0);
+ if (opt.default_zoom) {
+ winwid->zoom = 0.01 * opt.default_zoom;
+ winwidget_resize(winwid, winwid->im_w * winwid->zoom, winwid->im_h * winwid->zoom, 0);
+ } else {
+ winwidget_resize(winwid, winwid->im_w, winwid->im_h, 0);
+ }
winwidget_reset_image(winwid);
}
@@ -703,7 +739,7 @@ void winwidget_inotify_remove(winwidget winwid)
#ifdef HAVE_INOTIFY
void winwidget_inotify_add(winwidget winwid, feh_file * file)
{
- if (opt.auto_reload) {
+ if (opt.auto_reload && !path_is_url(file->filename)) {
D(("Adding inotify watch for %s\n", file->filename));
char dir[PATH_MAX];
feh_file_dirname(dir, file, PATH_MAX);
@@ -742,7 +778,7 @@ void feh_event_handle_inotify(void)
for (int j = 0; j < window_num; j++) {
if(windows[j]->inotify_wd == event->wd) {
if (event->mask & IN_IGNORED) {
- D(("inotify watch was implicitely removed\n"));
+ D(("inotify watch was implicitly removed\n"));
windows[j]->inotify_wd = -1;
} else if (event->mask & (IN_CLOSE_WRITE | IN_MOVED_TO)) {
if (strcmp(event->name, FEH_FILE(windows[j]->file->data)->name) == 0) {
@@ -1014,8 +1050,9 @@ void winwidget_rename(winwidget winwid, char *newname)
void winwidget_free_image(winwidget w)
{
- if (w->im)
+ if (w->im) {
gib_imlib_free_image(w->im);
+ }
w->im = NULL;
w->im_w = 0;
w->im_h = 0;
diff --git a/src/winwidget.h b/src/winwidget.h
index 9d74286..0894b5a 100644
--- a/src/winwidget.h
+++ b/src/winwidget.h
@@ -1,7 +1,7 @@
/* winwidget.h
Copyright (C) 1999-2003 Tom Gilbert.
-Copyright (C) 2010-2020 Daniel Friesel.
+Copyright (C) 2010-2020 Birte Kristina Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to