Added some better cache control options for Imlib2.
authorBrenden Matthews <brenden@rty.ca>
Wed, 3 Jun 2009 19:24:53 +0000 (13:24 -0600)
committerBrenden Matthews <brenden@rty.ca>
Wed, 3 Jun 2009 19:24:53 +0000 (13:24 -0600)
doc/config_settings.xml
doc/variables.xml
src/conky.c
src/imlib2.c
src/imlib2.h

index 7b442b4..101b6b0 100644 (file)
        <varlistentry>
                <term><command><option>imlib_cache_size</option></command></term>
                <listitem>
-                       IMLIB2 image cache size, in bytes.  Defaults to 4MiB.  Increase this value if you use $image lots.  Set to 0 to disable the image cache.
+                       Imlib2 image cache size, in bytes.  Defaults to 4MiB.  Increase this value if you use $image lots.  Set to 0 to disable the image cache.
+                       <para></para></listitem>
+       </varlistentry>
+
+       <varlistentry>
+               <term><command><option>imlib_cache_flush_interval</option></command></term>
+               <listitem>
+                       Interval (in seconds) to flush Imlib2 cache.
                        <para></para></listitem>
        </varlistentry>
 
index 748c62f..75f48a2 100644 (file)
        <varlistentry>
                <term>
                        <command><option>image</option></command>
-                       <option>&lt;path to image&gt; (-p x,y) (-s WxH)</option>
+                       <option>&lt;path to image&gt; (-p x,y) (-s WxH) (-n) (-f interval)</option>
                </term>
                <listitem>
-                       Renders an image from the path specified using IMLIB2.  Takes 2 optional arguments, one being a position, the other an size.  Changing the x,y position will move the position of the image, and changing the WxH will scale the image.  Example: ${image /home/brenden/cheeseburger.jpg -p 20,20 -s 200x200} will render 'cheeseburger.jpg' at (20,20) scaled to 200x200 pixels.  Conky does not make any attempt to adjust the position (or any other formatting) of images, they are just rendered as per the arguments passed.  The only reason $image is part of the TEXT section, is to allow for runtime modifications, through $execp $lua_parse, $lua_read_parse, or some other method.
+                       Renders an image from the path specified using Imlib2.  Takes 4 optional arguments: a position, a size, a no-cache switch, and a cache flush interval.  Changing the x,y position will move the position of the image, and changing the WxH will scale the image.  If you specify the no-cache flag (-n), the image will not be cached.  Alternately, you can specify the -f int switch to specify a cache flust interval for a particular image.  Example: ${image /home/brenden/cheeseburger.jpg -p 20,20 -s 200x200} will render 'cheeseburger.jpg' at (20,20) scaled to 200x200 pixels.  Conky does not make any attempt to adjust the position (or any other formatting) of images, they are just rendered as per the arguments passed.  The only reason $image is part of the TEXT section, is to allow for runtime modifications, through $execp $lua_parse, $lua_read_parse, or some other method.
                        <para></para></listitem>
        </varlistentry>
 
index b4deb13..ea37bd3 100644 (file)
@@ -8033,6 +8033,11 @@ static void load_config_file(const char *f)
                                cimlib_set_cache_size(atoi(value));
                        }
                }
+               CONF("imlib_cache_flush_interval") {
+                       if (value) {
+                               cimlib_set_cache_size(atoi(value));
+                       }
+               }
 #endif /* IMLIB2 */
 #endif /* X11 */
                CONF("update_interval") {
index 8f2ef5f..6b5c108 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include <limits.h>
+#include <time.h>
 
 struct image_list_s {
        char name[DEFAULT_TEXT_BUFFER_SIZE];
        Imlib_Image image;
        int x, y, w, h;
        int wh_set;
+       char no_cache;
+       int flush_interval;
+       int flush_last;
        struct image_list_s *next;
 };
 
@@ -47,6 +51,10 @@ Imlib_Image buffer, image;
 
 static int cache_size_set = 0;
 
+/* flush the image cache ever X seconds */
+static int cimlib_cache_flush_interval = 0;
+static int cimlib_cache_flush_last = 0;
+
 #define DEFAULT_CACHE_SIZE 4096 * 1024 /* default cache size for loaded images */
 
 void cimlib_set_cache_size(long size)
@@ -55,6 +63,11 @@ void cimlib_set_cache_size(long size)
        cache_size_set = 1;
 }
 
