Fix #926: Use system background color in window mode
[geeqie.git] / src / image.c
index 7fad282..1326ff1 100644 (file)
 
 
 #include "collect.h"
+#include "collect-table.h"
 #include "color-man.h"
 #include "exif.h"
 #include "metadata.h"
 #include "histogram.h"
+#include "history_list.h"
 #include "image-load.h"
 #include "image-overlay.h"
 #include "layout.h"
 
 static GList *image_list = NULL;
 
-static void image_update_title(ImageWindow *imd);
+void image_update_title(ImageWindow *imd);
 static void image_read_ahead_start(ImageWindow *imd);
 static void image_cache_set(ImageWindow *imd, FileData *fd);
 
+// For draw rectangle function
+static gint pixbuf_start_x;
+static gint pixbuf_start_y;
+static gint image_start_x;
+static gint image_start_y;
+static gint rect_x1, rect_x2, rect_y1, rect_y2;
+static gint rect_id = 0;
+
 /*
  *-------------------------------------------------------------------
  * 'signals'
@@ -67,10 +77,175 @@ static void image_click_cb(PixbufRenderer *pr, GdkEventButton *event, gpointer d
                }
 }
 
+static void switch_coords_orientation(ImageWindow *imd, gint x, gint y, gint width, gint height)
+{
+       switch (imd->orientation)
+               {
+               case EXIF_ORIENTATION_TOP_LEFT:
+                       /* normal -- nothing to do */
+                       rect_x1 = image_start_x;
+                       rect_y1 = image_start_y;
+                       rect_x2 = x;
+                       rect_y2 = y;
+                       break;
+               case EXIF_ORIENTATION_TOP_RIGHT:
+                       /* mirrored */
+                       rect_x1 = width - x;
+                       rect_y1 = image_start_y;
+                       rect_x2 = width - image_start_x;
+                       rect_y2 = y;
+                       break;
+               case EXIF_ORIENTATION_BOTTOM_RIGHT:
+                       /* upside down */
+                       rect_x1 = width - x;
+                       rect_y1 = height - y;
+                       rect_x2 = width - image_start_x;
+                       rect_y2 = height - image_start_y;
+                       break;
+               case EXIF_ORIENTATION_BOTTOM_LEFT:
+                       /* flipped */
+                       rect_x1 = image_start_x;
+                       rect_y1 = height - y;
+                       rect_x2 = x;
+                       rect_y2 = height - image_start_y;
+                       break;
+               case EXIF_ORIENTATION_LEFT_TOP:
+                       /* left mirrored */
+                       rect_x1 = image_start_y;
+                       rect_y1 = image_start_x;
+                       rect_x2 = y;
+                       rect_y2 = x;
+                       break;
+               case EXIF_ORIENTATION_RIGHT_TOP:
+                       /* rotated -90 (270) */
+                       rect_x1 = image_start_y;
+                       rect_y1 = width - x;
+                       rect_x2 = y;
+                       rect_y2 = width - image_start_x;
+                       break;
+               case EXIF_ORIENTATION_RIGHT_BOTTOM:
+                       /* right mirrored */
+                       rect_x1 = height - y;
+                       rect_y1 = width - x;
+                       rect_x2 = height - image_start_y;
+                       rect_y2 = width - image_start_x;
+                       break;
+               case EXIF_ORIENTATION_LEFT_BOTTOM:
+                       /* rotated 90 */
+                       rect_x1 = height - y;
+                       rect_y1 = image_start_x;
+                       rect_x2 = height - image_start_y;
+                       rect_y2 = x;
+                       break;
+               default:
+                       /* The other values are out of range */
+                       break;
+               }
+}
+
+static void image_press_cb(PixbufRenderer *pr, GdkEventButton *event, gpointer data)
+{
+       ImageWindow *imd = data;
+       LayoutWindow *lw;
+       gint x_pixel, y_pixel;
+
+       if(options->draw_rectangle)
+               {
+               pixbuf_renderer_get_mouse_position(pr, &x_pixel, &y_pixel);
+
+               pixbuf_start_x = event->x;
+               pixbuf_start_y = event->y;
+
+               if (x_pixel == -1)
+                       {
+                       image_start_x = 0;
+                       }
+               else
+                       {
+                       image_start_x = x_pixel;
+                       }
+
+               if (y_pixel == -1)
+                       {
+                       image_start_y = 0;
+                       }
+               else
+                       {
+                       image_start_y = y_pixel;
+                       }
+               }
+
+       if (rect_id)
+               {
+               pixbuf_renderer_overlay_remove((PixbufRenderer *)imd->pr, rect_id);
+               }
+
+       lw = layout_find_by_image(imd);
+       if (lw && event->button == MOUSE_BUTTON_LEFT && event->type == GDK_2BUTTON_PRESS
+                                                                                               && !options->image_lm_click_nav)
+               {
+               if (lw->full_screen)
+                       layout_image_full_screen_stop(lw);
+               }
+}
+
 static void image_drag_cb(PixbufRenderer *pr, GdkEventMotion *event, gpointer data)
 {
        ImageWindow *imd = data;
        gint width, height;
+       gint rect_width;
+       gint rect_height;
+       GdkPixbuf *rect_pixbuf;
+       gint x_pixel, y_pixel;
+       gint image_x_pixel, image_y_pixel;
+
+       if (options->draw_rectangle)
+               {
+               pixbuf_renderer_get_image_size(pr, &width, &height);
+               pixbuf_renderer_get_mouse_position(pr, &x_pixel, &y_pixel);
+
+               if (x_pixel == -1)
+                       {
+                       image_x_pixel = width;
+                       }
+               else
+                       {
+                       image_x_pixel = x_pixel;
+                       }
+
+               if (y_pixel == -1)
+                       {
+                       image_y_pixel = height;
+                       }
+               else
+                       {
+                       image_y_pixel = y_pixel;
+                       }
+
+               switch_coords_orientation(imd, image_x_pixel, image_y_pixel, width, height);
+               if (rect_id)
+                       {
+                       pixbuf_renderer_overlay_remove((PixbufRenderer *)imd->pr, rect_id);
+                       }
+
+               rect_width = pr->drag_last_x - pixbuf_start_x;
+               if (rect_width <= 0)
+                       {
+                       rect_width = 1;
+                       }
+               rect_height = pr->drag_last_y - pixbuf_start_y;
+               if (rect_height <= 0)
+                       {
+                       rect_height = 1;
+                       }
+
+               rect_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, rect_width, rect_height);
+               pixbuf_set_rect_fill(rect_pixbuf, 0, 0, rect_width, rect_height, 255, 255, 255, 0);
+               pixbuf_set_rect(rect_pixbuf, 1, 1, rect_width-2, rect_height - 2, 0, 0, 0, 255, 1, 1, 1, 1);
+               pixbuf_set_rect(rect_pixbuf, 2, 2, rect_width-4, rect_height - 4, 255, 255, 255, 255, 1, 1, 1, 1);
+
+               rect_id = pixbuf_renderer_overlay_add((PixbufRenderer *)imd->pr, rect_pixbuf, pixbuf_start_x, pixbuf_start_y, OVL_NORMAL);
+               }
 
        pixbuf_renderer_get_scaled_size(pr, &width, &height);
 
