on Anne's karmic koala, gtk_events_pending() is much more often true than on my machi...
[booh] / ext / rbbooh.cc
index 9becd2f75dcfe15f0f494a3946e554e9c20a6306..29c097d96b1f75466be0ded6ef2059c234e54219 100644 (file)
@@ -176,9 +176,10 @@ static VALUE modify_bg(VALUE self, VALUE state, VALUE color) {
 }
 
 // internalize pixbuf loading for 30% more speedup
-static VALUE load_not_freezing_ui(VALUE self, VALUE path, VALUE area_prepared_signal_id) {
+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");
@@ -186,26 +187,30 @@ static VALUE load_not_freezing_ui(VALUE self, VALUE path, VALUE area_prepared_si
                 gdk_pixbuf_loader_close(loader, NULL);
                 rb_raise(rb_eRuntimeError, "Unable to open file %s for reading", RVAL2CSTR(path));
         }
+        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 (gtk_events_pending()) {
+                off += amount;
+                if (gtk_events_pending() && !feof(f)) {
                         // 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);
+                        // display; we temporarily interrupt this loading
                         fclose(f);
-                        return Qfalse;
+                        return INT2NUM(off);
                 }
         }
         gdk_pixbuf_loader_close(loader, NULL);
         fclose(f);
-        return Qtrue;
+        return INT2NUM(0);
 }
 
 extern "C" {