+void cimlib_set_cache_flush_interval(long interval)
+{
+       cimlib_cache_flush_interval = interval;
+}
+
 void cimlib_cleanup(void)
 {
        struct image_list_s *cur = image_list_start, *last = NULL;
@@ -90,7 +103,7 @@ void cimlib_add_image(const char *args)
        memset(cur, 0, sizeof(struct image_list_s));
 
        if (!sscanf(args, "%1024s", cur->name)) {
-               ERR("Invalid args for $image.  Format is: '<path to image> (-p x,y) (-s WxH)' (got '%s')", args);
+               ERR("Invalid args for $image.  Format is: '<path to image> (-p x,y) (-s WxH) (-n) (-f interval)' (got '%s')", args);
        }
        to_real_path(cur->name, cur->name);
        // now we check for optional args
@@ -107,6 +120,19 @@ void cimlib_add_image(const char *args)
                }
        }
 
+       tmp = strstr(args, "-n");
+       if (tmp) {
+               cur->no_cache = 1;
+       }
+
+       tmp = strstr(args, "-f ");
+       if (tmp) {
+               tmp += 3;
+               if (sscanf(tmp, "%d", &cur->flush_interval)) {
+                       cur->no_cache = 0;
+               }
+       }
+
        if (image_list_end) {
                image_list_end->next = cur;
                image_list_end = cur;
@@ -120,7 +146,8 @@ static void cimlib_draw_image(struct image_list_s *cur, int *clip_x, int *clip_y
        image = imlib_load_image(cur->name);
        if (image) {
                int w, h;
-               DBGP("Drawing image '%s' at (%i,%i) scaled to %ix%i", cur->name, cur->x, cur->y, cur->w, cur->h);
+               time_t now = time(NULL);
+               DBGP("Drawing image '%s' at (%i,%i) scaled to %ix%i, caching interval set to %i (with -n opt %i)", cur->name, cur->x, cur->y, cur->w, cur->h, cur->flush_interval, cur->no_cache);
                imlib_context_set_image(image);
                /* turn alpha channel on */
                imlib_image_set_has_alpha(1);
@@ -134,7 +161,12 @@ static void cimlib_draw_image(struct image_list_s *cur, int *clip_x, int *clip_y
                imlib_blend_image_onto_image(image, 1, 0, 0, w, h,
                                cur->x, cur->y, cur->w, cur->h);
                imlib_context_set_image(image);
-               imlib_free_image();
+               if (cur->no_cache || (cur->flush_interval && now - cur->flush_interval > cur->flush_last)) {
+                       imlib_free_image_and_decache();
+                       cur->flush_last = now;
+               } else {
+                       imlib_free_image();
+               }
                if (cur->x < *clip_x) *clip_x = cur->x;
                if (cur->y < *clip_y) *clip_y = cur->y;
                if (cur->x + cur->w > *clip_x2) *clip_x2 = cur->x + cur->w;
@@ -157,8 +189,18 @@ void cimlib_render(int x, int y, int width, int height)
 {
        int clip_x = INT_MAX, clip_y = INT_MAX;
        int clip_x2 = 0, clip_y2 = 0;
+       time_t now;
 
        if (!image_list_start) return; /* are we actually drawing anything? */
+
+       /* cheque if it's time to flush our cache */
+       now = time(NULL);
+       if (cimlib_cache_flush_interval && now - cimlib_cache_flush_interval > cimlib_cache_flush_last) {
+               imlib_flush_loaders();
+               cimlib_cache_flush_last = now;
+               DBGP("Flushing Imlib2 cache (%li)\n", now);
+       }
+
        /* take all the little rectangles to redraw and merge them into
         * something sane for rendering */
        buffer = imlib_create_image(width, height);
index 69b9d1c..9a6e1f8 100644 (file)
@@ -26,6 +26,7 @@
 
 void cimlib_add_image(const char *name);
 void cimlib_set_cache_size(long size);
+void cimlib_set_cache_flush_interval(long interval);
 void cimlib_init(Display *display, Window drawable, Visual *visual, Colormap colourmap);
 void cimlib_render(int x, int y, int width, int height);
 void cimlib_cleanup(void);