@@ -158,11 +333,13 @@ static void image_zoom_cb(PixbufRenderer *pr, gdouble zoom, gpointer data)
  *-------------------------------------------------------------------
  */
 
-static void image_update_title(ImageWindow *imd)
+void image_update_title(ImageWindow *imd)
 {
        gchar *title = NULL;
        gchar *zoom = NULL;
        gchar *collection = NULL;
+       LayoutWindow *lw;
+       gchar *lw_ident = NULL;
 
        if (!imd->top_window) return;
 
@@ -180,13 +357,25 @@ static void image_update_title(ImageWindow *imd)
                g_free(buf);
                }
 
-       title = g_strdup_printf("%s%s%s%s%s%s",
+       lw = layout_find_by_image(imd);
+       if (lw)
+               {
+               lw_ident = g_strconcat(" (", lw->options.id, ")", NULL);
+               }
+
+       title = g_strdup_printf("%s%s%s%s%s%s%s",
                imd->title ? imd->title : "",
                imd->image_fd ? imd->image_fd->name : "",
                zoom ? zoom : "",
                collection ? collection : "",
                imd->image_fd ? " - " : "",
-               imd->title_right ? imd->title_right : "");
+               imd->title_right ? imd->title_right : "",
+               options->show_window_ids ? (lw_ident ? lw_ident : "") : ""
+               );
+       if (lw_ident)
+               {
+               g_free(lw_ident);
+               }
 
        gtk_window_set_title(GTK_WINDOW(imd->top_window), title);
 
