[gimp] plug-ins: imagemap, port to cairo



commit 8621807a9f848c226fef3dac2987f38c9cc2db04
Author: Mikael Magnusson <mikachu src gnome org>
Date:   Mon Feb 21 15:45:26 2011 +0100

    plug-ins: imagemap, port to cairo

 plug-ins/imagemap/imap_circle.c            |   18 ++--
 plug-ins/imagemap/imap_cmd_gimp_guides.c   |    2 +-
 plug-ins/imagemap/imap_cmd_insert_point.c  |    4 +-
 plug-ins/imagemap/imap_cmd_move.c          |    9 +-
 plug-ins/imagemap/imap_cmd_move_sash.c     |   11 +-
 plug-ins/imagemap/imap_cmd_select_region.c |   15 ++-
 plug-ins/imagemap/imap_edit_area_info.c    |    4 +-
 plug-ins/imagemap/imap_grid.c              |   62 +++++------
 plug-ins/imagemap/imap_grid.h              |    2 +-
 plug-ins/imagemap/imap_main.c              |  166 +++++++++++-----------------
 plug-ins/imagemap/imap_main.h              |   17 +--
 plug-ins/imagemap/imap_misc.c              |    4 +-
 plug-ins/imagemap/imap_misc.h              |    2 +-
 plug-ins/imagemap/imap_object.c            |   59 +++++++----
 plug-ins/imagemap/imap_object.h            |   10 +-
 plug-ins/imagemap/imap_polygon.c           |   12 +-
 plug-ins/imagemap/imap_preferences.c       |   29 ++++-
 plug-ins/imagemap/imap_preferences.h       |    4 +-
 plug-ins/imagemap/imap_preview.c           |   67 +++++------
 plug-ins/imagemap/imap_preview.h           |    8 +-
 plug-ins/imagemap/imap_rectangle.c         |   31 +++---
 21 files changed, 251 insertions(+), 285 deletions(-)
---
diff --git a/plug-ins/imagemap/imap_circle.c b/plug-ins/imagemap/imap_circle.c
index c31da7f..9854dfd 100644
--- a/plug-ins/imagemap/imap_circle.c
+++ b/plug-ins/imagemap/imap_circle.c
@@ -39,8 +39,8 @@
 static gboolean circle_is_valid(Object_t *obj);
 static Object_t *circle_clone(Object_t *obj);
 static void circle_assign(Object_t *obj, Object_t *des);
-static void circle_draw(Object_t* obj, GdkWindow *window, GdkGC* gc);
-static void circle_draw_sashes(Object_t* obj, GdkWindow *window, GdkGC* gc);
+static void circle_draw(Object_t* obj, cairo_t *cr);
+static void circle_draw_sashes(Object_t* obj, cairo_t *cr);
 static MoveSashFunc_t circle_near_sash(Object_t *obj, gint x, gint y);
 static gboolean circle_point_is_on(Object_t *obj, gint x, gint y);
 static void circle_get_dimensions(Object_t *obj, gint *x, gint *y,
@@ -128,20 +128,20 @@ circle_assign(Object_t *obj, Object_t *des)
 }
 
 static void
-circle_draw(Object_t *obj, GdkWindow *window, GdkGC *gc)
+circle_draw(Object_t *obj, cairo_t *cr)
 {
    Circle_t *circle = ObjectToCircle(obj);
-   draw_circle(window, gc, FALSE, circle->x, circle->y, circle->r);
+   draw_circle(cr, circle->x, circle->y, circle->r);
 }
 
 static void
-circle_draw_sashes(Object_t *obj, GdkWindow *window, GdkGC *gc)
+circle_draw_sashes(Object_t *obj, cairo_t *cr)
 {
    Circle_t *circle = ObjectToCircle(obj);
-   draw_sash(window, gc, circle->x - circle->r, circle->y - circle->r);
-   draw_sash(window, gc, circle->x + circle->r, circle->y - circle->r);
-   draw_sash(window, gc, circle->x - circle->r, circle->y + circle->r);
-   draw_sash(window, gc, circle->x + circle->r, circle->y + circle->r);
+   draw_sash(cr, circle->x - circle->r, circle->y - circle->r);
+   draw_sash(cr, circle->x + circle->r, circle->y - circle->r);
+   draw_sash(cr, circle->x - circle->r, circle->y + circle->r);
+   draw_sash(cr, circle->x + circle->r, circle->y + circle->r);
 }
 
 static gint sash_x;
diff --git a/plug-ins/imagemap/imap_cmd_gimp_guides.c b/plug-ins/imagemap/imap_cmd_gimp_guides.c
index abc72f2..309567c 100644
--- a/plug-ins/imagemap/imap_cmd_gimp_guides.c
+++ b/plug-ins/imagemap/imap_cmd_gimp_guides.c
@@ -132,7 +132,7 @@ gimp_guides_ok_cb(gpointer data)
    }
 
    subcommand_end();
-   redraw_preview();
+   preview_redraw();
 }
 
 static GimpGuidesDialog_t*
diff --git a/plug-ins/imagemap/imap_cmd_insert_point.c b/plug-ins/imagemap/imap_cmd_insert_point.c
index 168b477..3cf0edb 100644
--- a/plug-ins/imagemap/imap_cmd_insert_point.c
+++ b/plug-ins/imagemap/imap_cmd_insert_point.c
@@ -78,7 +78,7 @@ insert_point_command_execute(Command_t *parent)
                                       command->edge);
       command->position = command->edge;
    }
-   redraw_preview();
+   preview_redraw();
 
    return CMD_APPEND;
 }
@@ -92,5 +92,5 @@ insert_point_command_undo(Command_t *parent)
 
    g_free(p->data);
    polygon->points = g_list_remove_link(polygon->points, p);
-   redraw_preview();            /* Fix me! */
+   preview_redraw();            /* Fix me! */
 }
diff --git a/plug-ins/imagemap/imap_cmd_move.c b/plug-ins/imagemap/imap_cmd_move.c
index 0f8cb1c..e89a196 100644
--- a/plug-ins/imagemap/imap_cmd_move.c
+++ b/plug-ins/imagemap/imap_cmd_move.c
@@ -103,8 +103,6 @@ button_motion(GtkWidget *widget, GdkEventMotion *event, gpointer data)
    if (command->moved_first_time) {
       command->moved_first_time = FALSE;
       command->cursor = preview_set_cursor(command->preview, GDK_FLEUR);
-      gdk_gc_set_function(command->preferences->normal_gc, GDK_XOR);
-      gdk_gc_set_function(command->preferences->selected_gc, GDK_XOR);
       hide_url();
    }
 
@@ -118,14 +116,15 @@ button_motion(GtkWidget *widget, GdkEventMotion *event, gpointer data)
       dy = command->image_height - command->obj_height - command->obj_y;
 
    if (dx || dy) {
+
       command->start_x = get_real_coord((gint) event->x);
       command->start_y = get_real_coord((gint) event->y);
       command->obj_x += dx;
       command->obj_y += dy;
 
-      object_draw(obj, gtk_widget_get_window (widget));
       object_move(obj, dx, dy);
-      object_draw(obj, gtk_widget_get_window (widget));
+
+      preview_redraw ();
    }
 }
 
