? .ChangeLog.swp
? autom4te.cache
? src/.cache.c.swp
? src/.cache.h.swp
? src/.winwidget.c.swp
? src/cache.c
? src/cache.h
? src/feh_019048_000001_20021013-giblet_coding.jpg
? src/feh_019048_000002_dscf0128.jpg
? src/gmon.out
? src/im
? src/long_prof.txt
? src/long_prof_2.txt
? src/long_prof_3.txt
Index: ChangeLog
===================================================================
RCS file: /cvsroot/enlightenment/misc/feh/ChangeLog,v
retrieving revision 1.267
diff -u -r1.267 ChangeLog
--- ChangeLog	27 May 2003 13:58:35 -0000	1.267
+++ ChangeLog	4 Jan 2004 06:22:53 -0000
@@ -1,3 +1,13 @@
+Sun Jan 04 01:19:53 EST 2004  Paul Duncan <pabs@pablotron.org>
+
+  * added preliminary image and pixmap caching
+
+Sat Jan 03 19:04:11 EST 2004  Paul Duncan <pabs@pablotron.org>,
+
+  * removed extraneous XFlush
+  * switched to global file list length (avoid recalculating it
+    constantly)
+
 Tue May 27 14:55:02 BST 2003  Tom Gilbert <tom@linuxbrit.co.uk>
 
   * Released 1.2.6
Index: src/Makefile.am
===================================================================
RCS file: /cvsroot/enlightenment/misc/feh/src/Makefile.am,v
retrieving revision 1.42
diff -u -r1.42 Makefile.am
--- src/Makefile.am	23 Feb 2003 16:26:23 -0000	1.42
+++ src/Makefile.am	4 Jan 2004 06:22:53 -0000
@@ -15,7 +15,7 @@
 filelist.c filelist.h multiwindow.c imlib.c index.c slideshow.c \
 utils.c utils.h keyevents.c timers.c timers.h list.c collage.c debug.h \
 events.c events.h support.c support.h \
-thumbnail.c thumbnail.h ipc.c ipc.h
+thumbnail.c thumbnail.h ipc.c ipc.h cache.c cache.h
 feh_LDADD         = -lX11 @IMLIB_LIBS@ @GIBLIB_LIBS@
 
 images_DATA = about.png menubg_default.png menubg_sky.png \
Index: src/debug.h
===================================================================
RCS file: /cvsroot/enlightenment/misc/feh/src/debug.h,v
retrieving revision 1.17
diff -u -r1.17 debug.h
--- src/debug.h	23 Feb 2003 16:35:45 -0000	1.17
+++ src/debug.h	4 Jan 2004 06:22:53 -0000
@@ -26,7 +26,7 @@
 #ifndef DEBUG_H
 #define DEBUG_H
 
-/* #define DEBUG */
+#define DEBUG
 
 #ifdef WITH_DMALLOC
 #include <dmalloc.h>
Index: src/events.c
===================================================================
RCS file: /cvsroot/enlightenment/misc/feh/src/events.c,v
retrieving revision 1.68
diff -u -r1.68 events.c
--- src/events.c	23 Feb 2003 16:35:45 -0000	1.68
+++ src/events.c	4 Jan 2004 06:22:53 -0000
@@ -361,6 +361,7 @@
                opt.geom_w = w->w;
                opt.geom_h = w->h;
             }
+            feh_cache_destroy_pixmaps();
             winwidget_render_image(w, 0, 1);
          }
       }
Index: src/feh.h
===================================================================
RCS file: /cvsroot/enlightenment/misc/feh/src/feh.h,v
retrieving revision 1.127
diff -u -r1.127 feh.h
--- src/feh.h	23 Feb 2003 16:35:45 -0000	1.127
+++ src/feh.h	4 Jan 2004 06:22:53 -0000
@@ -66,8 +66,9 @@
 
 #include "utils.h"
 #include "getopt.h"
+#include "cache.h"
 
-
+#include "options.h"
 #include "debug.h"
 
 #define SLIDESHOW_RELOAD_MAX 4096