@@ -376,7 +565,7 @@ static void image_post_process_tile_color_cb(PixbufRenderer *pr, GdkPixbuf **pix
        ImageWindow *imd = (ImageWindow *)data;
        if (imd->cm) color_man_correct_region(imd->cm, *pixbuf, x, y, w, h);
        if (imd->desaturate) pixbuf_desaturate_rect(*pixbuf, x, y, w, h);
-
+       if (imd->overunderexposed) pixbuf_highlight_overunderexposed(*pixbuf, x, y, w, h);
 }
 
 void image_alter_orientation(ImageWindow *imd, FileData *fd_n, AlterType type)
@@ -400,7 +589,14 @@ void image_alter_orientation(ImageWindow *imd, FileData *fd_n, AlterType type)
        else
                if (options->metadata.write_orientation)
                        {
-                       orientation = metadata_read_int(fd_n, ORIENTATION_KEY, EXIF_ORIENTATION_TOP_LEFT);
+                       if (g_strcmp0(imd->image_fd->format_name, "heif") == 0)
+                               {
+                               orientation = EXIF_ORIENTATION_TOP_LEFT;
+                               }
+                       else
+                               {
+                               orientation = metadata_read_int(fd_n, ORIENTATION_KEY, EXIF_ORIENTATION_TOP_LEFT);
+                               }
                        }
        }
 
@@ -431,13 +627,21 @@ void image_alter_orientation(ImageWindow *imd, FileData *fd_n, AlterType type)
 
        if (orientation != (fd_n->exif_orientation ? fd_n->exif_orientation : 1))
                {
-               if (!options->metadata.write_orientation)
+               if (g_strcmp0(fd_n->format_name, "heif") != 0)
+                       {
+                       if (!options->metadata.write_orientation)
+                               {
+                               /* user_orientation does not work together with options->metadata.write_orientation,
+                                  use either one or the other.
+                                  we must however handle switching metadata.write_orientation on and off, therefore
+                                  we just disable referencing new fd's, not unreferencing the old ones
+                               */
+                               if (fd_n->user_orientation == 0) file_data_ref(fd_n);
+                               fd_n->user_orientation = orientation;
+                               }
+                       }
+               else
                        {
-                       /* user_orientation does not work together with options->metadata.write_orientation,
-                          use either one or the other.
-                          we must however handle switching metadata.write_orientation on and off, therefore
-                          we just disable referencing new fd's, not unreferencing the old ones
-                       */
                        if (fd_n->user_orientation == 0) file_data_ref(fd_n);
                        fd_n->user_orientation = orientation;
                        }
@@ -448,15 +652,18 @@ void image_alter_orientation(ImageWindow *imd, FileData *fd_n, AlterType type)
                fd_n->user_orientation = 0;
                }
 
-       if (options->metadata.write_orientation)
+       if (g_strcmp0(fd_n->format_name, "heif") != 0)
                {
-               if (type == ALTER_NONE)
-                       {
-                       metadata_write_revert(fd_n, ORIENTATION_KEY);
-                       }
-               else
+               if (options->metadata.write_orientation)
                        {
-                       metadata_write_int(fd_n, ORIENTATION_KEY, orientation);
+                       if (type == ALTER_NONE)
+                               {
+                               metadata_write_revert(fd_n, ORIENTATION_KEY);
+                               }
+                       else
+                               {
+                               metadata_write_int(fd_n, ORIENTATION_KEY, orientation);
+                               }
                        }
                }
 
