diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/collage.c | 1 | ||||
-rw-r--r-- | src/debug.h | 1 | ||||
-rw-r--r-- | src/deps.mk | 41 | ||||
-rw-r--r-- | src/events.c | 21 | ||||
-rw-r--r-- | src/feh.h | 5 | ||||
-rw-r--r-- | src/feh_png.c | 6 | ||||
-rw-r--r-- | src/fehrc.raw | 74 | ||||
-rw-r--r-- | src/filelist.c | 1 | ||||
-rw-r--r-- | src/help.raw | 17 | ||||
-rw-r--r-- | src/imlib.c | 307 | ||||
-rw-r--r-- | src/index.c | 1 | ||||
-rw-r--r-- | src/keyevents.c | 635 | ||||
-rw-r--r-- | src/list.c | 1 | ||||
-rw-r--r-- | src/main.c | 5 | ||||
-rw-r--r-- | src/menu.c | 18 | ||||
-rw-r--r-- | src/menu.h | 1 | ||||
-rw-r--r-- | src/multiwindow.c | 4 | ||||
-rw-r--r-- | src/options.c | 189 | ||||
-rw-r--r-- | src/options.h | 69 | ||||
-rw-r--r-- | src/signals.c | 5 | ||||
-rw-r--r-- | src/slideshow.c | 42 | ||||
-rw-r--r-- | src/structs.h | 3 | ||||
-rw-r--r-- | src/support.c | 174 | ||||
-rw-r--r-- | src/support.h | 1 | ||||
-rw-r--r-- | src/thumbnail.c | 54 | ||||
-rw-r--r-- | src/thumbnail.h | 7 | ||||
-rw-r--r-- | src/timers.c | 1 | ||||
-rw-r--r-- | src/winwidget.c | 39 | ||||
-rw-r--r-- | src/winwidget.h | 6 |
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; } @@ -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; } @@ -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 @@ -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(); @@ -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, @@ -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); |