Index: src/imlib.c
===================================================================
RCS file: /cvsroot/enlightenment/misc/feh/src/imlib.c,v
retrieving revision 1.150
diff -u -r1.150 imlib.c
--- src/imlib.c	23 Feb 2003 16:35:45 -0000	1.150
+++ src/imlib.c	4 Jan 2004 06:22:54 -0000
@@ -125,6 +125,10 @@
    if (!file || !file->filename)
       D_RETURN(4, 0);
 
+   if ((*im = feh_cache_get_image(file->filename)) != NULL) {
+     D_RETURN(4, 1);
+   }
+   
    /* Handle URLs */
    if ((!strncmp(file->filename, "http://", 7)) ||
        (!strncmp(file->filename, "https://", 8)) ||
@@ -246,6 +250,8 @@
       D(3, ("Load *failed*\n"));
       D_RETURN(4, 0);
    }
+
+   feh_cache_set_image(file->filename, *im);
 
    D(3, ("Loaded ok\n"));
    D_RETURN(4, 1);
Index: src/main.c
===================================================================
RCS file: /cvsroot/enlightenment/misc/feh/src/main.c,v
retrieving revision 1.80
diff -u -r1.80 main.c
--- src/main.c	23 Feb 2003 16:35:46 -0000	1.80
+++ src/main.c	4 Jan 2004 06:22:55 -0000
@@ -47,6 +47,8 @@
 
    feh_event_init();
 
+   feh_cache_init();
+
    if (opt.index)
       init_index_mode();
    else if (opt.collage)
Index: src/winwidget.c
===================================================================
RCS file: /cvsroot/enlightenment/misc/feh/src/winwidget.c,v
retrieving revision 1.117
diff -u -r1.117 winwidget.c
--- src/winwidget.c	4 Jan 2004 00:14:13 -0000	1.117
+++ src/winwidget.c	4 Jan 2004 06:22:57 -0000
@@ -301,6 +301,7 @@
       D(4, ("recreating background pixmap (%dx%d)\n", winwid->w, winwid->h));
       if (winwid->bg_pmap)
         XFreePixmap(disp, winwid->bg_pmap);
+      feh_cache_destroy_pixmaps();
 
       if (winwid->w == 0)
         winwid->w = 1;