@@ -470,7 +677,7 @@ void image_alter_orientation(ImageWindow *imd, FileData *fd_n, AlterType type)
 void image_set_desaturate(ImageWindow *imd, gboolean desaturate)
 {
        imd->desaturate = desaturate;
-       if (imd->cm || imd->desaturate)
+       if (imd->cm || imd->desaturate || imd->overunderexposed)
                pixbuf_renderer_set_post_process_func((PixbufRenderer *)imd->pr, image_post_process_tile_color_cb, (gpointer) imd, (imd->cm != NULL) );
        else
                pixbuf_renderer_set_post_process_func((PixbufRenderer *)imd->pr, NULL, NULL, TRUE);
@@ -482,6 +689,26 @@ gboolean image_get_desaturate(ImageWindow *imd)
        return imd->desaturate;
 }
 
+void image_set_overunderexposed(ImageWindow *imd, gboolean overunderexposed)
+{
+       imd->overunderexposed = overunderexposed;
+       if (imd->cm || imd->desaturate || imd->overunderexposed)
+               pixbuf_renderer_set_post_process_func((PixbufRenderer *)imd->pr, image_post_process_tile_color_cb, (gpointer) imd, (imd->cm != NULL) );
+       else
+               pixbuf_renderer_set_post_process_func((PixbufRenderer *)imd->pr, NULL, NULL, TRUE);
+       pixbuf_renderer_set_orientation((PixbufRenderer *)imd->pr, imd->orientation);
+}
+
+gboolean image_get_overunderexposed(ImageWindow *imd)
+{
+       return imd->overunderexposed;
+}
+
+void image_set_ignore_alpha(ImageWindow *imd, gboolean ignore_alpha)
+{
+   pixbuf_renderer_set_ignore_alpha((PixbufRenderer *)imd->pr, ignore_alpha);
+}
+
 /*
  *-------------------------------------------------------------------
  * read ahead (prebuffer)
@@ -658,7 +885,30 @@ static void image_load_done_cb(ImageLoader *il, gpointer data)
                {
                GdkPixbuf *pixbuf;
 
-               pixbuf = pixbuf_inline(PIXBUF_INLINE_BROKEN);
+               switch (imd->image_fd->format_class)
+                       {
+                       case FORMAT_CLASS_UNKNOWN:
+                               pixbuf = pixbuf_inline(PIXBUF_INLINE_UNKNOWN);
+                               break;
+                       case FORMAT_CLASS_META:
+                               pixbuf = pixbuf_inline(PIXBUF_INLINE_METADATA);
+                               break;
+                       case FORMAT_CLASS_VIDEO:
+                               pixbuf = pixbuf_inline(PIXBUF_INLINE_VIDEO);
+                               break;
+                       case FORMAT_CLASS_COLLECTION:
+                               pixbuf = pixbuf_inline(PIXBUF_INLINE_COLLECTION);
+                               break;
+                       case FORMAT_CLASS_DOCUMENT:
+                               pixbuf = pixbuf_inline(PIXBUF_INLINE_ICON_PDF);
+                               break;
+                       case FORMAT_CLASS_ARCHIVE:
+                               pixbuf = pixbuf_inline(PIXBUF_INLINE_ARCHIVE);
+                               break;
+                       default:
+                               pixbuf = pixbuf_inline(PIXBUF_INLINE_BROKEN);
+                       }
+
                image_change_pixbuf(imd, pixbuf, image_zoom_get(imd), FALSE);
                g_object_unref(pixbuf);
 
@@ -866,6 +1116,15 @@ static void image_change_complete(ImageWindow *imd, gdouble zoom)
                        pr = PIXBUF_RENDERER(imd->pr);
                        pr->zoom = zoom;        /* store the zoom, needed by the loader */
 
