on Anne's karmic koala, gtk_events_pending() is much more often true than on my machi...
[booh] / ext / rbbooh.cc
index f2dfca04d9a8fb2ca1f751f924d99a159cb7c49c..29c097d96b1f75466be0ded6ef2059c234e54219 100644 (file)
@@ -9,7 +9,7 @@
  * called Boo, so this one will be it "Booh". Or whatever.
  *
  *
- * Copyright (c) 2005-2008 Guillaume Cottenceau
+ * Copyright (c) 2005-2009 Guillaume Cottenceau
  *
  * This software may be freely redistributed under the terms of the GNU
  * public license version 2.
@@ -175,47 +175,42 @@ static VALUE modify_bg(VALUE self, VALUE state, VALUE color) {
         return self;
 }
 
-static int counter = 0;
-
 // internalize pixbuf loading for 30% more speedup
-static VALUE load_not_freezing_ui(VALUE self, VALUE path, VALUE interruptable, VALUE area_prepared_signal_id) {
-        int interruptable_ = RTEST(interruptable);
+static VALUE load_not_freezing_ui(VALUE self, VALUE path, VALUE offset) {
         char buf[65536];
         size_t amount;
+        size_t off = NUM2INT(offset);
         GdkPixbufLoader* loader = GDK_PIXBUF_LOADER(RVAL2GOBJ(self));
         GError* error = NULL;
         FILE* f = fopen(RVAL2CSTR(path), "r");
         if (!f) {
+                gdk_pixbuf_loader_close(loader, NULL);
                 rb_raise(rb_eRuntimeError, "Unable to open file %s for reading", RVAL2CSTR(path));
         }
-        counter++;
+        if (off > 0) {
+                if (fseek(f, off, SEEK_SET) != 0) {
+                        rb_raise(rb_eRuntimeError, "Unable to seek file %s", RVAL2CSTR(path));
+                        fclose(f);
+                        return 0;
+                }
+        }
         while ((amount = fread(buf, 1, 65536, f)) > 0) {
                 if (!gdk_pixbuf_loader_write(loader, (const guchar*) buf, amount, &error)) {
+                        gdk_pixbuf_loader_close(loader, NULL);
                         fclose(f);
                         RAISE_GERROR(error);
                 }
-                if (counter < 52) {
-                        // if the user scrolls too fast between thumbnails, there can be large amount of recursions,
-                        // and program may abort - probably on exhausted stack size; this figure is completely empiric
-                        while (gtk_events_pending()) {
-                                gtk_main_iteration();
-                        }
-                        if (interruptable_ && RTEST(rb_eval_string("$interrupt_loading"))) {
-                                // interrupted, case when the user clicked/keyboarded too quickly for this image to
-                                // display; we cancel this loading, but before we disconnect the area-prepared
-                                // signal handler, else the call to gdk_pixbuf_loader_get_pixbuf will take ages
-                                // (between 100 and 400 ms on my p4 for a large photo!)
-                                g_signal_handler_disconnect(loader, NUM2INT(area_prepared_signal_id));
-                                gdk_pixbuf_loader_close(loader, NULL);
-                                fclose(f);
-                                counter--;
-                                return Qfalse;
-                        }
+                off += amount;
+                if (gtk_events_pending() && !feof(f)) {
+                        // interrupted, case when the user clicked/keyboarded too quickly for this image to
+                        // display; we temporarily interrupt this loading
+                        fclose(f);
+                        return INT2NUM(off);
                 }
         }
+        gdk_pixbuf_loader_close(loader, NULL);
         fclose(f);
-        counter--;
-        return Qtrue;
+        return INT2NUM(0);
 }
 
 extern "C" {
@@ -234,7 +229,7 @@ Init_libadds()
     rb_define_method(cinfo->klass, "modify_bg", (VALUE (*)(...)) modify_bg, 2);
 
     cinfo = (RGObjClassInfo*)rbgobj_lookup_class_by_gtype(GDK_TYPE_PIXBUF_LOADER, Qnil);
-    rb_define_method(cinfo->klass, "load_not_freezing_ui", (VALUE (*)(...)) load_not_freezing_ui, 3);
+    rb_define_method(cinfo->klass, "load_not_freezing_ui", (VALUE (*)(...)) load_not_freezing_ui, 2);
 
     VALUE exif = rb_define_module("Exif");
     rb_define_module_function(exif, "orientation", (VALUE (*)(...)) exif_orientation, 1);