@@ -141,8 +140,6 @@ button_release(GtkWidget *widget, GdkEventButton *event, gpointer data)
 
    if (!command->moved_first_time) {
       preview_set_cursor(command->preview, command->cursor);
-      gdk_gc_set_function(command->preferences->normal_gc, GDK_COPY);
-      gdk_gc_set_function(command->preferences->selected_gc, GDK_COPY);
       show_url();
    }
    command->obj_x -= command->obj_start_x;
diff --git a/plug-ins/imagemap/imap_cmd_move_sash.c b/plug-ins/imagemap/imap_cmd_move_sash.c
index 6131e8c..b9ce0e0 100644
--- a/plug-ins/imagemap/imap_cmd_move_sash.c
+++ b/plug-ins/imagemap/imap_cmd_move_sash.c
@@ -105,10 +105,10 @@ sash_move(GtkWidget *widget, GdkEventMotion *event, gpointer data)
    command->x = x;
    command->y = y;
 
-   object_draw(obj, gtk_widget_get_window (widget));
    command->sash_func(obj, dx, dy);
    object_emit_geometry_signal(obj);
-   object_draw(obj, gtk_widget_get_window (widget));
+
+   preview_redraw ();
 }
 
 static void
@@ -123,8 +123,8 @@ sash_end(GtkWidget *widget, GdkEventButton *event, gpointer data)
                                         sash_end, data);
    if (obj->class->normalize)
       object_normalize(obj);
-   gdk_gc_set_function(get_preferences()->selected_gc, GDK_COPY);
-   preview_thaw();
+   preview_unset_tmp_obj(command->obj);
+   preview_redraw();
    show_url();
 }
 
@@ -134,12 +134,11 @@ move_sash_command_execute(Command_t *parent)
    MoveSashCommand_t *command = (MoveSashCommand_t*) parent;
 
    hide_url();
-   preview_freeze();
    g_signal_connect(command->widget, "button-release-event",
                     G_CALLBACK (sash_end), command);
    g_signal_connect(command->widget, "motion-notify-event",
                     G_CALLBACK (sash_move), command);
-   gdk_gc_set_function(get_preferences()->selected_gc, GDK_XOR);
+   preview_set_tmp_obj(command->obj);
 
    return CMD_APPEND;
 }
diff --git a/plug-ins/imagemap/imap_cmd_select_region.c b/plug-ins/imagemap/imap_cmd_select_region.c
index 876ed38..adbec9ce 100644
--- a/plug-ins/imagemap/imap_cmd_select_region.c
+++ b/plug-ins/imagemap/imap_cmd_select_region.c
@@ -83,13 +83,14 @@ select_motion(GtkWidget *widget, GdkEventMotion *event, gpointer data)
    SelectRegionCommand_t *command = (SelectRegionCommand_t*) data;
    Object_t *obj = command->obj;
    Rectangle_t *rectangle = ObjectToRectangle(obj);
+
    gint x = get_real_coord((gint) event->x);
    gint y = get_real_coord((gint) event->y);
 
-   object_draw(obj, gtk_widget_get_window (widget));
    rectangle->width = x - rectangle->x;
    rectangle->height = y - rectangle->y;
-   object_draw(obj, gtk_widget_get_window (widget));
+
+   preview_redraw ();
 }
 
 static void
@@ -106,9 +107,7 @@ select_release(GtkWidget *widget, GdkEventButton *event, gpointer data)
    g_signal_handlers_disconnect_by_func(widget,
                                         select_release, data);
 
-   object_draw(obj, gtk_widget_get_window (widget));
    object_normalize(obj);
-   gdk_gc_set_function(get_preferences()->normal_gc, GDK_COPY);
 
    id = object_list_add_select_cb(command->list, select_one_object, command);
    count = object_list_select_region(command->list, rectangle->x, rectangle->y,
@@ -121,7 +120,9 @@ select_release(GtkWidget *widget, GdkEventButton *event, gpointer data)
       if (command->unselect_command->sub_commands)
          command_list_add(&command->parent);
    }
-   object_unref(obj);
+   preview_unset_tmp_obj (command->obj);
+
+   preview_redraw ();
 }
 
 static CmdExecuteValue_t
@@ -130,12 +131,12 @@ select_region_command_execute(Command_t *parent)
    SelectRegionCommand_t *command = (SelectRegionCommand_t*) parent;
 
    command->obj = create_rectangle(command->x, command->y, 0, 0);
+   preview_set_tmp_obj (command->obj);
+
    g_signal_connect(command->widget, "button-release-event",
                     G_CALLBACK (select_release), command);
    g_signal_connect(command->widget, "motion-notify-event",
                     G_CALLBACK (select_motion), command);
 
-   gdk_gc_set_function(get_preferences()->normal_gc, GDK_XOR);
-
    return CMD_IGNORE;
 }
diff --git a/plug-ins/imagemap/imap_edit_area_info.c b/plug-ins/imagemap/imap_edit_area_info.c
index 9c965be..d71952b 100644
--- a/plug-ins/imagemap/imap_edit_area_info.c
+++ b/plug-ins/imagemap/imap_edit_area_info.c
@@ -394,7 +394,7 @@ edit_area_apply_cb(gpointer data)
    update_shape(obj);
 
    if (object_was_changed(param))
-      redraw_preview();
+      preview_redraw();
 }
 
 static void
@@ -429,7 +429,7 @@ edit_area_cancel_cb(gpointer data)
    object_unref(dialog->clone);
 
    if (changed)
-      redraw_preview();
+      preview_redraw();
 }
 
 static void
diff --git a/plug-ins/imagemap/imap_grid.c b/plug-ins/imagemap/imap_grid.c
index 1a77b02..9a222bf 100644
--- a/plug-ins/imagemap/imap_grid.c
+++ b/plug-ins/imagemap/imap_grid.c
@@ -60,7 +60,6 @@ typedef struct {
 } GridDialog_t;
 
 
-static GdkGC *grid_gc;
 static gboolean grid_snap = FALSE;
 static gint grid_width = 15;
 static gint grid_height = 15;
@@ -88,7 +87,7 @@ grid_settings_ok_cb(gpointer data)
       grid_snap = new_snap;
       menu_check_grid(grid_snap);
    }
-   redraw_preview();
+   preview_redraw();
 }
 
 static void
@@ -109,7 +108,7 @@ type_toggled_cb(GtkWidget *widget, gpointer data)
    if (gtk_widget_get_state (widget) & GTK_STATE_SELECTED)
      {
        grid_type = GPOINTER_TO_INT (data);
-       redraw_preview();
+       preview_redraw();
      }
 }
 
@@ -118,7 +117,7 @@ toggle_preview_cb(GtkWidget *widget, GridDialog_t *param)
 {
    param->enable_preview =
       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
-   redraw_preview();
+   preview_redraw();
 }
 
 static void
@@ -127,7 +126,7 @@ grid_assign_value(GtkWidget *widget, gpointer data, gint *value)
    GridDialog_t *dialog = (GridDialog_t*) data;
    if (dialog->enable_preview) {
       *value = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
-      redraw_preview();         /* Fix me! */
+      preview_redraw();         /* Fix me! */
    }
 }
 
@@ -326,56 +325,47 @@ do_grid_settings_dialog(void)
 }
 
 static void