+                       /* Disable 2-pass for GIFs. Animated GIFs can flicker when enabled
+                        * Reduce quality to worst but fastest to avoid dropped frames */
+                       if (g_ascii_strcasecmp(imd->image_fd->extension, ".GIF") == 0)
+                               {
+                               g_object_set(G_OBJECT(imd->pr), "zoom_2pass", FALSE, NULL);
+                               g_object_set(G_OBJECT(imd->pr), "zoom_quality", GDK_INTERP_NEAREST, NULL);
+                               }
+
+
                        if (image_load_begin(imd, imd->image_fd))
                                {
                                imd->unknown = FALSE;
@@ -929,12 +1188,47 @@ static gboolean image_focus_in_cb(GtkWidget *widget, GdkEventFocus *event, gpoin
 static gboolean image_scroll_cb(GtkWidget *widget, GdkEventScroll *event, gpointer data)
 {
        ImageWindow *imd = data;
+       gboolean in_lw = FALSE;
+       gint i = 0;
+       LayoutWindow *lw = NULL;
 
-       if (imd->func_scroll &&
-           event && event->type == GDK_SCROLL)
+       if (imd->func_scroll && event && event->type == GDK_SCROLL)
                {
-               imd->func_scroll(imd, event, imd->data_scroll);
-               return TRUE;
+               layout_valid(&lw);
+               /* check if the image is in a layout window */
+               for (i = 0; i < MAX_SPLIT_IMAGES; i++)
+                       {
+                       if (imd == lw->split_images[i])
+                               {
+                               in_lw = TRUE;
+                               break;
+                               }
+                       }
+
+               if (in_lw)
+                       {
+                       if (lw->options.split_pane_sync)
+                               {
+                               for (i = 0; i < MAX_SPLIT_IMAGES; i++)
+                                       {
+                                       if (lw->split_images[i])
+                                               {
+                                               layout_image_activate(lw, i, FALSE);
+                                               imd->func_scroll(lw->split_images[i], event, lw->split_images[i]->data_scroll);
+                                               }
+                                       }
+                               }
+                       else
+                               {
+                               imd->func_scroll(imd, event, imd->data_scroll);
+                               }
+                       return TRUE;
+                       }
+               else
+                       {
+                       imd->func_scroll(imd, event, imd->data_scroll);
+                       return TRUE;
+                       }
                }
 
        return FALSE;
@@ -949,6 +1243,8 @@ static gboolean image_scroll_cb(GtkWidget *widget, GdkEventScroll *event, gpoint
 void image_attach_window(ImageWindow *imd, GtkWidget *window,
                         const gchar *title, const gchar *title_right, gboolean show_zoom)
 {
+       LayoutWindow *lw;
+
        imd->top_window = window;
        g_free(imd->title);
        imd->title = g_strdup(title);
@@ -956,7 +1252,9 @@ void image_attach_window(ImageWindow *imd, GtkWidget *window,
        imd->title_right = g_strdup(title_right);
        imd->title_show_zoom = show_zoom;
 
-       if (!options->image.fit_window_to_image) window = NULL;
+       lw = layout_find_by_image(imd);
+
+       if (!(options->image.fit_window_to_image && lw && (lw->options.tools_float || lw->options.tools_hidden))) window = NULL;
 
        pixbuf_renderer_set_parent((PixbufRenderer *)imd->pr, (GtkWindow *)window);
 
@@ -1084,6 +1382,7 @@ GdkPixbuf *image_get_pixbuf(ImageWindow *imd)
 
 void image_change_pixbuf(ImageWindow *imd, GdkPixbuf *pixbuf, gdouble zoom, gboolean lazy)
 {
+       LayoutWindow *lw;
        StereoPixbufData stereo_data = STEREO_PIXBUF_DEFAULT;
        /* read_exif and similar functions can actually notice that the file has changed and trigger
           a notification that removes the pixbuf from cache and unrefs it. Therefore we must ref it
@@ -1099,8 +1398,16 @@ void image_change_pixbuf(ImageWindow *imd, GdkPixbuf *pixbuf, gdouble zoom, gboo
                        }
                else if (options->image.exif_rotate_enable)
                        {
-                       imd->orientation = metadata_read_int(imd->image_fd, ORIENTATION_KEY, EXIF_ORIENTATION_TOP_LEFT);
-                       imd->image_fd->exif_orientation = imd->orientation;
+                       if (g_strcmp0(imd->image_fd->format_name, "heif") == 0)
+                               {
+                               imd->orientation = EXIF_ORIENTATION_TOP_LEFT;
+                               imd->image_fd->exif_orientation = imd->orientation;
+                               }
+                       else
+                               {
+                               imd->orientation = metadata_read_int(imd->image_fd, ORIENTATION_KEY, EXIF_ORIENTATION_TOP_LEFT);
+                               imd->image_fd->exif_orientation = imd->orientation;
+                               }
                        }
                }
 
@@ -1133,12 +1440,14 @@ void image_change_pixbuf(ImageWindow *imd, GdkPixbuf *pixbuf, gdouble zoom, gboo
 
        if (pixbuf) g_object_unref(pixbuf);
 
-       if (imd->color_profile_enable)
+       /* Color correction takes too much time for an animated gif */
+       lw = layout_find_by_image(imd);
+       if (imd->color_profile_enable && lw && !lw->animation)
                {
-               image_post_process_color(imd, 0, FALSE); /* TODO: error handling */
+               image_post_process_color(imd, 0, FALSE); /** @todo error handling */
                }
 
-       if (imd->cm || imd->desaturate)
+       if (imd->cm || imd->desaturate || imd->overunderexposed)
                pixbuf_renderer_set_post_process_func((PixbufRenderer *)imd->pr, image_post_process_tile_color_cb, (gpointer) imd, (imd->cm != NULL) );
 
        image_state_set(imd, IMAGE_STATE_IMAGE);
@@ -1146,9 +1455,23 @@ void image_change_pixbuf(ImageWindow *imd, GdkPixbuf *pixbuf, gdouble zoom, gboo
 
 void image_change_from_collection(ImageWindow *imd, CollectionData *cd, CollectInfo *info, gdouble zoom)
 {
+       CollectWindow *cw;
+
        if (!cd || !info || !g_list_find(cd->list, info)) return;
 
        image_change_real(imd, info->fd, cd, info, zoom);
+       cw = collection_window_find(cd);
+       if (cw)
+               {
+               collection_table_set_focus(cw->table, info);
+               collection_table_unselect_all(cw->table);
+               collection_table_select(cw->table,info);
+               }
+
+       if (info->fd)
+               {
+               image_chain_append_end(info->fd->path);
+               }
 }
 
 CollectionData *image_get_collection(ImageWindow *imd, CollectInfo **info)
@@ -1247,7 +1570,7 @@ void image_move_from_image(ImageWindow *imd, ImageWindow *source)
 
        pixbuf_renderer_move(PIXBUF_RENDERER(imd->pr), PIXBUF_RENDERER(source->pr));
 
-       if (imd->cm || imd->desaturate)
+       if (imd->cm || imd->desaturate || imd->overunderexposed)
                pixbuf_renderer_set_post_process_func((PixbufRenderer *)imd->pr, image_post_process_tile_color_cb, (gpointer) imd, (imd->cm != NULL) );
        else
                pixbuf_renderer_set_post_process_func((PixbufRenderer *)imd->pr, NULL, NULL, TRUE);
@@ -1309,7 +1632,7 @@ void image_copy_from_image(ImageWindow *imd, ImageWindow *source)
 
        pixbuf_renderer_copy(PIXBUF_RENDERER(imd->pr), PIXBUF_RENDERER(source->pr));
 
-       if (imd->cm || imd->desaturate)
+       if (imd->cm || imd->desaturate || imd->overunderexposed)
                pixbuf_renderer_set_post_process_func((PixbufRenderer *)imd->pr, image_post_process_tile_color_cb, (gpointer) imd, (imd->cm != NULL) );
        else
                pixbuf_renderer_set_post_process_func((PixbufRenderer *)imd->pr, NULL, NULL, TRUE);
@@ -1531,7 +1854,7 @@ static void image_notify_cb(FileData *fd, NotifyType type, gpointer data)
        if ((type & NOTIFY_REREAD) && fd == imd->image_fd)
                {
                /* there is no need to reload on NOTIFY_CHANGE,
-                  modified files should be detacted anyway and NOTIFY_REREAD should be recieved
+                  modified files should be detacted anyway and NOTIFY_REREAD should be received
                   or they are removed from the filelist completely on "move" and "delete"
                */
                DEBUG_1("Notify image: %s %04x", fd->path, type);
@@ -1565,6 +1888,12 @@ void image_background_set_color(ImageWindow *imd, GdkColor *color)
 void image_background_set_color_from_options(ImageWindow *imd, gboolean fullscreen)
 {
        GdkColor *color = NULL;
+#if GTK_CHECK_VERSION(3,0,0)
+       GdkColor theme_color;
+       GdkRGBA bg_color;
+       GtkStyleContext *style_context;
+       LayoutWindow *lw = NULL;
+#endif
 
        if ((options->image.use_custom_border_color && !fullscreen) ||
            (options->image.use_custom_border_color_in_fullscreen && fullscreen))
@@ -1572,6 +1901,22 @@ void image_background_set_color_from_options(ImageWindow *imd, gboolean fullscre
                color = &options->image.border_color;
                }
 
+#if GTK_CHECK_VERSION(3,0,0)
+       else
+               {
+               if (!layout_valid(&lw)) return;
+
+               style_context = gtk_widget_get_style_context(lw->window);
+               gtk_style_context_get_background_color(style_context, GTK_STATE_FLAG_NORMAL, &bg_color);
+
+               theme_color.red = bg_color.red * 65535;
+               theme_color.green = bg_color.green * 65535;
+               theme_color.blue = bg_color.blue * 65535;
+
+               color = &theme_color;
+               }
+#endif
+
        image_background_set_color(imd, color);
 }
 
@@ -1743,6 +2088,7 @@ static void image_options_set(ImageWindow *imd)
                                        "window_limit_value", options->image.max_window_size,
                                        "autofit_limit", options->image.limit_autofit_size,
                                        "autofit_limit_value", options->image.max_autofit_size,
+                                       "enlargement_limit_value", options->image.max_enlargement_size,
 
                                        NULL);
 
@@ -1877,6 +2223,7 @@ void image_set_frame(ImageWindow *imd, gboolean frame)
        if (frame)
                {
                imd->frame = gtk_frame_new(NULL);
+               DEBUG_NAME(imd->frame);
                g_object_ref(imd->pr);
                if (imd->has_frame != -1) gtk_container_remove(GTK_CONTAINER(imd->widget), imd->pr);
                gtk_container_add(GTK_CONTAINER(imd->frame), imd->pr);
@@ -1931,10 +2278,12 @@ ImageWindow *image_new(gboolean frame)
        imd->orientation = 1;
 
        imd->pr = GTK_WIDGET(pixbuf_renderer_new());
+       DEBUG_NAME(imd->pr);
 
        image_options_set(imd);
 
        imd->widget = gtk_vbox_new(0, 0);
+       DEBUG_NAME(imd->widget);
 
        image_set_frame(imd, frame);
 
@@ -1942,6 +2291,8 @@ ImageWindow *image_new(gboolean frame)
 
        g_signal_connect(G_OBJECT(imd->pr), "clicked",
                         G_CALLBACK(image_click_cb), imd);
+       g_signal_connect(G_OBJECT(imd->pr), "button_press_event",
+                        G_CALLBACK(image_press_cb), imd);
        g_signal_connect(G_OBJECT(imd->pr), "scroll_notify",
                         G_CALLBACK(image_scroll_notify_cb), imd);
 
@@ -1964,4 +2315,13 @@ ImageWindow *image_new(gboolean frame)
 
        return imd;
 }
+
+void image_get_rectangle(gint *x1, gint *y1, gint *x2, gint *y2)
+{
+       *x1 = rect_x1;
+       *y1 = rect_y1;
+       *x2 = rect_x2;
+       *y2 = rect_y2;
+}
+
 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */