From 90df6aec51309372260b02b3a9bd518d35da4f40 Mon Sep 17 00:00:00 2001 From: Jon Bergli Heier Date: Wed, 6 Jan 2010 19:23:09 +0100 Subject: Implemented threaded preloading of images. The number of preloads is currently hardcoded in preload.c, an option to change this will be added shortly. --- window_main.c | 100 +++++++++++++++++++++++++++++++++------------------------- 1 file changed, 57 insertions(+), 43 deletions(-) (limited to 'window_main.c') diff --git a/window_main.c b/window_main.c index 984a4e0..a550943 100644 --- a/window_main.c +++ b/window_main.c @@ -9,6 +9,7 @@ #include "thumbnails.h" #include "walls_conf.h" #include "window_tag.h" +#include "preload.h" struct wallpaper_t *cur_wall = NULL; GdkPixbuf *orig_pixbuf = NULL; @@ -113,58 +114,41 @@ static void set_resize_msg(gdouble scale) { g_free(msg); } -static void resize_pixbuf() { - GdkPixbuf *pb; +static void set_image_pixbuf_resized(GdkPixbuf *pb, gint win_width, gint win_height, gint width, gint height, gdouble ratio) { + set_resize_msg(ratio); + + gtk_widget_set_size_request(GTK_WIDGET(image), width, height); + gtk_widget_set_uposition(GTK_WIDGET(image), (width < win_width ? win_width / 2 - width / 2 : 0), + (height < win_height ? win_height / 2 - height / 2 : 0)); + gtk_image_set_from_pixbuf(image, pb); + + gtk_layout_set_size(GTK_LAYOUT(layout), win_width, win_height); +} + +static void set_image_pixbuf() { GdkWindow *window; - gint win_width, win_height, img_width, img_height, width, height; - gdouble scalex, scaley, width_ratio, height_ratio; + GdkPixbuf *pb; + gint win_width, win_height, width, height; + gdouble ratio; - /* Skip if no pixbuf is loaded yet. */ - if(!orig_pixbuf) return; + if(!orig_pixbuf) + return; window = gtk_widget_get_window(layout); gdk_drawable_get_size(window, &win_width, &win_height); - gtk_layout_set_size(GTK_LAYOUT(layout), win_width, win_height); - img_width = gdk_pixbuf_get_width(orig_pixbuf); - img_height = gdk_pixbuf_get_height(orig_pixbuf); - - /* do we need to resize? */ - if(img_width > win_width || img_height > win_height) { - /* resize by width */ - width_ratio = (gdouble)img_width / (gdouble)win_width; - height_ratio = (gdouble)img_height / (gdouble)win_height; - if(width_ratio > height_ratio) { - width = win_width; - height = (gint)(1.0 / width_ratio * img_height); - scalex = (gdouble)width / (gdouble)img_width; - scaley = (gdouble)height / (gdouble)img_height; - } else { /* resize by height */ - height = win_height; - width = (gint)(1.0 / height_ratio * img_width); - scalex = (gdouble)width / (gdouble)img_width; - scaley = (gdouble)height / (gdouble)img_height; - } - if(width == 0 || height == 0) return; - pb = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, width, height); - gdk_pixbuf_scale(orig_pixbuf, pb, 0, 0, width, height, 0, 0, scalex, scaley, GDK_INTERP_BILINEAR); - } else { - width = img_width; - height = img_height; - pb = gdk_pixbuf_copy(orig_pixbuf); - } + pb = resize_pixbuf(orig_pixbuf, win_width, win_height, &width, &height, &ratio); + if(!pb) + return; - gtk_widget_set_size_request(GTK_WIDGET(image), width, height); - gtk_widget_set_uposition(GTK_WIDGET(image), (width < win_width ? win_width / 2 - width / 2 : 0), (height < win_height ? win_height / 2 - height / 2 : 0)); - gtk_image_set_from_pixbuf(image, pb); + set_image_pixbuf_resized(pb, win_width, win_height, width, height, ratio); g_object_unref(pb); - - set_resize_msg((gdouble)width / (gdouble)img_width); } void on_window_size_allocate(GtkWidget *widget, GtkAllocation *allocation, gpointer user_data) { if(orig_pixbuf && (allocation->width != last_width || allocation->height != last_height)) { - resize_pixbuf(); + preload_clear(); + set_image_pixbuf(); last_width = allocation->width; last_height = allocation->height; } @@ -176,7 +160,8 @@ static gboolean hpane_resize_idle_func(gpointer data) { pos = gtk_paned_get_position(GTK_PANED(data)); if(pos != hpane_last_pos) { - resize_pixbuf(); + preload_clear(); + set_image_pixbuf(); hpane_last_pos = pos; return TRUE; /* Ensure that we'll keep checking until we're done resizing. */ } @@ -208,11 +193,23 @@ static void load_pixbuf(const gchar *filepath) { GError *error = NULL; sqlite_uint64 wallid; struct wallpaper_t *wall; + struct preload_hash_table_value_t *pt; gchar *base; + GdkWindow *window; + gint win_width, win_height; if(orig_pixbuf) g_object_unref(orig_pixbuf); - orig_pixbuf = gdk_pixbuf_new_from_file(filepath, &error); + + pt = preload_get(filepath); + if(pt) + orig_pixbuf = gdk_pixbuf_copy(pt->pb); + else + orig_pixbuf = NULL; + + if(!orig_pixbuf) + orig_pixbuf = gdk_pixbuf_new_from_file(filepath, &error); + if(!orig_pixbuf) { g_warning("%s", error->message); g_error_free(error); @@ -246,7 +243,13 @@ static void load_pixbuf(const gchar *filepath) { walls_set_window_title(); } - resize_pixbuf(); + if(pt) { + window = gtk_widget_get_window(layout); + gdk_drawable_get_size(window, &win_width, &win_height); + + set_image_pixbuf_resized(orig_pixbuf, win_width, win_height, pt->width, pt->height, pt->ratio); + } else + set_image_pixbuf(); } /** @@ -326,6 +329,8 @@ void on_thumbview_selection_changed(GtkIconView *iconview, gpointer user_data) { GtkTreePath *path; GtkTreeModel *model; GtkTreeIter iter; + GdkWindow *window; + gint win_width, win_height; list = gtk_icon_view_get_selected_items(iconview); if(list) { @@ -341,6 +346,11 @@ void on_thumbview_selection_changed(GtkIconView *iconview, gpointer user_data) { g_list_foreach(list, (GFunc)gtk_tree_path_free, NULL); g_list_free(list); + + window = gtk_widget_get_window(layout); + gdk_drawable_get_size(window, &win_width, &win_height); + + preload_start_thread(GTK_WIDGET(thumbview), win_width, win_height); } } @@ -690,10 +700,14 @@ int gui_main(int argc, char **argv) { gtk_widget_show_all(GTK_WIDGET(window)); + preload_init(); + gdk_threads_enter(); gtk_main(); gdk_threads_leave(); + preload_free(); + db_close(); conf_close(); -- cgit v1.2.3