Index: app/display/gimpdisplayshell-callbacks.c
===================================================================
RCS file: /cvs/gnome/gimp/app/display/gimpdisplayshell-callbacks.c,v
retrieving revision 1.264
diff -u -p -r1.264 gimpdisplayshell-callbacks.c
--- app/display/gimpdisplayshell-callbacks.c	11 Sep 2004 19:19:26 -0000	1.264
+++ app/display/gimpdisplayshell-callbacks.c	30 Sep 2004 18:16:26 -0000
@@ -65,7 +65,6 @@
 #include "gimpdisplayshell-draw.h"
 #include "gimpdisplayshell-layer-select.h"
 #include "gimpdisplayshell-preview.h"
-#include "gimpdisplayshell-render.h"
 #include "gimpdisplayshell-scale.h"
 #include "gimpdisplayshell-scroll.h"
 #include "gimpdisplayshell-selection.h"
Index: app/display/gimpdisplayshell-draw.c
===================================================================
RCS file: /cvs/gnome/gimp/app/display/gimpdisplayshell-draw.c,v
retrieving revision 1.308
diff -u -p -r1.308 gimpdisplayshell-draw.c
--- app/display/gimpdisplayshell-draw.c	7 Sep 2004 19:08:55 -0000	1.308
+++ app/display/gimpdisplayshell-draw.c	30 Sep 2004 18:16:26 -0000
@@ -399,12 +399,21 @@ gimp_display_shell_draw_area (GimpDispla
                                 sx, sy, sw, sh,
                                 &x, &y, &w, &h))
     {
-      gint x2, y2;
-      gint i, j;
+      GdkRectangle  rect;
+      gint          x2, y2;
+      gint          i, j;
 
       x2 = x + w;
       y2 = y + h;
 
+      if (shell->highlight)
+        {
+          rect.x      = SCALEX (shell, shell->highlight->x);
+          rect.y      = SCALEY (shell, shell->highlight->y);
+          rect.width  = SCALEX (shell, shell->highlight->width);
+          rect.height = SCALEY (shell, shell->highlight->height);
+        }
+
       /*  display the image in RENDER_BUF_WIDTH x RENDER_BUF_HEIGHT
        *  sized chunks
        */
@@ -420,7 +429,8 @@ gimp_display_shell_draw_area (GimpDispla
               gimp_display_shell_render (shell,
                                          j - shell->disp_xoffset,
                                          i - shell->disp_yoffset,
-                                         dx, dy);
+                                         dx, dy,
+                                         shell->highlight ? &rect : NULL);
 
 #ifdef STRESS_TEST
               /* Invalidate the projection just after we render it! */
Index: app/display/gimpdisplayshell-render.c
===================================================================
RCS file: /cvs/gnome/gimp/app/display/gimpdisplayshell-render.c,v
retrieving revision 1.67
diff -u -p -r1.67 gimpdisplayshell-render.c
--- app/display/gimpdisplayshell-render.c	3 Sep 2004 00:06:20 -0000	1.67
+++ app/display/gimpdisplayshell-render.c	30 Sep 2004 18:16:26 -0000
@@ -297,6 +297,14 @@ static RenderFunc render_funcs[6] =
 };
 
 
+static void  gimp_display_shell_render_highlight (GimpDisplayShell *shell,
+                                                  gint              x,
+                                                  gint              y,
+                                                  gint              w,
+                                                  gint              h,
+                                                  GdkRectangle     *highlight);
+
+
 /*****************************************************************/
 /*  This function is the core of the display--it offsets and     */
 /*  scales the image according to the current parameters in the  */