@@ -321,185 +322,208 @@
 {
   int sx, sy, sw, sh, dx, dy, dw, dh;
   int calc_w, calc_h;
+  char *filename;
+  Pixmap pmap_cache;
+  GC gc;
 
   D_ENTER(4);
 
-  if (!winwid->full_screen && resize) {
-    winwidget_resize(winwid, winwid->im_w, winwid->im_h);
-    winwidget_reset_image(winwid);
-  }
+  filename = FEH_FILE(winwid->file->data)->filename;
+  D(2, ("filename = %s\n", filename));
 
-  /* bounds checks for panning */
-  if (winwid->im_x > winwid->w)
-    winwid->im_x = winwid->w;
-  if (winwid->im_y > winwid->h)
-    winwid->im_y = winwid->h;
-
-  winwidget_setup_pixmaps(winwid);
-
-  if (!winwid->full_screen
-      && ((gib_imlib_image_has_alpha(winwid->im)) || (opt.geom)
-          || (winwid->im_x || winwid->im_y) || (winwid->zoom != 1.0)
-          || (winwid->w > winwid->im_w || winwid->h > winwid->im_h)
-          || (winwid->has_rotated)))
-    feh_draw_checks(winwid);
-
-  if (!winwid->full_screen && opt.scale_down
-      && ((winwid->w < winwid->im_w) || (winwid->h < winwid->im_h))) {
-    D(2, ("scaling down image\n"));
-
-    feh_calc_needed_zoom(&(winwid->zoom), winwid->im_w, winwid->im_h,
-                         winwid->w, winwid->h);
-    winwidget_resize(winwid, winwid->im_w * winwid->zoom,
-                     winwid->im_h * winwid->zoom);
-  }
+  if ((pmap_cache = feh_cache_get_pixmap(filename)) == None) {
+    if (!winwid->full_screen && resize) {
+      winwidget_resize(winwid, winwid->im_w, winwid->im_h);
+      winwidget_reset_image(winwid);
+    }
 
-  if (resize && (winwid->full_screen || opt.geom)) {
-    int smaller;                /* Is the image smaller than screen? */
-    int max_w, max_h;
-
-    if (winwid->full_screen) {
-      max_w = scr->width;
-      max_h = scr->height;
+    /* bounds checks for panning */
+    if (winwid->im_x > winwid->w)
+      winwid->im_x = winwid->w;
+    if (winwid->im_y > winwid->h)
+      winwid->im_y = winwid->h;
+
+    winwidget_setup_pixmaps(winwid);
+
+    if (!winwid->full_screen
+        && ((gib_imlib_image_has_alpha(winwid->im)) || (opt.geom)
+            || (winwid->im_x || winwid->im_y) || (winwid->zoom != 1.0)
+            || (winwid->w > winwid->im_w || winwid->h > winwid->im_h)
+            || (winwid->has_rotated)))
+      feh_draw_checks(winwid);
+
+    if (!winwid->full_screen && opt.scale_down
+        && ((winwid->w < winwid->im_w) || (winwid->h < winwid->im_h))) {
+      D(2, ("scaling down image\n"));
+
+      feh_calc_needed_zoom(&(winwid->zoom), winwid->im_w, winwid->im_h,
+                           winwid->w, winwid->h);
+      winwidget_resize(winwid, winwid->im_w * winwid->zoom,
+                       winwid->im_h * winwid->zoom);
+    }
+
+    if (resize && (winwid->full_screen || opt.geom)) {
+      int smaller;                /* Is the image smaller than screen? */
+      int max_w, max_h;
+
+      if (winwid->full_screen) {
+        max_w = scr->width;
+        max_h = scr->height;
 #ifdef HAVE_LIBXINERAMA
-      if (opt.xinerama && xinerama_screens) {
-        max_w = xinerama_screens[xinerama_screen].width;
-        max_h = xinerama_screens[xinerama_screen].height;
-      }
+        if (opt.xinerama && xinerama_screens) {
+          max_w = xinerama_screens[xinerama_screen].width;
+          max_h = xinerama_screens[xinerama_screen].height;
+        }
 #endif /* HAVE_LIBXINERAMA */
-    } else if (opt.geom) {
-      max_w = opt.geom_w;
-      max_h = opt.geom_h;
-    }
+      } else if (opt.geom) {
+        max_w = opt.geom_w;
+        max_h = opt.geom_h;
+      }
 
-    D(4, ("Calculating for fullscreen/fixed geom render\n"));
-    smaller = ((winwid->im_w < max_w) && (winwid->im_h < max_h));
+      D(4, ("Calculating for fullscreen/fixed geom render\n"));
+      smaller = ((winwid->im_w < max_w) && (winwid->im_h < max_h));
 
-    if (!smaller || opt.auto_zoom) {
-      double ratio = 0.0;
+      if (!smaller || opt.auto_zoom) {
+        double ratio = 0.0;
 
-      /* Image is larger than the screen (so wants shrinking), or it's
-         smaller but wants expanding to fill it */
-      ratio =
-        feh_calc_needed_zoom(&(winwid->zoom), winwid->im_w, winwid->im_h,
-                             max_w, max_h);
-
-      /* contributed by Jens Laas <jens.laas@data.slu.se>
-       * What it does:
-       * zooms images by a fixed amount but never larger than the screen.
-       *
-       * Why:
-       * This is nice if you got a collection of images where some
-       * are small and can stand a small zoom. Large images are unaffected.
-       *
-       * When does it work, and how?
-       * You have to be in fullscreen mode _and_ have auto-zoom turned on.
-       *   "feh -FZ --zoom 130 imagefile" will do the trick.
-       *        -zoom percent - the new switch.
-       *                        100 = orignal size,
-       *                        130 is 30% larger.
-       */
-      if (opt.default_zoom) {
-        double old_zoom = winwid->zoom;
-
-        winwid->zoom = 0.01 * opt.default_zoom;
-        if ((winwid->im_h * winwid->zoom) > max_h)
-          winwid->zoom = old_zoom;
-        if ((winwid->im_w * winwid->zoom) > max_w)
-          winwid->zoom = old_zoom;
+        /* Image is larger than the screen (so wants shrinking), or it's
+           smaller but wants expanding to fill it */
+        ratio =
+          feh_calc_needed_zoom(&(winwid->zoom), winwid->im_w, winwid->im_h,
+                               max_w, max_h);
+
+        /* contributed by Jens Laas <jens.laas@data.slu.se>
+         * What it does:
+         * zooms images by a fixed amount but never larger than the screen.
+         *
+         * Why:
+         * This is nice if you got a collection of images where some
+         * are small and can stand a small zoom. Large images are unaffected.
+         *
+         * When does it work, and how?
+         * You have to be in fullscreen mode _and_ have auto-zoom turned on.
+         *   "feh -FZ --zoom 130 imagefile" will do the trick.
+         *        -zoom percent - the new switch.
+         *                        100 = orignal size,
+         *                        130 is 30% larger.
+         */
+        if (opt.default_zoom) {
+          double old_zoom = winwid->zoom;
+
+          winwid->zoom = 0.01 * opt.default_zoom;
+          if ((winwid->im_h * winwid->zoom) > max_h)
+            winwid->zoom = old_zoom;
+          if ((winwid->im_w * winwid->zoom) > max_w)
+            winwid->zoom = old_zoom;
 
-        winwid->im_x = ((int) (max_w - (winwid->im_w * winwid->zoom))) >> 1;
-        winwid->im_y = ((int) (max_h - (winwid->im_h * winwid->zoom))) >> 1;
-      } else {
-        if (ratio > 1.0) {
-          /* height is the factor */
-          winwid->im_x = 0;
+          winwid->im_x = ((int) (max_w - (winwid->im_w * winwid->zoom))) >> 1;
           winwid->im_y = ((int) (max_h - (winwid->im_h * winwid->zoom))) >> 1;
         } else {
-          /* width is the factor */
-          winwid->im_x = ((int) (max_w - (winwid->im_w * winwid->zoom))) >> 1;
-          winwid->im_y = 0;
+          if (ratio > 1.0) {
+            /* height is the factor */
+            winwid->im_x = 0;
+            winwid->im_y = ((int) (max_h - (winwid->im_h * winwid->zoom))) >> 1;
+          } else {
+            /* width is the factor */
+            winwid->im_x = ((int) (max_w - (winwid->im_w * winwid->zoom))) >> 1;
+            winwid->im_y = 0;
+          }
         }
-      }
-    } else {
-      /* my modification to jens hack, allow --zoom without auto-zoom mode */
-      if(opt.default_zoom) {
-        winwid->zoom = 0.01 * opt.default_zoom;
       } else {
-        winwid->zoom = 1.0;
+        /* my modification to jens hack, allow --zoom without auto-zoom mode */
+        if(opt.default_zoom) {
+          winwid->zoom = 0.01 * opt.default_zoom;
+        } else {
+          winwid->zoom = 1.0;
+        }
+        /* Just center the image in the window */
+        winwid->im_x = (int)(max_w - (winwid->im_w * winwid->zoom)) >> 1;
+        winwid->im_y = (int)(max_h - (winwid->im_h * winwid->zoom)) >> 1;
       }
-      /* Just center the image in the window */
-      winwid->im_x = (int)(max_w - (winwid->im_w * winwid->zoom)) >> 1;
-      winwid->im_y = (int)(max_h - (winwid->im_h * winwid->zoom)) >> 1;
     }
-  }
 
-  /* Now we ensure only to render the area we're looking at */
-  dx = winwid->im_x;
-  dy = winwid->im_y;
-  if (dx < 0)
-    dx = 0;
-  if (dy < 0)
-    dy = 0;
-
-  if (winwid->im_x < 0) {
-    if (winwid->zoom < 1.0)
-      sx = 0 - (winwid->im_x * winwid->zoom);
+    /* Now we ensure only to render the area we're looking at */
+    dx = winwid->im_x;
+    dy = winwid->im_y;
+    if (dx < 0)
+      dx = 0;
+    if (dy < 0)
+      dy = 0;
+
+    if (winwid->im_x < 0) {
+      if (winwid->zoom < 1.0)
+        sx = 0 - (winwid->im_x * winwid->zoom);
+      else
+        sx = 0 - (winwid->im_x / winwid->zoom);
+    } else
+      sx = 0;
+
+    if (winwid->im_y < 0) {
+      if (winwid->zoom < 1.0)
+        sy = 0 - (winwid->im_y * winwid->zoom);
+      else
+        sy = 0 - (winwid->im_y / winwid->zoom);
+    } else
+      sy = 0;
+    calc_w = winwid->im_w * winwid->zoom;
+    calc_h = winwid->im_h * winwid->zoom;
+    dw = (winwid->w - winwid->im_x);
+    dh = (winwid->h - winwid->im_y);
+    if (calc_w < dw)
+      dw = calc_w;
+    if (calc_h < dh)
+      dh = calc_h;
+    if (dw > winwid->w)
+      dw = winwid->w;
+    if (dh > winwid->h)
+      dh = winwid->h;
+
+    sw = dw / winwid->zoom;
+    sh = dh / winwid->zoom;
+
+    D(5,
+      ("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));
+
+    D(5, ("winwidget_render(): winwid->im_angle = %f\n", winwid->im_angle));
+    
+    /* create pixmap cache */
+    pmap_cache = XCreatePixmap(disp,
+                               winwid->win,
+                               winwid->w,
+                               winwid->h,
+                               depth);
+    feh_cache_set_pixmap(filename, pmap_cache);
+    
+    if (winwid->has_rotated)
+      gib_imlib_render_image_part_on_drawable_at_size_with_rotation(pmap_cache,
+                                                                    winwid->im,
+                                                                    sx, sy, sw,
+                                                                    sh, dx, dy,
+                                                                    dw, dh,
+                                                                    winwid->
+                                                                    im_angle, 1,
+                                                                    1, alias);
     else
-      sx = 0 - (winwid->im_x / winwid->zoom);
-  } else
-    sx = 0;
-
-  if (winwid->im_y < 0) {
-    if (winwid->zoom < 1.0)
-      sy = 0 - (winwid->im_y * winwid->zoom);
-    else
-      sy = 0 - (winwid->im_y / winwid->zoom);
-  } else
-    sy = 0;
-  calc_w = winwid->im_w * winwid->zoom;
-  calc_h = winwid->im_h * winwid->zoom;
-  dw = (winwid->w - winwid->im_x);
-  dh = (winwid->h - winwid->im_y);
-  if (calc_w < dw)
-    dw = calc_w;
-  if (calc_h < dh)
-    dh = calc_h;
-  if (dw > winwid->w)
-    dw = winwid->w;
-  if (dh > winwid->h)
-    dh = winwid->h;
-
-  sw = dw / winwid->zoom;
-  sh = dh / winwid->zoom;
-
-  D(5,
-    ("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));
-
-  D(5, ("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);
-  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_render_image_part_on_drawable_at_size(pmap_cache,
+                                                      winwid->im, sx, sy, sw,
+                                                      sh, dx, dy, dw, dh, 1,
+                                                      gib_imlib_image_has_alpha
+                                                      (winwid->im), alias);
+  } else {
+    fprintf(stderr, "using pixmap cache for %s\n", filename);
+    feh_cache_dump();
+  }
+
+  gc = XCreateGC(disp, winwid->win, 0, NULL);
+  XCopyArea(disp, pmap_cache, winwid->bg_pmap, gc, 0, 0, winwid->w, winwid->h, 0, 0);
+  XFreeGC(disp, gc);
+
   if (opt.caption_path) {
     /* cache bg pixmap. during caption entry, multiple redraws are done
      * because the caption overlay changes - the image doesn't though, so re-
      * rendering that is a waste of time */
     if (winwid->caption_entry) {
-      GC gc;
       if (winwid->bg_pmap_cache)
         XFreePixmap(disp, winwid->bg_pmap_cache);
       winwid->bg_pmap_cache = XCreatePixmap(disp,
@@ -697,9 +721,11 @@
 winwidget_loadimage(winwidget winwid,
                     feh_file * file)
 {
+  int res;
   D_ENTER(4);
   D(4, ("filename %s\n", file->filename));
-  D_RETURN(4, feh_load_image(&(winwid->im), file));
+  res = feh_load_image(&(winwid->im), file);
+  D_RETURN(4, res);
 }
 
 void

