summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/collage.c1
-rw-r--r--src/debug.h1
-rw-r--r--src/deps.mk41
-rw-r--r--src/events.c21
-rw-r--r--src/feh.h5
-rw-r--r--src/feh_png.c6
-rw-r--r--src/fehrc.raw74
-rw-r--r--src/filelist.c1
-rw-r--r--src/help.raw17
-rw-r--r--src/imlib.c307
-rw-r--r--src/index.c1
-rw-r--r--src/keyevents.c635
-rw-r--r--src/list.c1
-rw-r--r--src/main.c5
-rw-r--r--src/menu.c18
-rw-r--r--src/menu.h1
-rw-r--r--src/multiwindow.c4
-rw-r--r--src/options.c189
-rw-r--r--src/options.h69
-rw-r--r--src/signals.c5
-rw-r--r--src/slideshow.c42
-rw-r--r--src/structs.h3
-rw-r--r--src/support.c174
-rw-r--r--src/support.h1
-rw-r--r--src/thumbnail.c54
-rw-r--r--src/thumbnail.h7
-rw-r--r--src/timers.c1
-rw-r--r--src/winwidget.c39
-rw-r--r--src/winwidget.h6
29 files changed, 911 insertions, 818 deletions
diff --git a/src/collage.c b/src/collage.c
index 782d5f8..1f2fac4 100644
--- a/src/collage.c
+++ b/src/collage.c
@@ -1,6 +1,7 @@
/* collage.c
Copyright (C) 1999-2003 Tom Gilbert.
+Copyright (C) 2010-2011 Daniel 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/debug.h b/src/debug.h
index 93cb6bf..eb929e3 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -1,6 +1,7 @@
/* debug.h
Copyright (C) 1999-2003 Tom Gilbert.
+Copyright (C) 2010-2011 Daniel 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/deps.mk b/src/deps.mk
deleted file mode 100644
index 36b264f..0000000
--- a/src/deps.mk
+++ /dev/null
@@ -1,41 +0,0 @@
-collage.o: collage.c feh.h structs.h menu.h utils.h getopt.h debug.h \
- winwidget.h filelist.h options.h
-events.o: events.c feh.h structs.h menu.h utils.h getopt.h debug.h \
- filelist.h winwidget.h timers.h options.h events.h thumbnail.h
-feh_png.o: feh_png.c feh_png.h feh.h structs.h menu.h utils.h getopt.h \
- debug.h
-filelist.o: filelist.c feh.h structs.h menu.h utils.h getopt.h debug.h \
- filelist.h options.h
-getopt.o: getopt.c
-getopt1.o: getopt1.c getopt.h
-imlib.o: imlib.c feh.h structs.h menu.h utils.h getopt.h debug.h \
- filelist.h winwidget.h options.h
-index.o: index.c feh.h structs.h menu.h utils.h getopt.h debug.h \
- filelist.h winwidget.h options.h
-keyevents.o: keyevents.c feh.h structs.h menu.h utils.h getopt.h debug.h \
- thumbnail.h filelist.h winwidget.h options.h
-list.o: list.c feh.h structs.h menu.h utils.h getopt.h debug.h filelist.h \
- options.h
-main.o: main.c feh.h structs.h menu.h utils.h getopt.h debug.h filelist.h \
- winwidget.h timers.h options.h events.h support.h
-md5.o: md5.c md5.h
-menu.o: menu.c feh.h structs.h menu.h utils.h getopt.h debug.h support.h \
- thumbnail.h filelist.h winwidget.h options.h
-multiwindow.o: multiwindow.c feh.h structs.h menu.h utils.h getopt.h \
- debug.h winwidget.h timers.h filelist.h options.h
-options.o: options.c feh.h structs.h menu.h utils.h getopt.h debug.h \
- filelist.h options.h help.inc fehrc.inc
-signals.o: signals.c feh.h structs.h menu.h utils.h getopt.h debug.h \
- winwidget.h
-slideshow.o: slideshow.c feh.h structs.h menu.h utils.h getopt.h debug.h \
- filelist.h timers.h winwidget.h options.h signals.h
-support.o: support.c feh.h structs.h menu.h utils.h getopt.h debug.h \
- filelist.h options.h support.h
-thumbnail.o: thumbnail.c feh.h structs.h menu.h utils.h getopt.h debug.h \
- filelist.h winwidget.h options.h thumbnail.h md5.h feh_png.h
-timers.o: timers.c feh.h structs.h menu.h utils.h getopt.h debug.h \
- options.h timers.h
-utils.o: utils.c feh.h structs.h menu.h utils.h getopt.h debug.h \
- options.h
-winwidget.o: winwidget.c feh.h structs.h menu.h utils.h getopt.h debug.h \
- filelist.h winwidget.h options.h
diff --git a/src/events.c b/src/events.c
index 36379b1..a850137 100644
--- a/src/events.c
+++ b/src/events.c
@@ -1,6 +1,7 @@
/* events.c
Copyright (C) 1999-2003 Tom Gilbert.
+Copyright (C) 2010-2011 Daniel Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -182,7 +183,7 @@ static void feh_event_handle_ButtonRelease(XEvent * ev)
opt.mode = MODE_NORMAL;
winwid->mode = MODE_NORMAL;
winwidget_sanitise_offsets(winwid);
- winwidget_render_image(winwid, 0, 1);
+ winwidget_render_image(winwid, 0, 0);
}
} else if (opt.mode == MODE_NEXT) {
opt.mode = MODE_NORMAL;
@@ -247,7 +248,7 @@ static void feh_event_handle_ButtonRelease(XEvent * ev)
} else
winwidget_sanitise_offsets(winwid);
- winwidget_render_image(winwid, 0, 1);
+ winwidget_render_image(winwid, 0, 0);
}
} else if ((ev->xbutton.button == opt.blur_button)
&& ((opt.no_blur_ctrl_mask)
@@ -280,7 +281,7 @@ static void feh_event_handle_ConfigureNotify(XEvent * ev)
opt.geom_w = w->w;
opt.geom_h = w->h;
}
- winwidget_render_image(w, 0, 1);
+ winwidget_render_image(w, 0, 0);
}
}
}
@@ -403,7 +404,7 @@ static void feh_event_handle_MotionNotify(XEvent * ev)
winwid->im_y = winwid->click_offset_y
- (winwid->im_click_offset_y * winwid->zoom);
- winwidget_render_image(winwid, 0, 0);
+ winwidget_render_image(winwid, 0, 1);
}
} else if ((opt.mode == MODE_PAN) || (opt.mode == MODE_NEXT)) {
int orig_x, orig_y;
@@ -462,7 +463,7 @@ static void feh_event_handle_MotionNotify(XEvent * ev)
if ((winwid->im_x != orig_x)
|| (winwid->im_y != orig_y))
- winwidget_render_image(winwid, 0, 0);
+ winwidget_render_image(winwid, 0, 1);
}
} else if (opt.mode == MODE_ROTATE) {
while (XCheckTypedWindowEvent(disp, ev->xmotion.window, MotionNotify, ev));
@@ -482,7 +483,7 @@ static void feh_event_handle_MotionNotify(XEvent * ev)
}
winwid->im_angle = (ev->xmotion.x - winwid->w / 2) / ((double) winwid->w / 2) * 3.1415926535;
D(("angle: %f\n", winwid->im_angle));
- winwidget_render_image(winwid, 0, 0);
+ winwidget_render_image(winwid, 0, 1);
}
} else if (opt.mode == MODE_BLUR) {
while (XCheckTypedWindowEvent(disp, ev->xmotion.window, MotionNotify, ev));
@@ -502,7 +503,7 @@ static void feh_event_handle_MotionNotify(XEvent * ev)
gib_imlib_image_blur(temp, 0 - blur_radius);
ptr = winwid->im;
winwid->im = temp;
- winwidget_render_image(winwid, 0, 0);
+ winwidget_render_image(winwid, 0, 1);
gib_imlib_free_image_and_decache(winwid->im);
winwid->im = ptr;
}
@@ -521,7 +522,7 @@ static void feh_event_handle_MotionNotify(XEvent * ev)
imlib_context_set_image(winwid->im);
imlib_apply_filter("bump_map_point(x=[],y=[],map="
PREFIX "/share/feh/images/about.png);", &x, &y);
- winwidget_render_image(winwid, 0, 1);
+ winwidget_render_image(winwid, 0, 0);
gib_imlib_free_image_and_decache(winwid->im);
winwid->im = orig_im;
} else if (winwid->type == WIN_TYPE_THUMBNAIL) {
@@ -552,11 +553,11 @@ static void feh_event_handle_MotionNotify(XEvent * ev)
thumbnail->x + 2, thumbnail->y + 2,
thumbnail->w - 4, thumbnail->h - 4,
255, 255, 255, 255);
- winwidget_render_image(winwid, 0, 1);
+ winwidget_render_image(winwid, 0, 0);
gib_imlib_free_image_and_decache(winwid->im);
winwid->im = origwin;
} else
- winwidget_render_image(winwid, 0, 1);
+ winwidget_render_image(winwid, 0, 0);
}
last_thumb = thumbnail;
}
diff --git a/src/feh.h b/src/feh.h
index 22a9d4b..01006b2 100644
--- a/src/feh.h
+++ b/src/feh.h
@@ -1,6 +1,7 @@
/* feh.h
Copyright (C) 1999-2003 Tom Gilbert.
+Copyright (C) 2010-2011 Daniel Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -120,6 +121,7 @@ void show_mini_usage(void);
void slideshow_change_image(winwidget winwid, int change);
void slideshow_pause_toggle(winwidget w);
char *slideshow_create_name(feh_file * file);
+void init_keyevents(void);
void feh_event_handle_keypress(XEvent * ev);
void feh_action_run(feh_file * file, char *action);
char *feh_printf(char *str, feh_file * file);
@@ -137,12 +139,11 @@ 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);
-char *feh_strip_hostname(char *url);
void slideshow_save_image(winwidget win);
void feh_edit_inplace_orient(winwidget w, int orientation);
void feh_edit_inplace_lossless_rotate(winwidget w, int orientation);
gib_list *feh_wrap_string(char *text, int wrap_width, Imlib_Font fn, gib_style * style);
-char *build_caption_filename(feh_file * file);
+char *build_caption_filename(feh_file * file, short create_dir);
gib_list *feh_list_jump(gib_list * root, gib_list * l, int direction, int num);
/* Imlib stuff */
diff --git a/src/feh_png.c b/src/feh_png.c
index e2842f8..f02aecb 100644
--- a/src/feh_png.c
+++ b/src/feh_png.c
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <stdarg.h>
#define FEH_PNG_COMPRESSION 3
-#define FEH_PNG_NUM_COMMENTS 2 /* only Thumb::URI and Thumb::MTime for now */
+#define FEH_PNG_NUM_COMMENTS 4
gib_hash *feh_png_read_comments(char *file)
{
@@ -66,7 +66,7 @@ gib_hash *feh_png_read_comments(char *file)
return hash;
}
- if (setjmp(png_ptr->jmpbuf)) {
+ if (setjmp(png_jmpbuf(png_ptr))) {
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(fp);
return hash;
@@ -124,7 +124,7 @@ int feh_png_write_png(Imlib_Image image, char *file, ...)
return 0;
}
- if (setjmp(png_ptr->jmpbuf)) {
+ if (setjmp(png_jmpbuf(png_ptr))) {
fclose(fp);
png_destroy_write_struct(&png_ptr, &info_ptr);
png_destroy_info_struct(png_ptr, &info_ptr);
diff --git a/src/fehrc.raw b/src/fehrc.raw
deleted file mode 100644
index 154a6e1..0000000
--- a/src/fehrc.raw
+++ /dev/null
@@ -1,74 +0,0 @@
-# Feh configuration file.
-# Lines starting with # are comments. Don't use comments mid-line.
-
-# Feh expects to find this as ~/.fehrc or /etc/fehrc
-# If both are available, ~/.fehrc will be used
-
-# Options are defined in theme_name/options pairs.
-# Separate themename and options by whitespace.
-
-# There are two ways of specifying the theme. Either use feh -Tthemename,
-# or use a symbolic link to feh with the name of the theme. eg
-# ln -s `which feh` ~/bin/mkindex
-# Now when you run 'mkindex', feh will load the config specified for the
-# mkindex theme.
-
-# Multiple options can of course be used. If they are too long for one line,
-# you can (usually) use a \\ to make them continue on the next one:
-# imagemap -rV --quiet -W 400 -H 300 \\
-# --thumb-width 40 --thumb-height 30
-
-# ====================
-# A few default themes
-# ====================
-
-# Webcam mode, simply specify the url(s).
-# e.g. feh -Twebcam http://cam1 http://cam2
-webcam --multiwindow --reload 20
-
-# Create an index of the current directory. This version uses . as the
-# current dir, so you don't even need any commandline arguments.
-mkindex -iVO index.jpg .
-
-# More ambitious version...
-imgidx --index --output-only .fehindex.jpg --limit-width 1024 \\
- --thumb-width 128 --thumb-height 128 --verbose --quiet
-
-# Show a presentation
-present --full-screen --sort name --hide-pointer
-
-# Booth mode ;-)
-booth --full-screen --hide-pointer --slideshow-delay 20
-
-# Screw xscreensaver, use feh =)
-screensave --recursive --full-screen --randomize --slideshow-delay 10 --hide-pointer
-
-# Add <img> tags to your html with ease :-)
-newimg -q -L \"<img src=\\\"%f\\\" alt=\\\"%n\\\" border=\\\"0\\\" width=\\\"%w\\\" height=\\\"%h\\\">\"
-
-# Different menus
-brushed --menu-bg " PREFIX "/share/feh/images/menubg_brushed.png
-aluminium --menu-bg " PREFIX "/share/feh/images/menubg_aluminium.png
-aqua --menu-bg " PREFIX "/share/feh/images/menubg_aqua.png
-sky --menu-bg " PREFIX "/share/feh/images/menubg_sky.png
-black --menu-bg " PREFIX "/share/feh/images/menubg_black.png \\
- --menu-style " PREFIX "/share/feh/fonts/black.style
-
-# Some more examples, used by the feh developer
-
-rfs --full-screen --hide-pointer --auto-zoom --randomize
-fs --full-screen --hide-pointer --auto-zoom --sort filename
-
-thumb_s --thumbnails --cache-thumbnails --thumb-width 128 --thumb-height 128 \\
- --limit-width 1024 --sort filename \\
- --fontpath /usr/share/fonts/truetype/ttf-dejavu/ --font DejaVuSans/8
-
-thumb_b --thumbnails --cache-thumbnails --thumb-width 256 --thumb-height 256 \\
- --limit-width 1024 --sort filename \\
- --fontpath /usr/share/fonts/truetype/ttf-dejavu/ --font DejaVuSans/8
-
-thumb_s_nt --thumbnails --cache-thumbnails --thumb-width 128 --thumb-height 128 \\
- --limit-width 1024 --sort filename --index-name 0
-
-thumb_b_nt --thumbnails --cache-thumbnails --thumb-width 256 --thumb-height 256 \\
- --limit-width 1024 --sort filename --index-name 0
diff --git a/src/filelist.c b/src/filelist.c
index e1b4055..fa1735d 100644
--- a/src/filelist.c
+++ b/src/filelist.c
@@ -1,6 +1,7 @@
/* filelist.c
Copyright (C) 1999-2003 Tom Gilbert.
+Copyright (C) 2010-2011 Daniel 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/help.raw b/src/help.raw
index e0ea432..bbe5e37 100644
--- a/src/help.raw
+++ b/src/help.raw
@@ -2,7 +2,7 @@
Usage : " PACKAGE " [options] <files or directories ...>
- This is just a short option summary. Please consult the manual for details.
+ This is just a short option summary. Please see \"man " PACKAGE "\" for details.
OPTIONS
-h, --help Show help and exit
@@ -10,7 +10,6 @@ OPTIONS
-V, --verbose Show progress bars and other extra information
-q, --quiet Hide non-fatal errors. May be used with --verbose
-T, --theme THEME Load options with name THEME
- -_, --rcfile FILE Use FILE to parse themes and options from
-r, --recursive Recursively expand any directories in FILE to
the content of those directories. (Take it easy)
-z, --randomize Randomize the filelist
@@ -36,7 +35,6 @@ OPTIONS
-D, --slideshow-delay NUM Set delay between automatically changing slides
--cycle-once Exit after one loop through the slideshow
-R, --reload NUM Reload images after NUM seconds
- -Q, --builtin Use builtin http client instead of wget
-k, --keep-http Keep local copies when viewing HTTP/FTP files
-K, --caption-path PATH Path to caption directory, enables caption display
-j, --output-dir With -k: Output directory for saved files
@@ -50,8 +48,8 @@ OPTIONS
-A, --action ACTION Specify action to perform when pressing <return>.
Executed by /bin/sh, may contain FORMAT SPECIFIERS
--action[1-9] Extra actions triggered by pressing keys <1>to <9>
- --action-hold-slide Do not change to next image after running an action
-G, --draw-actions Show the defined actions in the image window
+ --force-aliasing Disable antialiasing
-m, --montage Enable montage mode
-c, --collage Montage mode with randomly distributed thumbnails
-i, --index Create an index print of all images
@@ -79,8 +77,6 @@ OPTIONS
-C, --fontpath PATH Specify an extra directory to look in for fonts,
can be used multiple times to add multiple paths.
-M, --menu-font FONT Use FONT for the font in menus.
- --menu-style FILE Use FILE as the style descriptor for menu text.
- -), --menu-bg BG Use BG for the background image in menus.
-B, --image-bg STYLE Set background for transparent images and the like.
Accepted values: white, black, default
-N, --no-menus Don't load or show any menus.
@@ -148,7 +144,7 @@ FORMAT SPECIFIERS
%l total number of files in the filelist
%u current file number
%% %
- \\n newline
+ \\n newline
KEYS
p, <BACKSPACE>, <LEFT> Go to previous slide
@@ -188,7 +184,8 @@ KEYS
1-9 Run action 1-9 specified by --action[1-9] options
This program is free software, see the file COPYING for licensing info.
-Copyright Tom Gilbert (and various contributors) 1999-2003
+Copyright Tom Gilbert (and various contributors) 1999-2003.
+Copyright Daniel Friesel 2010-2011.
-Homepage: https://derf.homelinux.org/p/feh
-Email bugs to <derf@finalrewind.org>
+Homepage: http://feh.finalrewind.org
+Report bugs to <derf@finalrewind.org> or #feh on irc.oftc.net.
diff --git a/src/imlib.c b/src/imlib.c
index 89271bf..dcf3c5c 100644
--- a/src/imlib.c
+++ b/src/imlib.c
@@ -1,6 +1,7 @@
/* imlib.c
Copyright (C) 1999-2003 Tom Gilbert.
+Copyright (C) 2010-2011 Daniel Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -33,6 +34,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
+#include <curl/curl.h>
Display *disp = NULL;
Visual *vis = NULL;
@@ -231,8 +233,16 @@ int feh_load_image(Imlib_Image * im, feh_file * file)
return(1);
}
+#ifdef HAVE_LIBCURL
+
char *feh_http_load_image(char *url)
{
+ CURL *curl;
+ CURLcode res;
+ char *sfn;
+ FILE *sfp;
+ int fd = -1;
+ char *ebuff;
char *tmpname;
char *basename;
char *path = NULL;
@@ -248,252 +258,64 @@ char *feh_http_load_image(char *url)
basename = strrchr(url, '/') + 1;
tmpname = feh_unique_filename(path, basename);
- if (opt.builtin_http) {
- /* state for HTTP header parser */
-#define SAW_NONE 1
-#define SAW_ONE_CM 2
-#define SAW_ONE_CJ 3
-#define SAW_TWO_CM 4
-#define IN_BODY 5
-
-#define OUR_BUF_SIZE 1024
-#define EOL "\015\012"
-
- int sockno = 0;
- int size;
- int body = SAW_NONE;
- struct addrinfo hints;
- struct addrinfo *result, *rp;
- char *hostname;
- char *get_string;
- char *host_string;
- char *query_string;
- char *get_url;
- static char buf[OUR_BUF_SIZE];
- char ua_string[] = "User-Agent: feh image viewer";
- char accept_string[] = "Accept: image/*";
- FILE *fp;
-
- D(("using builtin http collection\n"));
- fp = fopen(tmpname, "w");
- if (!fp) {
- weprintf("couldn't write to file %s:", tmpname);
- free(tmpname);
- return(NULL);
- }
-
- hostname = feh_strip_hostname(url);
- if (!hostname) {
- weprintf("couldn't work out hostname from %s:", url);
- fclose(fp);
- unlink(tmpname);
- free(tmpname);
- return(NULL);
- }
-
- D(("trying hostname %s\n", hostname));
-
- memset(&hints, 0, sizeof(struct addrinfo));
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_flags = AI_NUMERICSERV;
- hints.ai_protocol = 0;
- if (getaddrinfo(hostname, "80", &hints, &result) != 0) {
- weprintf("error resolving host %s:", hostname);
- fclose(fp);
- unlink(tmpname);
- free(hostname);
- free(tmpname);
- return(NULL);
- }
- for (rp = result; rp != NULL; rp = rp->ai_next) {
- sockno = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
- if (sockno == -1) {
- continue;
- }
- if (connect(sockno, rp->ai_addr, rp->ai_addrlen) != -1) {
- break;
- }
- close(sockno);
- }
- if (rp == NULL) {
- weprintf("error connecting socket:");
- freeaddrinfo(result);
- fclose(fp);
- unlink(tmpname);
- free(tmpname);
- free(hostname);
- return(NULL);
- }
- freeaddrinfo(result);
-
- get_url = strchr(url, '/') + 2;
- get_url = strchr(get_url, '/');
-
- get_string = estrjoin(" ", "GET", get_url, "HTTP/1.0", NULL);
- host_string = estrjoin(" ", "Host:", hostname, NULL);
- query_string = estrjoin(EOL, get_string, host_string, accept_string, ua_string, "", "", NULL);
- /* At this point query_string looks something like
- **
- ** GET /dir/foo.jpg?123456 HTTP/1.0^M^J
- ** Host: www.example.com^M^J
- ** Accept: image/ *^M^J
- ** User-Agent: feh image viewer^M^J
- ** ^M^J
- **
- ** Host: is required by HTTP/1.1 and very important for some sites,
- ** even with HTTP/1.0
- **
- ** -- BEG
- */
- if ((send(sockno, query_string, strlen(query_string), 0)) == -1) {
- free(get_string);
- free(host_string);
- free(query_string);
- free(tmpname);
- free(hostname);
- weprintf("error sending over socket:");
- return(NULL);
- }
- free(get_string);
- free(host_string);
- free(query_string);
- free(hostname);
-
- while ((size = read(sockno, &buf, OUR_BUF_SIZE))) {
- if (body == IN_BODY) {
- fwrite(buf, 1, size, fp);
- } else {
- int i;
-
- for (i = 0; i < size; i++) {
- /* We are looking for ^M^J^M^J, but will accept
- ** ^J^J from broken servers. Stray ^Ms will be
- ** ignored.
- **
- ** TODO:
- ** Checking the headers for a
- ** Content-Type: image/ *
- ** header would help detect problems with results.
- ** Maybe look at the response code too? But there is
- ** no fundamental reason why a 4xx or 5xx response
- ** could not return an image, it is just the 3xx
- ** series we need to worry about.
- **
- ** Also, grabbing the size from the Content-Length
- ** header and killing the connection after that
- ** many bytes where read would speed up closing the
- ** socket.
- ** -- BEG
- */
-
- switch (body) {
-
- case IN_BODY:
- fwrite(buf + i, 1, size - i, fp);
- i = size;
- break;
-
- case SAW_ONE_CM:
- if (buf[i] == '\012') {
- body = SAW_ONE_CJ;
- } else {
- body = SAW_NONE;
- }
- break;
-
- case SAW_ONE_CJ:
- if (buf[i] == '\015') {
- body = SAW_TWO_CM;
- } else {
- if (buf[i] == '\012') {
- body = IN_BODY;
- } else {
- body = SAW_NONE;
- }
- }
- break;
-
- case SAW_TWO_CM:
- if (buf[i] == '\012') {
- body = IN_BODY;
- } else {
- body = SAW_NONE;
- }
- break;
-
- case SAW_NONE:
- if (buf[i] == '\015') {
- body = SAW_ONE_CM;
- } else {
- if (buf[i] == '\012') {
- body = SAW_ONE_CJ;
- }
- }
- break;
-
- } /* switch */
- } /* for i */
+ curl = curl_easy_init();
+ if (!curl) {
+ weprintf("open url: libcurl initialization failure");
+ return NULL;
+ }
+
+ sfn = estrjoin("_", tmpname, "XXXXXX", NULL);
+ free(tmpname);
+ fd = mkstemp(sfn);
+ if (fd != -1) {
+ sfp = fdopen(fd, "w+");
+ if (sfp != NULL) {
+ curl_easy_setopt(curl, CURLOPT_URL, 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_FAILONERROR, 1L);
+
+ res = curl_easy_perform(curl);
+ curl_easy_cleanup(curl);
+ if (res != CURLE_OK) {
+ weprintf("open url: %s", ebuff);
+ unlink(sfn);
+ close(fd);
+ free(sfn);
+ sfn = NULL;
}
- } /* while read */
- close(sockno);
- fclose(fp);
- } else {
- int pid;
- int status;
-
- if ((pid = fork()) < 0) {
- weprintf("open url: fork failed:");
- free(tmpname);
- return(NULL);
- } else if (pid == 0) {
- char *quiet = NULL;
- if (!opt.verbose)
- quiet = estrdup("-q");
-
- execlp("wget", "wget", "--cache=off", "-O", tmpname, url, quiet, NULL);
- eprintf("url: Is 'wget' installed? Failed to exec wget:");
+ free(ebuff);
+ fclose(sfp);
+ return sfn;
} else {
- waitpid(pid, &status, 0);
-
- if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
- weprintf("url: wget failed to load URL %s\n", url);
- unlink(tmpname);
- free(tmpname);
- return(NULL);
- }
+ weprintf("open url: fdopen failed:");
+ free(sfn);
+ unlink(sfn);
+ close(fd);
}
+ } else {
+ weprintf("open url: mkstemp failed:");
+ free(sfn);
}
-
- return(tmpname);
+ curl_easy_cleanup(curl);
+ return NULL;
}
-char *feh_strip_hostname(char *url)
-{
- char *ret;
- char *start;
- char *finish;
- int len;
-
- start = strchr(url, '/');
- if (!start)
- return(NULL);
-
- start += 2;
-
- finish = strchr(start, '/');
- if (!finish)
- return(NULL);
+#else /* HAVE_LIBCURL */
- len = finish - start;
-
- ret = emalloc(len + 1);
- strncpy(ret, start, len);
- ret[len] = '\0';
- return(ret);
+char *feh_http_load_image(char *url)
+{
+ weprintf(
+ "Cannot load image %s\n Please recompile with libcurl support",
+ url
+ );
+ return NULL;
}
+#endif /* HAVE_LIBCURL */
+
void feh_draw_zoom(winwidget w)
{
static Imlib_Font fn = NULL;
@@ -683,7 +505,7 @@ void feh_draw_info(winwidget w)
return;
}
-char *build_caption_filename(feh_file * file)
+char *build_caption_filename(feh_file * file, short create_dir)
{
char *caption_filename;
char *s, *dir, *caption_dir;
@@ -702,6 +524,8 @@ char *build_caption_filename(feh_file * file)
D(("dir %s, cp %s, cdir %s\n", dir, opt.caption_path, caption_dir))
if (stat(caption_dir, &cdir_stat) == -1) {
+ if (!create_dir)
+ return NULL;
if (mkdir(caption_dir, 0755) == -1)
eprintf("Failed to create caption directory %s:", caption_dir);
} else if (!S_ISDIR(cdir_stat.st_mode))
@@ -737,9 +561,12 @@ void feh_draw_caption(winwidget w)
if (!file->caption) {
char *caption_filename;
- caption_filename = build_caption_filename(file);
- /* read caption from file */
- file->caption = ereadfile(caption_filename);
+ caption_filename = build_caption_filename(file, 0);
+ if (caption_filename)
+ /* read caption from file */
+ file->caption = ereadfile(caption_filename);
+ else
+ file->caption = estrdup("");
free(caption_filename);
}
diff --git a/src/index.c b/src/index.c
index 15dcea1..2829bad 100644
--- a/src/index.c
+++ b/src/index.c
@@ -1,6 +1,7 @@
/* index.c
Copyright (C) 1999-2003 Tom Gilbert.
+Copyright (C) 2010-2011 Daniel 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 7940973..e43ae33 100644
--- a/src/keyevents.c
+++ b/src/keyevents.c
@@ -1,6 +1,7 @@
/* keyevents.c
Copyright (C) 1999-2003 Tom Gilbert.
+Copyright (C) 2010-2011 Daniel 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,6 +30,276 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "winwidget.h"
#include "options.h"
+fehkb keys;
+
+static void feh_set_kb(fehkey *key, int s0, int y0, int s1, int y1, int s2, int y2) {
+ key->keystates[0] = s0;
+ key->keystates[1] = s1;
+ key->keystates[2] = s2;
+ key->keysyms[0] = y0;
+ key->keysyms[1] = y1;
+ key->keysyms[2] = y2;
+}
+
+static void feh_set_parse_kb_partial(fehkey *key, int index, char *ks) {
+ char *cur = ks;
+ int mod = 0;
+
+ if (!*ks) {
+ key->keysyms[index] = 0;
+ return;
+ }
+
+ if (ks[1] == '-') {
+ switch (ks[0]) {
+ case 'C':
+ mod = ControlMask;
+ break;
+ case '1':
+ mod = Mod1Mask;
+ break;
+ case '4':
+ mod = Mod4Mask;
+ break;
+ default:
+ weprintf("keys: invalid modifier %c in %s", ks[0], ks);
+ break;
+ }
+ cur = ks + 2;
+ }
+
+ key->keysyms[index] = XStringToKeysym(cur);
+ key->keystates[index] = mod;
+
+ if (key->keysyms[index] == NoSymbol)
+ weprintf("keys: Invalid keysym: %s", cur);
+}
+
+void init_keyevents(void) {
+ char *home = NULL;
+ char *confhome = NULL;
+ char *confpath = NULL;
+ char line[128];
+ char action[32], k1[32], k2[32], k3[32];
+ struct __fehkey *cur_kb = NULL;
+ FILE *conf = NULL;
+ int read = 0;
+
+ memset(&keys, 0, sizeof(keys));
+
+ feh_set_kb(&keys.menu_close, 0, XK_Escape , 0, 0 , 0, 0);
+ feh_set_kb(&keys.menu_parent,0, XK_Left , 0, 0 , 0, 0);
+ feh_set_kb(&keys.menu_down , 0, XK_Down , 0, 0 , 0, 0);
+ feh_set_kb(&keys.menu_up , 0, XK_Up , 0, 0 , 0, 0);
+ feh_set_kb(&keys.menu_child, 0, XK_Right , 0, 0 , 0, 0);
+ feh_set_kb(&keys.menu_select,0, XK_Return , 0, XK_space , 0, 0);
+ feh_set_kb(&keys.scroll_left,0, XK_KP_Left , 4, XK_Left , 0, 0);
+ feh_set_kb(&keys.scroll_right,0,XK_KP_Right , 4, XK_Right , 0, 0);
+ feh_set_kb(&keys.scroll_down,0, XK_KP_Down , 4, XK_Down , 0, 0);
+ feh_set_kb(&keys.scroll_up , 0, XK_KP_Up , 4, XK_Up , 0, 0);
+ feh_set_kb(&keys.prev_img , 0, XK_Left , 0, XK_p , 0, XK_BackSpace);
+ feh_set_kb(&keys.next_img , 0, XK_Right , 0, XK_n , 0, XK_space);
+ feh_set_kb(&keys.jump_back , 0, XK_Page_Up , 0, XK_KP_Page_Up, 0, 0);
+ feh_set_kb(&keys.jump_fwd , 0, XK_Page_Down , 0, XK_KP_Page_Down,0,0);
+ feh_set_kb(&keys.jump_random,0, XK_z , 0, 0 , 0, 0);
+ feh_set_kb(&keys.quit , 0, XK_Escape , 0, XK_q , 0, 0);
+ feh_set_kb(&keys.close , 0, XK_x , 0, 0 , 0, 0);
+ feh_set_kb(&keys.remove , 0, XK_Delete , 0, 0 , 0, 0);
+ feh_set_kb(&keys.delete , 4, XK_Delete , 0, 0 , 0, 0);
+ feh_set_kb(&keys.jump_first, 0, XK_Home , 0, XK_KP_Home , 0, 0);
+ feh_set_kb(&keys.jump_last , 0, XK_End , 0, XK_KP_End , 0, 0);
+ feh_set_kb(&keys.action_0 , 0, XK_Return , 0, XK_0 , 0, XK_KP_0);
+ feh_set_kb(&keys.action_1 , 0, XK_1 , 0, XK_KP_1 , 0, 0);
+ feh_set_kb(&keys.action_2 , 0, XK_2 , 0, XK_KP_2 , 0, 0);
+ feh_set_kb(&keys.action_3 , 0, XK_3 , 0, XK_KP_3 , 0, 0);
+ feh_set_kb(&keys.action_4 , 0, XK_4 , 0, XK_KP_4 , 0, 0);
+ feh_set_kb(&keys.action_5 , 0, XK_5 , 0, XK_KP_5 , 0, 0);
+ feh_set_kb(&keys.action_6 , 0, XK_6 , 0, XK_KP_6 , 0, 0);
+ feh_set_kb(&keys.action_7 , 0, XK_7 , 0, XK_KP_7 , 0, 0);
+ feh_set_kb(&keys.action_8 , 0, XK_8 , 0, XK_KP_8 , 0, 0);
+ feh_set_kb(&keys.action_9 , 0, XK_9 , 0, XK_KP_9 , 0, 0);
+ feh_set_kb(&keys.zoom_in , 0, XK_Up , 0, XK_KP_Add , 0, 0);
+ feh_set_kb(&keys.zoom_out , 0, XK_Down , 0, XK_KP_Subtract,0, 0);
+ feh_set_kb(&keys.zoom_default, 0, XK_KP_Multiply, 0, 0 , 0, 0);
+ feh_set_kb(&keys.zoom_fit , 0, XK_KP_Divide , 0, 0 , 0, 0);
+ feh_set_kb(&keys.size_to_image, 0, XK_w , 0, 0 , 0, 0);
+ feh_set_kb(&keys.render , 0, XK_KP_Begin , 0, 0 , 0, 0);
+ feh_set_kb(&keys.toggle_actions, 0, XK_a, 0, 0, 0, 0);
+ feh_set_kb(&keys.toggle_aliasing, 0, XK_A, 0, 0, 0, 0);
+ feh_set_kb(&keys.toggle_filenames, 0, XK_d, 0, 0, 0, 0);
+ feh_set_kb(&keys.toggle_pointer, 0, XK_o, 0, 0, 0, 0);
+ feh_set_kb(&keys.toggle_caption, 0, XK_c, 0, 0, 0, 0);
+ feh_set_kb(&keys.toggle_pause, 0, XK_h, 0, 0, 0, 0);
+ feh_set_kb(&keys.toggle_menu, 0, XK_m, 0, 0, 0, 0);
+ feh_set_kb(&keys.toggle_fullscreen, 0, XK_v, 0, 0, 0, 0);
+ feh_set_kb(&keys.reload_image, 0, XK_r, 0, 0, 0, 0);
+ feh_set_kb(&keys.save_image, 0, XK_s, 0, 0, 0, 0);
+ feh_set_kb(&keys.save_filelist, 0, XK_f, 0, 0, 0, 0);
+ feh_set_kb(&keys.orient_1, 0, XK_greater, 0, 0, 0, 0);
+ feh_set_kb(&keys.orient_3, 0, XK_less, 0, 0, 0, 0);
+ feh_set_kb(&keys.reload_minus, 0, XK_minus, 0, 0, 0, 0);
+ feh_set_kb(&keys.reload_plus, 0, XK_plus, 0, 0, 0, 0);
+
+ home = getenv("HOME");
+ if (!home)
+ eprintf("No HOME in environment\n");
+
+ confhome = getenv("XDG_CONFIG_HOME");
+
+ if (confhome)
+ confpath = estrjoin("/", confhome, "feh/keys", NULL);
+ else
+ confpath = estrjoin("/", home, ".config/feh/keys", NULL);
+
+ conf = fopen(confpath, "r");
+
+ free(confpath);
+
+ if (!conf && ((conf = fopen("/etc/feh/keys", "r")) == NULL))
+ return;
+
+ while (fgets(line, sizeof(line), conf)) {
+ *action = '\0';
+ *k1 = '\0';
+ *k2 = '\0';
+ *k3 = '\0';
+
+ read = sscanf(line, "%31s %31s %31s %31s\n",
+ (char *) &action, (char *) &k1, (char* ) &k2, (char *) &k3);
+
+ if ((read == EOF) || (read == 0) || (line[0] == '#'))
+ continue;
+
+ if (!strcmp(action, "menu_close"))
+ cur_kb = &keys.menu_close;
+ else if (!strcmp(action, "menu_parent"))
+ cur_kb = &keys.menu_parent;
+ else if (!strcmp(action, "menu_down"))
+ cur_kb = &keys.menu_down;
+ else if (!strcmp(action, "menu_up"))
+ cur_kb = &keys.menu_up;
+ else if (!strcmp(action, "menu_child"))
+ cur_kb = &keys.menu_child;
+ else if (!strcmp(action, "menu_select"))
+ cur_kb = &keys.menu_select;
+ else if (!strcmp(action, "scroll_right"))
+ cur_kb = &keys.scroll_right;
+ else if (!strcmp(action, "scroll_left"))
+ cur_kb = &keys.scroll_left;
+ else if (!strcmp(action, "scroll_up"))
+ cur_kb = &keys.scroll_up;
+ else if (!strcmp(action, "scroll_down"))
+ cur_kb = &keys.scroll_down;
+ else if (!strcmp(action, "prev_img"))
+ cur_kb = &keys.prev_img;
+ else if (!strcmp(action, "next_img"))
+ cur_kb = &keys.next_img;
+ else if (!strcmp(action, "jump_back"))
+ cur_kb = &keys.jump_back;
+ else if (!strcmp(action, "jump_fwd"))
+ cur_kb = &keys.jump_fwd;
+ else if (!strcmp(action, "jump_random"))
+ cur_kb = &keys.jump_random;
+ else if (!strcmp(action, "quit"))
+ cur_kb = &keys.quit;
+ else if (!strcmp(action, "close"))
+ cur_kb = &keys.close;
+ else if (!strcmp(action, "remove"))
+ cur_kb = &keys.remove;
+ else if (!strcmp(action, "delete"))
+ cur_kb = &keys.delete;
+ else if (!strcmp(action, "jump_first"))
+ cur_kb = &keys.jump_first;
+ else if (!strcmp(action, "jump_last"))
+ cur_kb = &keys.jump_last;
+ else if (!strcmp(action, "action_0"))
+ cur_kb = &keys.action_0;
+ else if (!strcmp(action, "action_1"))
+ cur_kb = &keys.action_1;
+ else if (!strcmp(action, "action_2"))
+ cur_kb = &keys.action_2;
+ else if (!strcmp(action, "action_3"))
+ cur_kb = &keys.action_3;
+ else if (!strcmp(action, "action_4"))
+ cur_kb = &keys.action_4;
+ else if (!strcmp(action, "action_5"))
+ cur_kb = &keys.action_5;
+ else if (!strcmp(action, "action_6"))
+ cur_kb = &keys.action_6;
+ else if (!strcmp(action, "action_7"))
+ cur_kb = &keys.action_7;
+ else if (!strcmp(action, "action_8"))
+ cur_kb = &keys.action_8;
+ else if (!strcmp(action, "action_9"))
+ cur_kb = &keys.action_9;
+ else if (!strcmp(action, "zoom_in"))
+ cur_kb = &keys.zoom_in;
+ else if (!strcmp(action, "zoom_out"))
+ cur_kb = &keys.zoom_out;
+ else if (!strcmp(action, "zoom_default"))
+ cur_kb = &keys.zoom_default;
+ else if (!strcmp(action, "zoom_fit"))
+ cur_kb = &keys.zoom_fit;
+ else if (!strcmp(action, "size_to_image"))
+ cur_kb = &keys.size_to_image;
+ else if (!strcmp(action, "render"))
+ cur_kb = &keys.render;
+ else if (!strcmp(action, "toggle_actions"))
+ cur_kb = &keys.toggle_actions;
+ else if (!strcmp(action, "toggle_aliasing"))
+ cur_kb = &keys.toggle_aliasing;
+ else if (!strcmp(action, "toggle_filenames"))
+ cur_kb = &keys.toggle_filenames;
+ else if (!strcmp(action, "toggle_pointer"))
+ cur_kb = &keys.toggle_pointer;
+ else if (!strcmp(action, "toggle_caption"))
+ cur_kb = &keys.toggle_caption;
+ else if (!strcmp(action, "toggle_pause"))
+ cur_kb = &keys.toggle_pause;
+ else if (!strcmp(action, "toggle_menu"))
+ cur_kb = &keys.toggle_menu;
+ else if (!strcmp(action, "toggle_fullscreen"))
+ cur_kb = &keys.toggle_fullscreen;
+ else if (!strcmp(action, "reload_image"))
+ cur_kb = &keys.reload_image;
+ else if (!strcmp(action, "save_image"))
+ cur_kb = &keys.save_image;
+ else if (!strcmp(action, "save_filelist"))
+ cur_kb = &keys.save_filelist;
+ else if (!strcmp(action, "orient_1"))
+ cur_kb = &keys.orient_1;
+ else if (!strcmp(action, "orient_3"))
+ cur_kb = &keys.orient_3;
+ else if (!strcmp(action, "reload_minus"))
+ cur_kb = &keys.reload_minus;
+ else if (!strcmp(action, "reload_plus"))
+ cur_kb = &keys.reload_plus;
+ else
+ weprintf("keys: Invalid action: %s", action);
+
+ if (cur_kb) {
+ feh_set_parse_kb_partial(cur_kb, 0, k1);
+ feh_set_parse_kb_partial(cur_kb, 1, k2);
+ feh_set_parse_kb_partial(cur_kb, 2, k3);
+ }
+ }
+ fclose(conf);
+}
+
+static short feh_is_kp(fehkey *key, int sym, int state) {
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ if (
+ (key->keysyms[i] == sym) &&
+ (key->keystates[i] == state))
+ return 1;
+ else if (key->keysyms[i] == 0)
+ return 0;
+ }
+ return 0;
+}
+
void feh_event_invoke_action(winwidget winwid, unsigned char action)
{
if (opt.actions[action]) {
@@ -54,6 +325,7 @@ void feh_event_invoke_action(winwidget winwid, unsigned char action)
void feh_event_handle_keypress(XEvent * ev)
{
int len;
+ int state;
char kbuf[20];
KeySym keysym;
XKeyEvent *kev;
@@ -71,34 +343,23 @@ void feh_event_handle_keypress(XEvent * ev)
kev = (XKeyEvent *) ev;
len = XLookupString(&ev->xkey, (char *) kbuf, sizeof(kbuf), &keysym, NULL);
+ state = kev->state & (ControlMask | Mod1Mask | Mod4Mask);
/* menus are showing, so this is a menu control keypress */
if (ev->xbutton.window == menu_cover) {
selected_item = feh_menu_find_selected_r(menu_root, &selected_menu);
- switch (keysym) {
- case XK_Escape:
+ if (feh_is_kp(&keys.menu_close, keysym, state))
feh_menu_hide(menu_root, True);
- break;
- case XK_Left:
+ else if (feh_is_kp(&keys.menu_parent, keysym, state))
feh_menu_select_parent(selected_menu);
- break;
- case XK_Down:
+ else if (feh_is_kp(&keys.menu_down, keysym, state))
feh_menu_select_next(selected_menu, selected_item);
- break;
- case XK_Up:
+ else if (feh_is_kp(&keys.menu_up, keysym, state))
feh_menu_select_prev(selected_menu, selected_item);
- break;
- case XK_Right:
+ else if (feh_is_kp(&keys.menu_child, keysym, state))
feh_menu_select_submenu(selected_menu);
- break;
- case XK_Return:
- case XK_space:
+ else if (feh_is_kp(&keys.menu_select, keysym, state))
feh_menu_item_activate(selected_menu, selected_item);
- break;
- default:
- break;
- }
-
return;
}
@@ -108,7 +369,7 @@ void feh_event_handle_keypress(XEvent * ev)
if (winwid->caption_entry) {
switch (keysym) {
case XK_Return:
- if (kev->state & ControlMask) {
+ if (state & ControlMask) {
/* insert actual newline */
ESTRAPPEND(FEH_FILE(winwid->file->data)->caption, "\n");
winwidget_render_image_cached(winwid);
@@ -116,14 +377,15 @@ void feh_event_handle_keypress(XEvent * ev)
/* finish caption entry, write to captions file */
FILE *fp;
char *caption_filename;
- caption_filename = build_caption_filename(FEH_FILE(winwid->file->data));
+ caption_filename =
+ build_caption_filename(FEH_FILE(winwid->file->data), 1);
winwid->caption_entry = 0;
winwidget_render_image_cached(winwid);
XFreePixmap(disp, winwid->bg_pmap_cache);
winwid->bg_pmap_cache = 0;
fp = fopen(caption_filename, "w");
if (!fp) {
- weprintf("couldn't write to captions file %s:", caption_filename);
+ eprintf("couldn't write to captions file %s:", caption_filename);
return;
}
fprintf(fp, "%s", FEH_FILE(winwid->file->data)->caption);
@@ -156,244 +418,179 @@ void feh_event_handle_keypress(XEvent * ev)
return;
}
- switch (keysym) {
- case XK_Left:
- if (kev->state & ControlMask) {
- winwid->im_x += 10;
- winwidget_render_image(winwid, 0, 0);
- }
- else if (opt.slideshow)
- slideshow_change_image(winwid, SLIDE_PREV);
- break;
- case XK_Right:
- if (kev->state & ControlMask) {
- winwid->im_x -= 10;
- winwidget_render_image(winwid, 0, 0);
- }
- else if (opt.slideshow)
+ if (feh_is_kp(&keys.next_img, keysym, state)) {
+ if (opt.slideshow)
slideshow_change_image(winwid, SLIDE_NEXT);
- break;
- case XK_Page_Up:
- case XK_KP_Page_Up:
+ }
+ else if (feh_is_kp(&keys.prev_img, keysym, state)) {
+ if (opt.slideshow)
+ slideshow_change_image(winwid, SLIDE_PREV);
+ }
+ else if (feh_is_kp(&keys.scroll_right, keysym, state)) {
+ winwid->im_x -= 20;
+ winwidget_render_image(winwid, 0, 1);
+ }
+ else if (feh_is_kp(&keys.scroll_left, keysym, state)) {
+ winwid->im_x += 20;
+ winwidget_render_image(winwid, 0, 1);
+ }
+ else if (feh_is_kp(&keys.scroll_down, keysym, state)) {
+ winwid->im_y -= 20;
+ winwidget_render_image(winwid, 0, 1);
+ }
+ else if (feh_is_kp(&keys.scroll_up, keysym, state)) {
+ winwid->im_y += 20;
+ winwidget_render_image(winwid, 0, 1);
+ }
+ else if (feh_is_kp(&keys.jump_back, keysym, state)) {
if (opt.slideshow)
slideshow_change_image(winwid, SLIDE_JUMP_BACK);
- break;
- case XK_Escape:
- winwidget_destroy_all();
- break;
- case XK_Page_Down:
- case XK_KP_Page_Down:
+ }
+ else if (feh_is_kp(&keys.jump_fwd, keysym, state)) {
if (opt.slideshow)
slideshow_change_image(winwid, SLIDE_JUMP_FWD);
- break;
- case XK_Delete:
- /* Holding ctrl gets you a filesystem deletion and removal from the *
- filelist. Just DEL gets you filelist removal only. */
- if (kev->state & ControlMask) {
- if (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER)
- feh_thumbnail_mark_removed(FEH_FILE(winwid->file->data), 1);
- feh_filelist_image_remove(winwid, 1);
- } else {
- if (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER)
- feh_thumbnail_mark_removed(FEH_FILE(winwid->file->data), 0);
- feh_filelist_image_remove(winwid, 0);
- }
- break;
- case XK_Home:
- case XK_KP_Home:
+ }
+ else if (feh_is_kp(&keys.quit, keysym, state)) {
+ winwidget_destroy_all();
+ }
+ else if (feh_is_kp(&keys.delete, keysym, state)) {
+ if (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER)
+ feh_thumbnail_mark_removed(FEH_FILE(winwid->file->data), 1);
+ feh_filelist_image_remove(winwid, 1);
+ }
+ else if (feh_is_kp(&keys.remove, keysym, state)) {
+ if (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER)
+ feh_thumbnail_mark_removed(FEH_FILE(winwid->file->data), 0);
+ feh_filelist_image_remove(winwid, 0);
+ }
+ else if (feh_is_kp(&keys.jump_first, keysym, state)) {
if (opt.slideshow)
slideshow_change_image(winwid, SLIDE_FIRST);
- break;
- case XK_End:
- case XK_KP_End:
+ }
+ else if (feh_is_kp(&keys.jump_last, keysym, state)) {
if (opt.slideshow)
slideshow_change_image(winwid, SLIDE_LAST);
- break;
- case XK_Return:
- case XK_KP_Enter:
- case XK_0:
- case XK_KP_0:
+ }
+ else if (feh_is_kp(&keys.action_0, keysym, state)) {
feh_event_invoke_action(winwid, 0);
- break;
- case XK_1:
- case XK_KP_1:
+ }
+ else if (feh_is_kp(&keys.action_1, keysym, state)) {
feh_event_invoke_action(winwid, 1);
- break;
- case XK_2:
- case XK_KP_2:
+ }
+ else if (feh_is_kp(&keys.action_2, keysym, state)) {
feh_event_invoke_action(winwid, 2);
- break;
- case XK_3:
- case XK_KP_3:
+ }
+ else if (feh_is_kp(&keys.action_3, keysym, state)) {
feh_event_invoke_action(winwid, 3);
- break;
- case XK_4:
- case XK_KP_4:
+ }
+ else if (feh_is_kp(&keys.action_4, keysym, state)) {
feh_event_invoke_action(winwid, 4);
- break;
- case XK_5:
- case XK_KP_5:
+ }
+ else if (feh_is_kp(&keys.action_5, keysym, state)) {
feh_event_invoke_action(winwid, 5);
- break;
- case XK_6:
- case XK_KP_6:
+ }
+ else if (feh_is_kp(&keys.action_6, keysym, state)) {
feh_event_invoke_action(winwid, 6);
- break;
- case XK_7:
- case XK_KP_7:
+ }
+ else if (feh_is_kp(&keys.action_7, keysym, state)) {
feh_event_invoke_action(winwid, 7);
- break;
- case XK_8:
- case XK_KP_8:
+ }
+ else if (feh_is_kp(&keys.action_8, keysym, state)) {
feh_event_invoke_action(winwid, 8);
- break;
- case XK_9:
- case XK_KP_9:
+ }
+ else if (feh_is_kp(&keys.action_9, keysym, state)) {
feh_event_invoke_action(winwid, 9);
- break;
- case XK_KP_Left:
- winwid->im_x += 10;
- winwidget_render_image(winwid, 0, 0);
- break;
- case XK_KP_Right:
- winwid->im_x -= 10;
- winwidget_render_image(winwid, 0, 0);
- break;
- case XK_KP_Up:
- winwid->im_y += 10;
+ }
+ else if (feh_is_kp(&keys.zoom_in, keysym, state)) {
+ winwid->old_zoom = winwid->zoom;
+ winwid->zoom = winwid->zoom * 1.25;
+ winwid->im_x = (winwid->w / 2) - (((winwid->w / 2) - winwid->im_x) /
+ winwid->old_zoom * winwid->zoom);
+ winwid->im_y = (winwid->h / 2) - (((winwid->h / 2) - winwid->im_y) /
+ winwid->old_zoom * winwid->zoom);
+ winwidget_sanitise_offsets(winwid);
winwidget_render_image(winwid, 0, 0);
- break;
- case XK_KP_Down:
- winwid->im_y -= 10;
+ }
+ else if (feh_is_kp(&keys.zoom_out, keysym, state)) {
+ winwid->old_zoom = winwid->zoom;
+ winwid->zoom = winwid->zoom * 0.80;
+ winwid->im_x = (winwid->w / 2) - (((winwid->w / 2) - winwid->im_x) /
+ winwid->old_zoom * winwid->zoom);
+ winwid->im_y = (winwid->h / 2) - (((winwid->h / 2) - winwid->im_y) /
+ winwid->old_zoom * winwid->zoom);
+ winwidget_sanitise_offsets(winwid);
winwidget_render_image(winwid, 0, 0);
- break;
- case XK_KP_Add:
- case XK_Up:
- if (kev->state & ControlMask) {
- winwid->im_y += 10;
- winwidget_render_image(winwid, 0, 0);
- }
- else {
- /* erroneously recognized as '+' in the *kbuf switch. Work around this. */
- len = 0;
- winwid->old_zoom = winwid->zoom;
- winwid->zoom = winwid->zoom * 1.25;
- winwid->im_x = (winwid->w / 2) - (((winwid->w / 2) - winwid->im_x) /
- winwid->old_zoom * winwid->zoom);
- winwid->im_y = (winwid->h / 2) - (((winwid->h / 2) - winwid->im_y) /
- winwid->old_zoom * winwid->zoom);
- winwidget_sanitise_offsets(winwid);
- winwidget_render_image(winwid, 0, 1);
- }
- break;
- case XK_KP_Subtract:
- case XK_Down:
- if (kev->state & ControlMask) {
- winwid->im_y -= 10;
- winwidget_render_image(winwid, 0, 0);
- }
- else {
- len = 0;
- winwid->old_zoom = winwid->zoom;
- winwid->zoom = winwid->zoom * 0.75;
- winwid->im_x = (winwid->w / 2) - (((winwid->w / 2) - winwid->im_x) /
- winwid->old_zoom * winwid->zoom);
- winwid->im_y = (winwid->h / 2) - (((winwid->h / 2) - winwid->im_y) /
- winwid->old_zoom * winwid->zoom);
- winwidget_sanitise_offsets(winwid);
- winwidget_render_image(winwid, 0, 1);
- }
- break;
- case XK_KP_Multiply:
- len = 0;
+ }
+ else if (feh_is_kp(&keys.zoom_default, keysym, state)) {
winwid->zoom = 1;
+ winwid->old_zoom = 1.001; /* hack for --scale-down */
winwidget_center_image(winwid);
winwidget_render_image(winwid, 0, 0);
- break;
- case XK_KP_Divide:
- len = 0;
+ }
+ else if (feh_is_kp(&keys.zoom_fit, keysym, state)) {
feh_calc_needed_zoom(&winwid->zoom, winwid->im_w, winwid->im_h, winwid->w, winwid->h);
winwidget_center_image(winwid);
- winwidget_render_image(winwid, 0, 1);
- break;
- case XK_KP_Begin:
- winwidget_render_image(winwid, 0, 1);
- break;
- default:
- break;
+ winwidget_render_image(winwid, 0, 0);
}
-
- if (len <= 0 || len > (int) sizeof(kbuf))
- return;
- kbuf[len] = '\0';
-
- switch (*kbuf) {
- case 'a':
+ else if (feh_is_kp(&keys.render, keysym, state)) {
+ winwidget_render_image(winwid, 0, 0);
+ }
+ else if (feh_is_kp(&keys.toggle_actions, keysym, state)) {
opt.draw_actions = !opt.draw_actions;
- winwidget_rerender_all(0, 1);
- break;
- case 'd':
+ winwidget_rerender_all(0);
+ }
+ else if (feh_is_kp(&keys.toggle_aliasing, keysym, state)) {
+ opt.force_aliasing = !opt.force_aliasing;
+ winwidget_rerender_all(0);
+ }
+ else if (feh_is_kp(&keys.toggle_filenames, keysym, state)) {
opt.draw_filename = !opt.draw_filename;
- winwidget_rerender_all(0, 1);
- break;
- case 'n':
- case ' ':
- if (opt.slideshow)
- slideshow_change_image(winwid, SLIDE_NEXT);
- break;
- case 'o':
+ winwidget_rerender_all(0);
+ }
+ else if (feh_is_kp(&keys.toggle_pointer, keysym, state)) {
winwidget_set_pointer(winwid, opt.hide_pointer);
opt.hide_pointer = !opt.hide_pointer;
- break;
- case 'p':
- case '\b':
- if (opt.slideshow)
- slideshow_change_image(winwid, SLIDE_PREV);
- break;
- case 'z':
- if (opt.slideshow)
- slideshow_change_image(winwid, SLIDE_RAND);
- break;
- case 'q':
- winwidget_destroy_all();
- break;
- case 'c':
+ }
+ else if (feh_is_kp(&keys.jump_random, keysym, state)) {
+ slideshow_change_image(winwid, SLIDE_RAND);
+ }
+ else if (feh_is_kp(&keys.toggle_caption, keysym, state)) {
if (opt.caption_path)
winwid->caption_entry = 1;
- winwidget_render_image(winwid, 0, 1);
- break;
- case 'r':
+ winwidget_render_image(winwid, 0, 0);
+ }
+ else if (feh_is_kp(&keys.reload_image, keysym, state)) {
feh_reload_image(winwid, 0, 0);
- break;
- case 'h':
+ }
+ else if (feh_is_kp(&keys.toggle_pause, keysym, state)) {
slideshow_pause_toggle(winwid);
- break;
- case 's':
+ }
+ else if (feh_is_kp(&keys.save_image, keysym, state)) {
slideshow_save_image(winwid);
- break;
- case 'f':
+ }
+ else if (feh_is_kp(&keys.save_filelist, keysym, state)) {
if ((winwid->type == WIN_TYPE_THUMBNAIL)
|| (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER))
weprintf("Filelist saving is not supported in thumbnail mode");
else
feh_save_filelist();
- break;
- case 'w':
+ }
+ else if (feh_is_kp(&keys.size_to_image, keysym, state)) {
winwidget_size_to_image(winwid);
- break;
- case 'm':
+ }
+ else if (feh_is_kp(&keys.toggle_menu, keysym, state)) {
winwidget_show_menu(winwid);
- break;
- case 'x':
+ }
+ else if (feh_is_kp(&keys.close, keysym, state)) {
winwidget_destroy(winwid);
- break;
- case '>':
+ }
+ else if (feh_is_kp(&keys.orient_1, keysym, state)) {
feh_edit_inplace_orient(winwid, 1);
- break;
- case '<':
+ }
+ else if (feh_is_kp(&keys.orient_3, keysym, state)) {
feh_edit_inplace_orient(winwid, 3);
- break;
- case 'v':
+ }
+ else if (feh_is_kp(&keys.toggle_fullscreen, keysym, state)) {
#ifdef HAVE_LIBXINERAMA
if (opt.xinerama && xinerama_screens) {
int i, rect[4];
@@ -425,7 +622,7 @@ void feh_event_handle_keypress(XEvent * ev)
winwid->full_screen = !winwid->full_screen;
winwidget_destroy_xwin(winwid);
winwidget_create_window(winwid, winwid->im_w, winwid->im_h);
- winwidget_render_image(winwid, 1, 1);
+ winwidget_render_image(winwid, 1, 0);
winwidget_show(winwid);
#ifdef HAVE_LIBXINERAMA
/* if we have xinerama and we're using it, then full screen the window
@@ -436,20 +633,18 @@ void feh_event_handle_keypress(XEvent * ev)
xinerama_screens[curr_screen].x_org, xinerama_screens[curr_screen].y_org);
}
#endif /* HAVE_LIBXINERAMA */
- case '+':
+ }
+ else if (feh_is_kp(&keys.reload_plus, keysym, state)){
if (opt.reload < SLIDESHOW_RELOAD_MAX)
opt.reload++;
else if (opt.verbose)
weprintf("Cannot set RELOAD higher than %d seconds.", opt.reload);
- break;
- case '-':
+ }
+ else if (feh_is_kp(&keys.reload_minus, keysym, state)) {
if (opt.reload > 1)
opt.reload--;
else if (opt.verbose)
weprintf("Cannot set RELOAD lower than 1 second.");
- break;
- default:
- break;
}
return;
}
diff --git a/src/list.c b/src/list.c
index 989cfcf..f52e0d5 100644
--- a/src/list.c
+++ b/src/list.c
@@ -1,6 +1,7 @@
/* list.c
Copyright (C) 1999-2003 Tom Gilbert.
+Copyright (C) 2010-2011 Daniel 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 8905508..6b28e52 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,6 +1,7 @@
/* main.c
Copyright (C) 1999-2003 Tom Gilbert.
+Copyright (C) 2010-2011 Daniel Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -43,8 +44,10 @@ int main(int argc, char **argv)
init_imlib_fonts();
- if (opt.display)
+ if (opt.display) {
init_x_and_imlib();
+ init_keyevents();
+ }
feh_event_init();
diff --git a/src/menu.c b/src/menu.c
index c50f015..f12f4ed 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -1,6 +1,7 @@
/* menu.c
Copyright (C) 1999-2003 Tom Gilbert.
+Copyright (C) 2010-2011 Daniel Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -1267,7 +1268,7 @@ void feh_menu_cb_opt_fullscreen(feh_menu * m, feh_menu_item * i)
winwidget_destroy_xwin(m->fehwin);
winwidget_create_window(m->fehwin, m->fehwin->im_w, m->fehwin->im_h);
- winwidget_render_image(m->fehwin, 1, 1);
+ winwidget_render_image(m->fehwin, 1, 0);
winwidget_show(m->fehwin);
#ifdef HAVE_LIBXINERAMA
@@ -1342,7 +1343,7 @@ void feh_menu_cb(feh_menu * m, feh_menu_item * i, int action, void *data)
winwidget_resize(m->fehwin, m->fehwin->im_w, m->fehwin->im_h);
}
winwidget_reset_image(m->fehwin);
- winwidget_render_image(m->fehwin, 1, 1);
+ winwidget_render_image(m->fehwin, 1, 0);
break;
case CB_RELOAD:
feh_reload_image(m->fehwin, 0, 0);
@@ -1403,7 +1404,7 @@ void feh_menu_cb(feh_menu * m, feh_menu_item * i, int action, void *data)
opt.draw_filename = TRUE;
else
opt.draw_filename = FALSE;
- winwidget_rerender_all(0, 1);
+ winwidget_rerender_all(0);
break;
case CB_OPT_DRAW_ACTIONS:
MENU_ITEM_TOGGLE(i);
@@ -1411,7 +1412,7 @@ void feh_menu_cb(feh_menu * m, feh_menu_item * i, int action, void *data)
opt.draw_actions = TRUE;
else
opt.draw_actions = FALSE;
- winwidget_rerender_all(0, 1);
+ winwidget_rerender_all(0);
break;
case CB_OPT_KEEP_HTTP:
MENU_ITEM_TOGGLE(i);
@@ -1435,8 +1436,11 @@ void feh_menu_cb(feh_menu * m, feh_menu_item * i, int action, void *data)
break;
case CB_OPT_AUTO_ZOOM:
MENU_ITEM_TOGGLE(i);
- opt.auto_zoom = MENU_ITEM_IS_ON(i) ? 1 : 0;
- winwidget_rerender_all(1, 1);
+ if (MENU_ITEM_IS_ON(i))
+ opt.zoom_mode = ZOOM_MODE_FILL;
+ else
+ opt.zoom_mode = 0;
+ winwidget_rerender_all(1);
break;
}
return;
@@ -1487,7 +1491,7 @@ static feh_menu *feh_menu_func_gen_options(feh_menu * m)
mm = feh_menu_new();
mm->name = estrdup("OPTIONS");
mm->fehwin = m->fehwin;
- feh_menu_add_toggle_entry(mm, "Auto-Zoom", NULL, NULL, CB_OPT_AUTO_ZOOM, NULL, NULL, opt.auto_zoom);
+ feh_menu_add_toggle_entry(mm, "Auto-Zoom", NULL, NULL, CB_OPT_AUTO_ZOOM, NULL, NULL, (opt.zoom_mode == ZOOM_MODE_FILL));
feh_menu_add_toggle_entry(mm, "Freeze Window Size", NULL, NULL,
CB_OPT_FREEZE_WINDOW, NULL, NULL, opt.geom_flags);
feh_menu_add_toggle_entry(mm, "Fullscreen", NULL, NULL,
diff --git a/src/menu.h b/src/menu.h
index 9e8cd21..9056d98 100644
--- a/src/menu.h
+++ b/src/menu.h
@@ -1,6 +1,7 @@
/* menu.h
Copyright (C) 1999-2003 Tom Gilbert.
+Copyright (C) 2010-2011 Daniel 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/multiwindow.c b/src/multiwindow.c
index c46e453..1bd8a8a 100644
--- a/src/multiwindow.c
+++ b/src/multiwindow.c
@@ -28,6 +28,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "timers.h"
#include "filelist.h"
#include "options.h"
+#include "signals.h"
void init_multiwindow_mode(void)
{
@@ -63,5 +64,8 @@ void init_multiwindow_mode(void)
}
free(s);
}
+
+ setup_signal_handlers();
+
return;
}
diff --git a/src/options.c b/src/options.c
index 2206f3e..de72429 100644
--- a/src/options.c
+++ b/src/options.c
@@ -1,6 +1,7 @@
/* options.c
Copyright (C) 1999-2003 Tom Gilbert.
+Copyright (C) 2010-2011 Daniel Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -28,9 +29,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "options.h"
static void check_options(void);
-static void feh_create_default_config(char *rcfile);
-static void feh_parse_option_array(int argc, char **argv);
-static void feh_parse_environment_options(void);
+static void feh_getopt_theme(int argc, char **argv);
+static void feh_parse_option_array(int argc, char **argv, int finalrun);
static void feh_check_theme_options(int arg, char **argv);
static void feh_parse_options_from_string(char *opts);
static void feh_load_options_for_theme(char *theme);
@@ -80,8 +80,6 @@ void init_parse_options(int argc, char **argv)
opt.start_list_at = NULL;
opt.jump_on_resort = 1;
- opt.builtin_http = 0;
-
opt.xinerama = 0;
opt.screen_clip = 1;
#ifdef HAVE_LIBXINERAMA
@@ -89,17 +87,15 @@ void init_parse_options(int argc, char **argv)
opt.xinerama = 1;
#endif /* HAVE_LIBXINERAMA */
- D(("About to parse env options (if any)\n"));
- /* Check for and parse any options in FEH_OPTIONS */
- feh_parse_environment_options();
-
- D(("About to parse commandline options\n"));
- /* Parse the cmdline args */
- feh_parse_option_array(argc, argv);
+ feh_getopt_theme(argc, argv);
D(("About to check for theme configuration\n"));
feh_check_theme_options(argc, argv);
+ D(("About to parse commandline options\n"));
+ /* Parse the cmdline args */
+ feh_parse_option_array(argc, argv, 1);
+
/* If we have a filelist to read, do it now */
if (opt.filelistfile) {
/* joining two reverse-sorted lists in this manner works nicely for us
@@ -147,35 +143,38 @@ static void feh_check_theme_options(int arg, char **argv)
static void feh_load_options_for_theme(char *theme)
{
FILE *fp = NULL;
- char *home;
+ char *home = getenv("HOME");
char *rcpath = NULL;
+ char *oldrcpath = NULL;
+ char *confbase = getenv("XDG_CONFIG_HOME");
char s[1024], s1[1024], s2[1024];
int cont = 0;
int bspos;
- if (opt.rcfile) {
- if ((fp = fopen(opt.rcfile, "r")) == NULL) {
- weprintf("couldn't load the specified rcfile %s\n", opt.rcfile);
- return;
- }
- } else {
- home = getenv("HOME");
- if (!home)
- eprintf("D'oh! Please define HOME in your environment! "
- "It would really help me out...\n");
- rcpath = estrjoin("/", home, ".fehrc", NULL);
- D(("Trying %s for config\n", rcpath));
- fp = fopen(rcpath, "r");
-
- if (!fp && ((fp = fopen("/etc/fehrc", "r")) == NULL)) {
- feh_create_default_config(rcpath);
-
- if ((fp = fopen(rcpath, "r")) == NULL)
- return;
- }
+ if (!home)
+ eprintf("You have no HOME, cannot read themes");
- free(rcpath);
- }
+ oldrcpath = estrjoin("/", home, ".fehrc", NULL);
+
+ if (confbase)
+ rcpath = estrjoin("/", confbase, "feh/themes", NULL);
+ else
+ rcpath = estrjoin("/", home, ".config/feh/themes", NULL);
+
+ fp = fopen(rcpath, "r");
+
+ free(rcpath);
+
+ if (!fp && ((fp = fopen(oldrcpath, "r")) != NULL))
+ weprintf("The theme config file was moved from ~/.fehrc to "
+ "~/.config/feh/themes. Run\n"
+ " mkdir -p ~/.config/feh; mv ~/.fehrc ~/.config/feh/themes\n"
+ "to fix this.");
+
+ free(oldrcpath);
+
+ if (!fp && ((fp = fopen("/etc/feh/themes", "r")) == NULL))
+ return;
/* Oooh. We have an options file :) */
for (; fgets(s, sizeof(s), fp);) {
@@ -221,22 +220,6 @@ static void feh_load_options_for_theme(char *theme)
return;
}
-static void feh_parse_environment_options(void)
-{
- char *opts;
-
- if ((opts = getenv("FEH_OPTIONS")) == NULL)
- return;
-
- weprintf
- ("The FEH_OPTIONS configuration method is depreciated and will soon die.\n"
- "Use the .fehrc configuration file instead.");
-
- /* We definitely have some options to parse */
- feh_parse_options_from_string(opts);
- return;
-}
-
/* FIXME This function is a crufty bitch ;) */
static void feh_parse_options_from_string(char *opts)
{
@@ -275,7 +258,7 @@ static void feh_parse_options_from_string(char *opts)
last = *t;
}
- feh_parse_option_array(num, list);
+ feh_parse_option_array(num, list, 0);
for (i = 0; i < num; i++)
if (list[i])
@@ -317,11 +300,31 @@ char *feh_string_normalize(char *str)
return(estrdup(ret));
}
-static void feh_parse_option_array(int argc, char **argv)
+static void feh_getopt_theme(int argc, char **argv)
+{
+ static char stropts[] = "-T:";
+ static struct option lopts[] = {
+ {"theme", 1, 0, 'T'},
+ {0, 0, 0, 0}
+ };
+ int optch = 0, cmdx = 0;
+
+ opterr = 0;
+
+ while ((optch = getopt_long(argc, argv, stropts, lopts, &cmdx)) != EOF) {
+ if (optch == 'T')
+ theme = estrdup(optarg);
+ }
+
+ opterr = 1;
+ optind = 0;
+}
+
+static void feh_parse_option_array(int argc, char **argv, int finalrun)
{
static char stropts[] =
- "a:A:b:B:cC:dD:e:E:f:Fg:GhH:iIj:J:kK:lL:mM:nNo:O:pPqQrR:sS:tT:uUvVwW:xXy:YzZ"
- "0:1:2:4:5:8:9:.@:^:~:):|:_:+:";
+ "a:A:b:B:cC:dD:e:E:f:Fg:GhH:iIj:J:kK:lL:mM:nNo:O:pPqrR:sS:tT:uUvVwW:xXy:YzZ"
+ "0:1:2:4:5:8:9:.@:^:~:):|:+:";
/* (*name, has_arg, *flag, val) See: struct option in getopts.h */
static struct option lopts[] = {
@@ -351,7 +354,6 @@ static void feh_parse_option_array(int argc, char **argv)
{"preload" , 0, 0, 'p'},
{"reverse" , 0, 0, 'n'},
{"thumbnails" , 0, 0, 't'},
- {"builtin" , 0, 0, 'Q'},
{"scale-down" , 0, 0, '.'},
{"no-jump-on-resort", 0, 0, 220},
{"hide-pointer" , 0, 0, 'Y'},
@@ -396,7 +398,6 @@ static void feh_parse_option_array(int argc, char **argv)
{"rotate-button" , 1, 0, '8'},
{"blur-button" , 1, 0, '9'},
{"start-at" , 1, 0, '|'},
- {"rcfile" , 1, 0, '_'},
{"debug" , 0, 0, '+'},
{"output-dir" , 1, 0, 'j'},
{"bg-tile" , 1, 0, 200},
@@ -422,11 +423,11 @@ static void feh_parse_option_array(int argc, char **argv)
{"index-dim" , 1, 0, 232},
{"thumb-redraw" , 1, 0, 'J'},
{"info" , 1, 0, 234},
+ {"force-aliasing", 0, 0, 235},
{0, 0, 0, 0}
};
int optch = 0, cmdx = 0;
- int i = 0;
/* Now to pass some optionarinos */
while ((optch = getopt_long(argc, argv, stropts, lopts, &cmdx)) != EOF) {
@@ -468,9 +469,6 @@ static void feh_parse_option_array(int argc, char **argv)
opt.list = 1;
opt.display = 0;
break;
- case 'Q':
- opt.builtin_http = 1;
- break;
case 'L':
opt.customlist = estrdup(optarg);
opt.display = 0;
@@ -522,7 +520,7 @@ static void feh_parse_option_array(int argc, char **argv)
opt.full_screen = 1;
break;
case 'Z':
- opt.auto_zoom = 1;
+ opt.zoom_mode = ZOOM_MODE_MAX;
break;
case 'U':
opt.loadables = 1;
@@ -591,9 +589,6 @@ static void feh_parse_option_array(int argc, char **argv)
opt.bg = 1;
opt.bg_file = estrdup(optarg);
break;
- case '_':
- opt.rcfile = estrdup(optarg);
- break;
case 'A':
opt.actions[0] = estrdup(optarg);
break;
@@ -612,6 +607,7 @@ static void feh_parse_option_array(int argc, char **argv)
case ')':
free(opt.menu_bg);
opt.menu_bg = estrdup(optarg);
+ weprintf("The --menu-bg option is deprecated and will be removed by 2012");
break;
case 'B':
free(opt.image_bg);
@@ -693,9 +689,15 @@ static void feh_parse_option_array(int argc, char **argv)
case 204:
free(opt.menu_style);
opt.menu_style = estrdup(optarg);
+ weprintf("The --menu-style option is deprecated and will be removed by 2012");
break;
case 205:
- opt.default_zoom = atoi(optarg);
+ if (!strcmp("fill", optarg))
+ opt.zoom_mode = ZOOM_MODE_FILL;
+ else if (!strcmp("max", optarg))
+ opt.zoom_mode = ZOOM_MODE_MAX;
+ else
+ opt.default_zoom = atoi(optarg);
break;
case 206:
opt.screen_clip = 0;
@@ -772,6 +774,9 @@ static void feh_parse_option_array(int argc, char **argv)
case 234:
opt.info_cmd = estrdup(optarg);
break;
+ case 235:
+ opt.force_aliasing = 1;
+ break;
default:
break;
}
@@ -785,13 +790,8 @@ static void feh_parse_option_array(int argc, char **argv)
add_file_to_filelist_recursively(argv[optind++], FILELIST_FIRST);
}
}
-
- for (i = 0; i < 10; i++) {
- if (opt.actions[i] && !opt.hold_actions[i] && (opt.actions[i][0] == ';')) {
- opt.hold_actions[i] = 1;
- opt.actions[i] = &opt.actions[i][1];
- }
- }
+ else if (finalrun && !opt.filelistfile && !opt.bgmode)
+ add_file_to_filelist_recursively(".", FILELIST_FIRST);
/* So that we can safely be called again */
optind = 1;
@@ -800,6 +800,14 @@ static void feh_parse_option_array(int argc, char **argv)
static void check_options(void)
{
+ int i;
+ for (i = 0; i < 10; i++) {
+ if (opt.actions[i] && !opt.hold_actions[i] && (opt.actions[i][0] == ';')) {
+ opt.hold_actions[i] = 1;
+ opt.actions[i] = &opt.actions[i][1];
+ }
+ }
+
if ((opt.index + opt.collage) > 1) {
weprintf("you can't use collage mode and index mode together.\n"
" I'm going with index");
@@ -843,7 +851,23 @@ static void check_options(void)
static void show_version(void)
{
- printf(PACKAGE " version " VERSION "\n");
+ puts(PACKAGE " version " VERSION);
+ puts("Compile-time switches: "
+
+#ifdef HAVE_LIBCURL
+ "curl "
+#endif
+
+#ifdef DEBUG
+ "debug "
+#endif
+
+#ifdef HAVE_LIBXINERAMA
+ "xinerama "
+#endif
+
+ );
+
exit(0);
}
@@ -861,20 +885,3 @@ static void show_usage(void)
, stdout);
exit(0);
}
-
-static void feh_create_default_config(char *rcfile)
-{
- FILE *fp;
-
- if ((fp = fopen(rcfile, "w")) == NULL) {
- weprintf("Unable to create default config file %s\n", rcfile);
- return;
- }
-
- fputs(
-#include "fehrc.inc"
- , fp);
- fclose(fp);
-
- return;
-}
diff --git a/src/options.h b/src/options.h
index e99c14c..431fdfc 100644
--- a/src/options.h
+++ b/src/options.h
@@ -1,6 +1,7 @@
/* options.h
Copyright (C) 1999-2003 Tom Gilbert.
+Copyright (C) 2010-2011 Daniel 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 +27,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef OPTIONS_H
#define OPTIONS_H
+#define ZOOM_MODE_FILL 1
+#define ZOOM_MODE_MAX 2
+
struct __fehoptions {
unsigned char multiwindow;
unsigned char montage;
@@ -50,7 +54,6 @@ struct __fehoptions {
unsigned char randomize;
unsigned char jump_on_resort;
unsigned char full_screen;
- unsigned char auto_zoom;
unsigned char draw_filename;
unsigned char list;
unsigned char quiet;
@@ -60,7 +63,6 @@ struct __fehoptions {
unsigned char reverse;
unsigned char no_menus;
unsigned char scale_down;
- unsigned char builtin_http;
unsigned char bgmode;
unsigned char xinerama;
unsigned char screen_clip;
@@ -84,7 +86,6 @@ struct __fehoptions {
char *customlist;
char *menu_bg;
char *image_bg;
- char *rcfile;
char *menu_style;
char *caption_path;
char *start_list_at;
@@ -106,6 +107,7 @@ struct __fehoptions {
unsigned char no_blur_ctrl_mask;
unsigned char no_pan_ctrl_mask;
+ int force_aliasing;
int thumb_w;
int thumb_h;
int limit_w;
@@ -120,6 +122,7 @@ struct __fehoptions {
unsigned int geom_w;
unsigned int geom_h;
int default_zoom;
+ int zoom_mode;
unsigned char adjust_reload;
unsigned char mode;
@@ -130,6 +133,66 @@ struct __fehoptions {
Imlib_Font menu_fn;
};
+struct __fehkey {
+ int keysyms[3];
+ int keystates[3];
+};
+
+struct __fehkb {
+ struct __fehkey menu_close;
+ struct __fehkey menu_parent;
+ struct __fehkey menu_down;
+ struct __fehkey menu_up;
+ struct __fehkey menu_child;
+ struct __fehkey menu_select;
+ struct __fehkey scroll_right;
+ struct __fehkey prev_img;
+ struct __fehkey scroll_left;
+ struct __fehkey next_img;
+ struct __fehkey scroll_up;
+ struct __fehkey scroll_down;
+ struct __fehkey jump_back;
+ struct __fehkey quit;
+ struct __fehkey jump_fwd;
+ struct __fehkey remove;
+ struct __fehkey delete;
+ struct __fehkey jump_first;
+ struct __fehkey jump_last;
+ struct __fehkey action_0;
+ struct __fehkey action_1;
+ struct __fehkey action_2;
+ struct __fehkey action_3;
+ struct __fehkey action_4;
+ struct __fehkey action_5;
+ struct __fehkey action_6;
+ struct __fehkey action_7;
+ struct __fehkey action_8;
+ struct __fehkey action_9;
+ struct __fehkey zoom_in;
+ struct __fehkey zoom_out;
+ struct __fehkey zoom_default;
+ struct __fehkey zoom_fit;
+ struct __fehkey render;
+ struct __fehkey toggle_actions;
+ struct __fehkey toggle_filenames;
+ struct __fehkey toggle_pointer;
+ struct __fehkey toggle_aliasing;
+ struct __fehkey jump_random;
+ struct __fehkey toggle_caption;
+ struct __fehkey toggle_pause;
+ struct __fehkey reload_image;
+ struct __fehkey save_image;
+ struct __fehkey save_filelist;
+ struct __fehkey size_to_image;
+ struct __fehkey toggle_menu;
+ struct __fehkey close;
+ struct __fehkey orient_1;
+ struct __fehkey orient_3;
+ struct __fehkey toggle_fullscreen;
+ struct __fehkey reload_minus;
+ struct __fehkey reload_plus;
+};
+
void init_parse_options(int argc, char **argv);
char *feh_string_normalize(char *str);
diff --git a/src/signals.c b/src/signals.c
index b3e118a..956c861 100644
--- a/src/signals.c
+++ b/src/signals.c
@@ -25,6 +25,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "feh.h"
#include "winwidget.h"
+#include "options.h"
void feh_handle_signal(int);
@@ -60,12 +61,16 @@ void feh_handle_signal(int signo)
{
winwidget winwid
= winwidget_get_first_window_of_type(WIN_TYPE_SLIDESHOW);
+ int i;
if (winwid) {
if (signo == SIGUSR1)
slideshow_change_image(winwid, SLIDE_NEXT);
else if (signo == SIGUSR2)
slideshow_change_image(winwid, SLIDE_PREV);
+ } else if (opt.multiwindow) {
+ for (i = window_num - 1; i >= 0; i--)
+ feh_reload_image(windows[i], 0, 0);
}
return;
diff --git a/src/slideshow.c b/src/slideshow.c
index de10300..79b931f 100644
--- a/src/slideshow.c
+++ b/src/slideshow.c
@@ -1,6 +1,7 @@
/* slideshow.c
Copyright (C) 1999-2003 Tom Gilbert.
+Copyright (C) 2010-2011 Daniel Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -100,12 +101,15 @@ void feh_reload_image(winwidget w, int resize, int force_new)
char *title, *new_title;
int len;
Imlib_Image tmp;
+ int old_w, old_h;
if (!w->file) {
weprintf("couldn't reload, this image has no file associated with it.");
return;
}
+ D(("resize %d, force_new %d\n", resize, force_new));
+
free(FEH_FILE(w->file->data)->caption);
FEH_FILE(w->file->data)->caption = NULL;
@@ -115,10 +119,11 @@ void feh_reload_image(winwidget w, int resize, int force_new)
title = estrdup(w->name);
winwidget_rename(w, new_title);
+ old_w = gib_imlib_image_get_width(w->im);
+ old_h = gib_imlib_image_get_height(w->im);
+
/* force imlib2 not to cache */
- if (force_new) {
- winwidget_free_image(w);
- }
+ winwidget_free_image(w);
/* if the image has changed in dimensions - we gotta resize */
if ((feh_load_image(&tmp, FEH_FILE(w->file->data))) == 0) {
@@ -133,19 +138,13 @@ void feh_reload_image(winwidget w, int resize, int force_new)
filelist = feh_file_remove_from_list(filelist, w->file);
return;
}
- if (force_new) {
- w->im = tmp;
+
+ if (!resize && ((old_w != gib_imlib_image_get_width(tmp)) ||
+ (old_h != gib_imlib_image_get_height(tmp))))
resize = 1;
- winwidget_reset_image(w);
- } else {
- if ((gib_imlib_image_get_width(w->im) != gib_imlib_image_get_width(tmp))
- || (gib_imlib_image_get_height(w->im) != gib_imlib_image_get_height(tmp))) {
- resize = 1;
- winwidget_reset_image(w);
- }
- winwidget_free_image(w);
- w->im = tmp;
- }
+
+ w->im = tmp;
+ winwidget_reset_image(w);
w->mode = MODE_NORMAL;
if ((w->im_w != gib_imlib_image_get_width(w->im))
@@ -162,7 +161,7 @@ void feh_reload_image(winwidget w, int resize, int force_new)
w->im_w = gib_imlib_image_get_width(w->im);
w->im_h = gib_imlib_image_get_height(w->im);
}
- winwidget_render_image(w, resize, 1);
+ winwidget_render_image(w, resize, 0);
winwidget_rename(w, title);
free(title);
@@ -251,10 +250,6 @@ void slideshow_change_image(winwidget winwid, int change)
filelist = feh_file_remove_from_list(filelist, last);
last = NULL;
}
- s = slideshow_create_name(FEH_FILE(current_file->data));
-
- winwidget_rename(winwid, s);
- free(s);
if ((winwidget_loadimage(winwid, FEH_FILE(current_file->data)))
!= 0) {
@@ -267,7 +262,12 @@ void slideshow_change_image(winwidget winwid, int change)
winwidget_reset_image(winwid);
winwid->im_w = gib_imlib_image_get_width(winwid->im);
winwid->im_h = gib_imlib_image_get_height(winwid->im);
- winwidget_render_image(winwid, 1, 1);
+ winwidget_render_image(winwid, 1, 0);
+
+ s = slideshow_create_name(FEH_FILE(current_file->data));
+ winwidget_rename(winwid, s);
+ free(s);
+
break;
} else
last = current_file;
diff --git a/src/structs.h b/src/structs.h
index a2d3527..3942bc0 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -1,6 +1,7 @@
/* structs.h
Copyright (C) 1999-2003 Tom Gilbert.
+Copyright (C) 2010-2011 Daniel Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -33,5 +34,7 @@ typedef struct __feh_file_info feh_file_info;
typedef struct __winwidget _winwidget;
typedef _winwidget *winwidget;
typedef struct __fehoptions fehoptions;
+typedef struct __fehkey fehkey;
+typedef struct __fehkb fehkb;
#endif
diff --git a/src/support.c b/src/support.c
index afb941b..e257271 100644
--- a/src/support.c
+++ b/src/support.c
@@ -1,6 +1,7 @@
/* support.c
Copyright (C) 1999-2003 Tom Gilbert.
+Copyright (C) 2010-2011 Daniel Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -130,7 +131,7 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled,
enl_ipc_sync();
} else {
Atom prop_root, prop_esetroot, type;
- int format;
+ int format, i;
unsigned long length, after;
unsigned char *data_root, *data_esetroot;
Pixmap pmap_d1, pmap_d2;
@@ -138,6 +139,10 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled,
char *fehbg = NULL;
char *home;
char filbuf[PATH_MAX];
+ char fehbg_xinerama[] = "--no-xinerama";
+
+ if (opt.xinerama)
+ fehbg_xinerama[0] = '\0';
/* local display to set closedownmode on */
Display *disp2;
@@ -162,21 +167,20 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled,
filbuf[out++] = 0;
if (scaled) {
- w = scr->width;
- h = scr->height;
-
-/* disable xinerama check for setting background */
-#if 0
-/* #ifdef HAVE_LIBXINERAMA */
- if (opt.xinerama && xinerama_screens) {
- w = xinerama_screens[xinerama_screen].width;
- h = xinerama_screens[xinerama_screen].height;
- }
-#endif /* HAVE_LIBXINERAMA */
-
- pmap_d1 = XCreatePixmap(disp, root, w, h, depth);
- gib_imlib_render_image_on_drawable_at_size(pmap_d1, im, 0, 0, w, h, 1, 0, 1);
- fehbg = estrjoin(" ", "feh --bg-scale", filbuf, NULL);
+ pmap_d1 = XCreatePixmap(disp, root, scr->width, scr->height, depth);
+
+#ifdef HAVE_LIBXINERAMA
+ if (opt.xinerama && xinerama_screens)
+ for (i = 0; i < num_xinerama_screens; i++)
+ gib_imlib_render_image_on_drawable_at_size(pmap_d1, im,
+ xinerama_screens[i].x_org, xinerama_screens[i].y_org,
+ xinerama_screens[i].width, xinerama_screens[i].height,
+ 1, 0, !opt.force_aliasing);
+ else
+#endif /* HAVE_LIBXINERAMA */
+ gib_imlib_render_image_on_drawable_at_size(pmap_d1, im, 0, 0,
+ scr->width, scr->height, 1, 0, !opt.force_aliasing);
+ fehbg = estrjoin(" ", "feh", fehbg_xinerama, "--bg-scale", filbuf, NULL);
} else if (centered) {
XGCValues gcval;
GC gc;
@@ -185,25 +189,33 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled,
D(("centering\n"));
w = scr->width;
h = scr->height;
-
-/* disable xinerama check for setting background */
-#if 0
-/* #ifdef HAVE_LIBXINERAMA */
- if (opt.xinerama && xinerama_screens) {
- w = xinerama_screens[xinerama_screen].width;
- h = xinerama_screens[xinerama_screen].height;
- }
-#endif /* HAVE_LIBXINERAMA */
+ x = (w - gib_imlib_image_get_width(im)) >> 1;
+ y = (h - gib_imlib_image_get_height(im)) >> 1;
pmap_d1 = XCreatePixmap(disp, root, w, h, depth);
gcval.foreground = BlackPixel(disp, DefaultScreen(disp));
gc = XCreateGC(disp, root, GCForeground, &gcval);
XFillRectangle(disp, pmap_d1, gc, 0, 0, w, h);
- x = (w - gib_imlib_image_get_width(im)) >> 1;
- y = (h - gib_imlib_image_get_height(im)) >> 1;
- gib_imlib_render_image_on_drawable(pmap_d1, im, x, y, 1, 0, 0);
+
+#ifdef HAVE_LIBXINERAMA
+ if (opt.xinerama && xinerama_screens)
+ for (i = 0; i < num_xinerama_screens; i++) {
+ w = xinerama_screens[i].width;
+ h = xinerama_screens[i].height;
+ x = (w - gib_imlib_image_get_width(im)) >> 1;
+ y = (h - gib_imlib_image_get_height(im)) >> 1;
+ gib_imlib_render_image_part_on_drawable_at_size(
+ pmap_d1, im,
+ ((x < 0) ? -x : 0) , ((y < 0) ? -y : 0), w, h,
+ xinerama_screens[i].x_org + ((x > 0) ? x : 0),
+ xinerama_screens[i].y_org + ((y > 0) ? y : 0),
+ w, h, 1, 0, 0);
+ }
+ else
+#endif /* HAVE_LIBXINERAMA */
+ gib_imlib_render_image_on_drawable(pmap_d1, im, x, y, 1, 0, 0);
XFreeGC(disp, gc);
- fehbg = estrjoin(" ", "feh --bg-center", filbuf, NULL);
+ fehbg = estrjoin(" ", "feh", fehbg_xinerama, "--bg-center", filbuf, NULL);
} else if (filled == 1) {
int scr_w = scr->width;
int scr_h = scr->height;
@@ -211,20 +223,44 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled,
int img_h = gib_imlib_image_get_height(im);
int render_x = 0;
int render_y = 0;
+ int cut_x = (((img_w * scr_h) > (img_h * scr_w)) ? 1 : 0);
+ w = (cut_x ? ((scr_h * img_w) / img_h) : scr_w);
+ h = (cut_x ? scr_h : ((scr_w * img_h) / img_w));
+
+ if (cut_x)
+ render_x = (scr_w - w) >> 1;
+ else
+ render_y = (scr_h - h) >> 1;
- if ((img_w * scr_h) > (scr_w * img_h)) {
- h = scr_h;
- w = (scr_h * img_w) / img_h;
- render_x = (scr_w - w) / 2;
- } else {
- h = (scr_w * img_h) / img_w;
- w = scr_w;
- render_y = (scr_h - h) / 2;
- }
pmap_d1 = XCreatePixmap(disp, root, w, h, depth);
- gib_imlib_render_image_on_drawable_at_size(pmap_d1, im,
- render_x, render_y, w, h, 1, 0, 1);
- fehbg = estrjoin(" ", "feh --bg-fill", filbuf, NULL);
+
+#ifdef HAVE_LIBXINERAMA
+ if (opt.xinerama && xinerama_screens)
+ for (i = 0; i < num_xinerama_screens; i++) {
+ scr_w = xinerama_screens[i].width;
+ scr_h = xinerama_screens[i].height;
+ cut_x = (((img_w * scr_h) > (img_h * scr_w)) ? 1 : 0);
+ w = (cut_x ? ((img_h * scr_w) / scr_h) : img_w);
+ h = (cut_x ? img_h : ((img_w * scr_h) / scr_w));
+ render_x = (cut_x ? ((img_w - w) >> 1) : 0);
+ render_y = (cut_x ? 0 : ((img_h - h) >> 1));
+
+ D(("cut_x %d w %5d h %5d x %5d y %5d\n",
+ cut_x, w, h, render_x, render_y));
+
+ gib_imlib_render_image_part_on_drawable_at_size(
+ pmap_d1, im,
+ render_x, render_y,
+ w, h,
+ xinerama_screens[i].x_org,
+ xinerama_screens[i].y_org,
+ scr_w, scr_h, 1, 0, !opt.force_aliasing);
+ }
+ else
+#endif /* HAVE_LIBXINERAMA */
+ gib_imlib_render_image_on_drawable_at_size(pmap_d1, im,
+ render_x, render_y, w, h, 1, 0, !opt.force_aliasing);
+ fehbg = estrjoin(" ", "feh", fehbg_xinerama, "--bg-fill", filbuf, NULL);
} else if (filled == 2) {
int scr_w = scr->width;
int scr_h = scr->height;
@@ -232,38 +268,48 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled,
int img_h = gib_imlib_image_get_height(im);
int render_x = 0;
int render_y = 0;
+ int border_x = (((img_w * scr_h) > (img_h * scr_w)) ? 0 : 1);
+ w = (border_x ? ((scr_h * img_w) / img_h) : scr_w);
+ h = (border_x ? scr_h : ((scr_w * img_h) / img_w));
XGCValues gcval;
- if (img_w > img_h) {
- w = scr_w;
- h = (((scr_w * 100) / img_w) * img_h) / 100;
- render_y = (scr_h - h) / 2;
- if (h > scr_h) {
- w = (((scr_h * 100) / h) * w) / 100;
- h = scr_h;
- render_x = (scr_w - w) / 2;
- render_y = 0;
- }
- } else {
- h = scr_h;
- w = (((scr_h * 100) / img_h) * img_w) / 100;
- render_x = (scr_w - w) / 2;
- if (w > scr_w) {
- h = (((scr_w * 100) / w) * h) / 100;
- w = scr_w;
- render_x = 0;
- render_y = (scr_h - h) / 2;
- }
- }
+ if (border_x)
+ render_x = (scr_w - w) >> 1;
+ else
+ render_y = (scr_h - h) >> 1;
pmap_d1 = XCreatePixmap(disp, root, scr_w, scr_h, depth);
gcval.foreground = BlackPixel(disp, DefaultScreen(disp));
gc = XCreateGC(disp, root, GCForeground, &gcval);
XFillRectangle(disp, pmap_d1, gc, 0, 0, scr_w, scr_h);
+
+#ifdef HAVE_LIBXINERAMA
+ if (opt.xinerama && xinerama_screens)
+ for (i = 0; i < num_xinerama_screens; i++) {
+ scr_w = xinerama_screens[i].width;
+ scr_h = xinerama_screens[i].height;
+ border_x = (((img_w * scr_h) > (img_h * scr_w)) ? 0 : 1);
+ w = (border_x ? ((scr_h * img_w) / img_h) : scr_w);
+ h = (border_x ? scr_h : ((scr_w * img_h) / img_w));
+ render_x = (border_x ? ((scr_w - w) >> 1) : 0);
+ render_y = (border_x ? 0 : ((scr_h - h) >> 1));
+
+ D(("border_x %d w %5d h %5d x %5d y %5d\n",
+ border_x, w, h, render_x, render_y));
+
+ gib_imlib_render_image_on_drawable_at_size(
+ pmap_d1, im,
+ xinerama_screens[i].x_org + render_x,
+ xinerama_screens[i].y_org + render_y,
+ w, h,
+ 1, 0, !opt.force_aliasing);
+ }
+ else
+#endif /* HAVE_LIBXINERAMA */
gib_imlib_render_image_on_drawable_at_size(pmap_d1, im,
- render_x, render_y, w, h, 1, 0, 1);
+ render_x, render_y, w, h, 1, 0, !opt.force_aliasing);
XFreeGC(disp, gc);
- fehbg = estrjoin(" ", "feh --bg-max", filbuf, NULL);
+ fehbg = estrjoin(" ", "feh", fehbg_xinerama, "--bg-max", filbuf, NULL);
} else {
w = gib_imlib_image_get_width(im);
h = gib_imlib_image_get_height(im);
diff --git a/src/support.h b/src/support.h
index bb17082..3cd0fe1 100644
--- a/src/support.h
+++ b/src/support.h
@@ -1,6 +1,7 @@
/* support.h
Copyright (C) 1999-2003 Tom Gilbert.
+Copyright (C) 2010-2011 Daniel 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/thumbnail.c b/src/thumbnail.c
index ed4e0fb..ca5c387 100644
--- a/src/thumbnail.c
+++ b/src/thumbnail.c
@@ -1,6 +1,7 @@
/* thumbnail.c
Copyright (C) 1999-2003 Tom Gilbert.
+Copyright (C) 2010-2011 Daniel 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 +58,7 @@ void init_thumbnail_mode(void)
Imlib_Image im_temp;
int ww = 0, hh = 0, www, hhh, xxx, yyy;
+ int orig_w, orig_h;
int x = 0, y = 0;
winwidget winwid = NULL;
Imlib_Image im_thumb = NULL;
@@ -204,7 +206,8 @@ void init_thumbnail_mode(void)
}
D(("About to load image %s\n", file->filename));
/* if (feh_load_image(&im_temp, file) != 0) */
- if (feh_thumbnail_get_thumbnail(&im_temp, file) != 0) {
+ if (feh_thumbnail_get_thumbnail(&im_temp, file, &orig_w, &orig_h)
+ != 0) {
if (opt.verbose)
feh_display_status('.');
D(("Successfully loaded %s\n", file->filename));
@@ -212,6 +215,12 @@ void init_thumbnail_mode(void)
hhh = opt.thumb_h;
ww = gib_imlib_image_get_width(im_temp);
hh = gib_imlib_image_get_height(im_temp);
+
+ if (!orig_w) {
+ orig_w = ww;
+ orig_h = hh;
+ }
+
thumbnailcount++;
if (gib_imlib_image_has_alpha(im_temp))
imlib_context_set_blend(1);
@@ -333,7 +342,7 @@ void init_thumbnail_mode(void)
td.font_main, NULL,
x + x_offset_dim,
y + opt.thumb_h + (lines++ * (th + 2)) + 2,
- create_index_dimension_string(ww, hh),
+ create_index_dimension_string(orig_w, orig_h),
IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255);
if (opt.index_show_size)
gib_imlib_text_draw(td.im_main,
@@ -355,7 +364,7 @@ void init_thumbnail_mode(void)
if (opt.display) {
/* thumb_counter is unsigned, so no need to catch overflows */
if (++thumb_counter == opt.thumb_redraw) {
- winwidget_render_image(winwid, 0, 0);
+ winwidget_render_image(winwid, 0, 1);
thumb_counter = 0;
}
if (!feh_main_iteration(0))
@@ -364,7 +373,7 @@ void init_thumbnail_mode(void)
}
if (thumb_counter != 0)
- winwidget_render_image(winwid, 0, 0);
+ winwidget_render_image(winwid, 0, 1);
if (opt.verbose)
fprintf(stdout, "\n");
@@ -717,21 +726,27 @@ void feh_thumbnail_calculate_geometry(void)
}
}
-int feh_thumbnail_get_thumbnail(Imlib_Image * image, feh_file * file)
+int feh_thumbnail_get_thumbnail(Imlib_Image * image, feh_file * file,
+ int * orig_w, int * orig_h)
{
int status = 0;
char *thumb_file = NULL, *uri = NULL;
+ *orig_w = 0;
+ *orig_h = 0;
+
if (!file || !file->filename)
return (0);
if (td.cache_thumbnails) {
uri = feh_thumbnail_get_name_uri(file->filename);
thumb_file = feh_thumbnail_get_name(uri);
- status = feh_thumbnail_get_generated(image, file, thumb_file);
+ status = feh_thumbnail_get_generated(image, file, thumb_file,
+ orig_w, orig_h);
if (!status)
- status = feh_thumbnail_generate(image, file, thumb_file, uri);
+ status = feh_thumbnail_generate(image, file, thumb_file, uri,
+ orig_w, orig_h);
D(("uri is %s, thumb_file is %s\n", uri, thumb_file));
free(uri);
@@ -808,15 +823,16 @@ char *feh_thumbnail_get_name_md5(char *uri)
}
int feh_thumbnail_generate(Imlib_Image * image, feh_file * file,
- char *thumb_file, char *uri)
+ char *thumb_file, char *uri, int * orig_w, int * orig_h)
{
int w, h, thumb_w, thumb_h;
Imlib_Image im_temp;
struct stat sb;
+ char c_width[8], c_height[8];
if (feh_load_image(&im_temp, file) != 0) {
- w = gib_imlib_image_get_width(im_temp);
- h = gib_imlib_image_get_height(im_temp);
+ *orig_w = w = gib_imlib_image_get_width(im_temp);
+ *orig_h = h = gib_imlib_image_get_height(im_temp);
thumb_w = td.cache_dim;
thumb_h = td.cache_dim;
@@ -834,8 +850,12 @@ int feh_thumbnail_generate(Imlib_Image * image, feh_file * file,
if (!stat(file->filename, &sb)) {
char c_mtime[128];
sprintf(c_mtime, "%d", (int)sb.st_mtime);
+ snprintf(c_width, 8, "%d", w);
+ snprintf(c_height, 8, "%d", h);
feh_png_write_png(*image, thumb_file, "Thumb::URI", uri,
- "Thumb::MTime", c_mtime);
+ "Thumb::MTime", c_mtime,
+ "Thumb::Image::Width", c_width,
+ "Thumb::Image::Height", c_height);
}
gib_imlib_free_image_and_decache(im_temp);
@@ -846,19 +866,27 @@ int feh_thumbnail_generate(Imlib_Image * image, feh_file * file,
return (0);
}
-int feh_thumbnail_get_generated(Imlib_Image * image, feh_file * file, char *thumb_file)
+int feh_thumbnail_get_generated(Imlib_Image * image, feh_file * file,
+ char *thumb_file, int * orig_w, int * orig_h)
{
struct stat sb;
char *c_mtime;
+ char *c_width, *c_height;
time_t mtime = 0;
gib_hash *hash;
if (!stat(file->filename, &sb)) {
hash = feh_png_read_comments(thumb_file);
if (hash != NULL) {
- c_mtime = (char *) gib_hash_get(hash, "Thumb::MTime");
+ c_mtime = (char *) gib_hash_get(hash, "Thumb::MTime");
+ c_width = (char *) gib_hash_get(hash, "Thumb::Image::Width");
+ c_height = (char *) gib_hash_get(hash, "Thumb::Image::Height");
if (c_mtime != NULL)
mtime = (time_t) strtol(c_mtime, NULL, 10);
+ if (c_width != NULL)
+ *orig_w = atoi(c_width);
+ if (c_height != NULL)
+ *orig_h = atoi(c_height);
gib_hash_free_and_data(hash);
}
diff --git a/src/thumbnail.h b/src/thumbnail.h
index a384d11..6d2dc77 100644
--- a/src/thumbnail.h
+++ b/src/thumbnail.h
@@ -1,6 +1,7 @@
/* thumbnail.h
Copyright (C) 1999-2003 Tom Gilbert.
+Copyright (C) 2010-2011 Daniel Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -73,9 +74,9 @@ void feh_thumbnail_mark_removed(feh_file * file, int deleted);
void feh_thumbnail_calculate_geometry(void);
-int feh_thumbnail_get_thumbnail(Imlib_Image * image, feh_file * file);
-int feh_thumbnail_generate(Imlib_Image * image, feh_file * file, char *thumb_file, char *uri);
-int feh_thumbnail_get_generated(Imlib_Image * image, feh_file * file, char *thumb_file);
+int feh_thumbnail_get_thumbnail(Imlib_Image * image, feh_file * file, int * orig_w, int * orig_h);
+int feh_thumbnail_generate(Imlib_Image * image, feh_file * file, char *thumb_file, char *uri, int * orig_w, int * orig_h);
+int feh_thumbnail_get_generated(Imlib_Image * image, feh_file * file, char * thumb_file, int * orig_w, int * orig_h);
char *feh_thumbnail_get_name(char *uri);
char *feh_thumbnail_get_name_uri(char *name);
char *feh_thumbnail_get_name_md5(char *uri);
diff --git a/src/timers.c b/src/timers.c
index cba0716..4cb5251 100644
--- a/src/timers.c
+++ b/src/timers.c
@@ -1,6 +1,7 @@
/* timers.c
Copyright (C) 1999-2003 Tom Gilbert.
+Copyright (C) 2010-2011 Daniel 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/winwidget.c b/src/winwidget.c
index 26a43e2..a39e8ef 100644
--- a/src/winwidget.c
+++ b/src/winwidget.c
@@ -1,6 +1,7 @@
/* winwidget.c
Copyright (C) 1999-2003 Tom Gilbert.
+Copyright (C) 2010-2011 Daniel 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 +58,7 @@ static winwidget winwidget_allocate(void)
ret->type = WIN_TYPE_UNSET;
ret->visible = 0;
ret->caption_entry = 0;
+ ret->force_aliasing = opt.force_aliasing;
/* Zoom stuff */
ret->mode = MODE_NORMAL;
@@ -98,7 +100,7 @@ winwidget winwidget_create_from_image(Imlib_Image im, char *name, char type)
if (opt.full_screen && (type != WIN_TYPE_THUMBNAIL))
ret->full_screen = True;
winwidget_create_window(ret, ret->w, ret->h);
- winwidget_render_image(ret, 1, 1);
+ winwidget_render_image(ret, 1, 0);
return(ret);
}
@@ -131,7 +133,7 @@ winwidget winwidget_create_from_file(gib_list * list, char *name, char type)
if (opt.full_screen)
ret->full_screen = True;
winwidget_create_window(ret, ret->w, ret->h);
- winwidget_render_image(ret, 1, 1);
+ winwidget_render_image(ret, 1, 0);
}
return(ret);
@@ -361,10 +363,11 @@ void winwidget_setup_pixmaps(winwidget winwid)
return;
}
-void winwidget_render_image(winwidget winwid, int resize, int alias)
+void winwidget_render_image(winwidget winwid, int resize, int force_alias)
{
int sx, sy, sw, sh, dx, dy, dw, dh;
int calc_w, calc_h;
+ int antialias = 0;
if (!winwid->full_screen && resize) {
winwidget_resize(winwid, winwid->im_w, winwid->im_h);
@@ -377,13 +380,14 @@ void winwidget_render_image(winwidget winwid, int resize, int alias)
if (winwid->im_y > winwid->h)
winwid->im_y = winwid->h;
- D(("winwidget_render_image resize %d alias %d im %dx%d\n",
- resize, alias, winwid->im_w, winwid->im_h));
+ D(("winwidget_render_image resize %d force_alias %d im %dx%d\n",
+ resize, force_alias, winwid->im_w, winwid->im_h));
winwidget_setup_pixmaps(winwid);
if (!winwid->full_screen && opt.scale_down && ((winwid->w < winwid->im_w)
- || (winwid->h < winwid->im_h))) {
+ || (winwid->h < winwid->im_h)) &&
+ (winwid->old_zoom == 1.0)) {
D(("scaling down image %dx%d\n", winwid->w, winwid->h));
feh_calc_needed_zoom(&(winwid->zoom), winwid->im_w, winwid->im_h, winwid->w, winwid->h);
@@ -424,7 +428,7 @@ void winwidget_render_image(winwidget winwid, int resize, int alias)
smaller = ((winwid->im_w < max_w)
&& (winwid->im_h < max_h));
- if (!smaller || opt.auto_zoom) {
+ if (!smaller || opt.zoom_mode) {
double ratio = 0.0;
/* Image is larger than the screen (so wants shrinking), or it's
@@ -522,17 +526,22 @@ void winwidget_render_image(winwidget winwid, int resize, int alias)
D(("sx: %d sy: %d sw: %d sh: %d dx: %d dy: %d dw: %d dh: %d zoom: %f\n",
sx, sy, sw, sh, dx, dy, dw, dh, winwid->zoom));
+ if ((winwid->zoom != 1.0) && !force_alias && !winwid->force_aliasing)
+ antialias = 1;
+
D(("winwidget_render(): winwid->im_angle = %f\n", winwid->im_angle));
if (winwid->has_rotated)
gib_imlib_render_image_part_on_drawable_at_size_with_rotation
- (winwid->bg_pmap, winwid->im, sx, sy, sw, sh, dx, dy, dw, dh, winwid->im_angle, 1, 1, alias);
+ (winwid->bg_pmap, winwid->im, sx, sy, sw, sh, dx, dy, dw, dh,
+ winwid->im_angle, 1, 1, antialias);
else
gib_imlib_render_image_part_on_drawable_at_size(winwid->bg_pmap,
winwid->im,
sx, sy, sw,
sh, dx, dy,
dw, dh, 1,
- gib_imlib_image_has_alpha(winwid->im), alias);
+ gib_imlib_image_has_alpha(winwid->im),
+ antialias);
if (opt.mode == MODE_NORMAL) {
if (opt.caption_path)
@@ -543,7 +552,7 @@ void winwidget_render_image(winwidget winwid, int resize, int alias)
feh_draw_actions(winwid);
if (opt.info_cmd)
feh_draw_info(winwid);
- } else if ((opt.mode == MODE_ZOOM) && !alias)
+ } else if ((opt.mode == MODE_ZOOM) && !antialias)
feh_draw_zoom(winwid);
XSetWindowBackgroundPixmap(disp, winwid->win, winwid->bg_pmap);
@@ -578,6 +587,9 @@ double feh_calc_needed_zoom(double *zoom, int orig_w, int orig_h, int dest_w, in
ratio = ((double) orig_w / orig_h) / ((double) dest_w / dest_h);
+ if (opt.zoom_mode == ZOOM_MODE_FILL)
+ ratio = 1.0 / ratio;
+
if (ratio > 1.0)
*zoom = ((double) dest_w / orig_w);
else
@@ -686,13 +698,13 @@ void winwidget_destroy_all(void)
return;
}
-void winwidget_rerender_all(int resize, int alias)
+void winwidget_rerender_all(int resize)
{
int i;
/* Have to DESCEND the list here, 'cos of the way _unregister works */
for (i = window_num - 1; i >= 0; i--)
- winwidget_render_image(windows[i], resize, alias);
+ winwidget_render_image(windows[i], resize, 0);
return;
}
@@ -908,6 +920,7 @@ void feh_debug_print_winwid(winwidget w)
void winwidget_reset_image(winwidget winwid)
{
winwid->zoom = 1.0;
+ winwid->old_zoom = 1.0;
winwid->im_x = 0;
winwid->im_y = 0;
winwid->im_angle = 0.0;
@@ -982,7 +995,7 @@ void winwidget_size_to_image(winwidget winwid)
{
winwidget_resize(winwid, winwid->im_w * winwid->zoom, winwid->im_h * winwid->zoom);
winwid->im_x = winwid->im_y = 0;
- winwidget_render_image(winwid, 0, 1);
+ winwidget_render_image(winwid, 0, 0);
return;
}
diff --git a/src/winwidget.h b/src/winwidget.h
index 012d78f..922ecf5 100644
--- a/src/winwidget.h
+++ b/src/winwidget.h
@@ -1,6 +1,7 @@
/* winwidget.h
Copyright (C) 1999-2003 Tom Gilbert.
+Copyright (C) 2010-2011 Daniel Friesel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -81,6 +82,7 @@ struct __winwidget {
int h;
int im_w;
int im_h;
+ int force_aliasing;
double im_angle;
enum win_type type;
unsigned char had_resize, full_screen;
@@ -122,14 +124,14 @@ void winwidget_hide(winwidget winwid);
void winwidget_destroy_all(void);
void winwidget_free_image(winwidget w);
void winwidget_center_image(winwidget w);
-void winwidget_render_image(winwidget winwid, int resize, int alias);
+void winwidget_render_image(winwidget winwid, int resize, int force_alias);
void winwidget_rotate_image(winwidget winid, double angle);
void winwidget_move(winwidget winwid, int x, int y);
void winwidget_resize(winwidget winwid, int w, int h);
void winwidget_setup_pixmaps(winwidget winwid);
void winwidget_update_title(winwidget ret);
void winwidget_update_caption(winwidget winwid);
-void winwidget_rerender_all(int resize, int alias);
+void winwidget_rerender_all(int resize);
void winwidget_destroy_xwin(winwidget winwid);
void winwidget_set_pointer(winwidget winwid, int visible);