@@ -309,7 +317,8 @@ gimp_display_shell_render (GimpDisplaySh
                            gint              x,
                            gint              y,
                            gint              w,
-                           gint              h)
+                           gint              h,
+                           GdkRectangle     *highlight)
 {
   RenderInfo     info;
   GimpImageType  image_type;
@@ -346,6 +355,10 @@ gimp_display_shell_render (GimpDisplaySh
                                       3,
                                       3 * GIMP_DISPLAY_SHELL_RENDER_BUF_WIDTH);
 
+  /*  dim pixels outside the highlighted rectangle  */
+  if (highlight)
+    gimp_display_shell_render_highlight (shell, x, y, w, h, highlight);
+
   /*  put it to the screen  */
   gimp_canvas_draw_rgb (GIMP_CANVAS (shell->canvas), GIMP_CANVAS_STYLE_RENDER,
                         x + shell->disp_xoffset, y + shell->disp_yoffset,
@@ -353,6 +366,76 @@ gimp_display_shell_render (GimpDisplaySh
                         shell->render_buf,
                         3 * GIMP_DISPLAY_SHELL_RENDER_BUF_WIDTH,
                         shell->offset_x, shell->offset_y);
+}
+
+
+#define GIMP_DISPLAY_SHELL_DIM_PIXEL(buf,x) \
+{ \
+  buf[3 * (x) + 0] >>= 1; \
+  buf[3 * (x) + 1] >>= 1; \
+  buf[3 * (x) + 2] >>= 1; \
+}
+
+/*  This function highlights the given area by dimming all pixels outside. */
+
+static void
+gimp_display_shell_render_highlight (GimpDisplayShell *shell,
+                                     gint              x,
+                                     gint              y,
+                                     gint              w,
+                                     gint              h,
+                                     GdkRectangle     *highlight)
+{
+  guchar       *buf  = shell->render_buf;
+  GdkRectangle  rect;
+
+  rect.x      = shell->offset_x + x;
+  rect.y      = shell->offset_y + y;
+  rect.width  = w;
+  rect.height = h;
+
+  if (gdk_rectangle_intersect (highlight, &rect, &rect))
+    {
+      rect.x -= shell->offset_x + x;
+      rect.y -= shell->offset_y + y;
+
+      for (y = 0; y < rect.y; y++)
+        {
+          for (x = 0; x < w; x++)
+            GIMP_DISPLAY_SHELL_DIM_PIXEL (buf, x)
+
+          buf += 3 * GIMP_DISPLAY_SHELL_RENDER_BUF_WIDTH;
+        }
+
+      for ( ; y < rect.y + rect.height; y++)
+        {
+          for (x = 0; x < rect.x; x++)
+            GIMP_DISPLAY_SHELL_DIM_PIXEL (buf, x)
+
+          for (x += rect.width; x < w; x++)
+            GIMP_DISPLAY_SHELL_DIM_PIXEL (buf, x)
+
+          buf += 3 * GIMP_DISPLAY_SHELL_RENDER_BUF_WIDTH;
+        }
+
+      for ( ; y < h; y++)
+        {
+          for (x = 0; x < w; x++)
+            GIMP_DISPLAY_SHELL_DIM_PIXEL (buf, x)
+
+          buf += 3 * GIMP_DISPLAY_SHELL_RENDER_BUF_WIDTH;
+        }
+    }
+  else
+    {
+      for (y = 0; y < h; y++)
+        {
+          for (x = 0; x < w; x++)
+            GIMP_DISPLAY_SHELL_DIM_PIXEL (buf, x)
+
+          buf += 3 * GIMP_DISPLAY_SHELL_RENDER_BUF_WIDTH;
+        }
+    }
 }
 
 
Index: app/display/gimpdisplayshell-render.h
===================================================================
RCS file: /cvs/gnome/gimp/app/display/gimpdisplayshell-render.h,v
retrieving revision 1.10
diff -u -p -r1.10 gimpdisplayshell-render.h
--- app/display/gimpdisplayshell-render.h	26 Feb 2003 16:16:20 -0000	1.10
+++ app/display/gimpdisplayshell-render.h	30 Sep 2004 18:16:26 -0000
@@ -31,7 +31,8 @@ void   gimp_display_shell_render (GimpDi
                                   gint              x,
                                   gint              y,
                                   gint              w,
-                                  gint              h);
+                                  gint              h,
+                                  GdkRectangle     *highlight);
 
 /*
  *  Extern variables
Index: app/display/gimpdisplayshell.c
===================================================================
RCS file: /cvs/gnome/gimp/app/display/gimpdisplayshell.c,v
retrieving revision 1.342
diff -u -p -r1.342 gimpdisplayshell.c
--- app/display/gimpdisplayshell.c	27 Sep 2004 12:30:03 -0000	1.342
+++ app/display/gimpdisplayshell.c	30 Sep 2004 18:16:27 -0000
@@ -18,6 +18,8 @@
 
 #include "config.h"
 
+#include <string.h>
+
 #include <gtk/gtk.h>
 
 #include "libgimpwidgets/gimpwidgets.h"
@@ -311,6 +313,8 @@ gimp_display_shell_init (GimpDisplayShel
   shell->scroll_start_y         = 0;
   shell->button_press_before_focus = FALSE;
 
+  shell->highlight              = NULL;
+
   gtk_window_set_role (GTK_WINDOW (shell), "gimp-image-window");
   gtk_window_set_resizable (GTK_WINDOW (shell), TRUE);
 
@@ -420,6 +424,12 @@ gimp_display_shell_destroy (GtkObject *o
       shell->render_buf = NULL;
     }
 
+  if (shell->highlight)
+    {
+      g_free (shell->highlight);
+      shell->highlight = NULL;
+    }
+
   if (shell->title_idle_id)
     {
       g_source_remove (shell->title_idle_id);
@@ -1416,5 +1426,66 @@ gimp_display_shell_selection_visibility 
           gimp_display_shell_selection_resume (shell->select);
           break;
         }
+    }
+}
+
+/**
+ * gimp_display_shell_set_highlight:
+ * @shell:     a #GimpDisplayShell
+ * @highlight: a rectangle in image coordinates that should be brought out
+ *
+ * This function allows to set an area of the image that should be
+ * accentuated. The actual implementation is to dim all pixels outside
+ * this rectangle. Passing %NULL for @highlight unsets the rectangle.
+ **/
+void
+gimp_display_shell_set_highlight (GimpDisplayShell   *shell,
+                                  const GdkRectangle *highlight)
+{
+  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
+
+  if (shell->highlight)
+    {
+      if (highlight)
+        {
+          GdkRectangle *rects;
+          GdkRegion    *old;
+          GdkRegion    *new;
+          gint          num_rects, i;
+
+          if (memcmp (shell->highlight, highlight, sizeof (GdkRectangle)) == 0)
+            return;
+
+          old = gdk_region_rectangle (shell->highlight);
+
+          *shell->highlight = *highlight;
+
+          new = gdk_region_rectangle (shell->highlight);
+
+          gdk_region_xor (old, new);
+
+          gdk_region_get_rectangles (old, &rects, &num_rects);
+
+          for (i = 0; i < num_rects; i++)
+            gimp_display_update_area (shell->gdisp, TRUE,
+                                      rects[i].x,
+                                      rects[i].y,
+                                      rects[i].width,
+                                      rects[i].height);
+          g_free (rects);
+        }
+      else
+        {
+          g_free (shell->highlight);
+          shell->highlight = NULL;
+
+          gimp_display_shell_expose_full (shell);
+        }
+    }
+  else if (highlight)
+    {
+      shell->highlight = g_memdup (highlight, sizeof (GdkRectangle));
+
+      gimp_display_shell_expose_full (shell);
     }
 }
