summaryrefslogtreecommitdiff
path: root/window_main.c
diff options
context:
space:
mode:
authorJon Bergli Heier <snakebite@jvnv.net>2010-01-06 19:23:09 +0100
committerJon Bergli Heier <snakebite@jvnv.net>2010-01-06 19:23:09 +0100
commit90df6aec51309372260b02b3a9bd518d35da4f40 (patch)
tree55010b820ccfa3dadb9b59637db96224203830b4 /window_main.c
parentb0f0ee3842bff277048316f9c006dd16188de6c4 (diff)
Implemented threaded preloading of images.
The number of preloads is currently hardcoded in preload.c, an option to change this will be added shortly.
Diffstat (limited to 'window_main.c')
-rw-r--r--window_main.c100
1 files changed, 57 insertions, 43 deletions
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();