-draw_lines(GdkWindow *window, GdkGC* gc, gint width, gint height)
+draw_lines(cairo_t *cr, gint width, gint height)
 {
    gint x, y;
+   gdouble dash = 4.;
 
-   for (x = grid_left; x < width; x += grid_width)
-      draw_line(window, grid_gc, x, 1, x, height);
-   for (y = grid_top; y < height; y += grid_height)
-      draw_line(window, grid_gc, 1, y, width, y);
+   cairo_set_dash (cr, &dash, 1, 0.);
+   for (x = grid_left % grid_width; x < width; x += grid_width)
+      draw_line(cr, x, 1, x, height);
+   for (y = grid_top % grid_height; y < height; y += grid_height)
+      draw_line(cr, 1, y, width, y);
 }
 
 static void
-draw_crosses(GdkWindow *window, GdkGC* gc, gint width, gint height)
+draw_crosses(cairo_t *cr, gint width, gint height)
 {
    gint x, y;
-
-   for (x = grid_left; x < width; x += grid_width) {
-      for (y = grid_top; y < height; y += grid_height) {
-         draw_line(window, gc, x - 3, y, x + 3, y);
-         draw_line(window, gc, x, y - 3, x, y + 3);
-      }
-   }
+   gdouble dash[4] = { 7., grid_height - 7., 7., grid_width - 7. };
+
+   cairo_set_dash (cr, dash, 2, 4.5 - grid_top);
+   for (x = grid_left % grid_width; x < width; x += grid_width)
+      draw_line(cr, x, 1, x, height);
+   cairo_set_dash (cr, dash+2, 2, 4.5 - grid_left);
+   for (y = grid_top % grid_height; y < height; y += grid_height)
+      draw_line(cr, 1, y, width, y);
 }
 
 void
-draw_grid(GtkWidget *preview)
+draw_grid(cairo_t *cr, gint width, gint height)
 {
   if (grid_snap && grid_type != GRID_HIDDEN)
     {
-      gint width = preview_get_width(preview);
-      gint height = preview_get_height(preview);
-
-      if (!grid_gc)
-        {
-          grid_gc = gdk_gc_new(gtk_widget_get_window (preview));
-
-          gdk_gc_set_line_attributes(grid_gc, 1, GDK_LINE_ON_OFF_DASH,
-                                     GDK_CAP_BUTT, GDK_JOIN_BEVEL);
-        }
-
+      cairo_save (cr);
       if (grid_type == GRID_LINES)
         {
-          draw_lines(gtk_widget_get_window (preview), grid_gc, width, height);
+          draw_lines(cr, width, height);
         }
       else
         {
-          GtkStyle *style = gtk_widget_get_style (preview);
-
-          draw_crosses(gtk_widget_get_window (preview), style->black_gc, width,
-                       height);
+          draw_crosses(cr, width, height);
         }
+      cairo_restore (cr);
     }
 }
 
@@ -383,7 +373,7 @@ void
 toggle_grid(void)
 {
    grid_snap = !grid_snap;
-   redraw_preview();
+   preview_redraw();
 }
 
 static gint
diff --git a/plug-ins/imagemap/imap_grid.h b/plug-ins/imagemap/imap_grid.h
index 5718255..68966d3 100644
--- a/plug-ins/imagemap/imap_grid.h
+++ b/plug-ins/imagemap/imap_grid.h
@@ -24,7 +24,7 @@
 #define _IMAP_GRID_H
 
 void do_grid_settings_dialog (void);
-void draw_grid (GtkWidget *preview);
+void draw_grid (cairo_t *cr, gint width, gint height);
 void toggle_grid (void);
 void round_to_grid (gint *x, gint *y);
 
diff --git a/plug-ins/imagemap/imap_main.c b/plug-ins/imagemap/imap_main.c
index 358eac1..058f5ba 100644
--- a/plug-ins/imagemap/imap_main.c
+++ b/plug-ins/imagemap/imap_main.c
@@ -204,8 +204,8 @@ get_preferences(void)
 static void
 init_preferences(void)
 {
-  GdkColormap *colormap = gdk_drawable_get_colormap(gtk_widget_get_window (_dlg));
-  ColorSelData_t *colors = &_preferences.colors;
+   GdkColormap *colormap = gdk_drawable_get_colormap(gtk_widget_get_window (_dlg));
+   ColorSelData_t *colors = &_preferences.colors;
 
    colors->normal_fg.red = 0;
    colors->normal_fg.green = 0xFFFF;
@@ -223,6 +223,14 @@ init_preferences(void)
    colors->selected_bg.green = 0;
    colors->selected_bg.blue = 0xFFFF;
 
+   colors->interactive_fg.red = 0xFFFF;
+   colors->interactive_fg.green = 0;
+   colors->interactive_fg.blue = 0xFFFF;
+
+   colors->interactive_bg.red = 0xFFFF;
+   colors->interactive_bg.green = 0xFFFF;
+   colors->interactive_bg.blue = 0;
+
    preferences_load(&_preferences);
 
    gdk_colormap_alloc_color(colormap, &colors->normal_fg, FALSE, TRUE);
@@ -230,20 +238,6 @@ init_preferences(void)
    gdk_colormap_alloc_color(colormap, &colors->selected_fg, FALSE, TRUE);
    gdk_colormap_alloc_color(colormap, &colors->selected_bg, FALSE, TRUE);
 
-   _preferences.normal_gc = gdk_gc_new(gtk_widget_get_window (_preview->preview));
-   _preferences.selected_gc = gdk_gc_new(gtk_widget_get_window (_preview->preview));
-
-   gdk_gc_set_line_attributes(_preferences.normal_gc, 1, GDK_LINE_DOUBLE_DASH,
-                              GDK_CAP_BUTT, GDK_JOIN_BEVEL);
-   gdk_gc_set_line_attributes(_preferences.selected_gc, 1,
-                              GDK_LINE_DOUBLE_DASH, GDK_CAP_BUTT,
-                              GDK_JOIN_BEVEL);
-
-   gdk_gc_set_foreground(_preferences.normal_gc, &colors->normal_fg);
-   gdk_gc_set_background(_preferences.normal_gc, &colors->normal_bg);
-   gdk_gc_set_foreground(_preferences.selected_gc, &colors->selected_fg);
-   gdk_gc_set_background(_preferences.selected_gc, &colors->selected_bg);
-
    mru_set_size(_mru, _preferences.mru_size);
    command_list_set_undo_level(_preferences.undo_levels);
 }
@@ -309,76 +303,44 @@ get_real_coord(gint coord)
 }
 
 void
-draw_line(GdkWindow *window, GdkGC *gc, gint x1, gint y1, gint x2, gint y2)
+draw_line(cairo_t *cr, gint x1, gint y1, gint x2, gint y2)
 {
-   gdk_draw_line(window, gc, ZOOMED(x1), ZOOMED(y1), ZOOMED(x2), ZOOMED(y2));
+   cairo_move_to (cr, ZOOMED (x1) + .5, ZOOMED (y1) + .5);
+   cairo_line_to (cr, ZOOMED (x2) + .5, ZOOMED (y2) + .5);
+   cairo_stroke (cr);
 }
 
 void
-draw_rectangle(GdkWindow *window, GdkGC *gc, gint filled, gint x, gint y,
+draw_rectangle(cairo_t *cr, gboolean filled, gint x, gint y,
                gint width, gint height)
 {
-   gdk_draw_rectangle(window, gc, filled, ZOOMED(x), ZOOMED(y),
-                      ZOOMED(width), ZOOMED(height));
-}
-
-void
-draw_arc(GdkWindow *window, GdkGC *gc, gint filled, gint x, gint y,
-         gint width, gint height, gint angle1, gint angle2)
-{
-   gdk_draw_arc(window, gc, filled, ZOOMED(x), ZOOMED(y),
-                ZOOMED(width), ZOOMED(height), angle1, angle2);
+   cairo_rectangle (cr, ZOOMED (x) + (filled ? 0. : .5),
+                        ZOOMED (y) + (filled ? 0. : .5),
+                    ZOOMED (width), ZOOMED (height));
+   if (filled)
+      cairo_fill (cr);
+   else
+      cairo_stroke (cr);
 }
 
 void
-draw_circle(GdkWindow *window, GdkGC *gc, gint filled, gint x, gint y, gint r)
+draw_circle(cairo_t *cr, gint x, gint y, gint r)
 {
-   draw_arc(window, gc, filled, x - r, y - r, 2 * r, 2 * r, 0, 360 * 64);
+   cairo_arc (cr, ZOOMED (x), ZOOMED (y), ZOOMED (r), 0., 2 * M_PI);
+   cairo_stroke (cr);
 }
 
 void
-draw_polygon(GdkWindow *window, GdkGC *gc, GList *list)
+draw_polygon(cairo_t *cr, GList *list)
 {
-   gint       npoints = g_list_length(list);
-   GdkPoint  *points = g_new(GdkPoint, npoints);
-   GdkPoint  *des = points;
    GList     *p;
 
-   for (p = list; p; p = p->next, des++) {
+   for (p = list; p; p = p->next) {
       GdkPoint *src = (GdkPoint*) p->data;
-      des->x = ZOOMED(src->x);
-      des->y = ZOOMED(src->y);
+      cairo_line_to (cr, ZOOMED (src->x) + .5, ZOOMED (src->y) + .5);
    }
-   gdk_draw_polygon(window, gc, FALSE, points, npoints);
-   g_free(points);
-}
-
-static gboolean _preview_redraw_blocked = FALSE;
-static gboolean _pending_redraw = FALSE;
-
-void
-preview_freeze(void)
-{
-   _preview_redraw_blocked = TRUE;
-}
-
-void
-preview_thaw(void)
-{
-   _preview_redraw_blocked = FALSE;
-   if (_pending_redraw) {
-      _pending_redraw = FALSE;
-      redraw_preview();
-   }
-}
-
-void
-redraw_preview(void)
-{
-   if (_preview_redraw_blocked)
-      _pending_redraw = TRUE;
-   else
-      preview_redraw(_preview);
+   cairo_close_path (cr);
+   cairo_stroke (cr);
 }
 
 void
@@ -390,6 +352,12 @@ set_preview_color (GtkRadioAction *action, GtkRadioAction *current,
 }
 
 void
+preview_redraw(void)
+{
+  gtk_widget_queue_draw(_preview->preview);
+}
+
+void
 set_zoom_factor (GtkRadioAction *action, GtkRadioAction *current,
                  gpointer user_data)
 {
@@ -625,10 +593,9 @@ do_zoom_out(void)
 }
 
 void
-draw_shapes(GtkWidget *preview)
+draw_shapes(cairo_t *cr)
 {
-  if (!_preview_redraw_blocked)
-    object_list_draw(_shapes, gtk_widget_get_window (preview));
+   object_list_draw(_shapes, cr);
 }
 
 static void
@@ -685,7 +652,7 @@ close_current(void)
    clear_map_info();
    main_set_title(NULL);
    set_all_sensitivities();
-   redraw_preview();
+   preview_redraw();
    object_list_clear_changed(_shapes);
    command_list_remove_all();
 }
@@ -719,21 +686,19 @@ do_quit(void)
 void
 do_undo(void)
 {
-   preview_freeze();
    selection_freeze(_selection);
    last_command_undo();
    selection_thaw(_selection);
-   preview_thaw();
+   preview_redraw();
 }
 
 void
 do_redo(void)
 {
-   preview_freeze();
    selection_freeze(_selection);
    last_command_redo();
    selection_thaw(_selection);
-   preview_thaw();
+   preview_redraw();
 }
 
 void
@@ -900,7 +865,7 @@ do_image_size_changed_dialog(void)
        object_list_resize(_shapes, per_x, per_y);
      }
 
-   preview_thaw();
+   preview_redraw();
    gtk_widget_destroy (dialog);
 }
 
@@ -917,7 +882,6 @@ really_load(gpointer data)
       _map_info.map_format = CSIM;
       if (_image_width != _map_info.old_image_width ||
           _image_height != _map_info.old_image_height) {
-         preview_freeze();
          do_image_size_changed_dialog();
       }
    } else if (load_ncsa(filename)) {
@@ -936,7 +900,7 @@ really_load(gpointer data)
    selection_thaw(_selection);
    main_set_title(filename);
    object_list_clear_changed(_shapes);
-   redraw_preview();
+   preview_redraw();
 }
 
 void
@@ -1027,13 +991,9 @@ move_sash_selected_objects(gint dx, gint dy, gboolean fast)
       dy *= 5;
    }
 
-   gdk_gc_set_function(_preferences.normal_gc, GDK_XOR);
-   gdk_gc_set_function(_preferences.selected_gc, GDK_XOR);
-   object_list_draw_selected(_shapes, gtk_widget_get_window (_preview->preview));
    object_list_move_sash_selected(_shapes, dx, dy);
-   object_list_draw_selected(_shapes, gtk_widget_get_window (_preview->preview));
-   gdk_gc_set_function(_preferences.normal_gc, GDK_COPY);
-   gdk_gc_set_function(_preferences.selected_gc, GDK_COPY);
+
+   preview_redraw ();
 }
 
 static void
@@ -1046,13 +1006,9 @@ move_selected_objects(gint dx, gint dy, gboolean fast)
    _dx += dx;
    _dy += dy;
 
-   gdk_gc_set_function(_preferences.normal_gc, GDK_XOR);
-   gdk_gc_set_function(_preferences.selected_gc, GDK_XOR);
-   object_list_draw_selected(_shapes, gtk_widget_get_window (_preview->preview));
    object_list_move_selected(_shapes, dx, dy);
-   object_list_draw_selected(_shapes, gtk_widget_get_window (_preview->preview));
-   gdk_gc_set_function(_preferences.normal_gc, GDK_COPY);
-   gdk_gc_set_function(_preferences.selected_gc, GDK_COPY);
+
+   preview_redraw ();
 }
 
 static gboolean
@@ -1067,7 +1023,7 @@ key_timeout_cb(gpointer data)
       _dx = _dy = 0;
       break;
    }
-   preview_thaw();
+   preview_redraw();
    return FALSE;
 }
 
@@ -1079,34 +1035,34 @@ key_press_cb(GtkWidget *widget, GdkEventKey *event)
    gboolean ctrl = event->state & GDK_CONTROL_MASK;
    Command_t *command;
 
-   preview_freeze();
    if (_timeout)
       g_source_remove(_timeout);