Index: app/display/gimpdisplayshell.h
===================================================================
RCS file: /cvs/gnome/gimp/app/display/gimpdisplayshell.h,v
retrieving revision 1.85
diff -u -p -r1.85 gimpdisplayshell.h
--- app/display/gimpdisplayshell.h	13 Sep 2004 15:14:02 -0000	1.85
+++ app/display/gimpdisplayshell.h	30 Sep 2004 18:16:27 -0000
@@ -166,6 +166,8 @@ struct _GimpDisplayShell
   gint              scroll_start_y;
   gboolean          button_press_before_focus;
   guint32           last_motion_time;
+
+  GdkRectangle     *highlight;         /* in image coordinates, can be NULL   */
 };
 
 struct _GimpDisplayShellClass
@@ -229,6 +231,8 @@ void        gimp_display_shell_shrink_wr
 
 void        gimp_display_shell_selection_visibility  (GimpDisplayShell *shell,
                                                       GimpSelectionControl  control);
+void        gimp_display_shell_set_highlight         (GimpDisplayShell *shell,
+                                                      const GdkRectangle *highlight);
 
 
 #endif /* __GIMP_DISPLAY_SHELL_H__ */
Index: app/tools/gimpcroptool.c
===================================================================
RCS file: /cvs/gnome/gimp/app/tools/gimpcroptool.c,v
retrieving revision 1.197
diff -u -p -r1.197 gimpcroptool.c
--- app/tools/gimpcroptool.c	13 Sep 2004 15:14:03 -0000	1.197
+++ app/tools/gimpcroptool.c	30 Sep 2004 18:16:28 -0000
@@ -259,6 +259,8 @@ gimp_crop_tool_control (GimpTool       *
       break;
 
     case HALT:
+      gimp_display_shell_set_highlight (GIMP_DISPLAY_SHELL (gdisp->shell),
+                                        NULL);
       crop_response (NULL, GTK_RESPONSE_CANCEL, crop);
       break;
 
@@ -854,16 +856,25 @@ crop_tool_crop_image (GimpImage    *gima
 static void
 crop_recalc (GimpCropTool *crop)
 {
-  GimpTool *tool = GIMP_TOOL (crop);
+  GimpTool         *tool  = GIMP_TOOL (crop);
+  GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (tool->gdisp->shell);
+  GdkRectangle      rect;
 
   if (! tool->gdisp)
     return;
 
-  gimp_display_shell_transform_xy (GIMP_DISPLAY_SHELL (tool->gdisp->shell),
+  rect.x      = crop->x1;
+  rect.y      = crop->y1;
+  rect.width  = crop->x2 - crop->x1;
+  rect.height = crop->y2 - crop->y1;
+
+  gimp_display_shell_set_highlight (shell, &rect);
+
+  gimp_display_shell_transform_xy (shell,
                                    crop->x1, crop->y1,
                                    &crop->dx1, &crop->dy1,
                                    FALSE);
-  gimp_display_shell_transform_xy (GIMP_DISPLAY_SHELL (tool->gdisp->shell),
+  gimp_display_shell_transform_xy (shell,
                                    crop->x2, crop->y2,
                                    &crop->dx2, &crop->dy2,
                                    FALSE);
@@ -1116,12 +1127,16 @@ crop_response (GtkWidget    *widget,
                                              GIMP_CROP_MODE_RESIZE, FALSE);
         }
 
+      gimp_display_shell_set_highlight (GIMP_DISPLAY_SHELL (tool->gdisp->shell),
+                                        NULL);
+
       crop_tool_crop_image (tool->gdisp->gimage,
                             GIMP_CONTEXT (options),
                             crop->x1, crop->y1,
                             crop->x2, crop->y2,
                             options->layer_only,
                             (GimpCropMode) response_id);
+
       break;
 
     default:
