diff src/image-load.c @ 1045:0ab0deb0cfcc

added possibility to redraw only the parts of image that are already loaded
author nadvornik
date Mon, 08 Sep 2008 19:57:51 +0000
parents 5fc64d6252e7
children 1646720364cf
line wrap: on
line diff
--- a/src/image-load.c	Mon Sep 08 15:53:01 2008 +0000
+++ b/src/image-load.c	Mon Sep 08 19:57:51 2008 +0000
@@ -172,6 +172,12 @@
 		il->area_param_list = g_list_delete_link(il->area_param_list, il->area_param_list);
 		}
 
+	while (il->area_param_delayed_list) 
+		{
+		g_free(il->area_param_delayed_list->data);
+		il->area_param_delayed_list = g_list_delete_link(il->area_param_delayed_list, il->area_param_delayed_list);
+		}
+
 	if (il->pixbuf) g_object_unref(il->pixbuf);
 
 	file_data_unref(il->fd);
@@ -267,6 +273,7 @@
 	g_idle_add_full(G_PRIORITY_HIGH, image_loader_emit_percent_cb, il, NULL);
 }
 
+/* this function expects that il->data_mutex is locked by caller */
 static void image_loader_emit_area_ready(ImageLoader *il, guint x, guint y, guint w, guint h)
 {
 	ImageLoaderAreaParam *par = g_new0(ImageLoaderAreaParam, 1);
@@ -276,9 +283,7 @@
 	par->w = w;
 	par->h = h;
 	
-	g_mutex_lock(il->data_mutex);
 	il->area_param_list = g_list_prepend(il->area_param_list, par);
-	g_mutex_unlock(il->data_mutex);
 	
 	g_idle_add_full(G_PRIORITY_HIGH, image_loader_emit_area_ready_cb, par, NULL);
 }
@@ -286,6 +291,21 @@
 /**************************************************************************************/
 /* the following functions may be executed in separate thread */
 
+/* this function expects that il->data_mutex is locked by caller */
+static void image_loader_queue_delayed_erea_ready(ImageLoader *il, guint x, guint y, guint w, guint h)
+{
+	ImageLoaderAreaParam *par = g_new0(ImageLoaderAreaParam, 1);
+	par->il = il;
+	par->x = x;
+	par->y = y;
+	par->w = w;
+	par->h = h;
+	
+	il->area_param_delayed_list = g_list_prepend(il->area_param_delayed_list, par);
+}
+
+
+
 static gint image_loader_get_stopping(ImageLoader *il)
 {
 	gint ret;
@@ -298,6 +318,7 @@
 	return ret;
 }
 
+
 static void image_loader_sync_pixbuf(ImageLoader *il)
 {
 	GdkPixbuf *pb;
@@ -340,7 +361,13 @@
 			log_printf("critical: area_ready signal with NULL pixbuf (out of mem?)\n");
 			}
 		}
-	image_loader_emit_area_ready(il, x, y, w, h);
+
+	g_mutex_lock(il->data_mutex);
+	if (il->delay_area_ready)
+		image_loader_queue_delayed_erea_ready(il, x, y, w, h);
+	else
+		image_loader_emit_area_ready(il, x, y, w, h);
+	g_mutex_unlock(il->data_mutex);
 }
 
 static void image_loader_area_prepared_cb(GdkPixbufLoader *loader, gpointer data)
@@ -666,6 +693,38 @@
 	
 }
 
+void image_loader_delay_area_ready(ImageLoader *il, gint enable)
+{
+	g_mutex_lock(il->data_mutex);
+	il->delay_area_ready = enable;
+	if (!enable)
+		{
+		/* send delayed */
+		GList *list, *work;
+		list = g_list_reverse(il->area_param_delayed_list);
+		il->area_param_delayed_list = NULL;
+		g_mutex_unlock(il->data_mutex);
+
+		work = list;
+
+		while (work)
+			{
+			ImageLoaderAreaParam *par = work->data;
+			work = work->next;
+			
+			g_signal_emit(il, signals[SIGNAL_AREA_READY], 0, par->x, par->y, par->w, par->h);
+			g_free(par);
+			}
+		g_list_free(list);
+		}
+	else
+		{
+		/* just unlock */
+		g_mutex_unlock(il->data_mutex);
+		}
+}
+
+
 /**************************************************************************************/
 /* execution via idle calls */