+   _timeout = 0;
 
    switch (event->keyval) {
    case GDK_Left:
-          if (ctrl)
+      if (ctrl)
          move_sash_selected_objects(-1, 0, shift);
       else
          move_selected_objects(-1, 0, shift);
       handled = TRUE;
       break;
    case GDK_Right:
-          if (ctrl)
+      if (ctrl)
          move_sash_selected_objects(1, 0, shift);
       else
          move_selected_objects(1, 0, shift);
       handled = TRUE;
       break;
    case GDK_Up:
-          if (ctrl)
+      if (ctrl)
          move_sash_selected_objects(0, -1, shift);
       else
          move_selected_objects(0, -1, shift);
       handled = TRUE;
       break;
    case GDK_Down:
-          if (ctrl)
+      if (ctrl)
          move_sash_selected_objects(0, 1, shift);
       else
          move_selected_objects(0, 1, shift);
@@ -1138,13 +1094,13 @@ key_release_cb(GtkWidget *widget, GdkEventKey *event)
 static void
 geometry_changed(Object_t *obj, gpointer data)
 {
-   redraw_preview();
+   preview_redraw();
 }
 
 static void
 data_changed(Object_t *obj, gpointer data)
 {
-   redraw_preview();
+   preview_redraw();
    set_all_sensitivities();
 }
 
@@ -1310,10 +1266,14 @@ dialog(GimpDrawable *drawable)
    gtk_box_pack_start(GTK_BOX(hbox), tools, FALSE, FALSE, 0);
 
    _preview = make_preview(drawable);
-   add_preview_motion_event(_preview, G_CALLBACK (preview_move));
-   add_enter_notify_event(_preview, G_CALLBACK (preview_enter));
-   add_leave_notify_event(_preview, G_CALLBACK (preview_leave));
-   add_preview_button_press_event(_preview, G_CALLBACK (button_press));
+   g_signal_connect(_preview->preview, "motion-notify-event",
+                    G_CALLBACK(preview_move), NULL);
+   g_signal_connect(_preview->preview, "enter-notify-event",
+                    G_CALLBACK(preview_enter), NULL);
+   g_signal_connect(_preview->preview, "leave-notify-event",
+                    G_CALLBACK(preview_leave), NULL);
+   g_signal_connect(_preview->preview, "button-press-event",
+                    G_CALLBACK(button_press), NULL);
    gtk_container_add(GTK_CONTAINER(hbox), _preview->window);
 
    object_list_add_geometry_cb(_shapes, geometry_changed, NULL);
diff --git a/plug-ins/imagemap/imap_main.h b/plug-ins/imagemap/imap_main.h
index 2d8307f..6c05bbb 100644
--- a/plug-ins/imagemap/imap_main.h
+++ b/plug-ins/imagemap/imap_main.h
@@ -26,6 +26,7 @@
 #include "imap_mru.h"
 #include "imap_object.h"
 #include "imap_preferences.h"
+#include "imap_preview.h"
 
 #define PLUG_IN_PROC   "plug-in-imagemap"
 #define PLUG_IN_BINARY "imagemap"
@@ -65,15 +66,13 @@ void main_toolbar_set_grid(gboolean active);
 
 void set_zoom(gint zoom_factor);
 gint get_real_coord(gint coord);
-void draw_line(GdkWindow *window, GdkGC *gc, gint x1, gint y1, gint x2,
+void draw_line(cairo_t *cr, gint x1, gint y1, gint x2,
                gint y2);
-void draw_rectangle(GdkWindow *window, GdkGC *gc, gint filled, gint x, gint y,
+void draw_rectangle(cairo_t *cr, gboolean filled, gint x, gint y,
                     gint width, gint height);
-void draw_arc(GdkWindow *window, GdkGC *gc, gint filled, gint x, gint y,
-              gint width, gint height, gint angle1, gint angle2);
-void draw_circle(GdkWindow *window, GdkGC *gc, gint filled, gint x, gint y,
+void draw_circle(cairo_t *cr, gint x, gint y,
                  gint r);
-void draw_polygon(GdkWindow *window, GdkGC *gc, GList *list);
+void draw_polygon(cairo_t *cr, GList *list);
 
 const char *get_filename(void);
 
@@ -84,11 +83,7 @@ void select_shape(GtkWidget *widget, GdkEventButton *event);
 void edit_shape(gint x, gint y);
 
 void do_popup_menu(GdkEventButton *event);
-void draw_shapes(GtkWidget *preview);
-
-void redraw_preview(void);
-void preview_freeze(void);
-void preview_thaw(void);
+void draw_shapes(cairo_t *cr);
 
 void show_url(void);
 void hide_url(void);
diff --git a/plug-ins/imagemap/imap_misc.c b/plug-ins/imagemap/imap_misc.c
index b99d4c8..c72177e 100644
--- a/plug-ins/imagemap/imap_misc.c
+++ b/plug-ins/imagemap/imap_misc.c
@@ -38,9 +38,9 @@ set_sash_size(gboolean double_size)
 }
 
 void
-draw_sash(GdkWindow *window, GdkGC *gc, gint x, gint y)
+draw_sash(cairo_t *cr, gint x, gint y)
 {
-   draw_rectangle(window, gc, TRUE, x - _sash_size / 2, y - _sash_size / 2,
+   draw_rectangle(cr, TRUE, x - _sash_size / 2, y - _sash_size / 2,
                   _sash_size, _sash_size);
 }
 
diff --git a/plug-ins/imagemap/imap_misc.h b/plug-ins/imagemap/imap_misc.h
index 6f7642c..343a11f 100644
--- a/plug-ins/imagemap/imap_misc.h
+++ b/plug-ins/imagemap/imap_misc.h
@@ -24,7 +24,7 @@
 #define _IMAP_MISC_H
 
 void set_sash_size(gboolean double_size);
-void draw_sash(GdkWindow *window, GdkGC *gc, gint x, gint y);
+void draw_sash(cairo_t *cr, gint x, gint y);
 gboolean near_sash(gint sash_x, gint sash_y, gint x, gint y);
 
 #endif /* _IMAP_MISC_H */
diff --git a/plug-ins/imagemap/imap_object.c b/plug-ins/imagemap/imap_object.c
index 127bbab..786dc02 100644
--- a/plug-ins/imagemap/imap_object.c
+++ b/plug-ins/imagemap/imap_object.c
@@ -248,14 +248,35 @@ object_assign(Object_t *obj, Object_t *des)
 }
 
 void
-object_draw(Object_t *obj, GdkWindow *window)
+object_draw(Object_t *obj, cairo_t *cr)
 {
    PreferencesData_t *preferences = get_preferences();
-   GdkGC *gc = (obj->selected) ? preferences->selected_gc
-      : preferences->normal_gc;
-   obj->class->draw(obj, window, gc);
+   ColorSelData_t *colors = &preferences->colors;
+   GdkColor *fg, *bg;
+   gdouble dash = 4.;
+
+   if (obj->selected & 4) {
+      fg = &colors->interactive_fg;
+      bg = &colors->interactive_bg;
+      obj->selected &= ~4;
+   } else if (obj->selected) {
+      fg = &colors->selected_fg;
+      bg = &colors->selected_bg;
+   } else {
+      fg = &colors->normal_fg;
+      bg = &colors->normal_bg;
+   }
+   
+   cairo_save (cr);
+   gdk_cairo_set_source_color (cr, bg);
+   obj->class->draw(obj, cr);
+   gdk_cairo_set_source_color (cr, fg);
+   cairo_set_dash (cr, &dash, 1, 0.);
+   obj->class->draw(obj, cr);
+
    if (obj->selected && preferences->show_area_handle)
-      obj->class->draw_sashes(obj, window, gc);
+      obj->class->draw_sashes(obj, cr);
+   cairo_restore (cr);
 }
 
 void
@@ -430,9 +451,9 @@ button_motion(GtkWidget *widget, GdkEventMotion *event,
 
    round_to_grid(&x, &y);
 
-   object_draw(factory->obj, gtk_widget_get_window (widget));
    factory->set_xy(factory->obj, event->state, x, y);
-   object_draw(factory->obj, gtk_widget_get_window (widget));
+
+   preview_redraw ();
 
    return FALSE;
 }
@@ -462,33 +483,31 @@ object_on_button_press(GtkWidget *widget, GdkEventButton *event, gpointer data)
                if (preferences->prompt_for_area_info)
                   object_edit(obj, FALSE);
             } else {
-              object_draw(obj, gtk_widget_get_window (widget));
-              object_unref(obj);
+               object_unref(obj);
             }
-            gdk_gc_set_function(preferences->normal_gc, GDK_COPY);
+            preview_unset_tmp_obj (obj);
+            preview_redraw ();
             obj = NULL;
             main_clear_dimension();
          }
       } else if (event->button == 3) {
-           object_draw(obj, gtk_widget_get_window (widget));
          if (!factory->cancel || factory->cancel(event, obj)) {
             g_signal_handlers_disconnect_by_func(widget,
                                                  button_motion,
                                                  factory);
             object_unref(obj);
-            gdk_gc_set_function(preferences->normal_gc, GDK_COPY);
+            preview_unset_tmp_obj (obj);
+            preview_redraw ();
             obj = NULL;
             main_clear_dimension();
-         } else {
-           object_draw(obj, gtk_widget_get_window (widget));
          }
+         return TRUE;
       }
    } else {
       if (event->button == 1) {
          factory = ((ObjectFactory_t*(*)(guint)) data)(event->state);
          obj = object_factory_create_object(factory, x, y);
-
-         gdk_gc_set_function(preferences->normal_gc, GDK_XOR);
+         preview_set_tmp_obj (obj);
 
          g_signal_connect(widget, "motion-notify-event",
                           G_CALLBACK(button_motion), factory);
@@ -582,21 +601,21 @@ object_list_update(ObjectList_t *list, Object_t *object)
 }
 
 void
-object_list_draw(ObjectList_t *list, GdkWindow *window)
+object_list_draw(ObjectList_t *list, cairo_t *cr)
 {
    GList *p;
    for (p = list->list; p; p = p->next)
-      object_draw((Object_t*) p->data, window);
+      object_draw((Object_t*) p->data, cr);
 }
 
 void
-object_list_draw_selected(ObjectList_t *list, GdkWindow *window)
+object_list_draw_selected(ObjectList_t *list, cairo_t *cr)
 {
    GList *p;
    for (p = list->list; p; p = p->next) {
       Object_t *obj = (Object_t*) p->data;
       if (obj->selected)
-         object_draw(obj, window);
+         object_draw(obj, cr);
    }
 }
 
diff --git a/plug-ins/imagemap/imap_object.h b/plug-ins/imagemap/imap_object.h
index e5f97c9..a33dff1 100644
--- a/plug-ins/imagemap/imap_object.h
+++ b/plug-ins/imagemap/imap_object.h
@@ -61,8 +61,8 @@ struct ObjectClass_t {
    Object_t* (*clone)(Object_t *obj);
    void (*assign)(Object_t *obj, Object_t *des);
    void (*normalize)(Object_t *obj);
-   void (*draw)(Object_t *obj, GdkWindow *window, GdkGC* gc);
-   void (*draw_sashes)(Object_t *obj, GdkWindow *window, GdkGC* gc);
+   void (*draw)(Object_t *obj, cairo_t *cr);
+   void (*draw_sashes)(Object_t *obj, cairo_t *cr);
    MoveSashFunc_t (*near_sash)(Object_t *obj, gint x, gint y);
    gboolean (*point_is_on)(Object_t *obj, gint x, gint y);
    void (*get_dimensions)(Object_t *obj, gint *x, gint *y, gint *width,
@@ -87,7 +87,7 @@ void object_unref(Object_t *obj);
 Object_t* object_init(Object_t *obj, ObjectClass_t *class);
 Object_t* object_clone(Object_t *obj);
 Object_t* object_assign(Object_t *src, Object_t *des);
-void object_draw(Object_t *obj, GdkWindow *window);
+void object_draw(Object_t *obj, cairo_t *cr);
 void object_edit(Object_t *obj, gboolean add);
 void object_select(Object_t *obj);
 void object_unselect(Object_t *obj);
@@ -171,8 +171,8 @@ void object_list_insert(ObjectList_t *list, gint position, Object_t *object);
 void object_list_remove(ObjectList_t *list, Object_t *object);
 void object_list_remove_link(ObjectList_t *list, GList *link);
 void object_list_update(ObjectList_t *list, Object_t *object);
-void object_list_draw(ObjectList_t *list, GdkWindow *window);
-void object_list_draw_selected(ObjectList_t *list, GdkWindow *window);
+void object_list_draw(ObjectList_t *list, cairo_t *cr);
+void object_list_draw_selected(ObjectList_t *list, cairo_t *cr);
 Object_t *object_list_find(ObjectList_t *list, gint x, gint y);
 Object_t *object_list_near_sash(ObjectList_t *list, gint x, gint y,
                                 MoveSashFunc_t *sash_func);
diff --git a/plug-ins/imagemap/imap_polygon.c b/plug-ins/imagemap/imap_polygon.c
index a6f61c9..4065f28 100644
--- a/plug-ins/imagemap/imap_polygon.c
+++ b/plug-ins/imagemap/imap_polygon.c
@@ -44,8 +44,8 @@ static gboolean polygon_is_valid(Object_t *obj);
 static void polygon_destruct(Object_t *obj);
 static Object_t *polygon_clone(Object_t *obj);
 static void polygon_assign(Object_t *obj, Object_t *des);
-static void polygon_draw(Object_t* obj, GdkWindow *window, GdkGC* gc);
-static void polygon_draw_sashes(Object_t* obj, GdkWindow *window, GdkGC* gc);
+static void polygon_draw(Object_t* obj, cairo_t *cr);
+static void polygon_draw_sashes(Object_t* obj, cairo_t *cr);
 static MoveSashFunc_t polygon_near_sash(Object_t *obj, gint x, gint y);
 static gboolean polygon_point_is_on(Object_t *obj, gint x, gint y);
 static void polygon_get_dimensions(Object_t *obj, gint *x, gint *y,
@@ -156,20 +156,20 @@ polygon_assign(Object_t *obj, Object_t *des)
 }
 
 static void
-polygon_draw(Object_t *obj, GdkWindow *window, GdkGC *gc)
+polygon_draw(Object_t *obj, cairo_t *cr)
 {
    Polygon_t *polygon = ObjectToPolygon(obj);
-   draw_polygon(window, gc, polygon->points);
+   draw_polygon(cr, polygon->points);
 }
 
 static void
-polygon_draw_sashes(Object_t *obj, GdkWindow *window, GdkGC *gc)
+polygon_draw_sashes(Object_t *obj, cairo_t *cr)
 {
    Polygon_t *polygon = ObjectToPolygon(obj);
    GList     *p;
    for (p = polygon->points; p; p = p->next) {
       GdkPoint *point = (GdkPoint*) p->data;
-      draw_sash(window, gc, point->x, point->y);
+      draw_sash(cr, point->x, point->y);
    }
 }
 
diff --git a/plug-ins/imagemap/imap_preferences.c b/plug-ins/imagemap/imap_preferences.c
index 69f594a..92404ed 100644
--- a/plug-ins/imagemap/imap_preferences.c
+++ b/plug-ins/imagemap/imap_preferences.c
@@ -61,6 +61,8 @@ typedef struct {
    GtkWidget            *normal_bg;
    GtkWidget            *selected_fg;
    GtkWidget            *selected_bg;
+   GtkWidget            *interactive_fg;
+   GtkWidget            *interactive_bg;
 
    GtkWidget            *threshold;
    GtkWidget            *auto_convert;
@@ -150,6 +152,10 @@ parse_line(PreferencesData_t *data, char *line)
       parse_color(&colors->selected_fg);
    } else if (!strcmp(token, "selected-bg-color")) {
       parse_color(&colors->selected_bg);
+   } else if (!strcmp(token, "interactive-fg-color")) {
+      parse_color(&colors->interactive_fg);
+   } else if (!strcmp(token, "interactive-bg-color")) {
+      parse_color(&colors->interactive_bg);
    } else if (!strcmp(token, "mru-entry")) {
       parse_mru_entry();
    } else {
@@ -227,6 +233,12 @@ preferences_save(PreferencesData_t *data)
       fprintf(out, "(selected-bg-color %d %d %d)\n",
               colors->selected_bg.red, colors->selected_bg.green,
               colors->selected_bg.blue);
+      fprintf(out, "(interactive-fg-color %d %d %d)\n",
+              colors->interactive_fg.red, colors->interactive_fg.green,
+              colors->interactive_fg.blue);
+      fprintf(out, "(interactive-bg-color %d %d %d)\n",
+              colors->interactive_bg.red, colors->interactive_bg.green,
+              colors->interactive_bg.blue);
 
       mru_write(get_mru(), out);
 
@@ -275,13 +287,8 @@ preferences_ok_cb(gpointer data)
 
    get_button_colors (param, colors);
 
-   gdk_gc_set_foreground(old_data->normal_gc, &colors->normal_fg);
-   gdk_gc_set_background(old_data->normal_gc, &colors->normal_bg);
-   gdk_gc_set_foreground(old_data->selected_gc, &colors->selected_fg);
-   gdk_gc_set_background(old_data->selected_gc, &colors->selected_bg);
-
    set_sash_size(old_data->use_doublesized);
-   redraw_preview();
+   preview_redraw();
 }
 
 static void
@@ -301,6 +308,8 @@ get_button_colors(PreferencesDialog_t *dialog, ColorSelData_t *colors)
   get_button_color (dialog->normal_bg, &colors->normal_bg);
   get_button_color (dialog->selected_fg, &colors->selected_fg);
   get_button_color (dialog->selected_bg, &colors->selected_bg);
+  get_button_color (dialog->interactive_fg, &colors->interactive_fg);
+  get_button_color (dialog->interactive_bg, &colors->interactive_bg);
 }
 
 static void
@@ -319,6 +328,8 @@ set_button_colors(PreferencesDialog_t *dialog, ColorSelData_t *colors)
   set_button_color (dialog->normal_bg, &colors->normal_bg);
   set_button_color (dialog->selected_fg, &colors->selected_fg);
   set_button_color (dialog->selected_bg, &colors->selected_bg);
+  set_button_color (dialog->interactive_fg, &colors->interactive_fg);
+  set_button_color (dialog->interactive_bg, &colors->interactive_bg);
 }
 
 static GtkWidget*
@@ -418,7 +429,7 @@ create_color_field(PreferencesDialog_t *data, GtkWidget *table, gint row,
 static void
 create_colors_tab(PreferencesDialog_t *data, GtkWidget *notebook)
 {
-   GtkWidget *table = create_tab(notebook, _("Colors"), 2, 3);
+   GtkWidget *table = create_tab(notebook, _("Colors"), 3, 3);
 
    create_label_in_table(table, 0, 0, _("Normal:"));
    data->normal_fg = create_color_field(data, table, 0, 1);
@@ -427,6 +438,10 @@ create_colors_tab(PreferencesDialog_t *data, GtkWidget *notebook)
    create_label_in_table(table, 1, 0, _("Selected:"));
    data->selected_fg = create_color_field(data, table, 1, 1);
    data->selected_bg = create_color_field(data, table, 1, 2);
+
+   create_label_in_table(table, 2, 0, _("Interaction:"));
+   data->interactive_fg = create_color_field(data, table, 2, 1);
+   data->interactive_bg = create_color_field(data, table, 2, 2);
 }
 
 #ifdef _NOT_READY_YET_
diff --git a/plug-ins/imagemap/imap_preferences.h b/plug-ins/imagemap/imap_preferences.h
index d27e444..8a46505 100644
--- a/plug-ins/imagemap/imap_preferences.h
+++ b/plug-ins/imagemap/imap_preferences.h
@@ -30,6 +30,8 @@ typedef struct {
    GdkColor normal_bg;
    GdkColor selected_fg;
    GdkColor selected_bg;
+   GdkColor interactive_bg;
+   GdkColor interactive_fg;
 } ColorSelData_t;
 
 typedef struct {
@@ -45,8 +47,6 @@ typedef struct {
    gint                 undo_levels;
    gint                 mru_size;
    ColorSelData_t       colors;
-   GdkGC               *normal_gc;
-   GdkGC               *selected_gc;
 } PreferencesData_t;
 
 void do_preferences_dialog(void);
diff --git a/plug-ins/imagemap/imap_preview.c b/plug-ins/imagemap/imap_preview.c
index 4a965b9..49a74d8 100644
--- a/plug-ins/imagemap/imap_preview.c
+++ b/plug-ins/imagemap/imap_preview.c
@@ -57,6 +57,8 @@
 #define OPAQUE     255
 #endif
 
+static Object_t *_tmp_obj;
+
 static Preview_t*
 preview_user_data(GtkWidget *preview)
 {
@@ -293,51 +295,42 @@ arrow_cb(GtkWidget *widget, GdkEventButton *event, gpointer data)
 static gboolean
 preview_expose(GtkWidget *widget, GdkEventExpose *event)
 {
-   draw_grid(widget);
-   draw_shapes(widget);
-   return FALSE;
-}
-
-void
-add_preview_motion_event(Preview_t *preview, GCallback func)
-{
-   g_return_if_fail (func != NULL);
-
-   g_signal_connect(preview->preview, "motion-notify-event",
-                    func, NULL);
-}
-
-void
-add_enter_notify_event(Preview_t *preview, GCallback func)
-{
-   g_return_if_fail (func != NULL);
-
-   g_signal_connect(preview->preview, "enter-notify-event",
-                    func, NULL);
-}
-
-void
-add_leave_notify_event(Preview_t *preview, GCallback func)
-{
-   g_return_if_fail (func != NULL);
+   cairo_t *cr;
+   gint width = preview_get_width (widget);
+   gint height = preview_get_height (widget);
+
+   cr = gdk_cairo_create (event->window);
+   gdk_cairo_region (cr, event->region);
+   cairo_clip (cr);
+   cairo_set_line_width (cr, 1.);
+   draw_grid (cr, width, height);
+   
+   draw_shapes (cr);
+
+   if (_tmp_obj)
+   {
+      /* this is a bit of a hack */
+      gdouble dash = 4.;
+      _tmp_obj->selected |= 4;
+      cairo_set_source_rgb (cr, 1., 0., 1.);
+      cairo_set_dash (cr, &dash, 1, dash);
+      object_draw (_tmp_obj, cr);
+   }
 
-   g_signal_connect(preview->preview, "leave-notify-event",
-                    func, NULL);
+   cairo_destroy (cr);
+   return FALSE;
 }
 
 void
-add_preview_button_press_event(Preview_t *preview, GCallback func)
+preview_set_tmp_obj (Object_t *obj)
 {
-   g_return_if_fail (func != NULL);
-
-   g_signal_connect(preview->preview, "button-press-event",
-                    func, NULL);
+   _tmp_obj = obj;
 }
 
 void
-preview_redraw(Preview_t *preview)
+preview_unset_tmp_obj (Object_t *obj)
 {
-  gtk_widget_queue_draw(preview->preview);
+   if (_tmp_obj == obj) _tmp_obj = NULL;
 }
 
 void
@@ -349,7 +342,7 @@ preview_zoom(Preview_t *preview, gint zoom_factor)
                                 preview->widget_height);
    gtk_widget_queue_resize(preview->window);
    render_preview(preview, &preview->src_rgn);
-   preview_redraw(preview);
+   preview_redraw();
 }
 
 GdkCursorType
diff --git a/plug-ins/imagemap/imap_preview.h b/plug-ins/imagemap/imap_preview.h
index b757886..576b977 100644
--- a/plug-ins/imagemap/imap_preview.h
+++ b/plug-ins/imagemap/imap_preview.h
@@ -41,12 +41,10 @@ typedef struct {
 } Preview_t;
 
 Preview_t *make_preview(GimpDrawable *drawable);
-void preview_redraw(Preview_t *preview);
+void preview_redraw(void);
 
-void add_preview_motion_event(Preview_t *preview, GCallback func);
-void add_enter_notify_event(Preview_t *preview, GCallback func);
-void add_leave_notify_event(Preview_t *preview, GCallback func);
-void add_preview_button_press_event(Preview_t *preview, GCallback func);
+void preview_unset_tmp_obj (Object_t *obj);
+void preview_set_tmp_obj (Object_t *obj);
 
 gint preview_get_width(GtkWidget *preview);
 gint preview_get_height(GtkWidget *preview);
diff --git a/plug-ins/imagemap/imap_rectangle.c b/plug-ins/imagemap/imap_rectangle.c
index 0b40be6..10b8d93 100644
--- a/plug-ins/imagemap/imap_rectangle.c
+++ b/plug-ins/imagemap/imap_rectangle.c
@@ -43,8 +43,8 @@ static gboolean rectangle_is_valid(Object_t *obj);
 static Object_t *rectangle_clone(Object_t *obj);
 static void rectangle_assign(Object_t *obj, Object_t *des);
 static void rectangle_normalize(Object_t *obj);
-static void rectangle_draw(Object_t *obj, GdkWindow *window, GdkGC* gc);
-static void rectangle_draw_sashes(Object_t *obj, GdkWindow *window, GdkGC* gc);
+static void rectangle_draw(Object_t *obj, cairo_t *cr);
+static void rectangle_draw_sashes(Object_t *obj, cairo_t *cr);
 static MoveSashFunc_t rectangle_near_sash(Object_t *obj, gint x, gint y);
 static gboolean rectangle_point_is_on(Object_t *obj, gint x, gint y);
 static void rectangle_get_dimensions(Object_t *obj, gint *x, gint *y,
@@ -106,8 +106,7 @@ create_rectangle(gint x, gint y, gint width, gint height)
 }
 
 static void
-draw_any_rectangle(GdkWindow *window, GdkGC *gc, gint x, gint y, gint w,
-                   gint h)
+draw_any_rectangle(cairo_t *cr, gint x, gint y, gint w, gint h)
 {
    if (w < 0) {
       x += w;
@@ -117,7 +116,7 @@ draw_any_rectangle(GdkWindow *window, GdkGC *gc, gint x, gint y, gint w,
       y += h;
       h = -h;
    }
-   draw_rectangle(window, gc, FALSE, x, y, w, h);
+   draw_rectangle(cr, FALSE, x, y, w, h);
 }
 
 static gboolean
@@ -166,27 +165,27 @@ rectangle_normalize(Object_t *obj)
 }
 
 static void
-rectangle_draw(Object_t *obj, GdkWindow *window, GdkGC *gc)
+rectangle_draw(Object_t *obj, cairo_t *cr)
 {
    Rectangle_t *rectangle = ObjectToRectangle(obj);
-   draw_any_rectangle(window, gc, rectangle->x, rectangle->y,
+   draw_any_rectangle(cr, rectangle->x, rectangle->y,
                       rectangle->width, rectangle->height);
 }
 
 static void
-rectangle_draw_sashes(Object_t *obj, GdkWindow *window, GdkGC *gc)
+rectangle_draw_sashes(Object_t *obj, cairo_t *cr)
 {
    Rectangle_t *rectangle = ObjectToRectangle(obj);
-   draw_sash(window, gc, rectangle->x, rectangle->y);
-   draw_sash(window, gc, rectangle->x + rectangle->width / 2, rectangle->y);
-   draw_sash(window, gc, rectangle->x + rectangle->width, rectangle->y);
-   draw_sash(window, gc, rectangle->x, rectangle->y + rectangle->height / 2);
-   draw_sash(window, gc, rectangle->x + rectangle->width,
+   draw_sash(cr, rectangle->x, rectangle->y);
+   draw_sash(cr, rectangle->x + rectangle->width / 2, rectangle->y);
+   draw_sash(cr, rectangle->x + rectangle->width, rectangle->y);
+   draw_sash(cr, rectangle->x, rectangle->y + rectangle->height / 2);
+   draw_sash(cr, rectangle->x + rectangle->width,
              rectangle->y + rectangle->height / 2);
-   draw_sash(window, gc, rectangle->x, rectangle->y + rectangle->height);
-   draw_sash(window, gc, rectangle->x + rectangle->width / 2,
+   draw_sash(cr, rectangle->x, rectangle->y + rectangle->height);
+   draw_sash(cr, rectangle->x + rectangle->width / 2,
              rectangle->y + rectangle->height);
-   draw_sash(window, gc, rectangle->x + rectangle->width,
+   draw_sash(cr, rectangle->x + rectangle->width,
              rectangle->y + rectangle->height);
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]