[evolution/foocanvas] Migrate from GnomeCanvas to FooCanvas (embedded).



commit 5906d201113d2bc2db811ab2f01a4a8b38380f21
Author: Matthew Barnes <mbarnes redhat com>
Date:   Thu Aug 13 22:48:30 2009 -0400

    Migrate from GnomeCanvas to FooCanvas (embedded).

 .../gui/widgets/e-addressbook-reflow-adapter.c     |   16 +-
 addressbook/gui/widgets/e-minicard-label.c         |   98 +-
 addressbook/gui/widgets/e-minicard-label.h         |   16 +-
 addressbook/gui/widgets/e-minicard-view-widget.c   |   20 +-
 addressbook/gui/widgets/e-minicard-view-widget.h   |    4 +-
 addressbook/gui/widgets/e-minicard-view.c          |   20 +-
 addressbook/gui/widgets/e-minicard.c               |  150 +-
 addressbook/gui/widgets/e-minicard.h               |   16 +-
 addressbook/gui/widgets/ea-addressbook.c           |    2 +-
 addressbook/gui/widgets/ea-minicard-view.c         |    2 +-
 addressbook/gui/widgets/ea-minicard.c              |    2 +-
 calendar/gui/e-cal-list-view.c                     |    4 +-
 calendar/gui/e-calendar-table.c                    |    4 +-
 calendar/gui/e-calendar-view.h                     |    2 +-
 calendar/gui/e-day-view-main-item.c                |   51 +-
 calendar/gui/e-day-view-main-item.h                |    4 +-
 calendar/gui/e-day-view-time-item.c                |   65 +-
 calendar/gui/e-day-view-time-item.h                |    4 +-
 calendar/gui/e-day-view-top-item.c                 |   56 +-
 calendar/gui/e-day-view-top-item.h                 |    4 +-
 calendar/gui/e-day-view.c                          |  210 +-
 calendar/gui/e-day-view.h                          |   36 +-
 calendar/gui/e-meeting-time-sel-item.c             |   88 +-
 calendar/gui/e-meeting-time-sel-item.h             |    8 +-
 calendar/gui/e-meeting-time-sel.c                  |   36 +-
 calendar/gui/e-meeting-time-sel.h                  |    6 +-
 calendar/gui/e-memo-table.c                        |    4 +-
 calendar/gui/e-week-view-event-item.c              |   82 +-
 calendar/gui/e-week-view-event-item.h              |    4 +-
 calendar/gui/e-week-view-main-item.c               |   50 +-
 calendar/gui/e-week-view-main-item.h               |    4 +-
 calendar/gui/e-week-view-titles-item.c             |   52 +-
 calendar/gui/e-week-view-titles-item.h             |    4 +-
 calendar/gui/e-week-view.c                         |   94 +-
 calendar/gui/e-week-view.h                         |   16 +-
 calendar/gui/ea-cal-view-event.c                   |   20 +-
 calendar/gui/ea-calendar-helpers.c                 |   16 +-
 calendar/gui/ea-calendar-helpers.h                 |    6 +-
 calendar/gui/ea-calendar.c                         |   16 +-
 calendar/gui/ea-day-view-cell.c                    |    4 +-
 calendar/gui/ea-jump-button.c                      |   20 +-
 calendar/gui/ea-week-view-cell.c                   |    4 +-
 calendar/gui/ea-week-view.c                        |    2 +-
 calendar/gui/goto.c                                |    4 +-
 calendar/gui/weekday-picker.c                      |   40 +-
 calendar/gui/weekday-picker.h                      |    6 +-
 configure.ac                                       |   41 +-
 mail/message-list.c                                |    2 +-
 modules/calendar/e-cal-shell-content.c             |    6 +-
 modules/mail/e-mail-shell-content.c                |    2 +-
 widgets/Makefile.am                                |    1 +
 widgets/libfoocanvas/Makefile.am                   |   63 +
 widgets/libfoocanvas/foo-canvas-i18n.h             |   68 +
 widgets/libfoocanvas/foo-canvas-line.c             | 1289 +++++++
 widgets/libfoocanvas/foo-canvas-line.h             |  150 +
 widgets/libfoocanvas/foo-canvas-marshal.list       |    2 +
 widgets/libfoocanvas/foo-canvas-pixbuf.c           |  825 ++++
 widgets/libfoocanvas/foo-canvas-pixbuf.h           |   62 +
 widgets/libfoocanvas/foo-canvas-polygon.c          |  826 ++++
 widgets/libfoocanvas/foo-canvas-polygon.h          |  121 +
 widgets/libfoocanvas/foo-canvas-rect-ellipse.c     | 1489 +++++++
 widgets/libfoocanvas/foo-canvas-rect-ellipse.h     |  174 +
 widgets/libfoocanvas/foo-canvas-text.c             | 1587 ++++++++
 widgets/libfoocanvas/foo-canvas-text.h             |  168 +
 widgets/libfoocanvas/foo-canvas-util.c             |  399 ++
 widgets/libfoocanvas/foo-canvas-util.h             |  105 +
 widgets/libfoocanvas/foo-canvas-widget.c           |  589 +++
 widgets/libfoocanvas/foo-canvas-widget.h           |  103 +
 widgets/libfoocanvas/foo-canvas.c                  | 4060 ++++++++++++++++++++
 widgets/libfoocanvas/foo-canvas.h                  |  542 +++
 widgets/libfoocanvas/libart-types.h                |   18 +
 widgets/libfoocanvas/libfoocanvas.h                |   45 +
 widgets/libfoocanvas/libfoocanvastypes.c           |   43 +
 widgets/misc/Makefile.am                           |   15 +-
 widgets/misc/e-calendar-item.c                     |  165 +-
 widgets/misc/e-calendar-item.h                     |    6 +-
 widgets/misc/e-calendar.c                          |   54 +-
 widgets/misc/e-calendar.h                          |    6 +-
 widgets/misc/e-canvas-background.c                 |   86 +-
 widgets/misc/e-canvas-background.h                 |    6 +-
 widgets/misc/e-canvas-utils.c                      |   41 +-
 widgets/misc/e-canvas-utils.h                      |   10 +-
 widgets/misc/e-canvas-vbox.c                       |   72 +-
 widgets/misc/e-canvas-vbox.h                       |   16 +-
 widgets/misc/e-canvas.c                            |  134 +-
 widgets/misc/e-canvas.h                            |   40 +-
 widgets/misc/e-dateedit.c                          |   10 +-
 widgets/misc/e-gui-utils.c                         |    2 +-
 widgets/misc/ea-calendar-cell.c                    |    4 +-
 widgets/misc/ea-calendar-item.c                    |    8 +-
 widgets/table/e-cell-checkbox.c                    |    2 +-
 widgets/table/e-cell-combo.c                       |   10 +-
 widgets/table/e-cell-date-edit.c                   |   12 +-
 widgets/table/e-cell-hbox.h                        |    2 +-
 widgets/table/e-cell-pixbuf.c                      |    6 +-
 widgets/table/e-cell-popup.c                       |    2 +-
 widgets/table/e-cell-popup.h                       |    2 +-
 widgets/table/e-cell-text.c                        |   51 +-
 widgets/table/e-cell-text.h                        |    6 +-
 widgets/table/e-cell-toggle.c                      |    6 +-
 widgets/table/e-cell-toggle.h                      |    2 +-
 widgets/table/e-cell-tree.c                        |    6 +-
 widgets/table/e-cell-tree.h                        |    2 +-
 widgets/table/e-cell-vbox.h                        |    2 +-
 widgets/table/e-table-click-to-add.c               |   64 +-
 widgets/table/e-table-click-to-add.h               |   12 +-
 widgets/table/e-table-field-chooser-item.c         |   99 +-
 widgets/table/e-table-field-chooser-item.h         |    6 +-
 widgets/table/e-table-field-chooser.c              |   24 +-
 widgets/table/e-table-field-chooser.h              |    6 +-
 widgets/table/e-table-group-container.c            |   66 +-
 widgets/table/e-table-group-container.h            |   12 +-
 widgets/table/e-table-group-leaf.c                 |   42 +-
 widgets/table/e-table-group-leaf.h                 |    4 +-
 widgets/table/e-table-group.c                      |   22 +-
 widgets/table/e-table-group.h                      |   10 +-
 widgets/table/e-table-header-item.c                |  117 +-
 widgets/table/e-table-header-item.h                |    8 +-
 widgets/table/e-table-item.c                       |  199 +-
 widgets/table/e-table-item.h                       |    6 +-
 widgets/table/e-table-scrolled.c                   |    2 +-
 widgets/table/e-table-tooltip.h                    |    4 +-
 widgets/table/e-table.c                            |   94 +-
 widgets/table/e-table.h                            |   14 +-
 widgets/table/e-tree-scrolled.c                    |    2 +-
 widgets/table/e-tree.c                             |   83 +-
 widgets/table/e-tree.h                             |    3 +-
 widgets/table/gal-a11y-e-cell-popup.c              |    2 +-
 widgets/table/gal-a11y-e-cell-toggle.c             |    6 +-
 widgets/table/gal-a11y-e-cell.c                    |    4 +-
 widgets/table/gal-a11y-e-table-click-to-add.c      |    6 +-
 widgets/table/gal-a11y-e-table-item.c              |    4 +-
 widgets/table/gal-a11y-e-table.c                   |    8 +-
 widgets/text/e-reflow-model.c                      |   16 +-
 widgets/text/e-reflow-model.h                      |   16 +-
 widgets/text/e-reflow.c                            |  172 +-
 widgets/text/e-reflow.h                            |   12 +-
 widgets/text/e-text.c                              |  219 +-
 widgets/text/e-text.h                              |    8 +-
 widgets/text/gal-a11y-e-text.c                     |   14 +-
 140 files changed, 14557 insertions(+), 1767 deletions(-)
---
diff --git a/addressbook/gui/widgets/e-addressbook-reflow-adapter.c b/addressbook/gui/widgets/e-addressbook-reflow-adapter.c
index 500b045..a171684 100644
--- a/addressbook/gui/widgets/e-addressbook-reflow-adapter.c
+++ b/addressbook/gui/widgets/e-addressbook-reflow-adapter.c
@@ -133,7 +133,7 @@ addressbook_count (EReflowModel *erm)
 
 /* This function returns the height of the minicontact in question */
 static gint
-addressbook_height (EReflowModel *erm, gint i, GnomeCanvasGroup *parent)
+addressbook_height (EReflowModel *erm, gint i, FooCanvasGroup *parent)
 {
 	EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(erm);
 	EAddressbookReflowAdapterPrivate *priv = adapter->priv;
@@ -141,7 +141,7 @@ addressbook_height (EReflowModel *erm, gint i, GnomeCanvasGroup *parent)
 	gint count = 0;
 	gchar *string;
 	EContact *contact = (EContact*)e_addressbook_model_contact_at (priv->model, i);
-	PangoLayout *layout = gtk_widget_create_pango_layout (GTK_WIDGET (GNOME_CANVAS_ITEM (parent)->canvas), "");
+	PangoLayout *layout = gtk_widget_create_pango_layout (GTK_WIDGET (FOO_CANVAS_ITEM (parent)->canvas), "");
 	gint height;
 
 	string = e_contact_get(contact, E_CONTACT_FILE_AS);
@@ -240,14 +240,14 @@ adapter_open_contact (EMinicard *card,
 	g_signal_emit (adapter, signals[OPEN_CONTACT], 0, contact);
 }
 
-static GnomeCanvasItem *
-addressbook_incarnate (EReflowModel *erm, gint i, GnomeCanvasGroup *parent)
+static FooCanvasItem *
+addressbook_incarnate (EReflowModel *erm, gint i, FooCanvasGroup *parent)
 {
 	EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(erm);
 	EAddressbookReflowAdapterPrivate *priv = adapter->priv;
-	GnomeCanvasItem *item;
+	FooCanvasItem *item;
 
-	item = gnome_canvas_item_new(parent,
+	item = foo_canvas_item_new(parent,
 				     e_minicard_get_type(),
 				     "contact", e_addressbook_model_contact_at (priv->model, i),
 				     "editable", e_addressbook_model_get_editable (priv->model),
@@ -268,12 +268,12 @@ addressbook_incarnate (EReflowModel *erm, gint i, GnomeCanvasGroup *parent)
 }
 
 static void
-addressbook_reincarnate (EReflowModel *erm, gint i, GnomeCanvasItem *item)
+addressbook_reincarnate (EReflowModel *erm, gint i, FooCanvasItem *item)
 {
 	EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(erm);
 	EAddressbookReflowAdapterPrivate *priv = adapter->priv;
 
-	gnome_canvas_item_set(item,
+	foo_canvas_item_set(item,
 			      "contact", e_addressbook_model_contact_at (priv->model, i),
 			      NULL);
 }
diff --git a/addressbook/gui/widgets/e-minicard-label.c b/addressbook/gui/widgets/e-minicard-label.c
index 074bf9f..7617fb4 100644
--- a/addressbook/gui/widgets/e-minicard-label.c
+++ b/addressbook/gui/widgets/e-minicard-label.c
@@ -25,7 +25,7 @@
 #include "e-minicard-label.h"
 
 #include <gtk/gtk.h>
-#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
+#include <libfoocanvas/foo-canvas-rect-ellipse.h>
 #include <glib/gi18n.h>
 #include <e-util/e-util.h>
 #include <text/e-text.h>
@@ -37,17 +37,17 @@ static void e_minicard_label_init		(EMinicardLabel		 *card);
 static void e_minicard_label_class_init	(EMinicardLabelClass	 *klass);
 static void e_minicard_label_set_property  (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
 static void e_minicard_label_get_property  (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
-static gboolean e_minicard_label_event (GnomeCanvasItem *item, GdkEvent *event);
-static void e_minicard_label_realize (GnomeCanvasItem *item);
-static void e_minicard_label_unrealize (GnomeCanvasItem *item);
-static void e_minicard_label_reflow(GnomeCanvasItem *item, gint flags);
+static gboolean e_minicard_label_event (FooCanvasItem *item, GdkEvent *event);
+static void e_minicard_label_realize (FooCanvasItem *item);
+static void e_minicard_label_unrealize (FooCanvasItem *item);
+static void e_minicard_label_reflow(FooCanvasItem *item, gint flags);
 static void e_minicard_label_style_set (EMinicardLabel *label, GtkStyle *previous_style);
 
 static void e_minicard_label_resize_children( EMinicardLabel *e_minicard_label );
 
 static void set_colors (EMinicardLabel *label);
 
-static GnomeCanvasGroupClass *parent_class = NULL;
+static FooCanvasGroupClass *parent_class = NULL;
 
 /* The arguments we take */
 enum {
@@ -87,7 +87,7 @@ e_minicard_label_get_type (void)
 			(GInstanceInitFunc) e_minicard_label_init,
 		};
 
-		type = g_type_register_static (gnome_canvas_group_get_type (), "EMinicardLabel", &info, 0);
+		type = g_type_register_static (foo_canvas_group_get_type (), "EMinicardLabel", &info, 0);
 	}
 
 	return type;
@@ -97,10 +97,10 @@ static void
 e_minicard_label_class_init (EMinicardLabelClass *klass)
 {
 	GObjectClass *object_class;
-	GnomeCanvasItemClass *item_class;
+	FooCanvasItemClass *item_class;
 
 	object_class = G_OBJECT_CLASS (klass);
-	item_class = (GnomeCanvasItemClass *) klass;
+	item_class = (FooCanvasItemClass *) klass;
 
 	klass->style_set = e_minicard_label_style_set;
 
@@ -176,7 +176,7 @@ e_minicard_label_class_init (EMinicardLabelClass *klass)
 			      G_TYPE_NONE, 1,
 			      GTK_TYPE_STYLE);
 
-	/* GnomeCanvasItem method overrides */
+	/* FooCanvasItem method overrides */
 	item_class->realize     = e_minicard_label_realize;
 	item_class->unrealize   = e_minicard_label_unrealize;
 	item_class->event       = e_minicard_label_event;
@@ -193,17 +193,17 @@ e_minicard_label_init (EMinicardLabel *minicard_label)
 
   minicard_label->max_field_name_length = -1;
 
-  e_canvas_item_set_reflow_callback(GNOME_CANVAS_ITEM(minicard_label), e_minicard_label_reflow);
+  e_canvas_item_set_reflow_callback(FOO_CANVAS_ITEM(minicard_label), e_minicard_label_reflow);
 }
 
 static void
 e_minicard_label_set_property  (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
 {
 	EMinicardLabel *e_minicard_label;
-	GnomeCanvasItem *item;
+	FooCanvasItem *item;
 
 	e_minicard_label = E_MINICARD_LABEL (object);
-	item = GNOME_CANVAS_ITEM (object);
+	item = FOO_CANVAS_ITEM (object);
 
 	switch (prop_id) {
 	case PROP_WIDTH:
@@ -216,13 +216,13 @@ e_minicard_label_set_property  (GObject *object, guint prop_id, const GValue *va
 			e_canvas_item_grab_focus(e_minicard_label->field, FALSE);
 		break;
 	case PROP_FIELD:
-		gnome_canvas_item_set( e_minicard_label->field, "text", g_value_get_string (value), NULL );
+		foo_canvas_item_set( e_minicard_label->field, "text", g_value_get_string (value), NULL );
 		break;
 	case PROP_FIELDNAME:
-		gnome_canvas_item_set( e_minicard_label->fieldname, "text", g_value_get_string (value), NULL );
+		foo_canvas_item_set( e_minicard_label->fieldname, "text", g_value_get_string (value), NULL );
 		break;
 	case PROP_TEXT_MODEL:
-		gnome_canvas_item_set( e_minicard_label->field, "model", g_value_get_object (value), NULL);
+		foo_canvas_item_set( e_minicard_label->field, "model", g_value_get_object (value), NULL);
 		break;
 	case PROP_MAX_FIELD_NAME_WIDTH:
 		e_minicard_label->max_field_name_length = g_value_get_double (value);
@@ -279,22 +279,22 @@ e_minicard_label_get_property  (GObject *object, guint prop_id, GValue *value, G
 }
 
 static void
-e_minicard_label_realize (GnomeCanvasItem *item)
+e_minicard_label_realize (FooCanvasItem *item)
 {
 	EMinicardLabel *e_minicard_label;
-	GnomeCanvasGroup *group;
+	FooCanvasGroup *group;
 
 	e_minicard_label = E_MINICARD_LABEL (item);
-	group = GNOME_CANVAS_GROUP( item );
+	group = FOO_CANVAS_GROUP( item );
 
-	if (GNOME_CANVAS_ITEM_CLASS( parent_class )->realize)
-		(* GNOME_CANVAS_ITEM_CLASS( parent_class )->realize) (item);
+	if (FOO_CANVAS_ITEM_CLASS( parent_class )->realize)
+		(* FOO_CANVAS_ITEM_CLASS( parent_class )->realize) (item);
 
 	e_canvas_item_request_reflow(item);
 
 	e_minicard_label->rect =
-	  gnome_canvas_item_new( group,
-				 gnome_canvas_rect_get_type(),
+	  foo_canvas_item_new( group,
+				 foo_canvas_rect_get_type(),
 				 "x1", (double) 0,
 				 "y1", (double) 0,
 				 "x2", (double) e_minicard_label->width - 1,
@@ -302,7 +302,7 @@ e_minicard_label_realize (GnomeCanvasItem *item)
 				 "outline_color", NULL,
 				 NULL );
 	e_minicard_label->fieldname =
-	  gnome_canvas_item_new( group,
+	  foo_canvas_item_new( group,
 				 e_text_get_type(),
 				 "anchor", GTK_ANCHOR_NW,
 				 "clip_width", (double) ( e_minicard_label->width / 2 - 4 ),
@@ -315,7 +315,7 @@ e_minicard_label_realize (GnomeCanvasItem *item)
 	e_canvas_item_move_absolute(e_minicard_label->fieldname, 2, 1);
 
 	e_minicard_label->field =
-	  gnome_canvas_item_new( group,
+	  foo_canvas_item_new( group,
 				 e_text_get_type(),
 				 "anchor", GTK_ANCHOR_NW,
 				 "clip_width", (double) ( ( e_minicard_label->width + 1 ) / 2 - 4 ),
@@ -334,14 +334,14 @@ e_minicard_label_realize (GnomeCanvasItem *item)
 }
 
 static void
-e_minicard_label_unrealize (GnomeCanvasItem *item)
+e_minicard_label_unrealize (FooCanvasItem *item)
 {
-	if (GNOME_CANVAS_ITEM_CLASS( parent_class )->unrealize)
-		(* GNOME_CANVAS_ITEM_CLASS( parent_class )->unrealize) (item);
+	if (FOO_CANVAS_ITEM_CLASS( parent_class )->unrealize)
+		(* FOO_CANVAS_ITEM_CLASS( parent_class )->unrealize) (item);
 }
 
 static gboolean
-e_minicard_label_event (GnomeCanvasItem *item, GdkEvent *event)
+e_minicard_label_event (FooCanvasItem *item, GdkEvent *event)
 {
 	EMinicardLabel *e_minicard_label;
 
@@ -350,11 +350,11 @@ e_minicard_label_event (GnomeCanvasItem *item, GdkEvent *event)
 	switch ( event->type ) {
 	case GDK_KEY_PRESS:
 		if (event->key.keyval == GDK_Escape) {
-			GnomeCanvasItem *parent;
+			FooCanvasItem *parent;
 
 			e_text_cancel_editing (E_TEXT (e_minicard_label->field));
 
-			parent = GNOME_CANVAS_ITEM (e_minicard_label)->parent;
+			parent = FOO_CANVAS_ITEM (e_minicard_label)->parent;
 			if (parent)
 				e_canvas_item_grab_focus(parent, FALSE);
 		}
@@ -383,8 +383,8 @@ e_minicard_label_event (GnomeCanvasItem *item, GdkEvent *event)
 		break;
 	}
 
-	if (GNOME_CANVAS_ITEM_CLASS( parent_class )->event)
-		return (* GNOME_CANVAS_ITEM_CLASS( parent_class )->event) (item, event);
+	if (FOO_CANVAS_ITEM_CLASS( parent_class )->event)
+		return (* FOO_CANVAS_ITEM_CLASS( parent_class )->event) (item, event);
 	else
 		return 0;
 }
@@ -403,10 +403,10 @@ e_minicard_label_resize_children(EMinicardLabel *e_minicard_label)
 
 	fieldnamewidth = (double) MAX ( left_width, 0 );
 	fieldwidth = (double) MAX ( e_minicard_label->width - 8 - left_width, 0 );
-	gnome_canvas_item_set( e_minicard_label->fieldname,
+	foo_canvas_item_set( e_minicard_label->fieldname,
 			       "clip_width", is_rtl ? fieldwidth : fieldnamewidth,
 			       NULL );
-	gnome_canvas_item_set( e_minicard_label->field,
+	foo_canvas_item_set( e_minicard_label->field,
 			       "clip_width", is_rtl ? fieldnamewidth : fieldwidth,
 			       NULL );
 }
@@ -414,34 +414,34 @@ e_minicard_label_resize_children(EMinicardLabel *e_minicard_label)
 static void
 set_colors (EMinicardLabel *label)
 {
-	if ( (GTK_OBJECT_FLAGS( label ) & GNOME_CANVAS_ITEM_REALIZED) ) {
-		GtkWidget *canvas = GTK_WIDGET (GNOME_CANVAS_ITEM (label)->canvas);
+	if ( (GTK_OBJECT_FLAGS( label ) & FOO_CANVAS_ITEM_REALIZED) ) {
+		GtkWidget *canvas = GTK_WIDGET (FOO_CANVAS_ITEM (label)->canvas);
 		GtkStyle *style = gtk_widget_get_style (canvas);
 		if (label->has_focus) {
-			gnome_canvas_item_set (label->rect,
+			foo_canvas_item_set (label->rect,
 					       "outline_color_gdk", &style->mid[GTK_STATE_SELECTED],
 					       "fill_color_gdk", &style->bg[GTK_STATE_NORMAL],
 					       NULL);
 
-			gnome_canvas_item_set (label->field,
+			foo_canvas_item_set (label->field,
 					       "fill_color_gdk", &canvas->style->text[GTK_STATE_NORMAL],
 					       NULL);
 
-			gnome_canvas_item_set (label->fieldname,
+			foo_canvas_item_set (label->fieldname,
 					       "fill_color_gdk", &canvas->style->text[GTK_STATE_NORMAL],
 					       NULL);
 		}
 		else {
-			gnome_canvas_item_set (label->rect,
+			foo_canvas_item_set (label->rect,
 					       "outline_color_gdk", NULL,
 					       "fill_color_gdk", NULL,
 					       NULL);
 
-			gnome_canvas_item_set (label->field,
+			foo_canvas_item_set (label->field,
 					       "fill_color_gdk", &canvas->style->text[GTK_STATE_NORMAL],
 					       NULL);
 
-			gnome_canvas_item_set (label->fieldname,
+			foo_canvas_item_set (label->fieldname,
 					       "fill_color_gdk", &canvas->style->text[GTK_STATE_NORMAL],
 					       NULL);
 		}
@@ -455,7 +455,7 @@ e_minicard_label_style_set (EMinicardLabel *label, GtkStyle *previous_style)
 }
 
 static void
-e_minicard_label_reflow(GnomeCanvasItem *item, gint flags)
+e_minicard_label_reflow(FooCanvasItem *item, gint flags)
 {
 	EMinicardLabel *e_minicard_label = E_MINICARD_LABEL(item);
 
@@ -479,12 +479,12 @@ e_minicard_label_reflow(GnomeCanvasItem *item, gint flags)
 		e_minicard_label->height = text_height;
 	e_minicard_label->height += 3;
 
-	gnome_canvas_item_set( e_minicard_label->rect,
+	foo_canvas_item_set( e_minicard_label->rect,
 			       "x2", (double) e_minicard_label->width - 1,
 			       "y2", (double) e_minicard_label->height - 1,
 			       NULL );
 
-	gnome_canvas_item_set( e_minicard_label->fieldname,
+	foo_canvas_item_set( e_minicard_label->fieldname,
 			       "clip_height", (double) e_minicard_label->height - 3,
 			       NULL );
 
@@ -499,10 +499,10 @@ e_minicard_label_reflow(GnomeCanvasItem *item, gint flags)
 		e_canvas_item_request_parent_reflow(item);
 }
 
-GnomeCanvasItem *
-e_minicard_label_new(GnomeCanvasGroup *parent)
+FooCanvasItem *
+e_minicard_label_new(FooCanvasGroup *parent)
 {
-	GnomeCanvasItem *item = gnome_canvas_item_new(parent, e_minicard_label_get_type(), NULL);
+	FooCanvasItem *item = foo_canvas_item_new(parent, e_minicard_label_get_type(), NULL);
 	return item;
 }
 
diff --git a/addressbook/gui/widgets/e-minicard-label.h b/addressbook/gui/widgets/e-minicard-label.h
index 6031b80..d932af7 100644
--- a/addressbook/gui/widgets/e-minicard-label.h
+++ b/addressbook/gui/widgets/e-minicard-label.h
@@ -24,7 +24,7 @@
 #define __E_MINICARD_LABEL_H__
 
 #include <glib.h>
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 
 G_BEGIN_DECLS
 
@@ -51,30 +51,30 @@ typedef struct _EMinicardLabelClass  EMinicardLabelClass;
 
 struct _EMinicardLabel
 {
-	GnomeCanvasGroup parent;
+	FooCanvasGroup parent;
 
 	/* item specific fields */
 	double width;
 	double height;
 	double max_field_name_length;
 	guint editable : 1;
-	GnomeCanvasItem *fieldname;
-	GnomeCanvasItem *field;
-	GnomeCanvasItem *rect;
+	FooCanvasItem *fieldname;
+	FooCanvasItem *field;
+	FooCanvasItem *rect;
 
 	gboolean has_focus;
 };
 
 struct _EMinicardLabelClass
 {
-	GnomeCanvasGroupClass parent_class;
+	FooCanvasGroupClass parent_class;
 
 	void (* style_set) (EMinicardLabel *label, GtkStyle *previous_style);
 };
 
 GType      e_minicard_label_get_type (void);
-GnomeCanvasItem *e_minicard_label_new(GnomeCanvasGroup *parent);
-void e_minicard_label_construct (GnomeCanvasItem *item);
+FooCanvasItem *e_minicard_label_new(FooCanvasGroup *parent);
+void e_minicard_label_construct (FooCanvasItem *item);
 
 G_END_DECLS
 
diff --git a/addressbook/gui/widgets/e-minicard-view-widget.c b/addressbook/gui/widgets/e-minicard-view-widget.c
index cb39047..67171f6 100644
--- a/addressbook/gui/widgets/e-minicard-view-widget.c
+++ b/addressbook/gui/widgets/e-minicard-view-widget.c
@@ -363,7 +363,7 @@ e_minicard_view_widget_style_set (GtkWidget *widget, GtkStyle *previous_style)
 	EMinicardViewWidget *view = E_MINICARD_VIEW_WIDGET(widget);
 
 	if (view->background)
-		gnome_canvas_item_set (view->background,
+		foo_canvas_item_set (view->background,
 				       "fill_color_gdk", &widget->style->base[GTK_STATE_NORMAL],
 				       NULL );
 
@@ -377,13 +377,13 @@ e_minicard_view_widget_realize (GtkWidget *widget)
 	EMinicardViewWidget *view = E_MINICARD_VIEW_WIDGET(widget);
 	GtkStyle *style = gtk_widget_get_style (widget);
 
-	view->background = gnome_canvas_item_new(gnome_canvas_root( GNOME_CANVAS(view) ),
+	view->background = foo_canvas_item_new(foo_canvas_root( FOO_CANVAS(view) ),
 						 e_canvas_background_get_type(),
 						 "fill_color_gdk", &style->base[GTK_STATE_NORMAL],
 						 NULL );
 
-	view->emv = gnome_canvas_item_new(
-		gnome_canvas_root( GNOME_CANVAS(view) ),
+	view->emv = foo_canvas_item_new(
+		foo_canvas_root( FOO_CANVAS(view) ),
 		e_minicard_view_get_type(),
 		"height", (double) 100,
 		"minimum_width", (double) 100,
@@ -424,17 +424,17 @@ e_minicard_view_widget_size_allocate(GtkWidget *widget, GtkAllocation *allocatio
 		double width;
 		EMinicardViewWidget *view = E_MINICARD_VIEW_WIDGET(widget);
 
-		gnome_canvas_item_set( view->emv,
+		foo_canvas_item_set( view->emv,
 				       "height", (double) allocation->height,
 				       NULL );
-		gnome_canvas_item_set( view->emv,
+		foo_canvas_item_set( view->emv,
 				       "minimum_width", (double) allocation->width,
 				       NULL );
 		g_object_get(view->emv,
 			     "width", &width,
 			     NULL);
 		width = MAX(width, allocation->width);
-		gnome_canvas_set_scroll_region (GNOME_CANVAS (view), 0, 0, width - 1, allocation->height - 1);
+		foo_canvas_set_scroll_region (FOO_CANVAS (view), 0, 0, width - 1, allocation->height - 1);
 	}
 }
 
@@ -451,7 +451,7 @@ e_minicard_view_widget_reflow(ECanvas *canvas)
 		     "width", &width,
 		     NULL);
 	width = MAX(width, GTK_WIDGET(canvas)->allocation.width);
-	gnome_canvas_set_scroll_region(GNOME_CANVAS(canvas), 0, 0, width - 1, GTK_WIDGET(canvas)->allocation.height - 1);
+	foo_canvas_set_scroll_region(FOO_CANVAS(canvas), 0, 0, width - 1, GTK_WIDGET(canvas)->allocation.height - 1);
 }
 
 ESelectionModel *
@@ -475,10 +475,10 @@ e_minicard_view_widget_get_view             (EMinicardViewWidget       *view)
 static gboolean
 e_minicard_view_widget_real_focus_in_event(GtkWidget *widget, GdkEventFocus *event)
 {
-	GnomeCanvas *canvas;
+	FooCanvas *canvas;
 	EMinicardViewWidget *view;
 
-	canvas = GNOME_CANVAS (widget);
+	canvas = FOO_CANVAS (widget);
 	view = E_MINICARD_VIEW_WIDGET(widget);
 
 	if (!canvas->focused_item) {
diff --git a/addressbook/gui/widgets/e-minicard-view-widget.h b/addressbook/gui/widgets/e-minicard-view-widget.h
index bf9fe8d..72ea6c3 100644
--- a/addressbook/gui/widgets/e-minicard-view-widget.h
+++ b/addressbook/gui/widgets/e-minicard-view-widget.h
@@ -42,8 +42,8 @@ struct _EMinicardViewWidget
 {
 	ECanvas parent;
 
-	GnomeCanvasItem *background;
-	GnomeCanvasItem *emv;
+	FooCanvasItem *background;
+	FooCanvasItem *emv;
 
 	EAddressbookReflowAdapter *adapter;
 
diff --git a/addressbook/gui/widgets/e-minicard-view.c b/addressbook/gui/widgets/e-minicard-view.c
index 80d7291..57de105 100644
--- a/addressbook/gui/widgets/e-minicard-view.c
+++ b/addressbook/gui/widgets/e-minicard-view.c
@@ -140,11 +140,11 @@ e_minicard_view_drag_begin (EAddressbookReflowAdapter *adapter, GdkEvent *event,
 
 	target_list = gtk_target_list_new (drag_types, num_drag_types);
 
-	context = gtk_drag_begin (GTK_WIDGET (GNOME_CANVAS_ITEM (view)->canvas),
+	context = gtk_drag_begin (GTK_WIDGET (FOO_CANVAS_ITEM (view)->canvas),
 				  target_list, actions, 1/*XXX*/, event);
 
 	if (!view->canvas_drag_data_get_id)
-		view->canvas_drag_data_get_id = g_signal_connect (GNOME_CANVAS_ITEM (view)->canvas,
+		view->canvas_drag_data_get_id = g_signal_connect (FOO_CANVAS_ITEM (view)->canvas,
 								  "drag_data_get",
 								  G_CALLBACK (e_minicard_view_drag_data_get),
 								  view);
@@ -333,7 +333,7 @@ e_minicard_view_dispose (GObject *object)
 	clear_drag_data (view);
 
 	if (view->canvas_drag_data_get_id) {
-		g_signal_handler_disconnect (GNOME_CANVAS_ITEM (view)->canvas,
+		g_signal_handler_disconnect (FOO_CANVAS_ITEM (view)->canvas,
 					     view->canvas_drag_data_get_id);
 		view->canvas_drag_data_get_id = 0;
 	}
@@ -372,7 +372,7 @@ e_minicard_view_right_click (EMinicardView *view, GdkEvent *event)
 }
 
 static gboolean
-e_minicard_view_event (GnomeCanvasItem *item, GdkEvent *event)
+e_minicard_view_event (FooCanvasItem *item, GdkEvent *event)
 {
 	EMinicardView *view;
 
@@ -404,14 +404,14 @@ e_minicard_view_event (GnomeCanvasItem *item, GdkEvent *event)
 		break;
 	}
 
-	if (GNOME_CANVAS_ITEM_CLASS(parent_class)->event)
-		return GNOME_CANVAS_ITEM_CLASS(parent_class)->event(item, event);
+	if (FOO_CANVAS_ITEM_CLASS(parent_class)->event)
+		return FOO_CANVAS_ITEM_CLASS(parent_class)->event(item, event);
 	else
 		return FALSE;
 }
 
 static gint
-e_minicard_view_selection_event (EReflow *reflow, GnomeCanvasItem *item, GdkEvent *event)
+e_minicard_view_selection_event (EReflow *reflow, FooCanvasItem *item, GdkEvent *event)
 {
 	EMinicardView *view;
 	gint return_val = FALSE;
@@ -503,11 +503,11 @@ static void
 e_minicard_view_class_init (EMinicardViewClass *klass)
 {
 	GObjectClass *object_class;
-	GnomeCanvasItemClass *item_class;
+	FooCanvasItemClass *item_class;
 	EReflowClass *reflow_class;
 
 	object_class = G_OBJECT_CLASS (klass);
-	item_class = (GnomeCanvasItemClass *) klass;
+	item_class = (FooCanvasItemClass *) klass;
 	reflow_class = (EReflowClass *) klass;
 
 	parent_class = g_type_class_peek_parent (klass);
@@ -572,7 +572,7 @@ e_minicard_view_class_init (EMinicardViewClass *klass)
 	item_class->event             = e_minicard_view_event;
 
 	reflow_class->selection_event = e_minicard_view_selection_event;
-	/* GnomeCanvasItem method overrides */
+	/* FooCanvasItem method overrides */
 
 	/* init the accessibility support for e_minicard_view */
 	e_minicard_view_a11y_init();
diff --git a/addressbook/gui/widgets/e-minicard.c b/addressbook/gui/widgets/e-minicard.c
index 1f6bc14..6445003 100644
--- a/addressbook/gui/widgets/e-minicard.c
+++ b/addressbook/gui/widgets/e-minicard.c
@@ -24,8 +24,8 @@
 #include <string.h>
 #include <gdk/gdkkeysyms.h>
 #include <glib/gi18n.h>
-#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
-#include <libgnomecanvas/gnome-canvas-pixbuf.h>
+#include <libfoocanvas/foo-canvas-rect-ellipse.h>
+#include <libfoocanvas/foo-canvas-pixbuf.h>
 #include <text/e-text.h>
 #include <e-util/e-util.h>
 #include <misc/e-canvas-utils.h>
@@ -46,10 +46,10 @@ static void e_minicard_set_property  (GObject *object, guint prop_id, const GVal
 static void e_minicard_get_property  (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
 static void e_minicard_dispose (GObject *object);
 static void e_minicard_finalize (GObject *object);
-static gboolean e_minicard_event (GnomeCanvasItem *item, GdkEvent *event);
-static void e_minicard_realize (GnomeCanvasItem *item);
-static void e_minicard_unrealize (GnomeCanvasItem *item);
-static void e_minicard_reflow ( GnomeCanvasItem *item, gint flags );
+static gboolean e_minicard_event (FooCanvasItem *item, GdkEvent *event);
+static void e_minicard_realize (FooCanvasItem *item);
+static void e_minicard_unrealize (FooCanvasItem *item);
+static void e_minicard_reflow ( FooCanvasItem *item, gint flags );
 static void e_minicard_style_set (EMinicard *minicard, GtkStyle *previous_style);
 
 static void e_minicard_resize_children( EMinicard *e_minicard );
@@ -121,7 +121,7 @@ e_minicard_get_type (void)
 			(GInstanceInitFunc) e_minicard_init,
 		};
 
-		type = g_type_register_static (gnome_canvas_group_get_type (), "EMinicard", &info, 0);
+		type = g_type_register_static (foo_canvas_group_get_type (), "EMinicard", &info, 0);
 	}
 
 	return type;
@@ -131,7 +131,7 @@ static void
 e_minicard_class_init (EMinicardClass *class)
 {
 	GObjectClass *object_class;
-	GnomeCanvasItemClass *item_class;
+	FooCanvasItemClass *item_class;
 
 	parent_class = g_type_class_peek_parent (class);
 
@@ -141,7 +141,7 @@ e_minicard_class_init (EMinicardClass *class)
 	object_class->dispose = e_minicard_dispose;
 	object_class->finalize = e_minicard_finalize;
 
-	item_class = GNOME_CANVAS_ITEM_CLASS (class);
+	item_class = FOO_CANVAS_ITEM_CLASS (class);
 	item_class->realize = e_minicard_realize;
 	item_class->unrealize = e_minicard_unrealize;
 	item_class->event = e_minicard_event;
@@ -261,31 +261,31 @@ e_minicard_init (EMinicard *minicard)
 
 	minicard->changed          = FALSE;
 
-	e_canvas_item_set_reflow_callback(GNOME_CANVAS_ITEM(minicard), e_minicard_reflow);
+	e_canvas_item_set_reflow_callback(FOO_CANVAS_ITEM(minicard), e_minicard_reflow);
 }
 
 static void
 set_selected (EMinicard *minicard, gboolean selected)
 {
-	GtkWidget *canvas = GTK_WIDGET(GNOME_CANVAS_ITEM(minicard)->canvas);
+	GtkWidget *canvas = GTK_WIDGET(FOO_CANVAS_ITEM(minicard)->canvas);
 	if (selected) {
-		gnome_canvas_item_set (minicard->rect,
+		foo_canvas_item_set (minicard->rect,
 				       "outline_color_gdk", &canvas->style->bg[GTK_STATE_ACTIVE],
 				       NULL);
-		gnome_canvas_item_set (minicard->header_rect,
+		foo_canvas_item_set (minicard->header_rect,
 				       "fill_color_gdk", &canvas->style->bg[GTK_STATE_SELECTED],
 				       NULL);
-		gnome_canvas_item_set (minicard->header_text,
+		foo_canvas_item_set (minicard->header_text,
 				       "fill_color_gdk", &canvas->style->text[GTK_STATE_SELECTED],
 				       NULL);
 	} else {
-		gnome_canvas_item_set (minicard->rect,
+		foo_canvas_item_set (minicard->rect,
 				       "outline_color", NULL,
 				       NULL);
-		gnome_canvas_item_set (minicard->header_rect,
+		foo_canvas_item_set (minicard->header_rect,
 				       "fill_color_gdk", &canvas->style->bg[GTK_STATE_NORMAL],
 				       NULL);
-		gnome_canvas_item_set (minicard->header_text,
+		foo_canvas_item_set (minicard->header_text,
 				       "fill_color_gdk", &canvas->style->text[GTK_STATE_NORMAL],
 				       NULL);
 	}
@@ -296,19 +296,19 @@ static void
 set_has_cursor (EMinicard *minicard, gboolean has_cursor)
 {
 	if (!minicard->has_focus && has_cursor)
-		e_canvas_item_grab_focus(GNOME_CANVAS_ITEM (minicard), FALSE);
+		e_canvas_item_grab_focus(FOO_CANVAS_ITEM (minicard), FALSE);
 	minicard->has_cursor = has_cursor;
 }
 
 static void
 e_minicard_set_property  (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
 {
-	GnomeCanvasItem *item;
+	FooCanvasItem *item;
 	EMinicard *e_minicard;
 	EContact *contact;
 	GList *l;
 
-	item = GNOME_CANVAS_ITEM (object);
+	item = FOO_CANVAS_ITEM (object);
 	e_minicard = E_MINICARD (object);
 
 	switch (prop_id) {
@@ -316,7 +316,7 @@ e_minicard_set_property  (GObject *object, guint prop_id, const GValue *value, G
 		if (e_minicard->width != g_value_get_double (value)) {
 			e_minicard->width = g_value_get_double (value);
 			e_minicard_resize_children(e_minicard);
-			if ( GTK_OBJECT_FLAGS( e_minicard ) & GNOME_CANVAS_ITEM_REALIZED )
+			if ( GTK_OBJECT_FLAGS( e_minicard ) & FOO_CANVAS_ITEM_REALIZED )
 				e_canvas_item_request_reflow(item);
 		}
 	  break;
@@ -324,11 +324,11 @@ e_minicard_set_property  (GObject *object, guint prop_id, const GValue *value, G
 		if (e_minicard->fields) {
 			if ( g_value_get_int(value) == E_FOCUS_START ||
 			     g_value_get_int(value) == E_FOCUS_CURRENT) {
-				gnome_canvas_item_set(E_MINICARD_FIELD(e_minicard->fields->data)->label,
+				foo_canvas_item_set(E_MINICARD_FIELD(e_minicard->fields->data)->label,
 						      "has_focus", g_value_get_int (value),
 						      NULL);
 			} else if ( g_value_get_int (value) == E_FOCUS_END ) {
-				gnome_canvas_item_set(E_MINICARD_FIELD(g_list_last(e_minicard->fields)->data)->label,
+				foo_canvas_item_set(E_MINICARD_FIELD(g_list_last(e_minicard->fields)->data)->label,
 						      "has_focus", g_value_get_int (value),
 						      NULL);
 			}
@@ -462,27 +462,27 @@ e_minicard_finalize (GObject *object)
 static void
 e_minicard_style_set (EMinicard *minicard, GtkStyle *previous_style)
 {
-	if ( (GTK_OBJECT_FLAGS( minicard ) & GNOME_CANVAS_ITEM_REALIZED) )
+	if ( (GTK_OBJECT_FLAGS( minicard ) & FOO_CANVAS_ITEM_REALIZED) )
 		set_selected (minicard, minicard->selected);
 }
 
 static void
-e_minicard_realize (GnomeCanvasItem *item)
+e_minicard_realize (FooCanvasItem *item)
 {
 	EMinicard *e_minicard;
-	GnomeCanvasGroup *group;
+	FooCanvasGroup *group;
 	GtkWidget *canvas;
 
 	e_minicard = E_MINICARD (item);
-	group = GNOME_CANVAS_GROUP( item );
-	canvas = GTK_WIDGET (GNOME_CANVAS_ITEM (item)->canvas);
+	group = FOO_CANVAS_GROUP( item );
+	canvas = GTK_WIDGET (FOO_CANVAS_ITEM (item)->canvas);
 
-	if (GNOME_CANVAS_ITEM_CLASS(parent_class)->realize)
-		(* GNOME_CANVAS_ITEM_CLASS(parent_class)->realize) (item);
+	if (FOO_CANVAS_ITEM_CLASS(parent_class)->realize)
+		(* FOO_CANVAS_ITEM_CLASS(parent_class)->realize) (item);
 
 	e_minicard->rect =
-	  gnome_canvas_item_new( group,
-				 gnome_canvas_rect_get_type(),
+	  foo_canvas_item_new( group,
+				 foo_canvas_rect_get_type(),
 				 "x1", (double) 0,
 				 "y1", (double) 0,
 				 "x2", (double) MAX (e_minicard->width - 1, 0),
@@ -491,8 +491,8 @@ e_minicard_realize (GnomeCanvasItem *item)
 				 NULL );
 
 	e_minicard->header_rect =
-	  gnome_canvas_item_new( group,
-				 gnome_canvas_rect_get_type(),
+	  foo_canvas_item_new( group,
+				 foo_canvas_rect_get_type(),
 				 "x1", (double) 2,
 				 "y1", (double) 2,
 				 "x2", (double) MAX (e_minicard->width - 3, 0),
@@ -501,7 +501,7 @@ e_minicard_realize (GnomeCanvasItem *item)
 				 NULL );
 
 	e_minicard->header_text =
-	  gnome_canvas_item_new( group,
+	  foo_canvas_item_new( group,
 				 e_text_get_type(),
 				 "anchor", GTK_ANCHOR_NW,
 				 "width", (double) MAX( e_minicard->width - 12, 0 ),
@@ -515,8 +515,8 @@ e_minicard_realize (GnomeCanvasItem *item)
 	e_canvas_item_move_absolute(e_minicard->header_text, 6, 6);
 
 	e_minicard->list_icon =
-		gnome_canvas_item_new ( group,
-					gnome_canvas_pixbuf_get_type(),
+		foo_canvas_item_new ( group,
+					foo_canvas_pixbuf_get_type(),
 					"pixbuf", e_minicard->list_icon_pixbuf,
 					NULL);
 
@@ -527,10 +527,10 @@ e_minicard_realize (GnomeCanvasItem *item)
 }
 
 static void
-e_minicard_unrealize (GnomeCanvasItem *item)
+e_minicard_unrealize (FooCanvasItem *item)
 {
-	if (GNOME_CANVAS_ITEM_CLASS(parent_class)->unrealize)
-		(* GNOME_CANVAS_ITEM_CLASS(parent_class)->unrealize) (item);
+	if (FOO_CANVAS_ITEM_CLASS(parent_class)->unrealize)
+		(* FOO_CANVAS_ITEM_CLASS(parent_class)->unrealize) (item);
 }
 
 void
@@ -542,7 +542,7 @@ e_minicard_activate_editor (EMinicard *minicard)
 }
 
 static gboolean
-e_minicard_event (GnomeCanvasItem *item, GdkEvent *event)
+e_minicard_event (FooCanvasItem *item, GdkEvent *event)
 {
 	EMinicard *e_minicard;
 
@@ -575,11 +575,11 @@ e_minicard_event (GnomeCanvasItem *item, GdkEvent *event)
 
 			e_canvas_item_grab_focus(item, TRUE);
 
-			if (gnome_canvas_item_grab (GNOME_CANVAS_ITEM (e_minicard),
+			if (foo_canvas_item_grab (FOO_CANVAS_ITEM (e_minicard),
 						    mask, NULL, event->button.time)) {
 				return FALSE;
 			}
-			gtk_grab_add (GTK_WIDGET (GNOME_CANVAS_ITEM (e_minicard)->canvas));
+			gtk_grab_add (GTK_WIDGET (FOO_CANVAS_ITEM (e_minicard)->canvas));
 			e_minicard->button_x = event->button.x;
 			e_minicard->button_y = event->button.y;
 			e_minicard->drag_button = event->button.button;
@@ -600,9 +600,9 @@ e_minicard_event (GnomeCanvasItem *item, GdkEvent *event)
 			e_minicard->button_x = -1;
 			e_minicard->button_y = -1;
 
-			if (GTK_WIDGET_HAS_GRAB (GNOME_CANVAS_ITEM (e_minicard)->canvas)) {
-				gtk_grab_remove (GTK_WIDGET (GNOME_CANVAS_ITEM (e_minicard)->canvas));
-				gnome_canvas_item_ungrab (GNOME_CANVAS_ITEM (e_minicard), event->button.time);
+			if (GTK_WIDGET_HAS_GRAB (FOO_CANVAS_ITEM (e_minicard)->canvas)) {
+				gtk_grab_remove (GTK_WIDGET (FOO_CANVAS_ITEM (e_minicard)->canvas));
+				foo_canvas_item_ungrab (FOO_CANVAS_ITEM (e_minicard), event->button.time);
 			}
 		}
 		break;
@@ -654,7 +654,7 @@ e_minicard_event (GnomeCanvasItem *item, GdkEvent *event)
 
 					model_index = e_sorter_sorted_to_model (E_SORTER (reflow->sorter), view_index);
 					if (reflow->items[model_index] == NULL) {
-						reflow->items[model_index] = e_reflow_model_incarnate (reflow->model, model_index, GNOME_CANVAS_GROUP (reflow));
+						reflow->items[model_index] = e_reflow_model_incarnate (reflow->model, model_index, FOO_CANVAS_GROUP (reflow));
 						g_object_set (reflow->items[model_index],
 							      "width", (double) reflow->column_width,
 							      NULL);
@@ -680,7 +680,7 @@ e_minicard_event (GnomeCanvasItem *item, GdkEvent *event)
 
 					model_index = e_sorter_sorted_to_model (E_SORTER (reflow->sorter), view_index);
 					if (reflow->items[model_index] == NULL) {
-						reflow->items[model_index] = e_reflow_model_incarnate (reflow->model, model_index, GNOME_CANVAS_GROUP (reflow));
+						reflow->items[model_index] = e_reflow_model_incarnate (reflow->model, model_index, FOO_CANVAS_GROUP (reflow));
 						g_object_set (reflow->items[model_index],
 							      "width", (double) reflow->column_width,
 							      NULL);
@@ -701,8 +701,8 @@ e_minicard_event (GnomeCanvasItem *item, GdkEvent *event)
 		break;
 	}
 
-	if (GNOME_CANVAS_ITEM_CLASS( parent_class )->event)
-		return (* GNOME_CANVAS_ITEM_CLASS( parent_class )->event) (item, event);
+	if (FOO_CANVAS_ITEM_CLASS( parent_class )->event)
+		return (* FOO_CANVAS_ITEM_CLASS( parent_class )->event) (item, event);
 	else
 		return FALSE;
 }
@@ -714,7 +714,7 @@ e_minicard_resize_children( EMinicard *e_minicard )
 	gboolean is_list = GPOINTER_TO_INT (e_contact_get (e_minicard->contact, E_CONTACT_IS_LIST));
 
 	if (e_minicard->header_text) {
-		gnome_canvas_item_set( e_minicard->header_text,
+		foo_canvas_item_set( e_minicard->header_text,
 				       "width", ((double) e_minicard->width - 12
 						 - (is_list ? e_minicard->list_icon_size : 0.0)),
 				       NULL );
@@ -725,7 +725,7 @@ e_minicard_resize_children( EMinicard *e_minicard )
 					    3);
 	}
 	for ( list = e_minicard->fields; list; list = g_list_next( list ) ) {
-		gnome_canvas_item_set( E_MINICARD_FIELD( list->data )->label,
+		foo_canvas_item_set( E_MINICARD_FIELD( list->data )->label,
 				       "width", (double) e_minicard->width - 4.0,
 				       NULL );
 	}
@@ -734,14 +734,14 @@ e_minicard_resize_children( EMinicard *e_minicard )
 static void
 add_field (EMinicard *e_minicard, EContactField field, gdouble left_width)
 {
-	GnomeCanvasItem *new_item;
-	GnomeCanvasGroup *group;
+	FooCanvasItem *new_item;
+	FooCanvasGroup *group;
 	EMinicardField *minicard_field;
 	gchar *name;
 	gchar *string;
 	gboolean is_rtl = (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL);
 
-	group = GNOME_CANVAS_GROUP( e_minicard );
+	group = FOO_CANVAS_GROUP( e_minicard );
 
 	name = g_strdup_printf("%s:", e_contact_pretty_name (field));
 	string = e_contact_get (e_minicard->contact, field);
@@ -749,7 +749,7 @@ add_field (EMinicard *e_minicard, EContactField field, gdouble left_width)
 	new_item = e_minicard_label_new(group);
 
 	if (e_minicard->contact && e_contact_get (e_minicard->contact, E_CONTACT_IS_LIST))
-		gnome_canvas_item_set (new_item,
+		foo_canvas_item_set (new_item,
 					"fieldname", is_rtl ? "" : string,
 					"field", is_rtl ? string : "",
 					"max_field_name_length", left_width,
@@ -757,7 +757,7 @@ add_field (EMinicard *e_minicard, EContactField field, gdouble left_width)
 					"width", e_minicard->width - 4.0,
 					NULL );
 	else
-		gnome_canvas_item_set (new_item,
+		foo_canvas_item_set (new_item,
 					"fieldname", is_rtl ? string : name,
 					"field", is_rtl ? name : string,
 					"max_field_name_length", left_width,
@@ -800,15 +800,15 @@ get_email_location (EVCardAttribute *attr)
 static void
 add_email_field (EMinicard *e_minicard, GList *email_list, gdouble left_width, gint limit, gboolean is_list)
 {
-	GnomeCanvasItem *new_item;
-	GnomeCanvasGroup *group;
+	FooCanvasItem *new_item;
+	FooCanvasGroup *group;
 	EMinicardField *minicard_field;
 	gchar *name;
 	GList *l, *le;
 	gint count =0;
 	gboolean is_rtl = (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL);
 	GList *emails = e_contact_get (e_minicard->contact, E_CONTACT_EMAIL);
-	group = GNOME_CANVAS_GROUP( e_minicard );
+	group = FOO_CANVAS_GROUP( e_minicard );
 
 	for (l=email_list, le=emails; l!=NULL && count < limit && le!=NULL; l = l->next, le=le->next) {
 		const gchar *tmp;
@@ -836,7 +836,7 @@ add_email_field (EMinicard *e_minicard, GList *email_list, gdouble left_width, g
 
 		new_item = e_minicard_label_new(group);
 
-		gnome_canvas_item_set (new_item,
+		foo_canvas_item_set (new_item,
 				       "fieldname", is_rtl ? string : name,
 				       "field", is_rtl ? name : string,
 				       "max_field_name_length", left_width,
@@ -881,7 +881,7 @@ get_left_width (EMinicard *e_minicard, gboolean is_list)
 	if (is_list)
 		return 0;
 
-	layout = gtk_widget_create_pango_layout (GTK_WIDGET (GNOME_CANVAS_ITEM (e_minicard)->canvas), "");
+	layout = gtk_widget_create_pango_layout (GTK_WIDGET (FOO_CANVAS_ITEM (e_minicard)->canvas), "");
 	for (field = E_CONTACT_FULL_NAME; field != E_CONTACT_LAST_SIMPLE_STRING; field++) {
 		gint this_width;
 
@@ -903,7 +903,7 @@ static void
 remodel( EMinicard *e_minicard )
 {
 	gint count = 0;
-	if ( !(GTK_OBJECT_FLAGS( e_minicard ) & GNOME_CANVAS_ITEM_REALIZED) )
+	if ( !(GTK_OBJECT_FLAGS( e_minicard ) & FOO_CANVAS_ITEM_REALIZED) )
 		return;
 	if (e_minicard->contact) {
 		EContactField field;
@@ -915,7 +915,7 @@ remodel( EMinicard *e_minicard )
 
 		if (e_minicard->header_text) {
 			file_as = e_contact_get (e_minicard->contact, E_CONTACT_FILE_AS);
-			gnome_canvas_item_set (e_minicard->header_text,
+			foo_canvas_item_set (e_minicard->header_text,
 					       "text", file_as ? file_as : "",
 					       NULL );
 			g_free(file_as);
@@ -925,9 +925,9 @@ remodel( EMinicard *e_minicard )
 			is_list = TRUE;
 
 		if (is_list)
-			gnome_canvas_item_show (e_minicard->list_icon);
+			foo_canvas_item_show (e_minicard->list_icon);
 		else
-			gnome_canvas_item_hide (e_minicard->list_icon);
+			foo_canvas_item_hide (e_minicard->list_icon);
 
 		list = e_minicard->fields;
 		e_minicard->fields = NULL;
@@ -1002,10 +1002,10 @@ remodel( EMinicard *e_minicard )
 }
 
 static void
-e_minicard_reflow(GnomeCanvasItem *item, gint flags)
+e_minicard_reflow(FooCanvasItem *item, gint flags)
 {
 	EMinicard *e_minicard = E_MINICARD(item);
-	if (GTK_OBJECT_FLAGS (e_minicard) & GNOME_CANVAS_ITEM_REALIZED) {
+	if (GTK_OBJECT_FLAGS (e_minicard) & FOO_CANVAS_ITEM_REALIZED) {
 		GList *list;
 		gdouble text_height;
 		gint old_height;
@@ -1018,14 +1018,14 @@ e_minicard_reflow(GnomeCanvasItem *item, gint flags)
 
 		e_minicard->height = text_height + 10.0;
 
-		gnome_canvas_item_set(e_minicard->header_rect,
+		foo_canvas_item_set(e_minicard->header_rect,
 				       "y2", text_height + 9.0,
 				       NULL);
 
 		for (list = e_minicard->fields; list; list = g_list_next(list)) {
 			EMinicardField *field = E_MINICARD_FIELD(list->data);
 			/* Why not use the item that is passed in? */
-			GnomeCanvasItem *item = field->label;
+			FooCanvasItem *item = field->label;
 			g_object_get (item,
 				      "height", &text_height,
 				      NULL);
@@ -1034,11 +1034,11 @@ e_minicard_reflow(GnomeCanvasItem *item, gint flags)
 		}
 		e_minicard->height += 2;
 
-		gnome_canvas_item_set(e_minicard->rect,
+		foo_canvas_item_set(e_minicard->rect,
 				       "x2", (double) e_minicard->width - 1.0,
 				       "y2", (double) e_minicard->height - 1.0,
 				       NULL);
-		gnome_canvas_item_set(e_minicard->header_rect,
+		foo_canvas_item_set(e_minicard->header_rect,
 				       "x2", (double) e_minicard->width - 3.0,
 				       NULL);
 
@@ -1099,7 +1099,7 @@ gint
 e_minicard_selected (EMinicard *minicard, GdkEvent *event)
 {
 	gint ret_val = 0;
-	GnomeCanvasItem *item = GNOME_CANVAS_ITEM (minicard);
+	FooCanvasItem *item = FOO_CANVAS_ITEM (minicard);
 	if (item->parent) {
 		guint signal_id = g_signal_lookup ("selection_event", G_OBJECT_TYPE (item->parent));
 		/* We should probably check the signature here, but I
@@ -1119,12 +1119,12 @@ static gint
 e_minicard_drag_begin (EMinicard *minicard, GdkEvent *event)
 {
 	gint ret_val = 0;
-	GnomeCanvasItem *parent;
+	FooCanvasItem *parent;
 	g_signal_emit (minicard,
 		       signals[DRAG_BEGIN], 0,
 		       event, &ret_val);
 
-	parent = GNOME_CANVAS_ITEM (minicard)->parent;
+	parent = FOO_CANVAS_ITEM (minicard)->parent;
 	if (parent && E_IS_REFLOW (parent)) {
 		E_REFLOW (parent)->maybe_in_drag = FALSE;
 	}
diff --git a/addressbook/gui/widgets/e-minicard.h b/addressbook/gui/widgets/e-minicard.h
index 4135090..1720c88 100644
--- a/addressbook/gui/widgets/e-minicard.h
+++ b/addressbook/gui/widgets/e-minicard.h
@@ -24,7 +24,7 @@
 #define __E_MINICARD_H__
 
 #include <gtk/gtk.h>
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 #include <libebook/e-contact.h>
 
 G_BEGIN_DECLS
@@ -57,15 +57,15 @@ enum _EMinicardFocusType {
 
 struct _EMinicard
 {
-	GnomeCanvasGroup parent;
+	FooCanvasGroup parent;
 
 	/* item specific fields */
 	EContact *contact;
 
-	GnomeCanvasItem *rect;
-	GnomeCanvasItem *header_rect;
-	GnomeCanvasItem *header_text;
-	GnomeCanvasItem *list_icon;
+	FooCanvasItem *rect;
+	FooCanvasItem *header_rect;
+	FooCanvasItem *header_text;
+	FooCanvasItem *list_icon;
 
 	GdkPixbuf *list_icon_pixbuf;
 	double list_icon_size;
@@ -94,7 +94,7 @@ struct _EMinicard
 
 struct _EMinicardClass
 {
-	GnomeCanvasGroupClass parent_class;
+	FooCanvasGroupClass parent_class;
 
 	gint (* selected) (EMinicard *minicard, GdkEvent *event);
 	gint (* drag_begin) (EMinicard *minicard, GdkEvent *event);
@@ -107,7 +107,7 @@ typedef struct _EMinicardField EMinicardField;
 
 struct _EMinicardField {
 	EContactField field;
-	GnomeCanvasItem *label;
+	FooCanvasItem *label;
 };
 
 #define E_MINICARD_FIELD(field) ((EMinicardField *)(field))
diff --git a/addressbook/gui/widgets/ea-addressbook.c b/addressbook/gui/widgets/ea-addressbook.c
index 14fc4c1..6850b57 100644
--- a/addressbook/gui/widgets/ea-addressbook.c
+++ b/addressbook/gui/widgets/ea-addressbook.c
@@ -72,7 +72,7 @@ ea_addressbook_focus_watcher (GSignalInvocationHint *ihint,
 	event = g_value_get_boxed (param_values + 1);
 
 	if (E_IS_MINICARD (object)) {
-                GnomeCanvasItem *item = GNOME_CANVAS_ITEM (object);
+                FooCanvasItem *item = FOO_CANVAS_ITEM (object);
 		ea_event = atk_gobject_accessible_for_object (object);
 		if (event->type == GDK_FOCUS_CHANGE) {
 			if ((event->focus_change.in) && (E_IS_MINICARD (item->canvas->focused_item)))
diff --git a/addressbook/gui/widgets/ea-minicard-view.c b/addressbook/gui/widgets/ea-minicard-view.c
index ffccbfa..847bfb7 100644
--- a/addressbook/gui/widgets/ea-minicard-view.c
+++ b/addressbook/gui/widgets/ea-minicard-view.c
@@ -101,7 +101,7 @@ ea_minicard_view_get_type (void)
 		 * we are run-time deriving from (GailWidget, in this case) */
 
 		factory = atk_registry_get_factory (atk_get_default_registry (),
-							GNOME_TYPE_CANVAS_GROUP);
+							FOO_TYPE_CANVAS_GROUP);
 		derived_atk_type = atk_object_factory_get_accessible_type (factory);
 		g_type_query (derived_atk_type, &query);
 
diff --git a/addressbook/gui/widgets/ea-minicard.c b/addressbook/gui/widgets/ea-minicard.c
index 8791a68..d64b27f 100644
--- a/addressbook/gui/widgets/ea-minicard.c
+++ b/addressbook/gui/widgets/ea-minicard.c
@@ -83,7 +83,7 @@ ea_minicard_get_type (void)
 		 */
 
 		factory = atk_registry_get_factory (atk_get_default_registry (),
-						    GNOME_TYPE_CANVAS_GROUP);
+						    FOO_TYPE_CANVAS_GROUP);
 		derived_atk_type = atk_object_factory_get_accessible_type (factory);
 		g_type_query (derived_atk_type, &query);
 
diff --git a/calendar/gui/e-cal-list-view.c b/calendar/gui/e-cal-list-view.c
index 1f9ca3f..bda49b5 100644
--- a/calendar/gui/e-cal-list-view.c
+++ b/calendar/gui/e-cal-list-view.c
@@ -193,7 +193,7 @@ setup_e_table (ECalListView *cal_list_view)
 	ETableExtras *extras;
 	GList *strings;
 	ECell *cell, *popup_cell;
-	GnomeCanvas *canvas;
+	FooCanvas *canvas;
 	GtkStyle *style;
 	gchar *etspecfile;
 
@@ -289,7 +289,7 @@ setup_e_table (ECalListView *cal_list_view)
 
 	/* Make sure text is readable on top of our color coding */
 
-	canvas = GNOME_CANVAS (e_table_scrolled_get_table (cal_list_view->table_scrolled)->table_canvas);
+	canvas = FOO_CANVAS (e_table_scrolled_get_table (cal_list_view->table_scrolled)->table_canvas);
 	style = gtk_widget_get_style (GTK_WIDGET (canvas));
 
 	style->fg [GTK_STATE_SELECTED] = style->text [GTK_STATE_NORMAL];
diff --git a/calendar/gui/e-calendar-table.c b/calendar/gui/e-calendar-table.c
index 13cbeee..c8cc0ba 100644
--- a/calendar/gui/e-calendar-table.c
+++ b/calendar/gui/e-calendar-table.c
@@ -1455,8 +1455,8 @@ clipboard_paste_received_cb (GtkClipboard *clipboard,
 {
 	ECalendarTable *cal_table = E_CALENDAR_TABLE (data);
 	ETable *e_table = e_calendar_table_get_table (cal_table);
-	GnomeCanvas *canvas = e_table->table_canvas;
-	GnomeCanvasItem *item = GNOME_CANVAS (canvas)->focused_item;
+	FooCanvas *canvas = e_table->table_canvas;
+	FooCanvasItem *item = FOO_CANVAS (canvas)->focused_item;
 
 	if (gtk_clipboard_wait_is_text_available (clipboard) &&
 	    GTK_WIDGET_HAS_FOCUS (canvas) &&
diff --git a/calendar/gui/e-calendar-view.h b/calendar/gui/e-calendar-view.h
index 58334d3..8f42ff5 100644
--- a/calendar/gui/e-calendar-view.h
+++ b/calendar/gui/e-calendar-view.h
@@ -70,7 +70,7 @@ typedef enum {
 } ECalViewMoveDirection;
 
 #define E_CALENDAR_VIEW_EVENT_FIELDS \
-	GnomeCanvasItem *canvas_item; \
+	FooCanvasItem *canvas_item; \
 	ECalModelComponent *comp_data; \
 	time_t start; \
 	time_t end; \
diff --git a/calendar/gui/e-day-view-main-item.c b/calendar/gui/e-day-view-main-item.c
index f0e988a..1325e39 100644
--- a/calendar/gui/e-day-view-main-item.c
+++ b/calendar/gui/e-day-view-main-item.c
@@ -29,6 +29,7 @@
 #include <config.h>
 #endif
 
+#include <math.h>
 #include "e-util/e-categories-config.h"
 #include "e-day-view-layout.h"
 #include "e-day-view-main-item.h"
@@ -43,18 +44,18 @@ static void e_day_view_main_item_set_property (GObject *object,
 					       guint property_id,
 					       const GValue *value,
 					       GParamSpec *pspec);
-static void e_day_view_main_item_update (GnomeCanvasItem *item,
-					 double *affine,
-					 ArtSVP *clip_path, gint flags);
-static void e_day_view_main_item_draw (GnomeCanvasItem *item,
+static void e_day_view_main_item_update (FooCanvasItem *item,
+					 double i2w_dx,
+					 double i2w_dy,
+					 gint flags);
+static void e_day_view_main_item_draw (FooCanvasItem *item,
 				       GdkDrawable *drawable,
-				       gint x, gint y,
-				       gint width, gint height);
-static double e_day_view_main_item_point (GnomeCanvasItem *item,
+				       GdkEventExpose *expose);
+static double e_day_view_main_item_point (FooCanvasItem *item,
 					  double x, double y,
 					  gint cx, gint cy,
-					  GnomeCanvasItem **actual_item);
-static gint e_day_view_main_item_event (GnomeCanvasItem *item,
+					  FooCanvasItem **actual_item);
+static gint e_day_view_main_item_event (FooCanvasItem *item,
 					GdkEvent *event);
 
 static void e_day_view_main_item_draw_long_events_in_vbars (EDayViewMainItem *dvmitem,
@@ -85,18 +86,18 @@ enum {
 	PROP_DAY_VIEW
 };
 
-G_DEFINE_TYPE (EDayViewMainItem, e_day_view_main_item, GNOME_TYPE_CANVAS_ITEM)
+G_DEFINE_TYPE (EDayViewMainItem, e_day_view_main_item, FOO_TYPE_CANVAS_ITEM)
 
 static void
 e_day_view_main_item_class_init (EDayViewMainItemClass *class)
 {
 	GObjectClass  *object_class;
-	GnomeCanvasItemClass *item_class;
+	FooCanvasItemClass *item_class;
 
 	object_class = G_OBJECT_CLASS (class);
 	object_class->set_property = e_day_view_main_item_set_property;
 
-	item_class = GNOME_CANVAS_ITEM_CLASS (class);
+	item_class = FOO_CANVAS_ITEM_CLASS (class);
 	item_class->update = e_day_view_main_item_update;
 	item_class->draw = e_day_view_main_item_draw;
 	item_class->point = e_day_view_main_item_point;
@@ -143,13 +144,13 @@ e_day_view_main_item_set_property (GObject *object,
 }
 
 static void
-e_day_view_main_item_update (GnomeCanvasItem *item,
-			    double *affine,
-			    ArtSVP *clip_path,
+e_day_view_main_item_update (FooCanvasItem *item,
+			    double i2w_dx,
+			    double i2w_dy,
 			    gint flags)
 {
-	if (GNOME_CANVAS_ITEM_CLASS (e_day_view_main_item_parent_class)->update)
-		(* GNOME_CANVAS_ITEM_CLASS (e_day_view_main_item_parent_class)->update) (item, affine, clip_path, flags);
+	if (FOO_CANVAS_ITEM_CLASS (e_day_view_main_item_parent_class)->update)
+		(* FOO_CANVAS_ITEM_CLASS (e_day_view_main_item_parent_class)->update) (item, i2w_dx, i2w_dy, flags);
 
 	/* The item covers the entire canvas area. */
 	item->x1 = 0;
@@ -192,8 +193,8 @@ icalcomp_is_transparent (icalcomponent *icalcomp)
  * DRAWING ROUTINES - functions to paint the canvas item.
  */
 static void
-e_day_view_main_item_draw (GnomeCanvasItem *canvas_item, GdkDrawable *drawable,
-			   gint x, gint y, gint width, gint height)
+e_day_view_main_item_draw (FooCanvasItem *canvas_item, GdkDrawable *drawable,
+			   GdkEventExpose *expose)
 {
 	EDayViewMainItem *dvmitem;
 	EDayView *day_view;
@@ -204,6 +205,7 @@ e_day_view_main_item_draw (GnomeCanvasItem *canvas_item, GdkDrawable *drawable,
 	gint work_day_start_y, work_day_end_y;
 	gint day_x, day_w, work_day;
 	gint start_row, end_row, rect_x, rect_y, rect_width, rect_height;
+	gint x, y, width, height;
 	struct icaltimetype day_start_tt, today_tt;
 	gint weekday;
 	cairo_t *cr;
@@ -211,6 +213,11 @@ e_day_view_main_item_draw (GnomeCanvasItem *canvas_item, GdkDrawable *drawable,
 	GdkRegion *draw_region;
 	GdkRectangle rect;
 
+	x = expose->area.x;
+	y = expose->area.y;
+	width = expose->area.width;
+	height = expose->area.height;
+
 	cr = gdk_cairo_create (drawable);
 
 #if 0
@@ -1251,16 +1258,16 @@ e_day_view_main_item_draw_day_event (EDayViewMainItem *dvmitem,
    Since we are the only item we just return ourself and 0 for the distance.
    This is needed so that we get button/motion events. */
 static double
-e_day_view_main_item_point (GnomeCanvasItem *item, double x, double y,
+e_day_view_main_item_point (FooCanvasItem *item, double x, double y,
 			    gint cx, gint cy,
-			    GnomeCanvasItem **actual_item)
+			    FooCanvasItem **actual_item)
 {
 	*actual_item = item;
 	return 0.0;
 }
 
 static gint
-e_day_view_main_item_event (GnomeCanvasItem *item, GdkEvent *event)
+e_day_view_main_item_event (FooCanvasItem *item, GdkEvent *event)
 {
 	switch (event->type) {
 	case GDK_BUTTON_PRESS:
diff --git a/calendar/gui/e-day-view-main-item.h b/calendar/gui/e-day-view-main-item.h
index 5204115..f869ff2 100644
--- a/calendar/gui/e-day-view-main-item.h
+++ b/calendar/gui/e-day-view-main-item.h
@@ -40,14 +40,14 @@ G_BEGIN_DECLS
 	e_day_view_main_item_get_type ()))
 
 typedef struct {
-	GnomeCanvasItem canvas_item;
+	FooCanvasItem canvas_item;
 
 	/* The parent EDayView widget. */
 	EDayView *day_view;
 } EDayViewMainItem;
 
 typedef struct {
-	GnomeCanvasItemClass parent_class;
+	FooCanvasItemClass parent_class;
 
 } EDayViewMainItemClass;
 
diff --git a/calendar/gui/e-day-view-time-item.c b/calendar/gui/e-day-view-time-item.c
index 8c4a2fd..ab9bd7b 100644
--- a/calendar/gui/e-day-view-time-item.c
+++ b/calendar/gui/e-day-view-time-item.c
@@ -62,18 +62,18 @@ static void e_day_view_time_item_set_property (GObject *object,
 
 static void e_day_view_time_item_finalize (GObject *object);
 
-static void e_day_view_time_item_update (GnomeCanvasItem *item,
-					 double *affine,
-					 ArtSVP *clip_path, gint flags);
-static void e_day_view_time_item_draw (GnomeCanvasItem *item,
+static void e_day_view_time_item_update (FooCanvasItem *item,
+					 double i2w_dx,
+					 double i2w_dy,
+					 gint flags);
+static void e_day_view_time_item_draw (FooCanvasItem *item,
 				       GdkDrawable *drawable,
-				       gint x, gint y,
-				       gint width, gint height);
-static double e_day_view_time_item_point (GnomeCanvasItem *item,
+				       GdkEventExpose *expose);
+static double e_day_view_time_item_point (FooCanvasItem *item,
 					  double x, double y,
 					  gint cx, gint cy,
-					  GnomeCanvasItem **actual_item);
-static gint e_day_view_time_item_event (GnomeCanvasItem *item,
+					  FooCanvasItem **actual_item);
+static gint e_day_view_time_item_event (FooCanvasItem *item,
 					GdkEvent *event);
 static void e_day_view_time_item_increment_time	(gint	*hour,
 						 gint	*minute,
@@ -98,19 +98,19 @@ enum {
 	PROP_DAY_VIEW
 };
 
-G_DEFINE_TYPE (EDayViewTimeItem, e_day_view_time_item, GNOME_TYPE_CANVAS_ITEM)
+G_DEFINE_TYPE (EDayViewTimeItem, e_day_view_time_item, FOO_TYPE_CANVAS_ITEM)
 
 static void
 e_day_view_time_item_class_init (EDayViewTimeItemClass *class)
 {
 	GObjectClass  *object_class;
-	GnomeCanvasItemClass *item_class;
+	FooCanvasItemClass *item_class;
 
 	object_class = G_OBJECT_CLASS (class);
 	object_class->set_property = e_day_view_time_item_set_property;
 	object_class->finalize = e_day_view_time_item_finalize;
 
-	item_class = GNOME_CANVAS_ITEM_CLASS (class);
+	item_class = FOO_CANVAS_ITEM_CLASS (class);
 	item_class->update = e_day_view_time_item_update;
 	item_class->draw = e_day_view_time_item_draw;
 	item_class->point = e_day_view_time_item_point;
@@ -180,13 +180,13 @@ e_day_view_time_item_finalize (GObject *object)
 }
 
 static void
-e_day_view_time_item_update (GnomeCanvasItem *item,
-			    double *affine,
-			    ArtSVP *clip_path,
+e_day_view_time_item_update (FooCanvasItem *item,
+			    double i2w_dx,
+			    double i2w_dy,
 			    gint flags)
 {
-	if (GNOME_CANVAS_ITEM_CLASS (e_day_view_time_item_parent_class)->update)
-		(* GNOME_CANVAS_ITEM_CLASS (e_day_view_time_item_parent_class)->update) (item, affine, clip_path, flags);
+	if (FOO_CANVAS_ITEM_CLASS (e_day_view_time_item_parent_class)->update)
+		(* FOO_CANVAS_ITEM_CLASS (e_day_view_time_item_parent_class)->update) (item, i2w_dx, i2w_dy, flags);
 
 	/* The item covers the entire canvas area. */
 	item->x1 = 0;
@@ -268,7 +268,7 @@ e_day_view_time_item_get_column_width (EDayViewTimeItem *dvtmitem)
  * DRAWING ROUTINES - functions to paint the canvas item.
  */
 static void
-edvti_draw_zone (GnomeCanvasItem   *canvas_item,
+edvti_draw_zone (FooCanvasItem   *canvas_item,
 		GdkDrawable	   *drawable,
 		gint		    x,
 		gint		    y,
@@ -606,18 +606,21 @@ edvti_draw_zone (GnomeCanvasItem   *canvas_item,
 }
 
 static void
-e_day_view_time_item_draw (GnomeCanvasItem *canvas_item,
+e_day_view_time_item_draw (FooCanvasItem *canvas_item,
 			   GdkDrawable	   *drawable,
-			   gint		    x,
-			   gint		    y,
-			   gint		    width,
-			   gint		    height)
+			   GdkEventExpose  *expose)
 {
 	EDayViewTimeItem *dvtmitem;
+	gint x, y, width, height;
 
 	dvtmitem = E_DAY_VIEW_TIME_ITEM (canvas_item);
 	g_return_if_fail (dvtmitem != NULL);
 
+	x = expose->area.x;
+	y = expose->area.y;
+	width = expose->area.width;
+	height = expose->area.height;
+
 	edvti_draw_zone (canvas_item, drawable, x, y, width, height, 0, NULL);
 
 	if (dvtmitem->second_zone)
@@ -642,16 +645,16 @@ e_day_view_time_item_increment_time	(gint	*hour,
 }
 
 static double
-e_day_view_time_item_point (GnomeCanvasItem *item, double x, double y,
+e_day_view_time_item_point (FooCanvasItem *item, double x, double y,
 			    gint cx, gint cy,
-			    GnomeCanvasItem **actual_item)
+			    FooCanvasItem **actual_item)
 {
 	*actual_item = item;
 	return 0.0;
 }
 
 static gint
-e_day_view_time_item_event (GnomeCanvasItem *item,
+e_day_view_time_item_event (FooCanvasItem *item,
 			    GdkEvent *event)
 {
 	EDayViewTimeItem *dvtmitem;
@@ -845,13 +848,13 @@ e_day_view_time_item_on_button_press (EDayViewTimeItem *dvtmitem,
 				      GdkEvent *event)
 {
 	EDayView *day_view;
-	GnomeCanvas *canvas;
+	FooCanvas *canvas;
 	gint row;
 
 	day_view = dvtmitem->day_view;
 	g_return_if_fail (day_view != NULL);
 
-	canvas = GNOME_CANVAS_ITEM (dvtmitem)->canvas;
+	canvas = FOO_CANVAS_ITEM (dvtmitem)->canvas;
 
 	row = e_day_view_time_item_convert_position_to_row (dvtmitem,
 							    event->button.y);
@@ -894,7 +897,7 @@ e_day_view_time_item_on_motion_notify (EDayViewTimeItem *dvtmitem,
 				       GdkEvent *event)
 {
 	EDayView *day_view;
-	GnomeCanvas *canvas;
+	FooCanvas *canvas;
 	gdouble window_y;
 	gint y, row;
 
@@ -904,13 +907,13 @@ e_day_view_time_item_on_motion_notify (EDayViewTimeItem *dvtmitem,
 	day_view = dvtmitem->day_view;
 	g_return_if_fail (day_view != NULL);
 
-	canvas = GNOME_CANVAS_ITEM (dvtmitem)->canvas;
+	canvas = FOO_CANVAS_ITEM (dvtmitem)->canvas;
 
 	y = event->motion.y;
 	row = e_day_view_time_item_convert_position_to_row (dvtmitem, y);
 
 	if (row != -1) {
-		gnome_canvas_world_to_window (canvas, 0, event->motion.y,
+		foo_canvas_world_to_window (canvas, 0, event->motion.y,
 					      NULL, &window_y);
 		e_day_view_update_selection (day_view, -1, row);
 		e_day_view_check_auto_scroll (day_view, -1, (gint) window_y);
diff --git a/calendar/gui/e-day-view-time-item.h b/calendar/gui/e-day-view-time-item.h
index 802ca50..a7141dd 100644
--- a/calendar/gui/e-day-view-time-item.h
+++ b/calendar/gui/e-day-view-time-item.h
@@ -41,7 +41,7 @@ G_BEGIN_DECLS
 	e_day_view_time_item_get_type ()))
 
 typedef struct {
-	GnomeCanvasItem canvas_item;
+	FooCanvasItem canvas_item;
 
 	/* The parent EDayView widget. */
 	EDayView *day_view;
@@ -58,7 +58,7 @@ typedef struct {
 } EDayViewTimeItem;
 
 typedef struct {
-	GnomeCanvasItemClass parent_class;
+	FooCanvasItemClass parent_class;
 
 } EDayViewTimeItemClass;
 
diff --git a/calendar/gui/e-day-view-top-item.c b/calendar/gui/e-day-view-top-item.c
index a1f083e..cd61c1d 100644
--- a/calendar/gui/e-day-view-top-item.c
+++ b/calendar/gui/e-day-view-top-item.c
@@ -42,16 +42,13 @@ static void e_day_view_top_item_set_property	(GObject	 *object,
 						 guint		  property_id,
 						 const GValue	 *value,
 						 GParamSpec	 *pspec);
-static void e_day_view_top_item_update		(GnomeCanvasItem *item,
-						 double		 *affine,
-						 ArtSVP		 *clip_path,
+static void e_day_view_top_item_update		(FooCanvasItem *item,
+						 double		  i2w_dx,
+						 double		  i2w_dy,
 						 gint		  flags);
-static void e_day_view_top_item_draw		(GnomeCanvasItem *item,
+static void e_day_view_top_item_draw		(FooCanvasItem *item,
 						 GdkDrawable	 *drawable,
-						 gint		  x,
-						 gint		  y,
-						 gint		  width,
-						 gint		  height);
+						 GdkEventExpose	 *expose);
 static void e_day_view_top_item_draw_long_event	(EDayViewTopItem *dvtitem,
 						 gint		  event_num,
 						 GdkDrawable	 *drawable,
@@ -66,13 +63,13 @@ static void e_day_view_top_item_draw_triangle	(EDayViewTopItem *dvtitem,
 						 gint		  w,
 						 gint		  h,
 						 gint             event_num);
-static double e_day_view_top_item_point		(GnomeCanvasItem *item,
+static double e_day_view_top_item_point		(FooCanvasItem *item,
 						 double		  x,
 						 double		  y,
 						 gint		  cx,
 						 gint		  cy,
-						 GnomeCanvasItem **actual_item);
-static gint e_day_view_top_item_event		(GnomeCanvasItem *item,
+						 FooCanvasItem **actual_item);
+static gint e_day_view_top_item_event		(FooCanvasItem *item,
 						 GdkEvent	 *event);
 
 /* The arguments we take */
@@ -82,18 +79,18 @@ enum {
 	PROP_SHOW_DATES
 };
 
-G_DEFINE_TYPE (EDayViewTopItem, e_day_view_top_item, GNOME_TYPE_CANVAS_ITEM)
+G_DEFINE_TYPE (EDayViewTopItem, e_day_view_top_item, FOO_TYPE_CANVAS_ITEM)
 
 static void
 e_day_view_top_item_class_init (EDayViewTopItemClass *class)
 {
 	GObjectClass  *object_class;
-	GnomeCanvasItemClass *item_class;
+	FooCanvasItemClass *item_class;
 
 	object_class = G_OBJECT_CLASS (class);
 	object_class->set_property = e_day_view_top_item_set_property;
 
-	item_class = GNOME_CANVAS_ITEM_CLASS (class);
+	item_class = FOO_CANVAS_ITEM_CLASS (class);
 	item_class->update = e_day_view_top_item_update;
 	item_class->draw = e_day_view_top_item_draw;
 	item_class->point = e_day_view_top_item_point;
@@ -149,13 +146,13 @@ e_day_view_top_item_set_property (GObject *object,
 }
 
 static void
-e_day_view_top_item_update (GnomeCanvasItem *item,
-			    double	    *affine,
-			    ArtSVP	    *clip_path,
-			    gint		     flags)
+e_day_view_top_item_update (FooCanvasItem *item,
+			    double	     i2w_dx,
+			    double	     i2w_dy,
+			    gint	     flags)
 {
-	if (GNOME_CANVAS_ITEM_CLASS (e_day_view_top_item_parent_class)->update)
-		(* GNOME_CANVAS_ITEM_CLASS (e_day_view_top_item_parent_class)->update) (item, affine, clip_path, flags);
+	if (FOO_CANVAS_ITEM_CLASS (e_day_view_top_item_parent_class)->update)
+		(* FOO_CANVAS_ITEM_CLASS (e_day_view_top_item_parent_class)->update) (item, i2w_dx, i2w_dy, flags);
 
 	/* The item covers the entire canvas area. */
 	item->x1 = 0;
@@ -168,12 +165,9 @@ e_day_view_top_item_update (GnomeCanvasItem *item,
  * DRAWING ROUTINES - functions to paint the canvas item.
  */
 static void
-e_day_view_top_item_draw (GnomeCanvasItem *canvas_item,
+e_day_view_top_item_draw (FooCanvasItem *canvas_item,
 			  GdkDrawable	  *drawable,
-			  gint		   x,
-			  gint		   y,
-			  gint		   width,
-			  gint		   height)
+			  GdkEventExpose  *expose)
 {
 	EDayViewTopItem *dvtitem;
 	EDayView *day_view;
@@ -186,8 +180,14 @@ e_day_view_top_item_draw (GnomeCanvasItem *canvas_item,
 	PangoLayout *layout;
 	cairo_t *cr;
 	GdkColor fg, bg, light, dark;
+	gint x, y, width, height;
 	gboolean show_dates;
 
+	x = expose->area.x;
+	y = expose->area.y;
+	width = expose->area.width;
+	height = expose->area.height;
+
 #if 0
 	g_print ("In e_day_view_top_item_draw %i,%i %ix%i\n",
 		 x, y, width, height);
@@ -792,16 +792,16 @@ e_day_view_top_item_draw_triangle (EDayViewTopItem *dvtitem,
    Since we are the only item we just return ourself and 0 for the distance.
    This is needed so that we get button/motion events. */
 static double
-e_day_view_top_item_point (GnomeCanvasItem *item, double x, double y,
+e_day_view_top_item_point (FooCanvasItem *item, double x, double y,
 			   gint cx, gint cy,
-			   GnomeCanvasItem **actual_item)
+			   FooCanvasItem **actual_item)
 {
 	*actual_item = item;
 	return 0.0;
 }
 
 static gint
-e_day_view_top_item_event (GnomeCanvasItem *item, GdkEvent *event)
+e_day_view_top_item_event (FooCanvasItem *item, GdkEvent *event)
 {
 	switch (event->type) {
 	case GDK_BUTTON_PRESS:
diff --git a/calendar/gui/e-day-view-top-item.h b/calendar/gui/e-day-view-top-item.h
index e163e3e..2eeb9b5 100644
--- a/calendar/gui/e-day-view-top-item.h
+++ b/calendar/gui/e-day-view-top-item.h
@@ -40,7 +40,7 @@ G_BEGIN_DECLS
 	e_day_view_top_item_get_type ()))
 
 typedef struct {
-	GnomeCanvasItem canvas_item;
+	FooCanvasItem canvas_item;
 
 	/* The parent EDayView widget. */
 	EDayView *day_view;
@@ -50,7 +50,7 @@ typedef struct {
 } EDayViewTopItem;
 
 typedef struct {
-	GnomeCanvasItemClass parent_class;
+	FooCanvasItemClass parent_class;
 
 } EDayViewTopItemClass;
 
diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c
index 879155f..6214cda 100644
--- a/calendar/gui/e-day-view.c
+++ b/calendar/gui/e-day-view.c
@@ -36,7 +36,7 @@
 #include <misc/e-popup-menu.h>
 #include <misc/e-gui-utils.h>
 #include <e-util/e-unicode.h>
-#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
+#include <libfoocanvas/foo-canvas-rect-ellipse.h>
 #include <glib/gi18n.h>
 #include <e-util/e-binding.h>
 #include <e-util/e-categories-config.h>
@@ -333,7 +333,7 @@ static void e_day_view_start_editing_event (EDayView *day_view,
 					    gint event_num,
 					    GdkEventKey *key_event);
 static void e_day_view_stop_editing_event (EDayView *day_view);
-static gboolean e_day_view_on_text_item_event (GnomeCanvasItem *item,
+static gboolean e_day_view_on_text_item_event (FooCanvasItem *item,
 					       GdkEvent *event,
 					       EDayView *day_view);
 static gboolean e_day_view_event_move (ECalendarView *cal_view, ECalViewMoveDirection direction);
@@ -342,9 +342,9 @@ time_t end_dt);
 static void e_day_view_change_event_end_time_up (EDayView *day_view);
 static void e_day_view_change_event_end_time_down (EDayView *day_view);
 static void e_day_view_on_editing_started (EDayView *day_view,
-					   GnomeCanvasItem *item);
+					   FooCanvasItem *item);
 static void e_day_view_on_editing_stopped (EDayView *day_view,
-					   GnomeCanvasItem *item);
+					   FooCanvasItem *item);
 
 static time_t e_day_view_convert_grid_position_to_time (EDayView *day_view,
 							gint col,
@@ -1051,7 +1051,7 @@ static void
 e_day_view_init (EDayView *day_view)
 {
 	gint day;
-	GnomeCanvasGroup *canvas_group;
+	FooCanvasGroup *canvas_group;
 	GtkWidget *w;
 
 	GTK_WIDGET_SET_FLAGS (day_view, GTK_CAN_FOCUS);
@@ -1189,34 +1189,34 @@ e_day_view_init (EDayView *day_view)
 	g_signal_connect (day_view->top_canvas, "drag_data_received",
 			  G_CALLBACK (e_day_view_on_top_canvas_drag_data_received), day_view);
 
-	canvas_group = GNOME_CANVAS_GROUP (GNOME_CANVAS (day_view->top_dates_canvas)->root);
+	canvas_group = FOO_CANVAS_GROUP (FOO_CANVAS (day_view->top_dates_canvas)->root);
 
 	day_view->top_dates_canvas_item =
-		gnome_canvas_item_new (canvas_group,
+		foo_canvas_item_new (canvas_group,
 				       e_day_view_top_item_get_type (),
 				       "EDayViewTopItem::day_view", day_view,
 				       "EDayViewTopItem::show_dates", TRUE,
 				       NULL);
 	gtk_widget_set_size_request (day_view->top_dates_canvas, -1, day_view->top_row_height);
 
-	canvas_group = GNOME_CANVAS_GROUP (GNOME_CANVAS (day_view->top_canvas)->root);
+	canvas_group = FOO_CANVAS_GROUP (FOO_CANVAS (day_view->top_canvas)->root);
 
 	day_view->top_canvas_item =
-		gnome_canvas_item_new (canvas_group,
+		foo_canvas_item_new (canvas_group,
 				       e_day_view_top_item_get_type (),
 				       "EDayViewTopItem::day_view", day_view,
 				       "EDayViewTopItem::show_dates", FALSE,
 				       NULL);
 
 	day_view->drag_long_event_rect_item =
-		gnome_canvas_item_new (canvas_group,
-				       gnome_canvas_rect_get_type (),
+		foo_canvas_item_new (canvas_group,
+				       foo_canvas_rect_get_type (),
 				       "width_pixels", 1,
 				       NULL);
-	gnome_canvas_item_hide (day_view->drag_long_event_rect_item);
+	foo_canvas_item_hide (day_view->drag_long_event_rect_item);
 
 	day_view->drag_long_event_item =
-		gnome_canvas_item_new (canvas_group,
+		foo_canvas_item_new (canvas_group,
 				       e_text_get_type (),
 				       "anchor", GTK_ANCHOR_NW,
 				       "line_wrap", TRUE,
@@ -1224,9 +1224,9 @@ e_day_view_init (EDayView *day_view)
 				       "max_lines", 1,
 				       "editable", TRUE,
 				       "draw_background", FALSE,
-				       "fill_color_rgba", GNOME_CANVAS_COLOR(0, 0, 0),
+				       "fill_color_rgba", FOO_CANVAS_COLOR(0, 0, 0),
 				       NULL);
-	gnome_canvas_item_hide (day_view->drag_long_event_item);
+	foo_canvas_item_hide (day_view->drag_long_event_item);
 
 	/*
 	 * Main Canvas
@@ -1273,39 +1273,39 @@ e_day_view_init (EDayView *day_view)
 	g_signal_connect (day_view->main_canvas, "drag_data_received",
 			  G_CALLBACK (e_day_view_on_main_canvas_drag_data_received), day_view);
 
-	canvas_group = GNOME_CANVAS_GROUP (GNOME_CANVAS (day_view->main_canvas)->root);
+	canvas_group = FOO_CANVAS_GROUP (FOO_CANVAS (day_view->main_canvas)->root);
 
 	day_view->main_canvas_item =
-		gnome_canvas_item_new (canvas_group,
+		foo_canvas_item_new (canvas_group,
 				       e_day_view_main_item_get_type (),
 				       "EDayViewMainItem::day_view", day_view,
 				       NULL);
 
 	day_view->drag_rect_item =
-		gnome_canvas_item_new (canvas_group,
-				       gnome_canvas_rect_get_type (),
+		foo_canvas_item_new (canvas_group,
+				       foo_canvas_rect_get_type (),
 				       "width_pixels", 1,
 				       NULL);
-	gnome_canvas_item_hide (day_view->drag_rect_item);
+	foo_canvas_item_hide (day_view->drag_rect_item);
 
 	day_view->drag_bar_item =
-		gnome_canvas_item_new (canvas_group,
-				       gnome_canvas_rect_get_type (),
+		foo_canvas_item_new (canvas_group,
+				       foo_canvas_rect_get_type (),
 				       "width_pixels", 1,
 				       NULL);
-	gnome_canvas_item_hide (day_view->drag_bar_item);
+	foo_canvas_item_hide (day_view->drag_bar_item);
 
 	day_view->drag_item =
-		gnome_canvas_item_new (canvas_group,
+		foo_canvas_item_new (canvas_group,
 				       e_text_get_type (),
 				       "anchor", GTK_ANCHOR_NW,
 				       "line_wrap", TRUE,
 				       "clip", TRUE,
 				       "editable", TRUE,
 				       "draw_background", FALSE,
-				       "fill_color_rgba", GNOME_CANVAS_COLOR(0, 0, 0),
+				       "fill_color_rgba", FOO_CANVAS_COLOR(0, 0, 0),
 				       NULL);
-	gnome_canvas_item_hide (day_view->drag_item);
+	foo_canvas_item_hide (day_view->drag_item);
 
 	/*
 	 * Times Canvas
@@ -1320,10 +1320,10 @@ e_day_view_init (EDayView *day_view)
 	g_signal_connect_after (day_view->time_canvas, "scroll_event",
 				G_CALLBACK (e_day_view_on_time_canvas_scroll), day_view);
 
-	canvas_group = GNOME_CANVAS_GROUP (GNOME_CANVAS (day_view->time_canvas)->root);
+	canvas_group = FOO_CANVAS_GROUP (FOO_CANVAS (day_view->time_canvas)->root);
 
 	day_view->time_canvas_item =
-		gnome_canvas_item_new (canvas_group,
+		foo_canvas_item_new (canvas_group,
 				       e_day_view_time_item_get_type (),
 				       "EDayViewTimeItem::day_view", day_view,
 				       NULL);
@@ -1385,7 +1385,7 @@ init_model (EDayView *day_view, ECalModel *model)
 }
 
 /* Turn off the background of the canvas windows. This reduces flicker
-   considerably when scrolling. (Why isn't it in GnomeCanvas?). */
+   considerably when scrolling. (Why isn't it in FooCanvas?). */
 static void
 e_day_view_on_canvas_realized (GtkWidget *widget,
 			       EDayView *day_view)
@@ -1496,17 +1496,17 @@ e_day_view_realize (GtkWidget *widget)
 	day_view->attach_icon = e_icon_factory_get_icon ("mail-attachment", GTK_ICON_SIZE_MENU);
 
 	/* Set the canvas item colors. */
-	gnome_canvas_item_set (day_view->drag_long_event_rect_item,
+	foo_canvas_item_set (day_view->drag_long_event_rect_item,
 			       "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND],
 			       "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER],
 			       NULL);
 
-	gnome_canvas_item_set (day_view->drag_rect_item,
+	foo_canvas_item_set (day_view->drag_rect_item,
 			       "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND],
 			       "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER],
 			       NULL);
 
-	gnome_canvas_item_set (day_view->drag_bar_item,
+	foo_canvas_item_set (day_view->drag_bar_item,
 			       "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR],
 			       "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER],
 			       NULL);
@@ -1608,23 +1608,23 @@ e_day_view_update_top_scroll (EDayView *day_view, gboolean scroll_to_top)
 	}
 
 	/* Set the scroll region of the top canvas */
-	gnome_canvas_get_scroll_region (GNOME_CANVAS (day_view->top_canvas),
+	foo_canvas_get_scroll_region (FOO_CANVAS (day_view->top_canvas),
 					NULL, NULL, &old_x2, &old_y2);
 	new_x2 = day_view->top_canvas->allocation.width - 1;
 	new_y2 = (MAX (1, day_view->rows_in_top_display) + 1) * day_view->top_row_height - 1;
 	if (old_x2 != new_x2 || old_y2 != new_y2) {
-		gnome_canvas_set_scroll_region (GNOME_CANVAS (day_view->top_canvas),
+		foo_canvas_set_scroll_region (FOO_CANVAS (day_view->top_canvas),
 						0, 0, new_x2, new_y2);
 
 		if (scroll_to_top)
-			gnome_canvas_scroll_to (GNOME_CANVAS (day_view->top_canvas), 0, 0);
+			foo_canvas_scroll_to (FOO_CANVAS (day_view->top_canvas), 0, 0);
 	}
 	new_y2 = day_view->top_row_height - 1 - 2;
-	gnome_canvas_get_scroll_region (GNOME_CANVAS (day_view->top_dates_canvas), NULL, NULL, &old_x2, &old_y2);
+	foo_canvas_get_scroll_region (FOO_CANVAS (day_view->top_dates_canvas), NULL, NULL, &old_x2, &old_y2);
 
 	if (old_x2 != new_x2 || old_y2 != new_y2) {
-		gnome_canvas_set_scroll_region (GNOME_CANVAS (day_view->top_dates_canvas), 0, 0, new_x2, new_y2);
-		gnome_canvas_scroll_to (GNOME_CANVAS (day_view->top_dates_canvas), 0, 0);
+		foo_canvas_set_scroll_region (FOO_CANVAS (day_view->top_dates_canvas), 0, 0, new_x2, new_y2);
+		foo_canvas_scroll_to (FOO_CANVAS (day_view->top_dates_canvas), 0, 0);
 	}
 }
 
@@ -1660,7 +1660,7 @@ e_day_view_style_set (GtkWidget *widget,
 			event = &g_array_index (day_view->events[week_day], EDayViewEvent, event_num);
 			if (event->canvas_item) {
 				color = e_day_view_get_text_color (day_view, event, widget);
-				gnome_canvas_item_set (event->canvas_item,
+				foo_canvas_item_set (event->canvas_item,
 						"fill_color_gdk", &color,
 						NULL);
 			}
@@ -1670,7 +1670,7 @@ e_day_view_style_set (GtkWidget *widget,
 		event = &g_array_index (day_view->long_events, EDayViewEvent, event_num);
 		if (event->canvas_item) {
 			color = e_day_view_get_text_color (day_view, event, widget);
-			gnome_canvas_item_set (event->canvas_item,
+			foo_canvas_item_set (event->canvas_item,
 					"fill_color_gdk", &color,
 					NULL);
 		}
@@ -1821,7 +1821,7 @@ e_day_view_recalc_main_canvas_size (EDayView *day_view)
 	   allocation. */
 	if (day_view->scroll_to_work_day) {
 		scroll_y = e_day_view_convert_time_to_position (day_view, day_view->work_day_start_hour, day_view->work_day_start_minute);
-		gnome_canvas_scroll_to (GNOME_CANVAS (day_view->main_canvas),
+		foo_canvas_scroll_to (FOO_CANVAS (day_view->main_canvas),
 					0, scroll_y);
 		day_view->scroll_to_work_day = FALSE;
 	}
@@ -2148,7 +2148,7 @@ set_text_as_bold (EDayViewEvent *event)
 	   If the attendee is not present, it might have come through a mailing list.
 	   In that case, we never show the meeting as bold even if it is unaccepted. */
 	if (at && (at->status == ICAL_PARTSTAT_NEEDSACTION))
-		gnome_canvas_item_set (event->canvas_item, "bold", TRUE, NULL);
+		foo_canvas_item_set (event->canvas_item, "bold", TRUE, NULL);
 
 	e_cal_component_free_attendee_list (attendees);
 	g_free (address);
@@ -2199,7 +2199,7 @@ e_day_view_update_event_label (EDayView *day_view,
 		}
 	}
 
-	gnome_canvas_item_set (event->canvas_item,
+	foo_canvas_item_set (event->canvas_item,
 			       "text", text,
 			       NULL);
 
@@ -2228,7 +2228,7 @@ e_day_view_update_long_event_label (EDayView *day_view,
 
 	summary = e_calendar_view_get_icalcomponent_summary (event->comp_data->client, event->comp_data->icalcomp, &free_text);
 
-	gnome_canvas_item_set (event->canvas_item,
+	foo_canvas_item_set (event->canvas_item,
 			       "text", summary ? summary : "",
 			       NULL);
 
@@ -2245,7 +2245,7 @@ e_day_view_update_long_event_label (EDayView *day_view,
    Returns TRUE if the event was found. */
 gboolean
 e_day_view_find_event_from_item (EDayView *day_view,
-				 GnomeCanvasItem *item,
+				 FooCanvasItem *item,
 				 gint *day_return,
 				 gint *event_num_return)
 {
@@ -3076,18 +3076,18 @@ e_day_view_update_scroll_regions (EDayView *day_view)
 
 	/* Set the scroll region of the time canvas to its allocated width,
 	   but with the height the same as the main canvas. */
-	gnome_canvas_get_scroll_region (GNOME_CANVAS (day_view->time_canvas),
+	foo_canvas_get_scroll_region (FOO_CANVAS (day_view->time_canvas),
 					NULL, NULL, &old_x2, &old_y2);
 	new_x2 = day_view->time_canvas->allocation.width - 1;
 	new_y2 = MAX (day_view->rows * day_view->row_height,
 		      day_view->main_canvas->allocation.height) - 1;
 	if (old_x2 != new_x2 || old_y2 != new_y2)
-		gnome_canvas_set_scroll_region (GNOME_CANVAS (day_view->time_canvas),
+		foo_canvas_set_scroll_region (FOO_CANVAS (day_view->time_canvas),
 						0, 0, new_x2, new_y2);
 
 	/* Set the scroll region of the main canvas to its allocated width,
 	   but with the height depending on the number of rows needed. */
-	gnome_canvas_get_scroll_region (GNOME_CANVAS (day_view->main_canvas),
+	foo_canvas_get_scroll_region (FOO_CANVAS (day_view->main_canvas),
 					NULL, NULL, &old_x2, &old_y2);
 	new_x2 = day_view->main_canvas->allocation.width - 1;
 
@@ -3096,7 +3096,7 @@ e_day_view_update_scroll_regions (EDayView *day_view)
 
 	if (old_x2 != new_x2 || old_y2 != new_y2) {
 		need_reshape = TRUE;
-		gnome_canvas_set_scroll_region (GNOME_CANVAS (day_view->main_canvas),
+		foo_canvas_set_scroll_region (FOO_CANVAS (day_view->main_canvas),
 						0, 0, new_x2, new_y2);
 	}
 
@@ -3530,7 +3530,7 @@ e_day_view_on_long_event_click (EDayView *day_view,
 	/* Ignore clicks on the EText while editing. */
 	if (pos == E_CALENDAR_VIEW_POS_EVENT
 	    && E_TEXT (event->canvas_item)->editing) {
-		GNOME_CANVAS_ITEM_GET_CLASS (event->canvas_item)->event (event->canvas_item, (GdkEvent*)bevent);
+		FOO_CANVAS_ITEM_GET_CLASS (event->canvas_item)->event (event->canvas_item, (GdkEvent*)bevent);
 		return;
 	}
 
@@ -3564,7 +3564,7 @@ e_day_view_on_long_event_click (EDayView *day_view,
 			e_day_view_reshape_resize_long_event_rect_item (day_view);
 
 			/* Raise the event's item, above the rect as well. */
-			gnome_canvas_item_raise_to_top (event->canvas_item);
+			foo_canvas_item_raise_to_top (event->canvas_item);
 		}
 	} else if (e_day_view_get_long_event_position (day_view, event_num,
 						       &start_day, &end_day,
@@ -3603,7 +3603,7 @@ e_day_view_on_event_click (EDayView *day_view,
 	/* Ignore clicks on the EText while editing. */
 	if (pos == E_CALENDAR_VIEW_POS_EVENT
 	    && E_TEXT (event->canvas_item)->editing) {
-		GNOME_CANVAS_ITEM_GET_CLASS (event->canvas_item)->event (event->canvas_item, (GdkEvent*)bevent);
+		FOO_CANVAS_ITEM_GET_CLASS (event->canvas_item)->event (event->canvas_item, (GdkEvent*)bevent);
 		return;
 	}
 
@@ -3644,7 +3644,7 @@ e_day_view_on_event_click (EDayView *day_view,
 			e_day_view_reshape_main_canvas_resize_bars (day_view);
 
 			/* Raise the event's item, above the rect as well. */
-			gnome_canvas_item_raise_to_top (event->canvas_item);
+			foo_canvas_item_raise_to_top (event->canvas_item);
 		}
 
 	} else {
@@ -4010,7 +4010,7 @@ e_day_view_on_top_canvas_motion (GtkWidget *widget,
 		}
 
 		if (event && E_IS_TEXT (event->canvas_item) && E_TEXT (event->canvas_item)->editing) {
-			GNOME_CANVAS_ITEM_GET_CLASS (event->canvas_item)->event (event->canvas_item, (GdkEvent*)mevent);
+			FOO_CANVAS_ITEM_GET_CLASS (event->canvas_item)->event (event->canvas_item, (GdkEvent*)mevent);
 		}
 	}
 
@@ -4118,7 +4118,7 @@ e_day_view_on_main_canvas_motion (GtkWidget *widget,
 		}
 
 		if (event && E_IS_TEXT (event->canvas_item) && E_TEXT (event->canvas_item)->editing) {
-			GNOME_CANVAS_ITEM_GET_CLASS (event->canvas_item)->event (event->canvas_item, (GdkEvent*)mevent);
+			FOO_CANVAS_ITEM_GET_CLASS (event->canvas_item)->event (event->canvas_item, (GdkEvent*)mevent);
 		}
 	}
 
@@ -4874,7 +4874,7 @@ e_day_view_reshape_long_event (EDayView *day_view,
 		color = e_day_view_get_text_color (day_view, event, widget);
 
 		event->canvas_item =
-			gnome_canvas_item_new (GNOME_CANVAS_GROUP (GNOME_CANVAS (day_view->top_canvas)->root),
+			foo_canvas_item_new (FOO_CANVAS_GROUP (FOO_CANVAS (day_view->top_canvas)->root),
 					       e_text_get_type (),
 					       "anchor", GTK_ANCHOR_NW,
 					       "clip", TRUE,
@@ -4942,7 +4942,7 @@ e_day_view_reshape_long_event (EDayView *day_view,
 	}
 
 	text_w = MAX (text_w, 0);
-	gnome_canvas_item_set (event->canvas_item,
+	foo_canvas_item_set (event->canvas_item,
 			       "clip_width", (gdouble) text_w,
 			       "clip_height", (gdouble) item_h,
 			       NULL);
@@ -5054,7 +5054,7 @@ e_day_view_reshape_day_event (EDayView *day_view,
 			color = e_day_view_get_text_color (day_view, event, widget);
 
 			event->canvas_item =
-				gnome_canvas_item_new (GNOME_CANVAS_GROUP (GNOME_CANVAS (day_view->main_canvas)->root),
+				foo_canvas_item_new (FOO_CANVAS_GROUP (FOO_CANVAS (day_view->main_canvas)->root),
 						       e_text_get_type (),
 						       "anchor", GTK_ANCHOR_NW,
 						       "line_wrap", TRUE,
@@ -5076,7 +5076,7 @@ e_day_view_reshape_day_event (EDayView *day_view,
 		}
 
 		item_w = MAX (item_w, 0);
-		gnome_canvas_item_set (event->canvas_item,
+		foo_canvas_item_set (event->canvas_item,
 				       "clip_width", (gdouble) item_w,
 				       "clip_height", (gdouble) item_h,
 				       "x_offset", (gdouble) icons_offset,
@@ -6095,7 +6095,7 @@ e_day_view_start_editing_event (EDayView *day_view,
 			gchar *initial_text;
 
 			initial_text = e_utf8_from_gtk_event_key (GTK_WIDGET (day_view), key_event->keyval, key_event->string);
-			gnome_canvas_item_set (event->canvas_item,
+			foo_canvas_item_set (event->canvas_item,
 					       "text", initial_text,
 					       NULL);
 			if (initial_text)
@@ -6178,7 +6178,7 @@ tooltip_get_view_event (EDayView *day_view, gint day, gint event_num)
 }
 
 static void
-tooltip_destroy (EDayView *day_view, GnomeCanvasItem *item)
+tooltip_destroy (EDayView *day_view, FooCanvasItem *item)
 {
 	EDayViewEvent *pevent;
 	gint event_num = GPOINTER_TO_INT(g_object_get_data ((GObject *)item, "event-num"));
@@ -6201,7 +6201,7 @@ tooltip_destroy (EDayView *day_view, GnomeCanvasItem *item)
 }
 
 static gboolean
-e_day_view_on_text_item_event (GnomeCanvasItem *item,
+e_day_view_on_text_item_event (FooCanvasItem *item,
 			       GdkEvent *event,
 			       EDayView *day_view)
 {
@@ -6581,7 +6581,7 @@ e_day_view_change_event_end_time_down (EDayView *day_view)
 
 static void
 e_day_view_on_editing_started (EDayView *day_view,
-			       GnomeCanvasItem *item)
+			       FooCanvasItem *item)
 {
 	gint day, event_num;
 
@@ -6620,7 +6620,7 @@ e_day_view_on_editing_started (EDayView *day_view,
 			scroll_y = gtk_adjustment_get_value (GTK_LAYOUT (day_view->top_canvas)->vadjustment);
 			if (item_y + day_view->top_row_height > day_view->top_canvas->allocation.height + scroll_y ||
 			    item_y < scroll_y)
-				gnome_canvas_scroll_to (GNOME_CANVAS (day_view->top_canvas), 0, item_y);
+				foo_canvas_scroll_to (FOO_CANVAS (day_view->top_canvas), 0, item_y);
 		}
 	} else {
 		day_view->resize_bars_event_day = day;
@@ -6634,7 +6634,7 @@ e_day_view_on_editing_started (EDayView *day_view,
 
 static void
 e_day_view_on_editing_stopped (EDayView *day_view,
-			       GnomeCanvasItem *item)
+			       FooCanvasItem *item)
 {
 	gint day, event_num;
 	EDayViewEvent *event;
@@ -6882,7 +6882,7 @@ e_day_view_check_auto_scroll (EDayView *day_view,
 {
 	gint scroll_x, scroll_y;
 
-	gnome_canvas_get_scroll_offsets (GNOME_CANVAS (day_view->main_canvas),
+	foo_canvas_get_scroll_offsets (FOO_CANVAS (day_view->main_canvas),
 					 &scroll_x, &scroll_y);
 
 	event_x -= scroll_x;
@@ -6940,7 +6940,7 @@ e_day_view_auto_scroll_handler (gpointer data)
 		return TRUE;
 	}
 
-	gnome_canvas_get_scroll_offsets (GNOME_CANVAS (day_view->main_canvas),
+	foo_canvas_get_scroll_offsets (FOO_CANVAS (day_view->main_canvas),
 					 &scroll_x, &scroll_y);
 
 	adj = GTK_LAYOUT (day_view->main_canvas)->vadjustment;
@@ -6954,7 +6954,7 @@ e_day_view_auto_scroll_handler (gpointer data)
 	if (new_scroll_y != scroll_y) {
 		/* NOTE: This reduces flicker, but only works if we don't use
 		   canvas items which have X windows. */
-		gnome_canvas_scroll_to (GNOME_CANVAS (day_view->main_canvas),
+		foo_canvas_scroll_to (FOO_CANVAS (day_view->main_canvas),
 					scroll_x, new_scroll_y);
 	}
 
@@ -6981,7 +6981,7 @@ e_day_view_auto_scroll_handler (gpointer data)
 		} else if (day_view->resize_drag_pos != E_CALENDAR_VIEW_POS_NONE) {
 			e_day_view_update_resize (day_view, row);
 		} else if (day_view->drag_item->object.flags
-			   & GNOME_CANVAS_ITEM_VISIBLE) {
+			   & FOO_CANVAS_ITEM_VISIBLE) {
 			e_day_view_update_main_canvas_drag (day_view, row,
 							    day);
 		}
@@ -7302,7 +7302,7 @@ e_day_view_on_top_canvas_drag_motion (GtkWidget      *widget,
 {
 	gint scroll_x, scroll_y;
 
-	gnome_canvas_get_scroll_offsets (GNOME_CANVAS (widget),
+	foo_canvas_get_scroll_offsets (FOO_CANVAS (widget),
 					 &scroll_x, &scroll_y);
 	day_view->drag_event_x = x + scroll_x;
 	day_view->drag_event_y = y + scroll_y;
@@ -7374,7 +7374,7 @@ e_day_view_update_top_canvas_drag (EDayView *day_view,
 	/* If the position hasn't changed, just return. */
 	if (day_view->drag_last_day == day
 	    && (day_view->drag_long_event_item->object.flags
-		& GNOME_CANVAS_ITEM_VISIBLE))
+		& FOO_CANVAS_ITEM_VISIBLE))
 		return;
 
 	day_view->drag_last_day = day;
@@ -7386,14 +7386,14 @@ e_day_view_update_top_canvas_drag (EDayView *day_view,
 	item_h = day_view->top_row_height - E_DAY_VIEW_TOP_CANVAS_Y_GAP;
 
 	/* Set the positions of the event & associated items. */
-	gnome_canvas_item_set (day_view->drag_long_event_rect_item,
+	foo_canvas_item_set (day_view->drag_long_event_rect_item,
 			       "x1", item_x,
 			       "y1", item_y,
 			       "x2", item_x + item_w - 1,
 			       "y2", item_y + item_h - 1,
 			       NULL);
 
-	gnome_canvas_item_set (day_view->drag_long_event_item,
+	foo_canvas_item_set (day_view->drag_long_event_item,
 			       "clip_width", item_w - (E_DAY_VIEW_LONG_EVENT_BORDER_WIDTH + E_DAY_VIEW_LONG_EVENT_X_PAD) * 2,
 			       "clip_height", item_h - (E_DAY_VIEW_LONG_EVENT_BORDER_HEIGHT + E_DAY_VIEW_LONG_EVENT_Y_PAD) * 2,
 			       NULL);
@@ -7401,16 +7401,16 @@ e_day_view_update_top_canvas_drag (EDayView *day_view,
 				     item_x + E_DAY_VIEW_LONG_EVENT_BORDER_WIDTH + E_DAY_VIEW_LONG_EVENT_X_PAD,
 				     item_y + E_DAY_VIEW_LONG_EVENT_BORDER_HEIGHT + E_DAY_VIEW_LONG_EVENT_Y_PAD);
 
-	if (!(day_view->drag_long_event_rect_item->object.flags & GNOME_CANVAS_ITEM_VISIBLE)) {
-		gnome_canvas_item_raise_to_top (day_view->drag_long_event_rect_item);
-		gnome_canvas_item_show (day_view->drag_long_event_rect_item);
+	if (!(day_view->drag_long_event_rect_item->object.flags & FOO_CANVAS_ITEM_VISIBLE)) {
+		foo_canvas_item_raise_to_top (day_view->drag_long_event_rect_item);
+		foo_canvas_item_show (day_view->drag_long_event_rect_item);
 	}
 
 	/* Set the text, if necessary. We don't want to set the text every
 	   time it moves, so we check if it is currently invisible and only
 	   set the text then. */
 	if (!(day_view->drag_long_event_item->object.flags
-	      & GNOME_CANVAS_ITEM_VISIBLE)) {
+	      & FOO_CANVAS_ITEM_VISIBLE)) {
 		const gchar *summary;
 
 		if (event) {
@@ -7420,11 +7420,11 @@ e_day_view_update_top_canvas_drag (EDayView *day_view,
 			text = NULL;
 		}
 
-		gnome_canvas_item_set (day_view->drag_long_event_item,
+		foo_canvas_item_set (day_view->drag_long_event_item,
 				       "text", text ? text : "",
 				       NULL);
-		gnome_canvas_item_raise_to_top (day_view->drag_long_event_item);
-		gnome_canvas_item_show (day_view->drag_long_event_item);
+		foo_canvas_item_raise_to_top (day_view->drag_long_event_item);
+		foo_canvas_item_show (day_view->drag_long_event_item);
 
 		g_free (text);
 	}
@@ -7440,7 +7440,7 @@ e_day_view_on_main_canvas_drag_motion (GtkWidget      *widget,
 {
 	gint scroll_x, scroll_y;
 
-	gnome_canvas_get_scroll_offsets (GNOME_CANVAS (widget),
+	foo_canvas_get_scroll_offsets (FOO_CANVAS (widget),
 					 &scroll_x, &scroll_y);
 
 	day_view->drag_event_x = x + scroll_x;
@@ -7491,7 +7491,7 @@ e_day_view_update_main_canvas_drag (EDayView *day_view,
 	/* If the position hasn't changed, just return. */
 	if (day_view->drag_last_day == day
 	    && day_view->drag_last_row == row
-	    && (day_view->drag_item->object.flags & GNOME_CANVAS_ITEM_VISIBLE))
+	    && (day_view->drag_item->object.flags & FOO_CANVAS_ITEM_VISIBLE))
 		return;
 
 	day_view->drag_last_day = day;
@@ -7534,21 +7534,21 @@ e_day_view_update_main_canvas_drag (EDayView *day_view,
 	item_h = num_rows * day_view->row_height;
 
 	/* Set the positions of the event & associated items. */
-	gnome_canvas_item_set (day_view->drag_rect_item,
+	foo_canvas_item_set (day_view->drag_rect_item,
 			       "x1", item_x + E_DAY_VIEW_BAR_WIDTH - 1,
 			       "y1", item_y,
 			       "x2", item_x + item_w - 1,
 			       "y2", item_y + item_h - 1,
 			       NULL);
 
-	gnome_canvas_item_set (day_view->drag_bar_item,
+	foo_canvas_item_set (day_view->drag_bar_item,
 			       "x1", item_x,
 			       "y1", item_y,
 			       "x2", item_x + E_DAY_VIEW_BAR_WIDTH - 1,
 			       "y2", item_y + item_h - 1,
 			       NULL);
 
-	gnome_canvas_item_set (day_view->drag_item,
+	foo_canvas_item_set (day_view->drag_item,
 			       "clip_width", item_w - E_DAY_VIEW_BAR_WIDTH - E_DAY_VIEW_EVENT_X_PAD * 2,
 			       "clip_height", item_h - (E_DAY_VIEW_EVENT_BORDER_HEIGHT + E_DAY_VIEW_EVENT_Y_PAD) * 2,
 			       NULL);
@@ -7556,20 +7556,20 @@ e_day_view_update_main_canvas_drag (EDayView *day_view,
 				     item_x + E_DAY_VIEW_BAR_WIDTH + E_DAY_VIEW_EVENT_X_PAD,
 				     item_y + E_DAY_VIEW_EVENT_BORDER_HEIGHT + E_DAY_VIEW_EVENT_Y_PAD);
 
-	if (!(day_view->drag_bar_item->object.flags & GNOME_CANVAS_ITEM_VISIBLE)) {
-		gnome_canvas_item_raise_to_top (day_view->drag_bar_item);
-		gnome_canvas_item_show (day_view->drag_bar_item);
+	if (!(day_view->drag_bar_item->object.flags & FOO_CANVAS_ITEM_VISIBLE)) {
+		foo_canvas_item_raise_to_top (day_view->drag_bar_item);
+		foo_canvas_item_show (day_view->drag_bar_item);
 	}
 
-	if (!(day_view->drag_rect_item->object.flags & GNOME_CANVAS_ITEM_VISIBLE)) {
-		gnome_canvas_item_raise_to_top (day_view->drag_rect_item);
-		gnome_canvas_item_show (day_view->drag_rect_item);
+	if (!(day_view->drag_rect_item->object.flags & FOO_CANVAS_ITEM_VISIBLE)) {
+		foo_canvas_item_raise_to_top (day_view->drag_rect_item);
+		foo_canvas_item_show (day_view->drag_rect_item);
 	}
 
 	/* Set the text, if necessary. We don't want to set the text every
 	   time it moves, so we check if it is currently invisible and only
 	   set the text then. */
-	if (!(day_view->drag_item->object.flags & GNOME_CANVAS_ITEM_VISIBLE)) {
+	if (!(day_view->drag_item->object.flags & FOO_CANVAS_ITEM_VISIBLE)) {
 		const gchar *summary;
 
 		if (event) {
@@ -7579,11 +7579,11 @@ e_day_view_update_main_canvas_drag (EDayView *day_view,
 			text = NULL;
 		}
 
-		gnome_canvas_item_set (day_view->drag_item,
+		foo_canvas_item_set (day_view->drag_item,
 				       "text", text ? text : "",
 				       NULL);
-		gnome_canvas_item_raise_to_top (day_view->drag_item);
-		gnome_canvas_item_show (day_view->drag_item);
+		foo_canvas_item_raise_to_top (day_view->drag_item);
+		foo_canvas_item_show (day_view->drag_item);
 
 		g_free (text);
 	}
@@ -7597,8 +7597,8 @@ e_day_view_on_top_canvas_drag_leave (GtkWidget      *widget,
 {
 	day_view->drag_last_day = -1;
 
-	gnome_canvas_item_hide (day_view->drag_long_event_rect_item);
-	gnome_canvas_item_hide (day_view->drag_long_event_item);
+	foo_canvas_item_hide (day_view->drag_long_event_rect_item);
+	foo_canvas_item_hide (day_view->drag_long_event_item);
 }
 
 static void
@@ -7611,9 +7611,9 @@ e_day_view_on_main_canvas_drag_leave (GtkWidget      *widget,
 
 	e_day_view_stop_auto_scroll (day_view);
 
-	gnome_canvas_item_hide (day_view->drag_rect_item);
-	gnome_canvas_item_hide (day_view->drag_bar_item);
-	gnome_canvas_item_hide (day_view->drag_item);
+	foo_canvas_item_hide (day_view->drag_rect_item);
+	foo_canvas_item_hide (day_view->drag_bar_item);
+	foo_canvas_item_hide (day_view->drag_item);
 
 	/* Hide the resize bars if they are being used in the drag. */
 	if (day_view->drag_event_day == day_view->resize_bars_event_day
@@ -7645,7 +7645,7 @@ e_day_view_on_drag_begin (GtkWidget      *widget,
 
 	/* Hide the text item, since it will be shown in the special drag
 	   items. */
-	gnome_canvas_item_hide (event->canvas_item);
+	foo_canvas_item_hide (event->canvas_item);
 }
 
 static void
@@ -7675,7 +7675,7 @@ e_day_view_on_drag_end (GtkWidget      *widget,
 	}
 
 	/* Show the text item again. */
-	gnome_canvas_item_show (event->canvas_item);
+	foo_canvas_item_show (event->canvas_item);
 
 	day_view->drag_event_day = -1;
 	day_view->drag_event_num = -1;
@@ -7863,7 +7863,7 @@ e_day_view_on_top_canvas_drag_data_received  (GtkWidget          *widget,
 			/* Show the text item again, just in case it hasn't
 			   moved. If we don't do this it may not appear. */
 			if (event->canvas_item)
-				gnome_canvas_item_show (event->canvas_item);
+				foo_canvas_item_show (event->canvas_item);
 
 			e_cal_component_commit_sequence (comp);
 			if (e_cal_component_has_recurrences (comp)) {
@@ -7989,7 +7989,7 @@ e_day_view_on_main_canvas_drag_data_received  (GtkWidget          *widget,
 
 	client = e_cal_model_get_default_client (e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)));
 
-	gnome_canvas_get_scroll_offsets (GNOME_CANVAS (widget),
+	foo_canvas_get_scroll_offsets (FOO_CANVAS (widget),
 					 &scroll_x, &scroll_y);
 	x += scroll_x;
 	y += scroll_y;
@@ -8068,7 +8068,7 @@ e_day_view_on_main_canvas_drag_data_received  (GtkWidget          *widget,
 			/* Show the text item again, just in case it hasn't
 			   moved. If we don't do this it may not appear. */
 			if (event->canvas_item)
-				gnome_canvas_item_show (event->canvas_item);
+				foo_canvas_item_show (event->canvas_item);
 
 			e_cal_component_commit_sequence (comp);
 			if (e_cal_component_has_recurrences (comp)) {
diff --git a/calendar/gui/e-day-view.h b/calendar/gui/e-day-view.h
index 683e231..c2d4873 100644
--- a/calendar/gui/e-day-view.h
+++ b/calendar/gui/e-day-view.h
@@ -26,7 +26,7 @@
 
 #include <time.h>
 #include <gtk/gtk.h>
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 
 #include "e-calendar-view.h"
 #include "gnome-cal.h"
@@ -209,11 +209,11 @@ struct _EDayView {
 
 	/* The top canvas where the dates are shown. */
 	GtkWidget *top_dates_canvas;
-	GnomeCanvasItem *top_dates_canvas_item;
+	FooCanvasItem *top_dates_canvas_item;
 
 	/* The top canvas where the dates and long appointments are shown. */
 	GtkWidget *top_canvas;
-	GnomeCanvasItem *top_canvas_item;
+	FooCanvasItem *top_canvas_item;
 
 	/* scrollbar for top_canvas */
 	GtkWidget *tc_vscrollbar;
@@ -223,11 +223,11 @@ struct _EDayView {
 
 	/* The main canvas where the rest of the appointments are shown. */
 	GtkWidget *main_canvas;
-	GnomeCanvasItem *main_canvas_item;
+	FooCanvasItem *main_canvas_item;
 
 	/* The canvas displaying the times of the day. */
 	GtkWidget *time_canvas;
-	GnomeCanvasItem *time_canvas_item;
+	FooCanvasItem *time_canvas_item;
 
 	GtkWidget *vscrollbar;
 
@@ -383,19 +383,19 @@ struct _EDayView {
 	 */
 
 	/* The horizontal bars to resize events in the main canvas. */
-	GnomeCanvasItem *main_canvas_top_resize_bar_item;
-	GnomeCanvasItem *main_canvas_bottom_resize_bar_item;
+	FooCanvasItem *main_canvas_top_resize_bar_item;
+	FooCanvasItem *main_canvas_bottom_resize_bar_item;
 
 	/* The event currently being edited. The day is -1 if no event is
 	 being edited, or E_DAY_VIEW_LONG_EVENT if a long event is edited. */
 	gint editing_event_day;
 	gint editing_event_num;
 
-	/* This is a GnomeCanvasRect which is placed around an item while it
+	/* This is a FooCanvasRect which is placed around an item while it
 	   is being resized, so we can raise it above all other EText items. */
-	GnomeCanvasItem *resize_long_event_rect_item;
-	GnomeCanvasItem *resize_rect_item;
-	GnomeCanvasItem *resize_bar_item;
+	FooCanvasItem *resize_long_event_rect_item;
+	FooCanvasItem *resize_rect_item;
+	FooCanvasItem *resize_bar_item;
 
 	/* The event for which a popup menu is being displayed, as above. */
 	gint popup_event_day;
@@ -468,13 +468,13 @@ struct _EDayView {
 	gint drag_last_day;
 	gint drag_last_row;
 
-	/* This is a GnomeCanvasRect which is placed around an item while it
+	/* This is a FooCanvasRect which is placed around an item while it
 	   is being resized, so we can raise it above all other EText items. */
-	GnomeCanvasItem *drag_long_event_rect_item;
-	GnomeCanvasItem *drag_long_event_item;
-	GnomeCanvasItem *drag_rect_item;
-	GnomeCanvasItem *drag_bar_item;
-	GnomeCanvasItem *drag_item;
+	FooCanvasItem *drag_long_event_rect_item;
+	FooCanvasItem *drag_long_event_item;
+	FooCanvasItem *drag_rect_item;
+	FooCanvasItem *drag_bar_item;
+	FooCanvasItem *drag_item;
 
 	/* "am" and "pm" in the current locale, and their widths. */
 	gchar *am_string;
@@ -624,7 +624,7 @@ gint	   e_day_view_event_sort_func		(const void	*arg1,
 						 const void	*arg2);
 
 gboolean e_day_view_find_event_from_item (EDayView *day_view,
-					  GnomeCanvasItem *item,
+					  FooCanvasItem *item,
 					  gint *day_return,
 					  gint *event_num_return);
 void e_day_view_update_calendar_selection_time (EDayView *day_view);
diff --git a/calendar/gui/e-meeting-time-sel-item.c b/calendar/gui/e-meeting-time-sel-item.c
index 041ae6e..a00c6b3 100644
--- a/calendar/gui/e-meeting-time-sel-item.c
+++ b/calendar/gui/e-meeting-time-sel-item.c
@@ -1,7 +1,7 @@
 /*
- * EMeetingTimeSelectorItem - A GnomeCanvasItem which is used for both the main
+ * EMeetingTimeSelectorItem - A FooCanvasItem which is used for both the main
  * display canvas and the top display (with the dates, times & All Attendees).
- * I didn't make these separate GnomeCanvasItems since they share a lot of
+ * I didn't make these separate FooCanvasItems since they share a lot of
  * code.
  *
  * This program is free software; you can redistribute it and/or
@@ -45,20 +45,20 @@ static void e_meeting_time_selector_item_set_property (GObject *object,
                                                        guint property_id,
                                                        const GValue *value,
                                                        GParamSpec *pspec);
-static void e_meeting_time_selector_item_realize (GnomeCanvasItem *item);
-static void e_meeting_time_selector_item_unrealize (GnomeCanvasItem *item);
-static void e_meeting_time_selector_item_update (GnomeCanvasItem *item,
-						 double *affine,
-						 ArtSVP *clip_path, gint flags);
-static void e_meeting_time_selector_item_draw (GnomeCanvasItem *item,
+static void e_meeting_time_selector_item_realize (FooCanvasItem *item);
+static void e_meeting_time_selector_item_unrealize (FooCanvasItem *item);
+static void e_meeting_time_selector_item_update (FooCanvasItem *item,
+						 double i2w_dx,
+						 double i2w_dy,
+						 gint flags);
+static void e_meeting_time_selector_item_draw (FooCanvasItem *item,
 					       GdkDrawable *drawable,
-					       gint x, gint y,
-					       gint width, gint height);
-static double e_meeting_time_selector_item_point (GnomeCanvasItem *item,
+					       GdkEventExpose *expose);
+static double e_meeting_time_selector_item_point (FooCanvasItem *item,
 						  double x, double y,
 						  gint cx, gint cy,
-						  GnomeCanvasItem **actual_item);
-static gint e_meeting_time_selector_item_event (GnomeCanvasItem *item,
+						  FooCanvasItem **actual_item);
+static gint e_meeting_time_selector_item_event (FooCanvasItem *item,
 						GdkEvent *event);
 static gint e_meeting_time_selector_item_button_press (EMeetingTimeSelectorItem *mts_item,
 						       GdkEvent *event);
@@ -96,19 +96,19 @@ enum {
 	PROP_MEETING_TIME_SELECTOR
 };
 
-G_DEFINE_TYPE (EMeetingTimeSelectorItem, e_meeting_time_selector_item, GNOME_TYPE_CANVAS_ITEM)
+G_DEFINE_TYPE (EMeetingTimeSelectorItem, e_meeting_time_selector_item, FOO_TYPE_CANVAS_ITEM)
 
 static void
 e_meeting_time_selector_item_class_init (EMeetingTimeSelectorItemClass *class)
 {
 	GObjectClass *object_class;
-	GnomeCanvasItemClass *item_class;
+	FooCanvasItemClass *item_class;
 
 	object_class = G_OBJECT_CLASS (class);
 	object_class->dispose = e_meeting_time_selector_item_dispose;
 	object_class->set_property = e_meeting_time_selector_item_set_property;
 
-	item_class = GNOME_CANVAS_ITEM_CLASS (class);
+	item_class = FOO_CANVAS_ITEM_CLASS (class);
 	item_class->realize = e_meeting_time_selector_item_realize;
 	item_class->unrealize = e_meeting_time_selector_item_unrealize;
 	item_class->update = e_meeting_time_selector_item_update;
@@ -129,7 +129,7 @@ e_meeting_time_selector_item_class_init (EMeetingTimeSelectorItemClass *class)
 static void
 e_meeting_time_selector_item_init (EMeetingTimeSelectorItem *mts_item)
 {
-	GnomeCanvasItem *item = GNOME_CANVAS_ITEM (mts_item);
+	FooCanvasItem *item = FOO_CANVAS_ITEM (mts_item);
 
 	mts_item->mts = NULL;
 
@@ -191,14 +191,14 @@ e_meeting_time_selector_item_set_property (GObject *object,
 }
 
 static void
-e_meeting_time_selector_item_realize (GnomeCanvasItem *item)
+e_meeting_time_selector_item_realize (FooCanvasItem *item)
 {
-	GnomeCanvas *canvas;
+	FooCanvas *canvas;
 	GdkWindow *window;
 	EMeetingTimeSelectorItem *mts_item;
 
-	if (GNOME_CANVAS_ITEM_CLASS (e_meeting_time_selector_item_parent_class)->realize)
-		(*GNOME_CANVAS_ITEM_CLASS (e_meeting_time_selector_item_parent_class)->realize)(item);
+	if (FOO_CANVAS_ITEM_CLASS (e_meeting_time_selector_item_parent_class)->realize)
+		(*FOO_CANVAS_ITEM_CLASS (e_meeting_time_selector_item_parent_class)->realize)(item);
 
 	mts_item = E_MEETING_TIME_SELECTOR_ITEM (item);
 
@@ -210,7 +210,7 @@ e_meeting_time_selector_item_realize (GnomeCanvasItem *item)
 }
 
 static void
-e_meeting_time_selector_item_unrealize (GnomeCanvasItem *item)
+e_meeting_time_selector_item_unrealize (FooCanvasItem *item)
 {
 	EMeetingTimeSelectorItem *mts_item;
 
@@ -221,15 +221,15 @@ e_meeting_time_selector_item_unrealize (GnomeCanvasItem *item)
 	g_object_unref (mts_item->stipple_gc);
 	mts_item->stipple_gc = NULL;
 
-	if (GNOME_CANVAS_ITEM_CLASS (e_meeting_time_selector_item_parent_class)->unrealize)
-		(*GNOME_CANVAS_ITEM_CLASS (e_meeting_time_selector_item_parent_class)->unrealize)(item);
+	if (FOO_CANVAS_ITEM_CLASS (e_meeting_time_selector_item_parent_class)->unrealize)
+		(*FOO_CANVAS_ITEM_CLASS (e_meeting_time_selector_item_parent_class)->unrealize)(item);
 }
 
 static void
-e_meeting_time_selector_item_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, gint flags)
+e_meeting_time_selector_item_update (FooCanvasItem *item, double i2w_dx, double i2w_dy, gint flags)
 {
-	if (GNOME_CANVAS_ITEM_CLASS (e_meeting_time_selector_item_parent_class)->update)
-		(* GNOME_CANVAS_ITEM_CLASS (e_meeting_time_selector_item_parent_class)->update) (item, affine, clip_path, flags);
+	if (FOO_CANVAS_ITEM_CLASS (e_meeting_time_selector_item_parent_class)->update)
+		(* FOO_CANVAS_ITEM_CLASS (e_meeting_time_selector_item_parent_class)->update) (item, i2w_dx, i2w_dy, flags);
 
 	/* The grid covers the entire canvas area. */
 	item->x1 = 0;
@@ -243,18 +243,24 @@ e_meeting_time_selector_item_update (GnomeCanvasItem *item, double *affine, ArtS
  */
 
 static void
-e_meeting_time_selector_item_draw (GnomeCanvasItem *item, GdkDrawable *drawable, gint x, gint y, gint width, gint height)
+e_meeting_time_selector_item_draw (FooCanvasItem *item, GdkDrawable *drawable, GdkEventExpose *expose)
 {
 	EMeetingTimeSelector *mts;
 	EMeetingTimeSelectorItem *mts_item;
 	EMeetingAttendee *ia;
 	gint day_x, meeting_start_x, meeting_end_x, bar_y, bar_height;
 	gint row, row_y, start_x, end_x;
+	gint x, y, width, height;
 	GDate date, last_date, current_date;
 	gboolean is_display_top, show_meeting_time;
 	GdkGC *gc, *stipple_gc;
 	cairo_t *cr;
 
+	x = expose->area.x;
+	y = expose->area.y;
+	width = expose->area.width;
+	height = expose->area.height;
+
 	mts_item = E_MEETING_TIME_SELECTOR_ITEM (item);
 	mts = mts_item->mts;
 	g_return_if_fail (mts != NULL);
@@ -314,7 +320,7 @@ e_meeting_time_selector_item_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
 		gdk_gc_set_foreground (stipple_gc, &mts->grid_color);
 		gdk_gc_set_background (stipple_gc, &mts->stipple_bg_color);
 		gdk_gc_set_stipple (stipple_gc, mts->stipple);
-		gnome_canvas_set_stipple_origin (item->canvas, stipple_gc);
+		foo_canvas_set_stipple_origin (item->canvas, stipple_gc);
 		gdk_gc_set_fill (stipple_gc, GDK_OPAQUE_STIPPLED);
 		row = y / mts->row_height;
 		row_y = row * mts->row_height - y;
@@ -354,7 +360,7 @@ e_meeting_time_selector_item_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
 	/* Now paint the visible days one by one. */
 	current_date = date;
 	for (;;) {
-		/* Currently we use the same GnomeCanvasItem class for the
+		/* Currently we use the same FooCanvasItem class for the
 		   top display and the main display. We may use separate
 		   classes in future if necessary. */
 		if (is_display_top)
@@ -775,23 +781,23 @@ e_meeting_time_selector_item_paint_attendee_busy_periods (EMeetingTimeSelectorIt
 }
 
 /*
- * CANVAS ITEM ROUTINES - functions to be a GnomeCanvasItem.
+ * CANVAS ITEM ROUTINES - functions to be a FooCanvasItem.
  */
 
 /* This is supposed to return the nearest item the the point and the distance.
    Since we are the only item we just return ourself and 0 for the distance.
    This is needed so that we get button/motion events. */
 static double
-e_meeting_time_selector_item_point (GnomeCanvasItem *item, double x, double y,
+e_meeting_time_selector_item_point (FooCanvasItem *item, double x, double y,
 				    gint cx, gint cy,
-				    GnomeCanvasItem **actual_item)
+				    FooCanvasItem **actual_item)
 {
 	*actual_item = item;
 	return 0.0;
 }
 
 static gint
-e_meeting_time_selector_item_event (GnomeCanvasItem *item, GdkEvent *event)
+e_meeting_time_selector_item_event (FooCanvasItem *item, GdkEvent *event)
 {
 	EMeetingTimeSelectorItem *mts_item;
 
@@ -817,7 +823,7 @@ e_meeting_time_selector_item_event (GnomeCanvasItem *item, GdkEvent *event)
 /* This handles all button press events for the item. If the cursor is over
    one of the meeting time vertical bars we start a drag. If not we set the
    meeting time to the nearest half-hour interval.
-   Note that GnomeCanvas converts the event coords to world coords,
+   Note that FooCanvas converts the event coords to world coords,
    i.e. relative to the entire canvas scroll area. */
 static gint
 e_meeting_time_selector_item_button_press (EMeetingTimeSelectorItem *mts_item,
@@ -837,7 +843,7 @@ e_meeting_time_selector_item_button_press (EMeetingTimeSelectorItem *mts_item,
 	position = e_meeting_time_selector_item_get_drag_position (mts_item,
 								   x, y);
 	if (position != E_MEETING_TIME_SELECTOR_POS_NONE) {
-		if (gnome_canvas_item_grab (GNOME_CANVAS_ITEM (mts_item),
+		if (foo_canvas_item_grab (FOO_CANVAS_ITEM (mts_item),
 					    GDK_POINTER_MOTION_MASK
 					    | GDK_BUTTON_RELEASE_MASK,
 					    mts_item->resize_cursor,
@@ -939,7 +945,7 @@ e_meeting_time_selector_item_button_release (EMeetingTimeSelectorItem *mts_item,
 	if (mts->dragging_position != E_MEETING_TIME_SELECTOR_POS_NONE) {
 		mts->dragging_position = E_MEETING_TIME_SELECTOR_POS_NONE;
 		e_meeting_time_selector_remove_timeout (mts);
-		gnome_canvas_item_ungrab (GNOME_CANVAS_ITEM (mts_item),
+		foo_canvas_item_ungrab (FOO_CANVAS_ITEM (mts_item),
 					  event->button.time);
 	}
 
@@ -948,7 +954,7 @@ e_meeting_time_selector_item_button_release (EMeetingTimeSelectorItem *mts_item,
 
 /* This handles all motion notify events for the item. If button1 is pressed
    we check if a drag is in progress. If not, we set the cursor if we are over
-   the meeting time vertical bars. Note that GnomeCanvas doesn't use motion
+   the meeting time vertical bars. Note that FooCanvas doesn't use motion
    hints, which may affect performance. */
 static gint
 e_meeting_time_selector_item_motion_notify (EMeetingTimeSelectorItem *mts_item,
@@ -983,7 +989,7 @@ e_meeting_time_selector_item_motion_notify (EMeetingTimeSelectorItem *mts_item,
 	/* Only set the cursor if it is different to the last one we set. */
 	if (mts_item->last_cursor_set != cursor) {
 		mts_item->last_cursor_set = cursor;
-		gdk_window_set_cursor (GTK_WIDGET (GNOME_CANVAS_ITEM (mts_item)->canvas)->window, cursor);
+		gdk_window_set_cursor (GTK_WIDGET (FOO_CANVAS_ITEM (mts_item)->canvas)->window, cursor);
 	}
 
 	return FALSE;
@@ -999,7 +1005,7 @@ e_meeting_time_selector_item_get_drag_position (EMeetingTimeSelectorItem *mts_it
 
 	mts = mts_item->mts;
 
-	is_display_top = (GTK_WIDGET (GNOME_CANVAS_ITEM (mts_item)->canvas) == mts->display_top) ? TRUE : FALSE;
+	is_display_top = (GTK_WIDGET (FOO_CANVAS_ITEM (mts_item)->canvas) == mts->display_top) ? TRUE : FALSE;
 
 	if (is_display_top && y < mts->row_height * 2)
 		return E_MEETING_TIME_SELECTOR_POS_NONE;
@@ -1051,5 +1057,5 @@ e_meeting_time_selector_item_set_normal_cursor (EMeetingTimeSelectorItem *mts_it
 {
 	g_return_if_fail (IS_E_MEETING_TIME_SELECTOR_ITEM (mts_item));
 
-	gdk_window_set_cursor (GTK_WIDGET (GNOME_CANVAS_ITEM (mts_item)->canvas)->window, mts_item->normal_cursor);
+	gdk_window_set_cursor (GTK_WIDGET (FOO_CANVAS_ITEM (mts_item)->canvas)->window, mts_item->normal_cursor);
 }
diff --git a/calendar/gui/e-meeting-time-sel-item.h b/calendar/gui/e-meeting-time-sel-item.h
index 547f01a..5581858 100644
--- a/calendar/gui/e-meeting-time-sel-item.h
+++ b/calendar/gui/e-meeting-time-sel-item.h
@@ -22,9 +22,9 @@
  */
 
 /*
- * MeetingTimeSelectorItem - A GnomeCanvasItem which is used for both the main
+ * MeetingTimeSelectorItem - A FooCanvasItem which is used for both the main
  * display canvas and the top display (with the dates, times & All Attendees).
- * I didn't make these separate GnomeCanvasItems since they share a lot of
+ * I didn't make these separate FooCanvasItems since they share a lot of
  * code.
  */
 
@@ -44,7 +44,7 @@ typedef struct _EMeetingTimeSelectorItemClass  EMeetingTimeSelectorItemClass;
 
 struct _EMeetingTimeSelectorItem
 {
-	GnomeCanvasItem canvas_item;
+	FooCanvasItem canvas_item;
 
 	/* The parent EMeetingTimeSelector widget. */
 	EMeetingTimeSelector *mts;
@@ -65,7 +65,7 @@ struct _EMeetingTimeSelectorItem
 
 struct _EMeetingTimeSelectorItemClass
 {
-	GnomeCanvasItemClass parent_class;
+	FooCanvasItemClass parent_class;
 };
 
 GType e_meeting_time_selector_item_get_type (void);
diff --git a/calendar/gui/e-meeting-time-sel.c b/calendar/gui/e-meeting-time-sel.c
index ea6fca8..f129cde 100644
--- a/calendar/gui/e-meeting-time-sel.c
+++ b/calendar/gui/e-meeting-time-sel.c
@@ -33,7 +33,7 @@
 #include <time.h>
 #include <gdk/gdkkeysyms.h>
 #include <glib/gi18n.h>
-#include <libgnomecanvas/gnome-canvas-widget.h>
+#include <libfoocanvas/foo-canvas-widget.h>
 
 #include "misc/e-canvas.h"
 #include "misc/e-canvas-utils.h"
@@ -481,9 +481,9 @@ e_meeting_time_selector_construct (EMeetingTimeSelector * mts, EMeetingStore *em
 	gtk_box_pack_start (GTK_BOX (mts->attendees_vbox), GTK_WIDGET (sw), TRUE, TRUE, 6);
 
 	/* The free/busy information */
-	mts->display_top = gnome_canvas_new ();
+	mts->display_top = foo_canvas_new ();
 	gtk_widget_set_size_request (mts->display_top, -1, mts->row_height * 3);
-	gnome_canvas_set_scroll_region (GNOME_CANVAS (mts->display_top),
+	foo_canvas_set_scroll_region (FOO_CANVAS (mts->display_top),
 					0, 0,
 					mts->day_width * E_MEETING_TIME_SELECTOR_DAYS_SHOWN,
 					mts->row_height * 3);
@@ -494,7 +494,7 @@ e_meeting_time_selector_construct (EMeetingTimeSelector * mts, EMeetingStore *em
 	g_signal_connect (mts->display_top, "realize",
 			  G_CALLBACK (e_meeting_time_selector_on_canvas_realized), mts);
 
-	mts->display_main = gnome_canvas_new ();
+	mts->display_main = foo_canvas_new ();
 	e_meeting_time_selector_update_main_canvas_scroll_region (mts);
 	/* Add some horizontal padding for the shadow around the display. */
 	gtk_table_attach (GTK_TABLE (mts), mts->display_main,
@@ -523,13 +523,13 @@ e_meeting_time_selector_construct (EMeetingTimeSelector * mts, EMeetingStore *em
 	gtk_widget_show (mts->vscrollbar);
 
 	/* Create the item in the top canvas. */
-	mts->item_top = gnome_canvas_item_new (GNOME_CANVAS_GROUP (GNOME_CANVAS (mts->display_top)->root),
+	mts->item_top = foo_canvas_item_new (FOO_CANVAS_GROUP (FOO_CANVAS (mts->display_top)->root),
 			       e_meeting_time_selector_item_get_type (),
 			       "EMeetingTimeSelectorItem::meeting_time_selector", mts,
 			       NULL);
 
 	/* Create the item in the main canvas. */
-	mts->item_main = gnome_canvas_item_new (GNOME_CANVAS_GROUP (GNOME_CANVAS (mts->display_main)->root),
+	mts->item_main = foo_canvas_item_new (FOO_CANVAS_GROUP (FOO_CANVAS (mts->display_main)->root),
 			       e_meeting_time_selector_item_get_type (),
 			       "EMeetingTimeSelectorItem::meeting_time_selector", mts,
 			       NULL);
@@ -2136,7 +2136,7 @@ e_meeting_time_selector_recalc_grid (EMeetingTimeSelector *mts)
 	/* Add one pixel for the extra vertical grid line. */
 	mts->day_width++;
 
-	gnome_canvas_set_scroll_region (GNOME_CANVAS (mts->display_top),
+	foo_canvas_set_scroll_region (FOO_CANVAS (mts->display_top),
 					0, 0,
 					mts->day_width * E_MEETING_TIME_SELECTOR_DAYS_SHOWN,
 					mts->row_height * 3);
@@ -2153,7 +2153,7 @@ e_meeting_time_selector_save_position (EMeetingTimeSelector *mts,
 {
 	gint scroll_x, scroll_y;
 
-	gnome_canvas_get_scroll_offsets (GNOME_CANVAS (mts->display_main),
+	foo_canvas_get_scroll_offsets (FOO_CANVAS (mts->display_main),
 					 &scroll_x, &scroll_y);
 	e_meeting_time_selector_calculate_time (mts, scroll_x, mtstime);
 }
@@ -2167,9 +2167,9 @@ e_meeting_time_selector_restore_position (EMeetingTimeSelector *mts,
 
 	new_scroll_x = e_meeting_time_selector_calculate_time_position (mts,
 									mtstime);
-	gnome_canvas_get_scroll_offsets (GNOME_CANVAS (mts->display_main),
+	foo_canvas_get_scroll_offsets (FOO_CANVAS (mts->display_main),
 					 &scroll_x, &scroll_y);
-	gnome_canvas_scroll_to (GNOME_CANVAS (mts->display_main),
+	foo_canvas_scroll_to (FOO_CANVAS (mts->display_main),
 				new_scroll_x, scroll_y);
 }
 
@@ -2318,7 +2318,7 @@ e_meeting_time_selector_recalc_date_format (EMeetingTimeSelector *mts)
 }
 
 /* Turn off the background of the canvas windows. This reduces flicker
-   considerably when scrolling. (Why isn't it in GnomeCanvas?). */
+   considerably when scrolling. (Why isn't it in FooCanvas?). */
 static void
 e_meeting_time_selector_on_canvas_realized (GtkWidget *widget,
 					    EMeetingTimeSelector *mts)
@@ -2479,7 +2479,7 @@ e_meeting_time_selector_update_main_canvas_scroll_region (EMeetingTimeSelector *
 
 	height = MAX (height,  canvas_height);
 
-	gnome_canvas_set_scroll_region (GNOME_CANVAS (mts->display_main),
+	foo_canvas_set_scroll_region (FOO_CANVAS (mts->display_main),
 					0, 0,
 					mts->day_width * E_MEETING_TIME_SELECTOR_DAYS_SHOWN,
 					height);
@@ -2499,7 +2499,7 @@ e_meeting_time_selector_drag_meeting_time (EMeetingTimeSelector *mts,
 	gboolean set_both_times = FALSE;
 
 	/* Get the x coords of visible part of the canvas. */
-	gnome_canvas_get_scroll_offsets (GNOME_CANVAS (mts->display_main),
+	foo_canvas_get_scroll_offsets (FOO_CANVAS (mts->display_main),
 					 &scroll_x, &scroll_y);
 	canvas_width = mts->display_main->allocation.width;
 
@@ -2659,7 +2659,7 @@ e_meeting_time_selector_timeout_handler (gpointer data)
 	}
 
 	/* Get the x coords of visible part of the canvas. */
-	gnome_canvas_get_scroll_offsets (GNOME_CANVAS (mts->display_main),
+	foo_canvas_get_scroll_offsets (FOO_CANVAS (mts->display_main),
 					 &scroll_x, &scroll_y);
 	canvas_width = mts->display_main->allocation.width;
 
@@ -2779,9 +2779,9 @@ e_meeting_time_selector_timeout_handler (gpointer data)
 	   get redrawn completely. Otherwise the pixels get scrolled left or
 	   right which is not good for us (since our vertical bars have been
 	   moved) and causes flicker. */
-	gnome_canvas_scroll_to (GNOME_CANVAS (mts->display_main),
+	foo_canvas_scroll_to (FOO_CANVAS (mts->display_main),
 				scroll_x, scroll_y);
-	gnome_canvas_scroll_to (GNOME_CANVAS (mts->display_top),
+	foo_canvas_scroll_to (FOO_CANVAS (mts->display_top),
 				scroll_x, scroll_y);
 
 	GDK_THREADS_LEAVE ();
@@ -2856,14 +2856,14 @@ e_meeting_time_selector_ensure_meeting_time_shown (EMeetingTimeSelector *mts)
 		start_x = e_meeting_time_selector_calculate_time_position (mts, &time);
 	}
 
-	gnome_canvas_get_scroll_offsets (GNOME_CANVAS (mts->display_main),
+	foo_canvas_get_scroll_offsets (FOO_CANVAS (mts->display_main),
 					 &scroll_x, &scroll_y);
 	canvas_width = mts->display_main->allocation.width;
 	if (start_x > scroll_x && end_x <= scroll_x + canvas_width)
 		return;
 
 	new_scroll_x = start_x;
-	gnome_canvas_scroll_to (GNOME_CANVAS (mts->display_main),
+	foo_canvas_scroll_to (FOO_CANVAS (mts->display_main),
 				new_scroll_x, scroll_y);
 }
 
diff --git a/calendar/gui/e-meeting-time-sel.h b/calendar/gui/e-meeting-time-sel.h
index 540443a..f4557aa 100644
--- a/calendar/gui/e-meeting-time-sel.h
+++ b/calendar/gui/e-meeting-time-sel.h
@@ -24,7 +24,7 @@
 #define E_MEETING_TIME_SELECTOR_H
 
 #include <gtk/gtk.h>
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 #include <text/e-text.h>
 #include <table/e-table-model.h>
 #include <table/e-table.h>
@@ -135,13 +135,13 @@ struct _EMeetingTimeSelector {
 	/* The canvas displaying the dates, times, and the summary
 	   'All Attendees' free/busy display. */
 	GtkWidget *display_top;
-	GnomeCanvasItem *item_top;
+	FooCanvasItem *item_top;
 
 	/* The canvas containing the free/busy displays of individual
 	   attendees. This is separate from display_top since it also scrolls
 	   vertically. */
 	GtkWidget *display_main;
-	GnomeCanvasItem *item_main;
+	FooCanvasItem *item_main;
 
 	/* The 'Add attendees from addressbook' button */
 	GtkWidget *add_attendees_button;
diff --git a/calendar/gui/e-memo-table.c b/calendar/gui/e-memo-table.c
index fd92070..d69d143 100644
--- a/calendar/gui/e-memo-table.c
+++ b/calendar/gui/e-memo-table.c
@@ -1167,8 +1167,8 @@ clipboard_paste_received_cb (GtkClipboard *clipboard,
 {
 	EMemoTable *memo_table = E_MEMO_TABLE (data);
 	ETable *e_table = e_memo_table_get_table (memo_table);
-	GnomeCanvas *canvas = e_table->table_canvas;
-	GnomeCanvasItem *item = GNOME_CANVAS (canvas)->focused_item;
+	FooCanvas *canvas = e_table->table_canvas;
+	FooCanvasItem *item = FOO_CANVAS (canvas)->focused_item;
 
 	if (gtk_clipboard_wait_is_text_available (clipboard) &&
 	    GTK_WIDGET_HAS_FOCUS (canvas) &&
diff --git a/calendar/gui/e-week-view-event-item.c b/calendar/gui/e-week-view-event-item.c
index 2cb699f..0fecc0a 100644
--- a/calendar/gui/e-week-view-event-item.c
+++ b/calendar/gui/e-week-view-event-item.c
@@ -44,16 +44,13 @@ static void e_week_view_event_item_set_property	(GObject	 *object,
 						 guint		  property_id,
 						 const GValue	 *value,
 						 GParamSpec	 *pspec);
-static void e_week_view_event_item_update	(GnomeCanvasItem *item,
-						 double		 *affine,
-						 ArtSVP		 *clip_path,
+static void e_week_view_event_item_update	(FooCanvasItem *item,
+						 double		 i2w_dx,
+						 double		 i2w_dy,
 						 gint		  flags);
-static void e_week_view_event_item_draw		(GnomeCanvasItem *item,
+static void e_week_view_event_item_draw		(FooCanvasItem *item,
 						 GdkDrawable	 *drawable,
-						 gint		  x,
-						 gint		  y,
-						 gint		  width,
-						 gint		  height);
+						 GdkEventExpose  *expose);
 static void e_week_view_draw_time		(EWeekView	*week_view,
 						 GdkDrawable	*drawable,
 						 gint		 time_x,
@@ -75,13 +72,13 @@ static void e_week_view_event_item_draw_triangle (EWeekViewEventItem *wveitem,
 						  gint		      w,
 						  gint		      h,
 						  GdkRegion          *draw_region);
-static double e_week_view_event_item_point	(GnomeCanvasItem *item,
+static double e_week_view_event_item_point	(FooCanvasItem *item,
 						 double		  x,
 						 double		  y,
 						 gint		  cx,
 						 gint		  cy,
-						 GnomeCanvasItem **actual_item);
-static gint e_week_view_event_item_event	(GnomeCanvasItem *item,
+						 FooCanvasItem **actual_item);
+static gint e_week_view_event_item_event	(FooCanvasItem *item,
 						 GdkEvent	 *event);
 static gboolean e_week_view_event_item_button_press (EWeekViewEventItem *wveitem,
 						     GdkEvent		*event);
@@ -100,18 +97,18 @@ enum {
 	PROP_SPAN_NUM
 };
 
-G_DEFINE_TYPE (EWeekViewEventItem, e_week_view_event_item, GNOME_TYPE_CANVAS_ITEM)
+G_DEFINE_TYPE (EWeekViewEventItem, e_week_view_event_item, FOO_TYPE_CANVAS_ITEM)
 
 static void
 e_week_view_event_item_class_init (EWeekViewEventItemClass *class)
 {
 	GObjectClass  *object_class;
-	GnomeCanvasItemClass *item_class;
+	FooCanvasItemClass *item_class;
 
 	object_class = G_OBJECT_CLASS (class);
 	object_class->set_property = e_week_view_event_item_set_property;
 
-	item_class = GNOME_CANVAS_ITEM_CLASS (class);
+	item_class = FOO_CANVAS_ITEM_CLASS (class);
 	item_class->update = e_week_view_event_item_update;
 	item_class->draw = e_week_view_event_item_draw;
 	item_class->point = e_week_view_event_item_point;
@@ -155,20 +152,20 @@ e_week_view_event_item_set_property (GObject *object,
                                      const GValue *value,
                                      GParamSpec *pspec)
 {
-	GnomeCanvasItem *item;
+	FooCanvasItem *item;
 	EWeekViewEventItem *wveitem;
 
-	item = GNOME_CANVAS_ITEM (object);
+	item = FOO_CANVAS_ITEM (object);
 	wveitem = E_WEEK_VIEW_EVENT_ITEM (object);
 
 	switch (property_id) {
 	case PROP_EVENT_NUM:
 		wveitem->event_num = g_value_get_int (value);
-		gnome_canvas_item_request_update (item);
+		foo_canvas_item_request_update (item);
 		return;
 	case PROP_SPAN_NUM:
 		wveitem->span_num = g_value_get_int (value);
-		gnome_canvas_item_request_update (item);
+		foo_canvas_item_request_update (item);
 		return;
 	}
 
@@ -176,9 +173,9 @@ e_week_view_event_item_set_property (GObject *object,
 }
 
 static void
-e_week_view_event_item_update (GnomeCanvasItem *item,
-			       double	       *affine,
-			       ArtSVP	       *clip_path,
+e_week_view_event_item_update (FooCanvasItem *item,
+			       double	        i2w_dx,
+			       double	        i2w_dy,
 			       gint		flags)
 {
 	EWeekViewEventItem *wveitem;
@@ -193,8 +190,8 @@ e_week_view_event_item_update (GnomeCanvasItem *item,
 	week_view = E_WEEK_VIEW (GTK_WIDGET (item->canvas)->parent);
 	g_return_if_fail (E_IS_WEEK_VIEW (week_view));
 
-	if (GNOME_CANVAS_ITEM_CLASS (e_week_view_event_item_parent_class)->update)
-		(* GNOME_CANVAS_ITEM_CLASS (e_week_view_event_item_parent_class)->update) (item, affine, clip_path, flags);
+	if (FOO_CANVAS_ITEM_CLASS (e_week_view_event_item_parent_class)->update)
+		(* FOO_CANVAS_ITEM_CLASS (e_week_view_event_item_parent_class)->update) (item, i2w_dx, i2w_dy, flags);
 
 	item->x1 = 0;
 	item->y1 = 0;
@@ -239,12 +236,9 @@ can_draw_in_region (GdkRegion *draw_region, gint x, gint y, gint width, gint hei
  * DRAWING ROUTINES - functions to paint the canvas item.
  */
 static void
-e_week_view_event_item_draw (GnomeCanvasItem  *canvas_item,
+e_week_view_event_item_draw (FooCanvasItem  *canvas_item,
 			     GdkDrawable      *drawable,
-			     gint	       x,
-			     gint	       y,
-			     gint	       width,
-			     gint	       height)
+			     GdkEventExpose   *expose)
 {
 	EWeekViewEventItem *wveitem;
 	EWeekView *week_view;
@@ -254,6 +248,7 @@ e_week_view_event_item_draw (GnomeCanvasItem  *canvas_item,
 	gint x1, y1, x2, y2, time_x, time_y;
 	gint icon_x, icon_y, time_width, min_end_time_x, max_icon_x;
 	gint rect_x, rect_w, rect_x2 = 0;
+	gint x, y, width, height;
 	gboolean one_day_event, editing_span = FALSE;
 	gint start_hour, start_minute, end_hour, end_minute;
 	gboolean draw_start, draw_end;
@@ -269,6 +264,11 @@ e_week_view_event_item_draw (GnomeCanvasItem  *canvas_item,
 	GdkRegion *draw_region;
 	GdkRectangle rect;
 
+	x = expose->area.x;
+	y = expose->area.y;
+	width = expose->area.width;
+	height = expose->area.height;
+
 #if 0
 	g_print ("In e_week_view_event_item_draw %i,%i %ix%i\n",
 		 x, y, width, height);
@@ -741,7 +741,7 @@ e_week_view_event_item_draw_icons (EWeekViewEventItem *wveitem,
 	GSList *categories_pixbufs = NULL, *pixbufs;
 	cairo_t *cr;
 
-	week_view = E_WEEK_VIEW (GTK_WIDGET (GNOME_CANVAS_ITEM (wveitem)->canvas)->parent);
+	week_view = E_WEEK_VIEW (GTK_WIDGET (FOO_CANVAS_ITEM (wveitem)->canvas)->parent);
 
 	event = &g_array_index (week_view->events, EWeekViewEvent,
 				wveitem->event_num);
@@ -856,7 +856,7 @@ e_week_view_event_item_draw_triangle (EWeekViewEventItem *wveitem,
 	if (!can_draw_in_region (draw_region, x, y, w, h))
 		return;
 
-	week_view = E_WEEK_VIEW (GTK_WIDGET (GNOME_CANVAS_ITEM (wveitem)->canvas)->parent);
+	week_view = E_WEEK_VIEW (GTK_WIDGET (FOO_CANVAS_ITEM (wveitem)->canvas)->parent);
 
 	event = &g_array_index (week_view->events, EWeekViewEvent,
 				wveitem->event_num);
@@ -920,16 +920,16 @@ e_week_view_event_item_draw_triangle (EWeekViewEventItem *wveitem,
    Since we are the only item we just return ourself and 0 for the distance.
    This is needed so that we get button/motion events. */
 static double
-e_week_view_event_item_point (GnomeCanvasItem *item, double x, double y,
+e_week_view_event_item_point (FooCanvasItem *item, double x, double y,
 			      gint cx, gint cy,
-			      GnomeCanvasItem **actual_item)
+			      FooCanvasItem **actual_item)
 {
 	*actual_item = item;
 	return 0.0;
 }
 
 static gint
-e_week_view_event_item_event (GnomeCanvasItem *item, GdkEvent *event)
+e_week_view_event_item_event (FooCanvasItem *item, GdkEvent *event)
 {
 	EWeekViewEventItem *wveitem;
 
@@ -959,9 +959,9 @@ e_week_view_event_item_button_press (EWeekViewEventItem *wveitem,
 	ECalendarViewPosition pos;
 	EWeekViewEvent *event;
 	EWeekViewEventSpan *span;
-	GnomeCanvasItem *item;
+	FooCanvasItem *item;
 
-	item = GNOME_CANVAS_ITEM (wveitem);
+	item = FOO_CANVAS_ITEM (wveitem);
 
 	week_view = E_WEEK_VIEW (GTK_WIDGET (item->canvas)->parent);
 	g_return_val_if_fail (E_IS_WEEK_VIEW (week_view), FALSE);
@@ -1025,9 +1025,9 @@ e_week_view_event_item_button_release (EWeekViewEventItem *wveitem,
 				       GdkEvent		  *event)
 {
 	EWeekView *week_view;
-	GnomeCanvasItem *item;
+	FooCanvasItem *item;
 
-	item = GNOME_CANVAS_ITEM (wveitem);
+	item = FOO_CANVAS_ITEM (wveitem);
 
 	week_view = E_WEEK_VIEW (GTK_WIDGET (item->canvas)->parent);
 	g_return_val_if_fail (E_IS_WEEK_VIEW (week_view), FALSE);
@@ -1058,9 +1058,9 @@ e_week_view_event_item_double_click (EWeekViewEventItem *wveitem,
 {
 	EWeekView *week_view;
 	EWeekViewEvent *event;
-	GnomeCanvasItem *item;
+	FooCanvasItem *item;
 
-	item = GNOME_CANVAS_ITEM (wveitem);
+	item = FOO_CANVAS_ITEM (wveitem);
 
 	week_view = E_WEEK_VIEW (GTK_WIDGET (item->canvas)->parent);
 	g_return_val_if_fail (E_IS_WEEK_VIEW (week_view), FALSE);
@@ -1089,9 +1089,9 @@ e_week_view_event_item_get_position (EWeekViewEventItem *wveitem,
 				     gdouble y)
 {
 	EWeekView *week_view;
-	GnomeCanvasItem *item;
+	FooCanvasItem *item;
 
-	item = GNOME_CANVAS_ITEM (wveitem);
+	item = FOO_CANVAS_ITEM (wveitem);
 
 	week_view = E_WEEK_VIEW (GTK_WIDGET (item->canvas)->parent);
 	g_return_val_if_fail (E_IS_WEEK_VIEW (week_view), E_CALENDAR_VIEW_POS_NONE);
diff --git a/calendar/gui/e-week-view-event-item.h b/calendar/gui/e-week-view-event-item.h
index 6c07774..feb93cf 100644
--- a/calendar/gui/e-week-view-event-item.h
+++ b/calendar/gui/e-week-view-event-item.h
@@ -42,7 +42,7 @@ G_BEGIN_DECLS
 	e_week_view_event_item_get_type ()))
 
 typedef struct {
-	GnomeCanvasItem canvas_item;
+	FooCanvasItem canvas_item;
 
 	/* The event index in the EWeekView events array. */
 	gint event_num;
@@ -52,7 +52,7 @@ typedef struct {
 } EWeekViewEventItem;
 
 typedef struct {
-	GnomeCanvasItemClass parent_class;
+	FooCanvasItemClass parent_class;
 
 } EWeekViewEventItemClass;
 
diff --git a/calendar/gui/e-week-view-main-item.c b/calendar/gui/e-week-view-main-item.c
index ed4d142..1fbea2c 100644
--- a/calendar/gui/e-week-view-main-item.c
+++ b/calendar/gui/e-week-view-main-item.c
@@ -36,16 +36,13 @@ static void e_week_view_main_item_set_property	(GObject	 *object,
 						 guint		  property_id,
 						 const GValue	 *value,
 						 GParamSpec	 *pspec);
-static void e_week_view_main_item_update	(GnomeCanvasItem *item,
-						 double		 *affine,
-						 ArtSVP		 *clip_path,
+static void e_week_view_main_item_update	(FooCanvasItem *item,
+						 double		  i2w_dx,
+						 double		  i2w_dy,
 						 gint		  flags);
-static void e_week_view_main_item_draw		(GnomeCanvasItem *item,
+static void e_week_view_main_item_draw		(FooCanvasItem *item,
 						 GdkDrawable	 *drawable,
-						 gint		  x,
-						 gint		  y,
-						 gint		  width,
-						 gint		  height);
+						 GdkEventExpose	 *expose);
 static void e_week_view_main_item_draw_day	(EWeekViewMainItem *wvmitem,
 						 gint		   day,
 						 GDate		  *date,
@@ -54,12 +51,12 @@ static void e_week_view_main_item_draw_day	(EWeekViewMainItem *wvmitem,
 						 gint		   y,
 						 gint		   width,
 						 gint		   height);
-static double e_week_view_main_item_point	(GnomeCanvasItem *item,
+static double e_week_view_main_item_point	(FooCanvasItem *item,
 						 double		  x,
 						 double		  y,
 						 gint		  cx,
 						 gint		  cy,
-						 GnomeCanvasItem **actual_item);
+						 FooCanvasItem **actual_item);
 
 /* The arguments we take */
 enum {
@@ -67,18 +64,18 @@ enum {
 	PROP_WEEK_VIEW
 };
 
-G_DEFINE_TYPE (EWeekViewMainItem, e_week_view_main_item, GNOME_TYPE_CANVAS_ITEM)
+G_DEFINE_TYPE (EWeekViewMainItem, e_week_view_main_item, FOO_TYPE_CANVAS_ITEM)
 
 static void
 e_week_view_main_item_class_init (EWeekViewMainItemClass *class)
 {
 	GObjectClass  *object_class;
-	GnomeCanvasItemClass *item_class;
+	FooCanvasItemClass *item_class;
 
 	object_class = G_OBJECT_CLASS (class);
 	object_class->set_property = e_week_view_main_item_set_property;
 
-	item_class = GNOME_CANVAS_ITEM_CLASS (class);
+	item_class = FOO_CANVAS_ITEM_CLASS (class);
 	item_class->update = e_week_view_main_item_update;
 	item_class->draw = e_week_view_main_item_draw;
 	item_class->point = e_week_view_main_item_point;
@@ -124,13 +121,13 @@ e_week_view_main_item_set_property (GObject *object,
 }
 
 static void
-e_week_view_main_item_update (GnomeCanvasItem *item,
-			      double	      *affine,
-			      ArtSVP	      *clip_path,
+e_week_view_main_item_update (FooCanvasItem *item,
+			      double	       i2w_dx,
+			      double	       i2w_dy,
 			      gint	       flags)
 {
-	if (GNOME_CANVAS_ITEM_CLASS (e_week_view_main_item_parent_class)->update)
-		(* GNOME_CANVAS_ITEM_CLASS (e_week_view_main_item_parent_class)->update) (item, affine, clip_path, flags);
+	if (FOO_CANVAS_ITEM_CLASS (e_week_view_main_item_parent_class)->update)
+		(* FOO_CANVAS_ITEM_CLASS (e_week_view_main_item_parent_class)->update) (item, i2w_dx, i2w_dy, flags);
 
 	/* The item covers the entire canvas area. */
 	item->x1 = 0;
@@ -143,17 +140,20 @@ e_week_view_main_item_update (GnomeCanvasItem *item,
  * DRAWING ROUTINES - functions to paint the canvas item.
  */
 static void
-e_week_view_main_item_draw (GnomeCanvasItem  *canvas_item,
+e_week_view_main_item_draw (FooCanvasItem  *canvas_item,
 			    GdkDrawable      *drawable,
-			    gint		      x,
-			    gint		      y,
-			    gint		      width,
-			    gint		      height)
+			    GdkEventExpose   *expose)
 {
 	EWeekViewMainItem *wvmitem;
 	EWeekView *week_view;
 	GDate date;
 	gint num_days, day, day_x, day_y, day_w, day_h;
+	gint x, y, width, height;
+
+	x = expose->area.x;
+	y = expose->area.y;
+	width = expose->area.width;
+	height = expose->area.height;
 
 #if 0
 	g_print ("In e_week_view_main_item_draw %i,%i %ix%i\n",
@@ -443,9 +443,9 @@ e_week_view_main_item_draw_day (EWeekViewMainItem *wvmitem,
    Since we are the only item we just return ourself and 0 for the distance.
    This is needed so that we get button/motion events. */
 static double
-e_week_view_main_item_point (GnomeCanvasItem *item, double x, double y,
+e_week_view_main_item_point (FooCanvasItem *item, double x, double y,
 			     gint cx, gint cy,
-			     GnomeCanvasItem **actual_item)
+			     FooCanvasItem **actual_item)
 {
 	*actual_item = item;
 	return 0.0;
diff --git a/calendar/gui/e-week-view-main-item.h b/calendar/gui/e-week-view-main-item.h
index 3be9bbe..3822912 100644
--- a/calendar/gui/e-week-view-main-item.h
+++ b/calendar/gui/e-week-view-main-item.h
@@ -41,14 +41,14 @@ G_BEGIN_DECLS
 	e_week_view_main_item_get_type ()))
 
 typedef struct {
-	GnomeCanvasItem canvas_item;
+	FooCanvasItem canvas_item;
 
 	/* The parent EWeekView widget. */
 	EWeekView *week_view;
 } EWeekViewMainItem;
 
 typedef struct {
-	GnomeCanvasItemClass parent_class;
+	FooCanvasItemClass parent_class;
 
 } EWeekViewMainItemClass;
 
diff --git a/calendar/gui/e-week-view-titles-item.c b/calendar/gui/e-week-view-titles-item.c
index 69108f4..49cc146 100644
--- a/calendar/gui/e-week-view-titles-item.c
+++ b/calendar/gui/e-week-view-titles-item.c
@@ -33,22 +33,19 @@ static void e_week_view_titles_item_set_property(GObject	 *object,
 						 guint		  property_id,
 						 const GValue	 *value,
 						 GParamSpec	 *pspec);
-static void e_week_view_titles_item_update	(GnomeCanvasItem *item,
-						 double		 *affine,
-						 ArtSVP		 *clip_path,
+static void e_week_view_titles_item_update	(FooCanvasItem *item,
+						 double		  i2w_dx,
+						 double		  i2w_dy,
 						 gint		  flags);
-static void e_week_view_titles_item_draw	(GnomeCanvasItem *item,
+static void e_week_view_titles_item_draw	(FooCanvasItem *item,
 						 GdkDrawable	 *drawable,
-						 gint		  x,
-						 gint		  y,
-						 gint		  width,
-						 gint		  height);
-static double e_week_view_titles_item_point	(GnomeCanvasItem *item,
+						 GdkEventExpose  *expose);
+static double e_week_view_titles_item_point	(FooCanvasItem *item,
 						 double		  x,
 						 double		  y,
 						 gint		  cx,
 						 gint		  cy,
-						 GnomeCanvasItem **actual_item);
+						 FooCanvasItem **actual_item);
 
 /* The arguments we take */
 enum {
@@ -56,18 +53,18 @@ enum {
 	PROP_WEEK_VIEW
 };
 
-G_DEFINE_TYPE (EWeekViewTitlesItem, e_week_view_titles_item, GNOME_TYPE_CANVAS_ITEM)
+G_DEFINE_TYPE (EWeekViewTitlesItem, e_week_view_titles_item, FOO_TYPE_CANVAS_ITEM)
 
 static void
 e_week_view_titles_item_class_init (EWeekViewTitlesItemClass *class)
 {
 	GObjectClass  *object_class;
-	GnomeCanvasItemClass *item_class;
+	FooCanvasItemClass *item_class;
 
 	object_class = G_OBJECT_CLASS (class);
 	object_class->set_property = e_week_view_titles_item_set_property;
 
-	item_class = GNOME_CANVAS_ITEM_CLASS (class);
+	item_class = FOO_CANVAS_ITEM_CLASS (class);
 	item_class->update = e_week_view_titles_item_update;
 	item_class->draw = e_week_view_titles_item_draw;
 	item_class->point = e_week_view_titles_item_point;
@@ -108,13 +105,13 @@ e_week_view_titles_item_set_property (GObject *object,
 }
 
 static void
-e_week_view_titles_item_update (GnomeCanvasItem *item,
-				double	    *affine,
-				ArtSVP	    *clip_path,
-				gint		     flags)
+e_week_view_titles_item_update (FooCanvasItem *item,
+				double	     i2w_dx,
+				double	     i2w_dy,
+				gint	     flags)
 {
-	if (GNOME_CANVAS_ITEM_CLASS (e_week_view_titles_item_parent_class)->update)
-		(* GNOME_CANVAS_ITEM_CLASS (e_week_view_titles_item_parent_class)->update) (item, affine, clip_path, flags);
+	if (FOO_CANVAS_ITEM_CLASS (e_week_view_titles_item_parent_class)->update)
+		(* FOO_CANVAS_ITEM_CLASS (e_week_view_titles_item_parent_class)->update) (item, i2w_dx, i2w_dy, flags);
 
 	/* The item covers the entire canvas area. */
 	item->x1 = 0;
@@ -128,12 +125,9 @@ e_week_view_titles_item_update (GnomeCanvasItem *item,
  */
 
 static void
-e_week_view_titles_item_draw (GnomeCanvasItem  *canvas_item,
+e_week_view_titles_item_draw (FooCanvasItem  *canvas_item,
 			      GdkDrawable      *drawable,
-			      gint		x,
-			      gint		y,
-			      gint		width,
-			      gint		height)
+			      GdkEventExpose   *expose)
 {
 	EWeekViewTitlesItem *wvtitem;
 	EWeekView *week_view;
@@ -144,8 +138,14 @@ e_week_view_titles_item_draw (GnomeCanvasItem  *canvas_item,
 	GdkRectangle clip_rect;
 	gboolean abbreviated;
 	gint weekday;
+	gint x, y, width, height;
 	PangoLayout *layout;
 
+	x = expose->area.x;
+	y = expose->area.y;
+	width = expose->area.width;
+	height = expose->area.height;
+
 #if 0
 	g_print ("In e_week_view_titles_item_draw %i,%i %ix%i\n",
 		 x, y, width, height);
@@ -263,9 +263,9 @@ e_week_view_titles_item_draw (GnomeCanvasItem  *canvas_item,
    Since we are the only item we just return ourself and 0 for the distance.
    This is needed so that we get button/motion events. */
 static double
-e_week_view_titles_item_point (GnomeCanvasItem *item, double x, double y,
+e_week_view_titles_item_point (FooCanvasItem *item, double x, double y,
 			       gint cx, gint cy,
-			       GnomeCanvasItem **actual_item)
+			       FooCanvasItem **actual_item)
 {
 	*actual_item = item;
 	return 0.0;
diff --git a/calendar/gui/e-week-view-titles-item.h b/calendar/gui/e-week-view-titles-item.h
index 3b27034..0bc7946 100644
--- a/calendar/gui/e-week-view-titles-item.h
+++ b/calendar/gui/e-week-view-titles-item.h
@@ -41,14 +41,14 @@ G_BEGIN_DECLS
 	e_week_view_titles_item_get_type ()))
 
 typedef struct {
-	GnomeCanvasItem canvas_item;
+	FooCanvasItem canvas_item;
 
 	/* The parent EWeekView widget. */
 	EWeekView *week_view;
 } EWeekViewTitlesItem;
 
 typedef struct {
-	GnomeCanvasItemClass parent_class;
+	FooCanvasItemClass parent_class;
 
 } EWeekViewTitlesItemClass;
 
diff --git a/calendar/gui/e-week-view.c b/calendar/gui/e-week-view.c
index 7efd90a..40d31b7 100644
--- a/calendar/gui/e-week-view.c
+++ b/calendar/gui/e-week-view.c
@@ -35,7 +35,7 @@
 #include <math.h>
 #include <gdk/gdkkeysyms.h>
 #include <glib/gi18n.h>
-#include <libgnomecanvas/gnome-canvas-pixbuf.h>
+#include <libfoocanvas/foo-canvas-pixbuf.h>
 #include <text/e-text.h>
 #include <misc/e-canvas-utils.h>
 #include <misc/e-gui-utils.h>
@@ -148,9 +148,9 @@ static void e_week_view_reshape_event_span (EWeekView *week_view,
 static void e_week_view_recalc_day_starts (EWeekView *week_view,
 					   time_t lower);
 static void e_week_view_on_editing_started (EWeekView *week_view,
-					    GnomeCanvasItem *item);
+					    FooCanvasItem *item);
 static void e_week_view_on_editing_stopped (EWeekView *week_view,
-					    GnomeCanvasItem *item);
+					    FooCanvasItem *item);
 static gboolean e_week_view_find_event_from_uid (EWeekView	  *week_view,
 						 ECal             *client,
 						 const gchar	  *uid,
@@ -163,13 +163,13 @@ static void e_week_view_foreach_event_with_uid (EWeekView *week_view,
 						const gchar *uid,
 						EWeekViewForeachEventCallback callback,
 						gpointer data);
-static gboolean e_week_view_on_text_item_event (GnomeCanvasItem *item,
+static gboolean e_week_view_on_text_item_event (FooCanvasItem *item,
 						GdkEvent *event,
 						EWeekView *week_view);
 static gboolean e_week_view_event_move (ECalendarView *cal_view, ECalViewMoveDirection direction);
 static gint e_week_view_get_day_offset_of_event (EWeekView *week_view, time_t event_time);
 static void e_week_view_change_event_time (EWeekView *week_view, time_t start_dt, time_t end_dt, gboolean is_all_day);
-static gboolean e_week_view_on_jump_button_event (GnomeCanvasItem *item,
+static gboolean e_week_view_on_jump_button_event (FooCanvasItem *item,
 						  GdkEvent *event,
 						  EWeekView *week_view);
 static gboolean e_week_view_key_press (GtkWidget *widget, GdkEventKey *event);
@@ -462,7 +462,7 @@ e_week_view_class_init (EWeekViewClass *class)
 static void
 e_week_view_init (EWeekView *week_view)
 {
-	GnomeCanvasGroup *canvas_group;
+	FooCanvasGroup *canvas_group;
 	GtkObject *adjustment;
 	GdkPixbuf *pixbuf;
 	gint i;
@@ -535,10 +535,10 @@ e_week_view_init (EWeekView *week_view)
 	gtk_table_attach (GTK_TABLE (week_view), week_view->titles_canvas,
 			  1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
 
-	canvas_group = GNOME_CANVAS_GROUP (GNOME_CANVAS (week_view->titles_canvas)->root);
+	canvas_group = FOO_CANVAS_GROUP (FOO_CANVAS (week_view->titles_canvas)->root);
 
 	week_view->titles_canvas_item =
-		gnome_canvas_item_new (canvas_group,
+		foo_canvas_item_new (canvas_group,
 				       e_week_view_titles_item_get_type (),
 				       "EWeekViewTitlesItem::week_view", week_view,
 				       NULL);
@@ -552,10 +552,10 @@ e_week_view_init (EWeekView *week_view)
 			  GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 1, 1);
 	gtk_widget_show (week_view->main_canvas);
 
-	canvas_group = GNOME_CANVAS_GROUP (GNOME_CANVAS (week_view->main_canvas)->root);
+	canvas_group = FOO_CANVAS_GROUP (FOO_CANVAS (week_view->main_canvas)->root);
 
 	week_view->main_canvas_item =
-		gnome_canvas_item_new (canvas_group,
+		foo_canvas_item_new (canvas_group,
 				       e_week_view_main_item_get_type (),
 				       "EWeekViewMainItem::week_view", week_view,
 				       NULL);
@@ -573,10 +573,10 @@ e_week_view_init (EWeekView *week_view)
 	pixbuf = gdk_pixbuf_new_from_xpm_data ((const gchar **) jump_xpm);
 
 	for (i = 0; i < E_WEEK_VIEW_MAX_WEEKS * 7; i++) {
-		week_view->jump_buttons[i] = gnome_canvas_item_new
+		week_view->jump_buttons[i] = foo_canvas_item_new
 			(canvas_group,
-			 gnome_canvas_pixbuf_get_type (),
-			 "GnomeCanvasPixbuf::pixbuf", pixbuf,
+			 foo_canvas_pixbuf_get_type (),
+			 "FooCanvasPixbuf::pixbuf", pixbuf,
 			 NULL);
 
 		g_signal_connect (week_view->jump_buttons[i], "event",
@@ -1097,7 +1097,7 @@ e_week_view_style_set (GtkWidget *widget,
 			span = &g_array_index (week_view->spans,
 					EWeekViewEventSpan, span_num);
 			if (span->text_item) {
-				gnome_canvas_item_set (span->text_item,
+				foo_canvas_item_set (span->text_item,
 						"fill_color_gdk", &widget->style->text[GTK_STATE_NORMAL],
 						NULL);
 			}
@@ -1200,22 +1200,22 @@ e_week_view_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
 	e_week_view_recalc_cell_sizes (week_view);
 
 	/* Set the scroll region of the top canvas to its allocated size. */
-	gnome_canvas_get_scroll_region (GNOME_CANVAS (week_view->titles_canvas),
+	foo_canvas_get_scroll_region (FOO_CANVAS (week_view->titles_canvas),
 					NULL, NULL, &old_x2, &old_y2);
 	new_x2 = week_view->titles_canvas->allocation.width - 1;
 	new_y2 = week_view->titles_canvas->allocation.height - 1;
 	if (old_x2 != new_x2 || old_y2 != new_y2)
-		gnome_canvas_set_scroll_region (GNOME_CANVAS (week_view->titles_canvas),
+		foo_canvas_set_scroll_region (FOO_CANVAS (week_view->titles_canvas),
 						0, 0, new_x2, new_y2);
 
 	/* Set the scroll region of the main canvas to its allocated width,
 	   but with the height depending on the number of rows needed. */
-	gnome_canvas_get_scroll_region (GNOME_CANVAS (week_view->main_canvas),
+	foo_canvas_get_scroll_region (FOO_CANVAS (week_view->main_canvas),
 					NULL, NULL, &old_x2, &old_y2);
 	new_x2 = week_view->main_canvas->allocation.width - 1;
 	new_y2 = week_view->main_canvas->allocation.height - 1;
 	if (old_x2 != new_x2 || old_y2 != new_y2)
-		gnome_canvas_set_scroll_region (GNOME_CANVAS (week_view->main_canvas),
+		foo_canvas_set_scroll_region (FOO_CANVAS (week_view->main_canvas),
 						0, 0, new_x2, new_y2);
 
 	/* Flag that we need to reshape the events. */
@@ -1526,7 +1526,7 @@ e_week_view_focus (GtkWidget *widget, GtkDirectionType direction)
 
 				/* focus go to the jump button */
 				e_week_view_stop_editing_event (week_view);
-				gnome_canvas_item_grab_focus (week_view->jump_buttons[current_day]);
+				foo_canvas_item_grab_focus (week_view->jump_buttons[current_day]);
 				return TRUE;
 			}
 		}
@@ -2156,7 +2156,7 @@ set_text_as_bold (EWeekViewEvent *event, EWeekViewEventSpan *span)
 	   If the attendee is not present, it might have come through a mailing list.
 	   In that case, we never show the meeting as bold even if it is unaccepted. */
 	if (at && (at->status == ICAL_PARTSTAT_NEEDSACTION))
-		gnome_canvas_item_set (span->text_item, "bold", TRUE, NULL);
+		foo_canvas_item_set (span->text_item, "bold", TRUE, NULL);
 
 	e_cal_component_free_attendee_list (attendees);
 	g_free (address);
@@ -2357,7 +2357,7 @@ ewv_pass_gdkevent_to_etext (EWeekView *week_view, GdkEvent *gevent)
 		span = &g_array_index (week_view->spans, EWeekViewEventSpan, event->spans_index + week_view->editing_span_num);
 
 		if (span->text_item && E_IS_TEXT (span->text_item)) {
-			GNOME_CANVAS_ITEM_GET_CLASS (span->text_item)->event (span->text_item, gevent);
+			FOO_CANVAS_ITEM_GET_CLASS (span->text_item)->event (span->text_item, gevent);
 			return TRUE;
 		}
 	}
@@ -2673,7 +2673,7 @@ e_week_view_free_events (EWeekView *week_view)
 
 	/* Hide all the jump buttons. */
 	for (day = 0; day < E_WEEK_VIEW_MAX_WEEKS * 7; day++) {
-		gnome_canvas_item_hide (week_view->jump_buttons[day]);
+		foo_canvas_item_hide (week_view->jump_buttons[day]);
 	}
 }
 
@@ -2859,24 +2859,24 @@ e_week_view_reshape_events (EWeekView *week_view)
 
 		/* Determine whether the jump button should be shown. */
 		if (week_view->rows_per_day[day] <= max_rows) {
-			gnome_canvas_item_hide (week_view->jump_buttons[day]);
+			foo_canvas_item_hide (week_view->jump_buttons[day]);
 		} else {
 			e_week_view_get_day_position (week_view, day,
 						      &day_x, &day_y,
 						      &day_w, &day_h);
 
-			gnome_canvas_item_set (week_view->jump_buttons[day],
-					       "GnomeCanvasPixbuf::x", (gdouble) (day_x + day_w - E_WEEK_VIEW_JUMP_BUTTON_X_PAD - E_WEEK_VIEW_JUMP_BUTTON_WIDTH),
-					       "GnomeCanvasPixbuf::y", (gdouble) (day_y + day_h - E_WEEK_VIEW_JUMP_BUTTON_Y_PAD - E_WEEK_VIEW_JUMP_BUTTON_HEIGHT),
+			foo_canvas_item_set (week_view->jump_buttons[day],
+					       "FooCanvasPixbuf::x", (gdouble) (day_x + day_w - E_WEEK_VIEW_JUMP_BUTTON_X_PAD - E_WEEK_VIEW_JUMP_BUTTON_WIDTH),
+					       "FooCanvasPixbuf::y", (gdouble) (day_y + day_h - E_WEEK_VIEW_JUMP_BUTTON_Y_PAD - E_WEEK_VIEW_JUMP_BUTTON_HEIGHT),
 					       NULL);
 
-			gnome_canvas_item_show (week_view->jump_buttons[day]);
-			gnome_canvas_item_raise_to_top (week_view->jump_buttons[day]);
+			foo_canvas_item_show (week_view->jump_buttons[day]);
+			foo_canvas_item_raise_to_top (week_view->jump_buttons[day]);
 		}
 	}
 
 	for (day = num_days; day < E_WEEK_VIEW_MAX_WEEKS * 7; day++) {
-		gnome_canvas_item_hide (week_view->jump_buttons[day]);
+		foo_canvas_item_hide (week_view->jump_buttons[day]);
 	}
 }
 
@@ -2891,7 +2891,7 @@ tooltip_get_view_event (EWeekView *week_view, gint day, gint event_num)
 }
 
 static void
-tooltip_destroy (EWeekView *week_view, GnomeCanvasItem *item)
+tooltip_destroy (EWeekView *week_view, FooCanvasItem *item)
 {
 	gint event_num = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (item), "event-num"));
 	EWeekViewEvent *pevent;
@@ -2915,7 +2915,7 @@ tooltip_destroy (EWeekView *week_view, GnomeCanvasItem *item)
 }
 
 static gboolean
-tooltip_event_cb (GnomeCanvasItem *item,
+tooltip_event_cb (FooCanvasItem *item,
 		  GdkEvent *event,
 		  EWeekView *view)
 {
@@ -3040,7 +3040,7 @@ e_week_view_reshape_event_span (EWeekView *week_view,
 	/* Create the background canvas item if necessary. */
 	if (!span->background_item) {
 		span->background_item =
-			gnome_canvas_item_new (GNOME_CANVAS_GROUP (GNOME_CANVAS (week_view->main_canvas)->root),
+			foo_canvas_item_new (FOO_CANVAS_GROUP (FOO_CANVAS (week_view->main_canvas)->root),
 					       e_week_view_event_item_get_type (),
 					       NULL);
 	}
@@ -3050,7 +3050,7 @@ e_week_view_reshape_event_span (EWeekView *week_view,
 			  G_CALLBACK (tooltip_event_cb),
 			  week_view);
 
-	gnome_canvas_item_set (span->background_item,
+	foo_canvas_item_set (span->background_item,
 			       "event_num", event_num,
 			       "span_num", span_num,
 			       NULL);
@@ -3068,7 +3068,7 @@ e_week_view_reshape_event_span (EWeekView *week_view,
 		summary = e_calendar_view_get_icalcomponent_summary (event->comp_data->client, event->comp_data->icalcomp, &free_text);
 
 		span->text_item =
-			gnome_canvas_item_new (GNOME_CANVAS_GROUP (GNOME_CANVAS (week_view->main_canvas)->root),
+			foo_canvas_item_new (FOO_CANVAS_GROUP (FOO_CANVAS (week_view->main_canvas)->root),
 					       e_text_get_type (),
 					       "anchor", GTK_ANCHOR_NW,
 					       "clip", TRUE,
@@ -3224,7 +3224,7 @@ e_week_view_reshape_event_span (EWeekView *week_view,
 	/* Make sure we don't try to use a negative width. */
 	text_w = MAX (text_w, 0);
 
-	gnome_canvas_item_set (span->text_item,
+	foo_canvas_item_set (span->text_item,
 			       "clip_width", (gdouble) text_w,
 			       "clip_height", (gdouble) text_h,
 			       NULL);
@@ -3273,7 +3273,7 @@ e_week_view_start_editing_event (EWeekView *week_view,
 	}
 
 	if (initial_text) {
-		gnome_canvas_item_set (span->text_item,
+		foo_canvas_item_set (span->text_item,
 				       "text", initial_text,
 				       NULL);
 	}
@@ -3362,7 +3362,7 @@ cancel_editing (EWeekView *week_view)
 }
 
 static gboolean
-e_week_view_on_text_item_event (GnomeCanvasItem *item,
+e_week_view_on_text_item_event (FooCanvasItem *item,
 				GdkEvent *gdkevent,
 				EWeekView *week_view)
 {
@@ -3739,7 +3739,7 @@ out:
 
 static void
 e_week_view_on_editing_started (EWeekView *week_view,
-				GnomeCanvasItem *item)
+				FooCanvasItem *item)
 {
 	gint event_num, span_num;
 
@@ -3766,7 +3766,7 @@ e_week_view_on_editing_started (EWeekView *week_view,
 
 static void
 e_week_view_on_editing_stopped (EWeekView *week_view,
-				GnomeCanvasItem *item)
+				FooCanvasItem *item)
 {
 	gint event_num, span_num;
 	EWeekViewEvent *event;
@@ -3924,7 +3924,7 @@ e_week_view_on_editing_stopped (EWeekView *week_view,
 
 gboolean
 e_week_view_find_event_from_item (EWeekView	  *week_view,
-				  GnomeCanvasItem *item,
+				  FooCanvasItem *item,
 				  gint		  *event_num_return,
 				  gint		  *span_num_return)
 {
@@ -4345,7 +4345,7 @@ e_week_view_popup_menu (GtkWidget *widget)
 }
 
 void
-e_week_view_jump_to_button_item (EWeekView *week_view, GnomeCanvasItem *item)
+e_week_view_jump_to_button_item (EWeekView *week_view, FooCanvasItem *item)
 {
 #if 0  /* KILL-BONOBO */
 	gint day;
@@ -4367,7 +4367,7 @@ e_week_view_jump_to_button_item (EWeekView *week_view, GnomeCanvasItem *item)
 }
 
 static gboolean
-e_week_view_on_jump_button_event (GnomeCanvasItem *item,
+e_week_view_on_jump_button_event (FooCanvasItem *item,
 				  GdkEvent *event,
 				  EWeekView *week_view)
 {
@@ -4404,15 +4404,15 @@ e_week_view_on_jump_button_event (GnomeCanvasItem *item,
 		if (focus_event->in) {
 			week_view->focused_jump_button = day;
 			pixbuf = gdk_pixbuf_new_from_xpm_data ((const gchar **) jump_xpm_focused);
-			gnome_canvas_item_set (week_view->jump_buttons[day],
-					       "GnomeCanvasPixbuf::pixbuf",
+			foo_canvas_item_set (week_view->jump_buttons[day],
+					       "FooCanvasPixbuf::pixbuf",
 					       pixbuf, NULL);
 		}
 		else {
 			week_view->focused_jump_button = E_WEEK_VIEW_JUMP_BUTTON_NO_FOCUS;
 			pixbuf = gdk_pixbuf_new_from_xpm_data ((const gchar **) jump_xpm);
-			gnome_canvas_item_set (week_view->jump_buttons[day],
-					       "GnomeCanvasPixbuf::pixbuf",
+			foo_canvas_item_set (week_view->jump_buttons[day],
+					       "FooCanvasPixbuf::pixbuf",
 					       pixbuf, NULL);
 		}
 		if (pixbuf)
@@ -4525,7 +4525,7 @@ e_week_view_is_jump_button_visible (EWeekView *week_view, gint day)
 	g_return_val_if_fail (E_IS_WEEK_VIEW (week_view), FALSE);
 
 	if ((day >= 0) && (day < E_WEEK_VIEW_MAX_WEEKS * 7))
-		return week_view->jump_buttons[day]->object.flags & GNOME_CANVAS_ITEM_VISIBLE;
+		return week_view->jump_buttons[day]->object.flags & FOO_CANVAS_ITEM_VISIBLE;
 	return FALSE;
 }
 
diff --git a/calendar/gui/e-week-view.h b/calendar/gui/e-week-view.h
index ef4a5c0..ed587ac 100644
--- a/calendar/gui/e-week-view.h
+++ b/calendar/gui/e-week-view.h
@@ -24,7 +24,7 @@
 #define E_WEEK_VIEW_H
 
 #include <gtk/gtk.h>
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 
 #include "e-calendar-view.h"
 #include "gnome-cal.h"
@@ -154,8 +154,8 @@ struct _EWeekViewEventSpan {
 	guint start_day : 6;
 	guint num_days : 3;
 	guint row : 7;
-	GnomeCanvasItem *background_item;
-	GnomeCanvasItem *text_item;
+	FooCanvasItem *background_item;
+	FooCanvasItem *text_item;
 };
 
 typedef struct _EWeekViewEvent EWeekViewEvent;
@@ -174,13 +174,13 @@ struct _EWeekView {
 
 	/* The top canvas where the dates are shown. */
 	GtkWidget *titles_canvas;
-	GnomeCanvasItem *titles_canvas_item;
+	FooCanvasItem *titles_canvas_item;
 
 	/* The main canvas where the appointments are shown. */
 	GtkWidget *main_canvas;
-	GnomeCanvasItem *main_canvas_item;
+	FooCanvasItem *main_canvas_item;
 
-	GnomeCanvasItem *jump_buttons[E_WEEK_VIEW_MAX_WEEKS * 7];
+	FooCanvasItem *jump_buttons[E_WEEK_VIEW_MAX_WEEKS * 7];
 	gint focused_jump_button;
 
 	GtkWidget *vscrollbar;
@@ -463,7 +463,7 @@ gint		e_week_view_event_sort_func	(gconstpointer arg1,
 						 gconstpointer arg2);
 
 gboolean	e_week_view_find_event_from_item (EWeekView *week_view,
-						 GnomeCanvasItem *item,
+						 FooCanvasItem *item,
 						 gint *event_num_return,
 						 gint *span_num_return);
 
@@ -471,7 +471,7 @@ gboolean	e_week_view_is_jump_button_visible
 						(EWeekView *week_view,
 						 gint day);
 void		e_week_view_jump_to_button_item	(EWeekView *week_view,
-						 GnomeCanvasItem *item);
+						 FooCanvasItem *item);
 void		e_week_view_scroll_a_step	(EWeekView *week_view,
 						 ECalViewMoveDirection direction);
 
diff --git a/calendar/gui/ea-cal-view-event.c b/calendar/gui/ea-cal-view-event.c
index 5f0af90..8b2adc7 100644
--- a/calendar/gui/ea-cal-view-event.c
+++ b/calendar/gui/ea-cal-view-event.c
@@ -167,7 +167,7 @@ ea_cal_view_event_new (GObject *obj)
 	ECalendarView *cal_view;
 
 	g_return_val_if_fail (E_IS_TEXT (obj), NULL);
-	cal_view = ea_calendar_helpers_get_cal_view_from (GNOME_CANVAS_ITEM (obj));
+	cal_view = ea_calendar_helpers_get_cal_view_from (FOO_CANVAS_ITEM (obj));
 	if (!cal_view)
 		return NULL;
 
@@ -181,7 +181,7 @@ ea_cal_view_event_new (GObject *obj)
 		 * the first span of the same event
 		 */
 		if (!e_week_view_find_event_from_item (week_view,
-						       GNOME_CANVAS_ITEM (obj),
+						       FOO_CANVAS_ITEM (obj),
 						       &event_num,
 						       &span_num))
 			return NULL;
@@ -255,7 +255,7 @@ ea_cal_view_event_get_name (AtkObject *accessible)
 	g_obj = atk_gobject_accessible_get_object (atk_gobj);
 	if (!g_obj || !E_IS_TEXT (g_obj))
 		return NULL;
-	event = ea_calendar_helpers_get_cal_view_event_from (GNOME_CANVAS_ITEM(g_obj));
+	event = ea_calendar_helpers_get_cal_view_event_from (FOO_CANVAS_ITEM(g_obj));
 
 	alarm_string = recur_string = meeting_string = "";
 	if (event && event->comp_data) {
@@ -302,7 +302,7 @@ ea_cal_view_event_get_parent (AtkObject *accessible)
 {
 	AtkGObjectAccessible *atk_gobj;
 	GObject *g_obj;
-	GnomeCanvasItem *canvas_item;
+	FooCanvasItem *canvas_item;
 	ECalendarView *cal_view;
 
 	g_return_val_if_fail (EA_IS_CAL_VIEW_EVENT (accessible), NULL);
@@ -312,7 +312,7 @@ ea_cal_view_event_get_parent (AtkObject *accessible)
 	if (g_obj == NULL)
 		/* Object is defunct */
 		return NULL;
-	canvas_item = GNOME_CANVAS_ITEM (g_obj);
+	canvas_item = FOO_CANVAS_ITEM (g_obj);
 
 	cal_view = ea_calendar_helpers_get_cal_view_from (canvas_item);
 
@@ -326,7 +326,7 @@ static gint
 ea_cal_view_event_get_index_in_parent (AtkObject *accessible)
 {
 	GObject *g_obj;
-	GnomeCanvasItem *canvas_item;
+	FooCanvasItem *canvas_item;
 	ECalendarView *cal_view;
 	ECalendarViewEvent *cal_view_event;
 
@@ -336,7 +336,7 @@ ea_cal_view_event_get_index_in_parent (AtkObject *accessible)
 		/* defunct object*/
 		return -1;
 
-	canvas_item = GNOME_CANVAS_ITEM (g_obj);
+	canvas_item = FOO_CANVAS_ITEM (g_obj);
 	cal_view = ea_calendar_helpers_get_cal_view_from (canvas_item);
 	if (!cal_view)
 		return -1;
@@ -424,7 +424,7 @@ ea_cal_view_get_extents (AtkComponent   *component,
                          AtkCoordType   coord_type)
 {
 	GObject *g_obj;
-	GnomeCanvasItem *canvas_item;
+	FooCanvasItem *canvas_item;
 	gint x_window, y_window;
 	gint scroll_x, scroll_y;
 	ECalendarView *cal_view;
@@ -439,7 +439,7 @@ ea_cal_view_get_extents (AtkComponent   *component,
 		return;
 	g_return_if_fail (E_IS_TEXT (g_obj));
 
-	canvas_item = GNOME_CANVAS_ITEM (g_obj);
+	canvas_item = FOO_CANVAS_ITEM (g_obj);
 	cal_view = ea_calendar_helpers_get_cal_view_from (canvas_item);
 	if (!cal_view)
 		return;
@@ -496,7 +496,7 @@ ea_cal_view_get_extents (AtkComponent   *component,
 
 	gdk_window_get_origin (canvas->window,
 			       &x_window, &y_window);
-	gnome_canvas_get_scroll_offsets (GNOME_CANVAS (canvas), &scroll_x, &scroll_y);
+	foo_canvas_get_scroll_offsets (FOO_CANVAS (canvas), &scroll_x, &scroll_y);
 
 	*x = item_x + x_window - scroll_x;
 	*y = item_y + y_window - scroll_y;
diff --git a/calendar/gui/ea-calendar-helpers.c b/calendar/gui/ea-calendar-helpers.c
index f07cdfa..70f4a0e 100644
--- a/calendar/gui/ea-calendar-helpers.c
+++ b/calendar/gui/ea-calendar-helpers.c
@@ -28,7 +28,7 @@
 #include "e-week-view.h"
 
 #include <text/e-text.h>
-#include <libgnomecanvas/gnome-canvas-pixbuf.h>
+#include <libfoocanvas/foo-canvas-pixbuf.h>
 
 /**
  * ea_calendar_helpers_get_accessible_for
@@ -37,12 +37,12 @@
  *
  **/
 AtkObject *
-ea_calendar_helpers_get_accessible_for (GnomeCanvasItem *canvas_item)
+ea_calendar_helpers_get_accessible_for (FooCanvasItem *canvas_item)
 {
 	AtkObject *atk_obj = NULL;
 	GObject *g_obj;
 
-	g_return_val_if_fail ((E_IS_TEXT (canvas_item)) || (GNOME_IS_CANVAS_ITEM (canvas_item)), NULL);;
+	g_return_val_if_fail ((E_IS_TEXT (canvas_item)) || (FOO_IS_CANVAS_ITEM (canvas_item)), NULL);;
 
 	g_obj = G_OBJECT (canvas_item);
 	/* we cannot use atk_gobject_accessible_for_object here,
@@ -54,7 +54,7 @@ ea_calendar_helpers_get_accessible_for (GnomeCanvasItem *canvas_item)
                 if (E_IS_TEXT (canvas_item)) {
 		atk_obj = ea_cal_view_event_new (g_obj);
                 }
-                else if (GNOME_IS_CANVAS_PIXBUF(canvas_item)) {
+                else if (FOO_IS_CANVAS_PIXBUF(canvas_item)) {
                         atk_obj = ea_jump_button_new (g_obj);
                 }
                 else
@@ -72,13 +72,13 @@ ea_calendar_helpers_get_accessible_for (GnomeCanvasItem *canvas_item)
  *
  **/
 ECalendarView *
-ea_calendar_helpers_get_cal_view_from (GnomeCanvasItem *canvas_item)
+ea_calendar_helpers_get_cal_view_from (FooCanvasItem *canvas_item)
 {
-	GnomeCanvas *canvas;
+	FooCanvas *canvas;
 	GtkWidget *view_widget = NULL;
 
 	g_return_val_if_fail (canvas_item, NULL);
-	g_return_val_if_fail ((E_IS_TEXT (canvas_item)) || (GNOME_IS_CANVAS_ITEM (canvas_item)), NULL);
+	g_return_val_if_fail ((E_IS_TEXT (canvas_item)) || (FOO_IS_CANVAS_ITEM (canvas_item)), NULL);
 
 	/* canvas_item is the e_text for the event */
 	/* canvas_item->canvas is the ECanvas for day view */
@@ -100,7 +100,7 @@ ea_calendar_helpers_get_cal_view_from (GnomeCanvasItem *canvas_item)
  *
  **/
 ECalendarViewEvent *
-ea_calendar_helpers_get_cal_view_event_from (GnomeCanvasItem *canvas_item)
+ea_calendar_helpers_get_cal_view_event_from (FooCanvasItem *canvas_item)
 {
 	ECalendarView *cal_view;
 	gboolean event_found;
diff --git a/calendar/gui/ea-calendar-helpers.h b/calendar/gui/ea-calendar-helpers.h
index a4045cd..780955b 100644
--- a/calendar/gui/ea-calendar-helpers.h
+++ b/calendar/gui/ea-calendar-helpers.h
@@ -30,12 +30,12 @@
 #include "ea-cal-view.h"
 
 AtkObject *
-ea_calendar_helpers_get_accessible_for (GnomeCanvasItem *canvas_item);
+ea_calendar_helpers_get_accessible_for (FooCanvasItem *canvas_item);
 
 ECalendarView *
-ea_calendar_helpers_get_cal_view_from (GnomeCanvasItem *canvas_item);
+ea_calendar_helpers_get_cal_view_from (FooCanvasItem *canvas_item);
 
 ECalendarViewEvent *
-ea_calendar_helpers_get_cal_view_event_from (GnomeCanvasItem *canvas_item);
+ea_calendar_helpers_get_cal_view_event_from (FooCanvasItem *canvas_item);
 
 #endif /* _EA_CALENDAR_HELPERS_H__ */
diff --git a/calendar/gui/ea-calendar.c b/calendar/gui/ea-calendar.c
index dcdf8bd..5980c16 100644
--- a/calendar/gui/ea-calendar.c
+++ b/calendar/gui/ea-calendar.c
@@ -21,7 +21,7 @@
  */
 
 #include <text/e-text.h>
-#include <libgnomecanvas/gnome-canvas-pixbuf.h>
+#include <libfoocanvas/foo-canvas-pixbuf.h>
 #include "ea-calendar-helpers.h"
 #include "a11y/ea-factory.h"
 #include "ea-calendar.h"
@@ -59,7 +59,7 @@ gnome_calendar_a11y_init (void)
 
 		/* force loading some types */
 		e_text_type = g_type_class_ref (E_TYPE_TEXT);
-		pixbuf_type = g_type_class_ref (GNOME_TYPE_CANVAS_PIXBUF);
+		pixbuf_type = g_type_class_ref (FOO_TYPE_CANVAS_PIXBUF);
 		e_day_view_type = g_type_class_ref (e_day_view_get_type ());
 		e_week_view_type = g_type_class_ref (E_TYPE_WEEK_VIEW);
 		e_day_view_main_item_type = g_type_class_ref (e_day_view_main_item_get_type ());
@@ -68,7 +68,7 @@ gnome_calendar_a11y_init (void)
 		g_signal_add_emission_hook (g_signal_lookup ("event", E_TYPE_TEXT),
 					    0, ea_calendar_focus_watcher,
 					    NULL, (GDestroyNotify) NULL);
-		g_signal_add_emission_hook (g_signal_lookup ("event", GNOME_TYPE_CANVAS_PIXBUF),
+		g_signal_add_emission_hook (g_signal_lookup ("event", FOO_TYPE_CANVAS_PIXBUF),
                                             0, ea_calendar_focus_watcher,
                                             NULL, (GDestroyNotify) NULL);
 		g_signal_add_emission_hook (g_signal_lookup ("event-after",
@@ -134,12 +134,12 @@ ea_calendar_focus_watcher (GSignalInvocationHint *ihint,
 	object = g_value_get_object (param_values + 0);
 	event = g_value_get_boxed (param_values + 1);
 
-	if ((E_IS_TEXT (object)) || (GNOME_IS_CANVAS_PIXBUF (object))) {
+	if ((E_IS_TEXT (object)) || (FOO_IS_CANVAS_PIXBUF (object))) {
 		/* "event" signal on canvas item
 		 */
-		GnomeCanvasItem *canvas_item;
+		FooCanvasItem *canvas_item;
 
-		canvas_item = GNOME_CANVAS_ITEM (object);
+		canvas_item = FOO_CANVAS_ITEM (object);
 		if (event->type == GDK_FOCUS_CHANGE) {
 			if (event->focus_change.in) {
 				ea_event =
@@ -157,7 +157,7 @@ ea_calendar_focus_watcher (GSignalInvocationHint *ihint,
 		if (event->type == GDK_FOCUS_CHANGE) {
 			if (event->focus_change.in) {
 				/* give main item chance to emit focus */
-				gnome_canvas_item_grab_focus (day_view->main_canvas_item);
+				foo_canvas_item_grab_focus (day_view->main_canvas_item);
 			}
 		}
 	}
@@ -180,7 +180,7 @@ ea_calendar_focus_watcher (GSignalInvocationHint *ihint,
 		if (event->type == GDK_FOCUS_CHANGE) {
 			if (event->focus_change.in) {
 				/* give main item chance to emit focus */
-				gnome_canvas_item_grab_focus (week_view->main_canvas_item);
+				foo_canvas_item_grab_focus (week_view->main_canvas_item);
 			}
 		}
 	}
diff --git a/calendar/gui/ea-day-view-cell.c b/calendar/gui/ea-day-view-cell.c
index 2d42a47..6f72fa6 100644
--- a/calendar/gui/ea-day-view-cell.c
+++ b/calendar/gui/ea-day-view-cell.c
@@ -207,7 +207,7 @@ ea_day_view_cell_get_name (AtkObject *accessible)
 
 	if (!accessible->name) {
 		AtkObject *ea_main_item;
-		GnomeCanvasItem *main_item;
+		FooCanvasItem *main_item;
 		gchar *new_name = g_strdup ("");
 		const gchar *row_label, *column_label;
 
@@ -349,7 +349,7 @@ component_interface_get_extents (AtkComponent *component,
 				   x, y,
 				   &day_view_width, &day_view_height,
 				   coord_type);
-	gnome_canvas_get_scroll_offsets (GNOME_CANVAS (day_view->main_canvas),
+	foo_canvas_get_scroll_offsets (FOO_CANVAS (day_view->main_canvas),
 					 &scroll_x, &scroll_y);
 	*x += day_view->day_offsets[cell->column] - scroll_x;
 	*y += day_view->row_height * cell->row
diff --git a/calendar/gui/ea-jump-button.c b/calendar/gui/ea-jump-button.c
index a6775ad..0ba4d25 100644
--- a/calendar/gui/ea-jump-button.c
+++ b/calendar/gui/ea-jump-button.c
@@ -25,7 +25,7 @@
 #include "ea-calendar-helpers.h"
 #include "ea-week-view.h"
 #include "e-week-view.h"
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 #include <glib/gi18n.h>
 
 static void ea_jump_button_class_init (EaJumpButtonClass *klass);
@@ -74,18 +74,18 @@ ea_jump_button_get_type (void)
 
 		/*
 		 * Figure out the size of the class and instance
-		 * we are run-time deriving from (atk object for GNOME_TYPE_CANVAS_ITEM, in this case)
+		 * we are run-time deriving from (atk object for FOO_TYPE_CANVAS_ITEM, in this case)
 		 */
 
 		factory = atk_registry_get_factory (atk_get_default_registry (),
-						    GNOME_TYPE_CANVAS_ITEM);
+						    FOO_TYPE_CANVAS_ITEM);
 		derived_atk_type = atk_object_factory_get_accessible_type (factory);
 		g_type_query (derived_atk_type, &query);
 
 		tinfo.class_size = query.class_size;
 		tinfo.instance_size = query.instance_size;
 
-		/* we inherit the component and other interfaces from GNOME_TYPE_CANVAS_ITEM */
+		/* we inherit the component and other interfaces from FOO_TYPE_CANVAS_ITEM */
 		type = g_type_register_static (derived_atk_type,
 					       "EaJumpButton", &tinfo, 0);
 
@@ -113,7 +113,7 @@ ea_jump_button_new (GObject *obj)
 	AtkObject *atk_obj = NULL;
 	GObject *target_obj;
 
-	g_return_val_if_fail (GNOME_IS_CANVAS_ITEM (obj), NULL);
+	g_return_val_if_fail (FOO_IS_CANVAS_ITEM (obj), NULL);
 
 	target_obj = obj;
 	atk_obj = g_object_get_data (target_obj, "accessible-object");
@@ -128,7 +128,7 @@ ea_jump_button_new (GObject *obj)
 		atk_obj->role = event_role;
 	}
 
-	/* the registered factory for GNOME_TYPE_CANVAS_ITEM is cannot create a EaJumpbutton,
+	/* the registered factory for FOO_TYPE_CANVAS_ITEM is cannot create a EaJumpbutton,
 	 * we should save the EaJumpbutton object in it.
 	 */
 	g_object_set_data (obj, "accessible-object", atk_obj);
@@ -172,7 +172,7 @@ jump_button_do_action (AtkAction *action,
   gboolean return_value = TRUE;
   AtkGObjectAccessible *atk_gobj;
   GObject *g_obj;
-  GnomeCanvasItem *item;
+  FooCanvasItem *item;
   ECalendarView *cal_view;
   EWeekView *week_view;
 
@@ -181,14 +181,14 @@ jump_button_do_action (AtkAction *action,
   if (!g_obj)
 	  return FALSE;
 
-  item = GNOME_CANVAS_ITEM (g_obj);
-  cal_view = ea_calendar_helpers_get_cal_view_from (GNOME_CANVAS_ITEM (item));
+  item = FOO_CANVAS_ITEM (g_obj);
+  cal_view = ea_calendar_helpers_get_cal_view_from (FOO_CANVAS_ITEM (item));
   week_view = E_WEEK_VIEW (cal_view);
 
   switch (i)
     {
     case 0:
-	    e_week_view_jump_to_button_item (week_view, GNOME_CANVAS_ITEM (item));
+	    e_week_view_jump_to_button_item (week_view, FOO_CANVAS_ITEM (item));
 	    break;
     default:
 	    return_value = FALSE;
diff --git a/calendar/gui/ea-week-view-cell.c b/calendar/gui/ea-week-view-cell.c
index e4b28e3..4b7802e 100644
--- a/calendar/gui/ea-week-view-cell.c
+++ b/calendar/gui/ea-week-view-cell.c
@@ -207,7 +207,7 @@ ea_week_view_cell_get_name (AtkObject *accessible)
 
 	if (!accessible->name) {
 		AtkObject *ea_main_item;
-		GnomeCanvasItem *main_item;
+		FooCanvasItem *main_item;
 		gchar *new_name = g_strdup ("");
 		const gchar *row_label, *column_label;
                 gint new_column, new_row;
@@ -362,7 +362,7 @@ component_interface_get_extents (AtkComponent *component,
 				   x, y,
 				   &week_view_width, &week_view_height,
 				   coord_type);
-	gnome_canvas_get_scroll_offsets (GNOME_CANVAS (week_view->main_canvas),
+	foo_canvas_get_scroll_offsets (FOO_CANVAS (week_view->main_canvas),
 					 &scroll_x, &scroll_y);
         start_day = week_view->display_start_day;
         if (week_view->multi_week_view) {
diff --git a/calendar/gui/ea-week-view.c b/calendar/gui/ea-week-view.c
index 6e9751e..c4ff2d2 100644
--- a/calendar/gui/ea-week-view.c
+++ b/calendar/gui/ea-week-view.c
@@ -230,7 +230,7 @@ ea_week_view_get_n_children (AtkObject *accessible)
 
 	/* add the number of visible jump buttons */
 	for (i = 0; i < E_WEEK_VIEW_MAX_WEEKS * 7; i++) {
-		if (week_view->jump_buttons[i]->object.flags & GNOME_CANVAS_ITEM_VISIBLE)
+		if (week_view->jump_buttons[i]->object.flags & FOO_CANVAS_ITEM_VISIBLE)
 			++count;
 	}
 
diff --git a/calendar/gui/goto.c b/calendar/gui/goto.c
index 5f3e80f..ffc4b9b 100644
--- a/calendar/gui/goto.c
+++ b/calendar/gui/goto.c
@@ -149,7 +149,7 @@ create_ecal (GoToDialog *dlg)
 	dlg->ecal = E_CALENDAR (e_calendar_new ());
 	calitem = dlg->ecal->calitem;
 
-	gnome_canvas_item_set (GNOME_CANVAS_ITEM (calitem),
+	foo_canvas_item_set (FOO_CANVAS_ITEM (calitem),
 			"move_selection_when_moving", FALSE,
 			NULL);
 	e_calendar_item_set_display_popup (calitem, FALSE);
@@ -268,7 +268,7 @@ goto_dialog (GnomeCalendar *gcal)
 	/* Set week_start_day. Convert it to 0 (Mon) to 6 (Sun), which is what we use. */
 	dlg->ecal->calitem->week_start_day = (calendar_config_get_week_start_day () + 6) % 7;
 
-	gnome_canvas_item_grab_focus (GNOME_CANVAS_ITEM (dlg->ecal->calitem));
+	foo_canvas_item_grab_focus (FOO_CANVAS_ITEM (dlg->ecal->calitem));
 
 	b = gtk_dialog_run (GTK_DIALOG (dlg->dialog));
 	gtk_widget_destroy (dlg->dialog);
diff --git a/calendar/gui/weekday-picker.c b/calendar/gui/weekday-picker.c
index 12c09b4..b20d097 100644
--- a/calendar/gui/weekday-picker.c
+++ b/calendar/gui/weekday-picker.c
@@ -30,8 +30,8 @@
 #include <gtk/gtk.h>
 #include <gdk/gdkkeysyms.h>
 #include <glib/gi18n.h>
-#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
-#include <libgnomecanvas/gnome-canvas-text.h>
+#include <libfoocanvas/foo-canvas-rect-ellipse.h>
+#include <libfoocanvas/foo-canvas-text.h>
 #include <e-util/e-util.h>
 #include "weekday-picker.h"
 
@@ -58,8 +58,8 @@ struct _WeekdayPickerPrivate {
 	gint max_letter_width;
 
 	/* Components */
-	GnomeCanvasItem *boxes[7];
-	GnomeCanvasItem *labels[7];
+	FooCanvasItem *boxes[7];
+	FooCanvasItem *labels[7];
 };
 
 
@@ -81,7 +81,7 @@ static void colorize_items (WeekdayPicker *wp);
 
 static guint wp_signals[LAST_SIGNAL];
 
-G_DEFINE_TYPE (WeekdayPicker, weekday_picker, GNOME_TYPE_CANVAS)
+G_DEFINE_TYPE (WeekdayPicker, weekday_picker, FOO_TYPE_CANVAS)
 
 /* Class initialization function for the weekday picker */
 static void
@@ -162,13 +162,13 @@ handle_key_press_event (WeekdayPicker *wp, GdkEvent *event)
 		priv->focus_day = 6;
 
 	colorize_items (wp);
-	gnome_canvas_item_grab_focus (priv->boxes[priv->focus_day]);
+	foo_canvas_item_grab_focus (priv->boxes[priv->focus_day]);
 	return TRUE;
 }
 
 /* Event handler for the day items */
 static gint
-day_event_cb (GnomeCanvasItem *item, GdkEvent *event, gpointer data)
+day_event_cb (FooCanvasItem *item, GdkEvent *event, gpointer data)
 {
 	WeekdayPicker *wp;
 	WeekdayPickerPrivate *priv;
@@ -196,7 +196,7 @@ day_event_cb (GnomeCanvasItem *item, GdkEvent *event, gpointer data)
 		i -= 7;
 
 	priv->focus_day = i;
-	gnome_canvas_item_grab_focus (priv->boxes[i]);
+	foo_canvas_item_grab_focus (priv->boxes[i]);
 	day_clicked (wp, i);
 	return TRUE;
 }
@@ -208,21 +208,21 @@ static void
 create_items (WeekdayPicker *wp)
 {
 	WeekdayPickerPrivate *priv;
-	GnomeCanvasGroup *parent;
+	FooCanvasGroup *parent;
 	gint i;
 
 	priv = wp->priv;
 
-	parent = gnome_canvas_root (GNOME_CANVAS (wp));
+	parent = foo_canvas_root (FOO_CANVAS (wp));
 
 	for (i = 0; i < 7; i++) {
-		priv->boxes[i] = gnome_canvas_item_new (parent,
-							GNOME_TYPE_CANVAS_RECT,
+		priv->boxes[i] = foo_canvas_item_new (parent,
+							FOO_TYPE_CANVAS_RECT,
 							NULL);
 		g_signal_connect (priv->boxes[i], "event", G_CALLBACK (day_event_cb), wp);
 
-		priv->labels[i] = gnome_canvas_item_new (parent,
-							 GNOME_TYPE_CANVAS_TEXT,
+		priv->labels[i] = foo_canvas_item_new (parent,
+							 FOO_TYPE_CANVAS_TEXT,
 							 NULL);
 		g_signal_connect (priv->labels[i], "event", G_CALLBACK (day_event_cb), wp);
 	}
@@ -303,12 +303,12 @@ colorize_items (WeekdayPicker *wp)
 		else
 			o = outline;
 
-		gnome_canvas_item_set (priv->boxes[i],
+		foo_canvas_item_set (priv->boxes[i],
 				       "fill_color_gdk", f,
 				       "outline_color_gdk", o,
 				       NULL);
 
-		gnome_canvas_item_set (priv->labels[i],
+		foo_canvas_item_set (priv->labels[i],
 				       "fill_color_gdk", t,
 				       NULL);
 	}
@@ -349,7 +349,7 @@ configure_items (WeekdayPicker *wp)
 		if (day >= 7)
 			day -= 7;
 
-		gnome_canvas_item_set (priv->boxes[i],
+		foo_canvas_item_set (priv->boxes[i],
 				       "x1", (double) (i * box_width),
 				       "y1", (double) 0,
 				       "x2", (double) ((i + 1) * box_width),
@@ -358,7 +358,7 @@ configure_items (WeekdayPicker *wp)
 				       NULL);
 
 		c = get_day_text (day);
-		gnome_canvas_item_set (priv->labels[i],
+		foo_canvas_item_set (priv->labels[i],
 				       "text", c,
 				       "x", (double) (i * box_width) + box_width / 2.0,
 				       "y", (double) (1 + PADDING),
@@ -409,7 +409,7 @@ weekday_picker_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
 	if (GTK_WIDGET_CLASS (weekday_picker_parent_class)->size_allocate)
 		(* GTK_WIDGET_CLASS (weekday_picker_parent_class)->size_allocate) (widget, allocation);
 
-	gnome_canvas_set_scroll_region (GNOME_CANVAS (wp),
+	foo_canvas_set_scroll_region (FOO_CANVAS (wp),
 					0, 0, allocation->width, allocation->height);
 
 	configure_items (wp);
@@ -636,7 +636,7 @@ weekday_picker_focus (GtkWidget *widget, GtkDirectionType direction)
 	}
 
 	priv->focus_day = priv->week_start_day;
-	gnome_canvas_item_grab_focus (priv->boxes[priv->focus_day]);
+	foo_canvas_item_grab_focus (priv->boxes[priv->focus_day]);
 	colorize_items (wp);
 
 	return TRUE;
diff --git a/calendar/gui/weekday-picker.h b/calendar/gui/weekday-picker.h
index f92eb37..083d4d2 100644
--- a/calendar/gui/weekday-picker.h
+++ b/calendar/gui/weekday-picker.h
@@ -24,7 +24,7 @@
 #ifndef WEEKDAY_PICKER_H
 #define WEEKDAY_PICKER_H
 
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 
 G_BEGIN_DECLS
 
@@ -42,14 +42,14 @@ typedef struct _WeekdayPickerClass WeekdayPickerClass;
 typedef struct _WeekdayPickerPrivate WeekdayPickerPrivate;
 
 struct _WeekdayPicker {
-	GnomeCanvas canvas;
+	FooCanvas canvas;
 
 	/* Private data */
 	WeekdayPickerPrivate *priv;
 };
 
 struct _WeekdayPickerClass {
-	GnomeCanvasClass parent_class;
+	FooCanvasClass parent_class;
 
 	void (* changed) (WeekdayPicker *wp);
 };
diff --git a/configure.ac b/configure.ac
index 938fea0..8829fa4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -53,11 +53,9 @@ m4_define([eds_minimum_version], [evo_version])
 m4_define([gnome_icon_theme_minimum_version], [2.19.91])
 m4_define([gnome_desktop_minimum_version], [2.26.0])
 m4_define([libbonobo_minimum_version], [2.20.3])
-m4_define([libbonoboui_minimum_version], [2.4.2])
 m4_define([libgtkhtml_minimum_version], [3.27.90])
 m4_define([gconf_minimum_version], [2.0.0])		dnl XXX Just a Guess
 m4_define([libglade_minimum_version], [2.0.0])		dnl XXX Just a Guess
-m4_define([libgnomecanvas_minimum_version], [2.0.0])	dnl XXX Just a Guess
 m4_define([libgnomeui_minimum_version], [2.0.0])	dnl XXX Just a Guess
 m4_define([libxml_minimum_version], [2.7.3])
 m4_define([shared_mime_info_minimum_version], [0.22])
@@ -236,9 +234,7 @@ PKG_CHECK_MODULES([GNOME_PLATFORM],
 	 gtk+-2.0 >= gtk_minimum_version
 	 gconf-2.0 >= gconf_minimum_version
 	 libbonobo-2.0 >= libbonobo_minimum_version
-	 libbonoboui-2.0 >= libbonoboui_minimum_version
 	 libglade-2.0 >= libglade_minimum_version
-	 libgnomecanvas-2.0 >= libgnomecanvas_minimum_version
 	 libgnomeui-2.0 >= libgnomeui_minimum_version
 	 libxml-2.0 >= libxml_minimum_version
 	 shared-mime-info >= shared_mime_info_minimum_version
@@ -1347,6 +1343,16 @@ if test x$no_x != xyes ; then
 fi
 ])
 
+dnl ****************************************
+dnl Check for Xft/XRender (for libfoocanvas)
+dnl ****************************************
+
+AC_CHECK_LIB(Xrender, XRenderFindFormat,
+	[AC_SUBST(RENDER_LIBS, "-lXrender -lXext")
+	 AC_DEFINE(HAVE_RENDER, 1, [Define if libXrender is available])],
+	[AC_SUBST(RENDER_LIBS, "")],
+	[-lXext])
+
 dnl *************************
 dnl Check for the Gtk backend
 dnl if it's X11, we -lX11
@@ -1388,17 +1394,11 @@ AC_DEFUN([EVO_SET_COMPILE_FLAGS], [
 	$1_LIBS="[$]$1_LIBS $4"
 ])
 
-dnl ************************
-dnl Required version numbers
-dnl ************************
-BONOBOUI_REQUIRED=libbonoboui_minimum_version
-AC_SUBST(BONOBOUI_REQUIRED)
-
 dnl ********************************
 dnl Flags to get all the GNOME stuff
 dnl ********************************
 
-FULL_GNOME_DEPS="libbonoboui-2.0 gconf-2.0 gthread-2.0 gobject-2.0 libgnomeui-2.0 libglade-2.0"
+FULL_GNOME_DEPS="gconf-2.0 gthread-2.0 gobject-2.0 libgnomeui-2.0 libglade-2.0"
 
 PKG_CHECK_MODULES([HAL], [hal >= hal_minimum_version], [HAVE_HAL="yes"], [HAVE_HAL="no"])
 if test "x$HAVE_HAL" = "xyes"; then
@@ -1526,7 +1526,7 @@ AC_SUBST(CERT_UI_LIBS)
 dnl ******************************
 dnl E_NAME Flags
 dnl ******************************
-EVO_SET_COMPILE_FLAGS(E_NAME, libgnomeui-2.0 libbonoboui-2.0)
+EVO_SET_COMPILE_FLAGS(E_NAME, libgnomeui-2.0)
 AC_SUBST(E_NAME_CFLAGS)
 AC_SUBST(E_NAME_LIBS)
 
@@ -1544,7 +1544,7 @@ fi
 dnl ************
 dnl E_UTIL Flags
 dnl ************
-EVO_SET_COMPILE_FLAGS(E_UTIL, libbonoboui-2.0 libglade-2.0 libgnomeui-2.0 gnome-desktop-2.0 libedataserver-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE camel-$EDS_PACKAGE $mozilla_nspr, $THREADS_CFLAGS $MANUAL_NSPR_CFLAGS $E_UTIL_X11_CFLAGS, $THREADS_LIBS $MANUAL_NSPR_LIBS $E_UTIL_X11_LIBS)
+EVO_SET_COMPILE_FLAGS(E_UTIL, libglade-2.0 libgnomeui-2.0 gnome-desktop-2.0 libedataserver-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE camel-$EDS_PACKAGE $mozilla_nspr, $THREADS_CFLAGS $MANUAL_NSPR_CFLAGS $E_UTIL_X11_CFLAGS, $THREADS_LIBS $MANUAL_NSPR_LIBS $E_UTIL_X11_LIBS)
 AC_SUBST(E_UTIL_CFLAGS)
 AC_SUBST(E_UTIL_LIBS)
 
@@ -1560,14 +1560,14 @@ AC_SUBST(TZDIALOG_LIBS)
 dnl ***************
 dnl E_WIDGETS Flags
 dnl ***************
-EVO_SET_COMPILE_FLAGS(E_WIDGETS, libbonoboui-2.0 gio-2.0 gconf-2.0 gobject-2.0 libgnomeui-2.0 libglade-2.0 libedataserverui-$EDS_PACKAGE libedataserver-$EDS_PACKAGE gtkhtml-editor)
+EVO_SET_COMPILE_FLAGS(E_WIDGETS, gio-2.0 gconf-2.0 gobject-2.0 libgnomeui-2.0 libglade-2.0 libedataserverui-$EDS_PACKAGE libedataserver-$EDS_PACKAGE gtkhtml-editor)
 AC_SUBST(E_WIDGETS_CFLAGS)
 AC_SUBST(E_WIDGETS_LIBS)
 
 dnl ***************
 dnl IMPORTERS Flags
 dnl ***************
-EVO_SET_COMPILE_FLAGS(IMPORTERS, libedataserverui-$EDS_PACKAGE camel-provider-$EDS_PACKAGE camel-$EDS_PACKAGE libglade-2.0 libbonoboui-2.0 libgnomeui-2.0 libebook-$EDS_PACKAGE)
+EVO_SET_COMPILE_FLAGS(IMPORTERS, libedataserverui-$EDS_PACKAGE camel-provider-$EDS_PACKAGE camel-$EDS_PACKAGE libglade-2.0 libgnomeui-2.0 libebook-$EDS_PACKAGE)
 AC_SUBST(IMPORTERS_CFLAGS)
 AC_SUBST(IMPORTERS_LIBS)
 
@@ -1581,7 +1581,7 @@ AC_SUBST(LIBFILTER_LIBS)
 dnl ***********
 dnl Shell Flags
 dnl ***********
-EVO_SET_COMPILE_FLAGS(SHELL, libgnomeui-2.0 libbonoboui-2.0 gnome-desktop-2.0 libglade-2.0 gio-2.0 gconf-2.0 gobject-2.0 libgtkhtml-$GTKHTML_PACKAGE unique-1.0 libedataserverui-$EDS_PACKAGE)
+EVO_SET_COMPILE_FLAGS(SHELL, libgnomeui-2.0 gnome-desktop-2.0 libglade-2.0 gio-2.0 gconf-2.0 gobject-2.0 libgtkhtml-$GTKHTML_PACKAGE unique-1.0 libedataserverui-$EDS_PACKAGE)
 
 AC_SUBST(SHELL_CFLAGS)
 AC_SUBST(SHELL_LIBS)
@@ -1589,7 +1589,7 @@ AC_SUBST(SHELL_LIBS)
 dnl *****************
 dnl Addressbook Flags
 dnl *****************
-EVOLUTION_ADDRESSBOOK_DEPS="libbonoboui-2.0 libglade-2.0 libgnomeui-2.0 gio-2.0 gconf-2.0 gobject-2.0 libgtkhtml-$GTKHTML_PACKAGE libebook-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE camel-$EDS_PACKAGE gtkhtml-editor unique-1.0"
+EVOLUTION_ADDRESSBOOK_DEPS="libglade-2.0 libgnomeui-2.0 gio-2.0 gconf-2.0 gobject-2.0 libgtkhtml-$GTKHTML_PACKAGE libebook-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE camel-$EDS_PACKAGE gtkhtml-editor unique-1.0"
 EVO_SET_COMPILE_FLAGS(EVOLUTION_ADDRESSBOOK, $EVOLUTION_ADDRESSBOOK_DEPS)
 AC_SUBST(EVOLUTION_ADDRESSBOOK_CFLAGS)
 AC_SUBST(EVOLUTION_ADDRESSBOOK_LIBS)
@@ -1622,7 +1622,7 @@ EVO_SET_COMPILE_FLAGS(LIBSOUP, libsoup-2.4 >= 2.3.0)
 AC_SUBST(LIBSOUP_CFLAGS)
 AC_SUBST(LIBSOUP_LIBS)
 
-EVO_SET_COMPILE_FLAGS(EVOLUTION_CALENDAR, libgnomeui-2.0 libbonoboui-2.0 libglade-2.0 gio-2.0 gconf-2.0 gobject-2.0 libgtkhtml-$GTKHTML_PACKAGE libebook-$EDS_PACKAGE libecal-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE libebackend-$EDS_PACKAGE $HAL_REQUIREMENT $libnotify gtkhtml-editor libgdata-$EDS_PACKAGE libgdata-google-$EDS_PACKAGE unique-1.0)
+EVO_SET_COMPILE_FLAGS(EVOLUTION_CALENDAR, libgnomeui-2.0 libglade-2.0 gio-2.0 gconf-2.0 gobject-2.0 libgtkhtml-$GTKHTML_PACKAGE libebook-$EDS_PACKAGE libecal-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE libebackend-$EDS_PACKAGE $HAL_REQUIREMENT $libnotify gtkhtml-editor libgdata-$EDS_PACKAGE libgdata-google-$EDS_PACKAGE unique-1.0)
 AC_SUBST(EVOLUTION_CALENDAR_CFLAGS)
 AC_SUBST(EVOLUTION_CALENDAR_LIBS)
 
@@ -1635,7 +1635,7 @@ fi
 dnl **********
 dnl Mail Flags
 dnl **********
-EVO_SET_COMPILE_FLAGS(EVOLUTION_MAIL, camel-provider-$EDS_PACKAGE libgnomeui-2.0 libbonoboui-2.0 libglade-2.0 gio-2.0 gconf-2.0 gobject-2.0 libgtkhtml-$GTKHTML_PACKAGE gtkhtml-editor bonobo-activation-2.0 $mozilla_nss libebook-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE unique-1.0)
+EVO_SET_COMPILE_FLAGS(EVOLUTION_MAIL, camel-provider-$EDS_PACKAGE libgnomeui-2.0 libglade-2.0 gio-2.0 gconf-2.0 gobject-2.0 libgtkhtml-$GTKHTML_PACKAGE gtkhtml-editor bonobo-activation-2.0 $mozilla_nss libebook-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE unique-1.0)
 AC_SUBST(EVOLUTION_MAIL_CFLAGS)
 AC_SUBST(EVOLUTION_MAIL_LIBS)
 
@@ -1900,7 +1900,7 @@ if echo ${plugins_enabled} | grep "exchange-operations" > /dev/null ; then
 		dnl **************************************************
 		dnl * Exchange Operations plugin
 		dnl **************************************************
-		EVO_SET_COMPILE_FLAGS(CAMEL_EXCHANGE, libbonoboui-2.0 libglade-2.0 gconf-2.0 camel-provider-$EDS_PACKAGE libebook-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE libexchange-storage-$EDS_PACKAGE libecal-$EDS_PACKAGE)
+		EVO_SET_COMPILE_FLAGS(CAMEL_EXCHANGE, libglade-2.0 gconf-2.0 camel-provider-$EDS_PACKAGE libebook-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE libexchange-storage-$EDS_PACKAGE libecal-$EDS_PACKAGE)
 		AC_SUBST(CAMEL_EXCHANGE_CFLAGS)
 		AC_SUBST(CAMEL_EXCHANGE_LIBS)
 	else
@@ -2031,6 +2031,7 @@ views/tasks/Makefile
 views/memos/Makefile
 widgets/Makefile
 widgets/e-timezone-dialog/Makefile
+widgets/libfoocanvas/Makefile
 widgets/menus/Makefile
 widgets/misc/Makefile
 widgets/text/Makefile
diff --git a/mail/message-list.c b/mail/message-list.c
index 7e0fb9b..4313e70 100644
--- a/mail/message-list.c
+++ b/mail/message-list.c
@@ -1997,7 +1997,7 @@ message_list_setup_etree (MessageList *message_list, gboolean outgoing)
 		d(printf ("folder name is '%s'\n", name));
 
 		path = mail_config_folder_to_cachename (message_list->folder, "et-expanded-");
-		g_object_set_data (G_OBJECT (((GnomeCanvasItem *) item)->canvas), "freeze-cursor", &data);
+		g_object_set_data (G_OBJECT (((FooCanvasItem *) item)->canvas), "freeze-cursor", &data);
 
 		if (path && g_stat (path, &st) == 0 && st.st_size > 0 && S_ISREG (st.st_mode)) {
 			/* build based on saved file */
diff --git a/modules/calendar/e-cal-shell-content.c b/modules/calendar/e-cal-shell-content.c
index eccd146..b0e2cd9 100644
--- a/modules/calendar/e-cal-shell-content.c
+++ b/modules/calendar/e-cal-shell-content.c
@@ -169,13 +169,13 @@ cal_shell_content_get_focus_location (ECalShellContent *cal_shell_content)
 		if (GTK_WIDGET_HAS_FOCUS (day_view->top_canvas))
 			return FOCUS_CALENDAR;
 
-		if (GNOME_CANVAS (day_view->top_canvas)->focused_item != NULL)
+		if (FOO_CANVAS (day_view->top_canvas)->focused_item != NULL)
 			return FOCUS_CALENDAR;
 
 		if (GTK_WIDGET_HAS_FOCUS (day_view->main_canvas))
 			return FOCUS_CALENDAR;
 
-		if (GNOME_CANVAS (day_view->main_canvas)->focused_item != NULL)
+		if (FOO_CANVAS (day_view->main_canvas)->focused_item != NULL)
 			return FOCUS_CALENDAR;
 
 		if (GTK_WIDGET_HAS_FOCUS (day_view))
@@ -187,7 +187,7 @@ cal_shell_content_get_focus_location (ECalShellContent *cal_shell_content)
 		if (GTK_WIDGET_HAS_FOCUS (week_view->main_canvas))
 			return FOCUS_CALENDAR;
 
-		if (GNOME_CANVAS (week_view->main_canvas)->focused_item != NULL)
+		if (FOO_CANVAS (week_view->main_canvas)->focused_item != NULL)
 			return FOCUS_CALENDAR;
 
 		if (GTK_WIDGET_HAS_FOCUS (week_view))
diff --git a/modules/mail/e-mail-shell-content.c b/modules/mail/e-mail-shell-content.c
index b801093..24611ff 100644
--- a/modules/mail/e-mail-shell-content.c
+++ b/modules/mail/e-mail-shell-content.c
@@ -88,7 +88,7 @@ mail_shell_content_etree_unfreeze (MessageList *message_list,
 	GObject *object;
 
 	item = e_tree_get_item (message_list->tree);
-	object = G_OBJECT (((GnomeCanvasItem *) item)->canvas);
+	object = G_OBJECT (((FooCanvasItem *) item)->canvas);
 
 	g_object_set_data (object, "freeze-cursor", 0);
 }
diff --git a/widgets/Makefile.am b/widgets/Makefile.am
index 99305b8..661422b 100644
--- a/widgets/Makefile.am
+++ b/widgets/Makefile.am
@@ -1,5 +1,6 @@
 
 SUBDIRS =			\
+	libfoocanvas		\
 	misc			\
 	text			\
 	e-timezone-dialog	\
diff --git a/widgets/libfoocanvas/Makefile.am b/widgets/libfoocanvas/Makefile.am
new file mode 100644
index 0000000..703362c
--- /dev/null
+++ b/widgets/libfoocanvas/Makefile.am
@@ -0,0 +1,63 @@
+AM_CPPFLAGS = \
+	-I$(top_srcdir)					\
+	-I$(top_srcdir)/widgets				\
+	-I$(top_builddir)				\
+	$(E_WIDGETS_CFLAGS)				\
+	-DFOOCANVASLIBDIR=\""$(libdir)"\" 		\
+	-DFOOCANVASDATADIR=\""$(datadir)"\" 		\
+	-DFOOCANVASPIXMAPDIR=\""$(datadir)/pixmaps"\"	\
+	-DFOOCANVASBINDIR=\""$(bindir)"\" 		\
+	-DFOOCANVASLOCALSTATEDIR=\""$(localstatedir)"\"	\
+	-DFOOCANVASLOCALEDIR=\""$(gnomelocaledir)"\" 	\
+	-DG_LOG_DOMAIN=\"Foocanvas\"			\
+	-DVERSION=\"$(VERSION)\"
+
+noinst_LTLIBRARIES = libfoocanvas.la
+
+libfoocanvas_la_LIBADD = \
+	$(RENDER_LIBS)				\
+	$(E_WIDGETS_LIBS)
+
+libfoocanvas_la_SOURCES =			\
+	libart-types.h				\
+	foo-canvas-i18n.h			\
+	foo-canvas-line.c			\
+	foo-canvas-line.h			\
+	foo-canvas-marshal.list			\
+	foo-canvas-pixbuf.c			\
+	foo-canvas-pixbuf.h			\
+	foo-canvas-polygon.c			\
+	foo-canvas-polygon.h			\
+	foo-canvas-rect-ellipse.c		\
+	foo-canvas-rect-ellipse.h		\
+	foo-canvas-text.c			\
+	foo-canvas-text.h			\
+	foo-canvas-util.c			\
+	foo-canvas-util.h			\
+	foo-canvas-widget.c			\
+	foo-canvas-widget.h			\
+	foo-canvas.c				\
+	foo-canvas.h				\
+	libfoocanvas.h				\
+	libfoocanvastypes.c
+
+GENMARSHAL_COMMAND = $(GLIB_GENMARSHAL) --prefix=foo_canvas_marshal
+SUFFIXES = .list
+
+.list.h:
+	$(GENMARSHAL_COMMAND) --header $< >$@
+
+.list.c:
+	(echo '/* This file has been automatically generated.  Do not edit. */' && \
+	echo '#include "$*.h"' && \
+	$(GENMARSHAL_COMMAND) --body $< ) >$@
+
+# A hint is needed to build the header first:
+BUILT_SOURCES = foo-canvas-marshal.h
+
+# Another hint, see bugs #172211 and #172212:
+non-intermediate: foo-canvas-marshal.c
+
+CLEANFILES = foo-canvas-marshal.h foo-canvas-marshal.c
+
+-include $(top_srcdir)/git.mk
diff --git a/widgets/libfoocanvas/foo-canvas-i18n.h b/widgets/libfoocanvas/foo-canvas-i18n.h
new file mode 100644
index 0000000..1675bc4
--- /dev/null
+++ b/widgets/libfoocanvas/foo-canvas-i18n.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * The Gnome Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+/*
+ * Handles all of the internationalization configuration options.
+ * Author: Tom Tromey <tromey creche cygnus com>
+ */
+
+#ifndef __LIBFOO_CANVAS_I18N_H__
+#define __LIBFOO_CANVAS_I18N_H__ 
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#if !defined(__LIBFOO_CANVAS_I18NP_H__)
+
+#ifdef ENABLE_NLS
+#    include <libintl.h>
+#    ifdef GNOME_EXPLICIT_TRANSLATION_DOMAIN
+#        undef _
+#        define _(String) dgettext (GNOME_EXPLICIT_TRANSLATION_DOMAIN, String)
+#    else 
+#        define _(String) gettext (String)
+#    endif
+#    ifdef gettext_noop
+#        define N_(String) gettext_noop (String)
+#    else
+#        define N_(String) (String)
+#    endif
+#else
+/* Stubs that do something close enough.  */
+#    define textdomain(String) (String)
+#    define gettext(String) (String)
+#    define dgettext(Domain,Message) (Message)
+#    define dcgettext(Domain,Message,Type) (Message)
+#    define bindtextdomain(Domain,Directory) (Domain)
+#    define _(String) (String)
+#    define N_(String) (String)
+#endif
+
+#endif
+
+G_END_DECLS
+
+#endif /* __LIBFOO_CANVAS_I18N_H__ */
diff --git a/widgets/libfoocanvas/foo-canvas-line.c b/widgets/libfoocanvas/foo-canvas-line.c
new file mode 100644
index 0000000..570ead1
--- /dev/null
+++ b/widgets/libfoocanvas/foo-canvas-line.c
@@ -0,0 +1,1289 @@
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * The Gnome Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+/* Line/curve item type for FooCanvas widget
+ *
+ * FooCanvas is basically a port of the Tk toolkit's most excellent canvas widget.  Tk is
+ * copyrighted by the Regents of the University of California, Sun Microsystems, and other parties.
+ *
+ *
+ * Author: Federico Mena <federico nuclecu unam mx>
+ */
+
+#include <config.h>
+#include <math.h>
+#include <string.h>
+#include "libfoocanvas.h"
+
+#define noVERBOSE
+
+#define DEFAULT_SPLINE_STEPS 12		/* this is what Tk uses */
+#define NUM_ARROW_POINTS     6		/* number of points in an arrowhead */
+#define NUM_STATIC_POINTS    256	/* number of static points to use to avoid allocating arrays */
+
+
+#define GROW_BOUNDS(bx1, by1, bx2, by2, x, y) {	\
+	if (x < bx1)				\
+		bx1 = x;			\
+						\
+	if (x > bx2)				\
+		bx2 = x;			\
+						\
+	if (y < by1)				\
+		by1 = y;			\
+						\
+	if (y > by2)				\
+		by2 = y;			\
+}
+
+
+enum {
+	PROP_0,
+	PROP_POINTS,
+	PROP_FILL_COLOR,
+	PROP_FILL_COLOR_GDK,
+	PROP_FILL_COLOR_RGBA,
+	PROP_FILL_STIPPLE,
+	PROP_WIDTH_PIXELS,
+	PROP_WIDTH_UNITS,
+	PROP_CAP_STYLE,
+	PROP_JOIN_STYLE,
+	PROP_LINE_STYLE,
+	PROP_FIRST_ARROWHEAD,
+	PROP_LAST_ARROWHEAD,
+	PROP_SMOOTH,
+	PROP_SPLINE_STEPS,
+	PROP_ARROW_SHAPE_A,
+	PROP_ARROW_SHAPE_B,
+	PROP_ARROW_SHAPE_C
+};
+
+
+static void foo_canvas_line_class_init   (FooCanvasLineClass *klass);
+static void foo_canvas_line_init         (FooCanvasLine      *line);
+static void foo_canvas_line_destroy      (GtkObject            *object);
+static void foo_canvas_line_set_property (GObject              *object,
+					    guint                 param_id,
+					    const GValue         *value,
+					    GParamSpec           *pspec);
+static void foo_canvas_line_get_property (GObject              *object,
+					    guint                 param_id,
+					    GValue               *value,
+					    GParamSpec           *pspec);
+
+static void   foo_canvas_line_update      (FooCanvasItem *item,
+					     double i2w_dx, double i2w_dy,
+					     int flags);
+static void   foo_canvas_line_realize     (FooCanvasItem *item);
+static void   foo_canvas_line_unrealize   (FooCanvasItem *item);
+static void   foo_canvas_line_draw        (FooCanvasItem *item, GdkDrawable *drawable,
+					     GdkEventExpose   *event);
+static double foo_canvas_line_point       (FooCanvasItem *item, double x, double y,
+					     int cx, int cy, FooCanvasItem **actual_item);
+static void   foo_canvas_line_translate   (FooCanvasItem *item, double dx, double dy);
+static void   foo_canvas_line_bounds      (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2);
+
+
+static FooCanvasItemClass *parent_class;
+
+G_DEFINE_TYPE (FooCanvasLine, foo_canvas_line, FOO_TYPE_CANVAS_ITEM)
+
+static void
+foo_canvas_line_class_init (FooCanvasLineClass *klass)
+{
+	GObjectClass *gobject_class;
+	GtkObjectClass *object_class;
+	FooCanvasItemClass *item_class;
+
+	gobject_class = (GObjectClass *) klass;
+	object_class = (GtkObjectClass *) klass;
+	item_class = (FooCanvasItemClass *) klass;
+
+	parent_class = g_type_class_peek_parent (klass);
+
+	gobject_class->set_property = foo_canvas_line_set_property;
+	gobject_class->get_property = foo_canvas_line_get_property;
+
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_POINTS,
+                 g_param_spec_boxed ("points", NULL, NULL,
+				     FOO_TYPE_CANVAS_POINTS,
+				     G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_FILL_COLOR,
+                 g_param_spec_string ("fill-color", NULL, NULL,
+                                      NULL,
+                                      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_FILL_COLOR_GDK,
+                 g_param_spec_boxed ("fill-color-gdk", NULL, NULL,
+				     GDK_TYPE_COLOR,
+				     G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_FILL_COLOR_RGBA,
+                 g_param_spec_uint ("fill-color-rgba", NULL, NULL,
+				    0, G_MAXUINT, 0,
+				    G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_FILL_STIPPLE,
+                 g_param_spec_object ("fill-stipple", NULL, NULL,
+                                      GDK_TYPE_DRAWABLE,
+                                      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_WIDTH_PIXELS,
+                 g_param_spec_uint ("width-pixels", NULL, NULL,
+				    0, G_MAXUINT, 0,
+				    G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_WIDTH_UNITS,
+                 g_param_spec_double ("width-units", NULL, NULL,
+				      0.0, G_MAXDOUBLE, 0.0,
+				      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_CAP_STYLE,
+                 g_param_spec_enum ("cap-style", NULL, NULL,
+                                    GDK_TYPE_CAP_STYLE,
+                                    GDK_CAP_BUTT,
+                                    G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_JOIN_STYLE,
+                 g_param_spec_enum ("join-style", NULL, NULL,
+                                    GDK_TYPE_JOIN_STYLE,
+                                    GDK_JOIN_MITER,
+                                    G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_LINE_STYLE,
+                 g_param_spec_enum ("line-style", NULL, NULL,
+                                    GDK_TYPE_LINE_STYLE,
+                                    GDK_LINE_SOLID,
+                                    G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_FIRST_ARROWHEAD,
+                 g_param_spec_boolean ("first-arrowhead", NULL, NULL,
+				       FALSE,
+				       G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_LAST_ARROWHEAD,
+                 g_param_spec_boolean ("last-arrowhead", NULL, NULL,
+				       FALSE,
+				       G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_SMOOTH,
+                 g_param_spec_boolean ("smooth", NULL, NULL,
+				       FALSE,
+				       G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_SPLINE_STEPS,
+                 g_param_spec_uint ("spline-steps", NULL, NULL,
+				    0, G_MAXUINT, DEFAULT_SPLINE_STEPS,
+				    G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_ARROW_SHAPE_A,
+                 g_param_spec_double ("arrow-shape-a", NULL, NULL,
+				      -G_MAXDOUBLE, G_MAXDOUBLE, 0,
+				      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_ARROW_SHAPE_B,
+                 g_param_spec_double ("arrow-shape-b", NULL, NULL,
+				      -G_MAXDOUBLE, G_MAXDOUBLE, 0,
+				      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_ARROW_SHAPE_C,
+                 g_param_spec_double ("arrow-shape-c", NULL, NULL,
+				      -G_MAXDOUBLE, G_MAXDOUBLE, 0,
+				      G_PARAM_READWRITE));
+
+	object_class->destroy = foo_canvas_line_destroy;
+
+	item_class->update = foo_canvas_line_update;
+	item_class->realize = foo_canvas_line_realize;
+	item_class->unrealize = foo_canvas_line_unrealize;
+	item_class->draw = foo_canvas_line_draw;
+	item_class->point = foo_canvas_line_point;
+	item_class->translate = foo_canvas_line_translate;
+	item_class->bounds = foo_canvas_line_bounds;
+}
+
+static void
+foo_canvas_line_init (FooCanvasLine *line)
+{
+	line->width = 0.0;
+	line->cap = GDK_CAP_BUTT;
+	line->join = GDK_JOIN_MITER;
+	line->line_style = GDK_LINE_SOLID;
+	line->shape_a = 0.0;
+	line->shape_b = 0.0;
+	line->shape_c = 0.0;
+	line->spline_steps = DEFAULT_SPLINE_STEPS;
+}
+
+static void
+foo_canvas_line_destroy (GtkObject *object)
+{
+	FooCanvasLine *line;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (FOO_IS_CANVAS_LINE (object));
+
+	line = FOO_CANVAS_LINE (object);
+
+	/* remember, destroy can be run multiple times! */
+
+	if (line->coords)
+		g_free (line->coords);
+	line->coords = NULL;
+
+	if (line->first_coords)
+		g_free (line->first_coords);
+	line->first_coords = NULL;
+
+	if (line->last_coords)
+		g_free (line->last_coords);
+	line->last_coords = NULL;
+
+	if (line->stipple)
+		g_object_unref (line->stipple);
+	line->stipple = NULL;
+
+	if (GTK_OBJECT_CLASS (parent_class)->destroy)
+		(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+/* Computes the bounding box of the line, including its arrow points.  Assumes that the number of
+ * points in the line is not zero.
+ */
+static void
+get_bounds (FooCanvasLine *line, double *bx1, double *by1, double *bx2, double *by2)
+{
+	double *coords;
+	double x1, y1, x2, y2;
+	double width;
+	int i;
+
+	if (!line->coords) {
+	    *bx1 = *by1 = *bx2 = *by2 = 0.0;
+	    return;
+	}
+	
+	/* Find bounding box of line's points */
+
+	x1 = x2 = line->coords[0];
+	y1 = y2 = line->coords[1];
+
+	for (i = 1, coords = line->coords + 2; i < line->num_points; i++, coords += 2)
+		GROW_BOUNDS (x1, y1, x2, y2, coords[0], coords[1]);
+
+	/* Add possible over-estimate for wide lines */
+
+	if (line->width_pixels)
+		width = line->width / line->item.canvas->pixels_per_unit;
+	else
+		width = line->width;
+
+	x1 -= width;
+	y1 -= width;
+	x2 += width;
+	y2 += width;
+
+	/* For mitered lines, make a second pass through all the points.  Compute the location of
+	 * the two miter vertex points and add them to the bounding box.
+	 */
+
+	if (line->join == GDK_JOIN_MITER)
+		for (i = line->num_points, coords = line->coords; i >= 3; i--, coords += 2) {
+			double mx1, my1, mx2, my2;
+
+			if (foo_canvas_get_miter_points (coords[0], coords[1],
+							   coords[2], coords[3],
+							   coords[4], coords[5],
+							   width,
+							   &mx1, &my1, &mx2, &my2)) {
+				GROW_BOUNDS (x1, y1, x2, y2, mx1, my1);
+				GROW_BOUNDS (x1, y1, x2, y2, mx2, my2);
+			}
+		}
+
+	/* Add the arrow points, if any */
+
+	if (line->first_arrow && line->first_coords)
+		for (i = 0, coords = line->first_coords; i < NUM_ARROW_POINTS; i++, coords += 2)
+			GROW_BOUNDS (x1, y1, x2, y2, coords[0], coords[1]);
+
+	if (line->last_arrow && line->last_coords)
+		for (i = 0, coords = line->last_coords; i < NUM_ARROW_POINTS; i++, coords += 2)
+			GROW_BOUNDS (x1, y1, x2, y2, coords[0], coords[1]);
+
+	/* Done */
+
+	*bx1 = x1;
+	*by1 = y1;
+	*bx2 = x2;
+	*by2 = y2;
+}
+
+/* Computes the bounding box of the line, in canvas coordinates.  Assumes that the number of points in the polygon is
+ * not zero. 
+ */
+static void
+get_bounds_canvas (FooCanvasLine *line,
+		   double *bx1, double *by1, double *bx2, double *by2,
+		   double i2w_dx, double i2w_dy)
+{
+	FooCanvasItem *item;
+	double bbox_x0, bbox_y0, bbox_x1, bbox_y1;
+
+	item = FOO_CANVAS_ITEM (line);
+
+	get_bounds (line, &bbox_x0, &bbox_y0, &bbox_x1, &bbox_y1);
+
+	bbox_x0 += i2w_dx; 
+	bbox_y0 += i2w_dy; 
+	bbox_x1 += i2w_dx; 
+	bbox_y1 += i2w_dy; 
+
+	foo_canvas_w2c_rect_d (item->canvas,
+				 &bbox_x0, &bbox_y0, &bbox_x1, &bbox_y1);
+	
+	/* include 1 pixel of fudge */
+	*bx1 = bbox_x0 - 1;
+	*by1 = bbox_y0 - 1;
+	*bx2 = bbox_x1 + 1;
+	*by2 = bbox_y1 + 1;
+}
+
+/* Recalculates the arrow polygons for the line */
+static void
+reconfigure_arrows (FooCanvasLine *line)
+{
+	double *poly, *coords;
+	double dx, dy, length;
+	double sin_theta, cos_theta, tmp;
+	double frac_height;	/* Line width as fraction of arrowhead width */
+	double backup;		/* Distance to backup end points so the line ends in the middle of the arrowhead */
+	double vx, vy;		/* Position of arrowhead vertex */
+	double shape_a, shape_b, shape_c;
+	double width;
+	int i;
+
+	if (line->num_points == 0)
+		return;
+
+	/* Set up things */
+
+	if (line->first_arrow) {
+		if (line->first_coords) {
+			line->coords[0] = line->first_coords[0];
+			line->coords[1] = line->first_coords[1];
+		} else
+			line->first_coords = g_new (double, 2 * NUM_ARROW_POINTS);
+	} else if (line->first_coords) {
+		line->coords[0] = line->first_coords[0];
+		line->coords[1] = line->first_coords[1];
+
+		g_free (line->first_coords);
+		line->first_coords = NULL;
+	}
+
+	i = 2 * (line->num_points - 1);
+
+	if (line->last_arrow) {
+		if (line->last_coords) {
+			line->coords[i] = line->last_coords[0];
+			line->coords[i + 1] = line->last_coords[1];
+		} else
+			line->last_coords = g_new (double, 2 * NUM_ARROW_POINTS);
+	} else if (line->last_coords) {
+		line->coords[i] = line->last_coords[0];
+		line->coords[i + 1] = line->last_coords[1];
+
+		g_free (line->last_coords);
+		line->last_coords = NULL;
+	}
+
+	if (!line->first_arrow && !line->last_arrow)
+		return;
+
+	if (line->width_pixels)
+		width = line->width / line->item.canvas->pixels_per_unit;
+	else
+		width = line->width;
+
+	/* Add fudge value for better-looking results */
+
+	shape_a = line->shape_a;
+	shape_b = line->shape_b;
+	shape_c = line->shape_c + width / 2.0;
+
+	if (line->width_pixels) {
+		shape_a /= line->item.canvas->pixels_per_unit;
+		shape_b /= line->item.canvas->pixels_per_unit;
+		shape_c /= line->item.canvas->pixels_per_unit;
+	}
+
+	shape_a += 0.001;
+	shape_b += 0.001;
+	shape_c += 0.001;
+
+	/* Compute the polygon for the first arrowhead and adjust the first point in the line so
+	 * that the line does not stick out past the leading edge of the arrowhead.
+	 */
+
+	frac_height = (line->width / 2.0) / shape_c;
+	backup = frac_height * shape_b + shape_a * (1.0 - frac_height) / 2.0;
+
+	if (line->first_arrow) {
+		poly = line->first_coords;
+		poly[0] = poly[10] = line->coords[0];
+		poly[1] = poly[11] = line->coords[1];
+
+		dx = poly[0] - line->coords[2];
+		dy = poly[1] - line->coords[3];
+		length = sqrt (dx * dx + dy * dy);
+		if (length < FOO_CANVAS_EPSILON)
+			sin_theta = cos_theta = 0.0;
+		else {
+			sin_theta = dy / length;
+			cos_theta = dx / length;
+		}
+
+		vx = poly[0] - shape_a * cos_theta;
+		vy = poly[1] - shape_a * sin_theta;
+
+		tmp = shape_c * sin_theta;
+
+		poly[2] = poly[0] - shape_b * cos_theta + tmp;
+		poly[8] = poly[2] - 2.0 * tmp;
+
+		tmp = shape_c * cos_theta;
+
+		poly[3] = poly[1] - shape_b * sin_theta - tmp;
+		poly[9] = poly[3] + 2.0 * tmp;
+
+		poly[4] = poly[2] * frac_height + vx * (1.0 - frac_height);
+		poly[5] = poly[3] * frac_height + vy * (1.0 - frac_height);
+		poly[6] = poly[8] * frac_height + vx * (1.0 - frac_height);
+		poly[7] = poly[9] * frac_height + vy * (1.0 - frac_height);
+
+		/* Move the first point towards the second so that the corners at the end of the
+		 * line are inside the arrowhead.
+		 */
+
+		line->coords[0] = poly[0] - backup * cos_theta;
+		line->coords[1] = poly[1] - backup * sin_theta;
+	}
+
+	/* Same process for last arrowhead */
+
+	if (line->last_arrow) {
+		coords = line->coords + 2 * (line->num_points - 2);
+		poly = line->last_coords;
+		poly[0] = poly[10] = coords[2];
+		poly[1] = poly[11] = coords[3];
+
+		dx = poly[0] - coords[0];
+		dy = poly[1] - coords[1];
+		length = sqrt (dx * dx + dy * dy);
+		if (length < FOO_CANVAS_EPSILON)
+			sin_theta = cos_theta = 0.0;
+		else {
+			sin_theta = dy / length;
+			cos_theta = dx / length;
+		}
+
+		vx = poly[0] - shape_a * cos_theta;
+		vy = poly[1] - shape_a * sin_theta;
+
+		tmp = shape_c * sin_theta;
+
+		poly[2] = poly[0] - shape_b * cos_theta + tmp;
+		poly[8] = poly[2] - 2.0 * tmp;
+
+		tmp = shape_c * cos_theta;
+
+		poly[3] = poly[1] - shape_b * sin_theta - tmp;
+		poly[9] = poly[3] + 2.0 * tmp;
+
+		poly[4] = poly[2] * frac_height + vx * (1.0 - frac_height);
+		poly[5] = poly[3] * frac_height + vy * (1.0 - frac_height);
+		poly[6] = poly[8] * frac_height + vx * (1.0 - frac_height);
+		poly[7] = poly[9] * frac_height + vy * (1.0 - frac_height);
+
+		coords[2] = poly[0] - backup * cos_theta;
+		coords[3] = poly[1] - backup * sin_theta;
+	}
+}
+
+/* Convenience function to set the line's GC's foreground color */
+static void
+set_line_gc_foreground (FooCanvasLine *line)
+{
+	GdkColor c;
+
+	if (!line->gc)
+		return;
+
+	c.pixel = line->fill_pixel;
+	gdk_gc_set_foreground (line->gc, &c);
+}
+
+/* Recalculate the line's width and set it in its GC */
+static void
+set_line_gc_width (FooCanvasLine *line)
+{
+	int width;
+
+	if (!line->gc)
+		return;
+
+	if (line->width_pixels)
+		width = (int) line->width;
+	else
+		width = (int) (line->width * line->item.canvas->pixels_per_unit + 0.5);
+
+	gdk_gc_set_line_attributes (line->gc,
+				    width,
+				    line->line_style,
+				    (line->first_arrow || line->last_arrow) ? GDK_CAP_BUTT : line->cap,
+				    line->join);
+}
+
+/* Sets the stipple pattern for the line */
+static void
+set_stipple (FooCanvasLine *line, GdkBitmap *stipple, int reconfigure)
+{
+	if (line->stipple && !reconfigure)
+		g_object_unref (line->stipple);
+
+	line->stipple = stipple;
+	if (stipple && !reconfigure)
+		g_object_ref (stipple);
+
+	if (line->gc) {
+		if (stipple) {
+			gdk_gc_set_stipple (line->gc, stipple);
+			gdk_gc_set_fill (line->gc, GDK_STIPPLED);
+		} else
+			gdk_gc_set_fill (line->gc, GDK_SOLID);
+	}
+}
+
+static void
+foo_canvas_line_set_property (GObject              *object,
+				guint                 param_id,
+				const GValue         *value,
+				GParamSpec           *pspec)
+{
+	FooCanvasItem *item;
+	FooCanvasLine *line;
+	FooCanvasPoints *points;
+	GdkColor color = { 0, 0, 0, 0, };
+	GdkColor *pcolor;
+	gboolean color_changed;
+	int have_pixel;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (FOO_IS_CANVAS_LINE (object));
+
+	item = FOO_CANVAS_ITEM (object);
+	line = FOO_CANVAS_LINE (object);
+
+	color_changed = FALSE;
+	have_pixel = FALSE;
+
+	switch (param_id) {
+	case PROP_POINTS:
+		points = g_value_get_boxed (value);
+
+		if (line->coords) {
+			g_free (line->coords);
+			line->coords = NULL;
+		}
+
+		if (!points)
+			line->num_points = 0;
+		else {
+			line->num_points = points->num_points;
+			line->coords = g_new (double, 2 * line->num_points);
+			memcpy (line->coords, points->coords, 2 * line->num_points * sizeof (double));
+		}
+
+		/* Drop the arrowhead polygons if they exist -- they will be regenerated */
+
+		if (line->first_coords) {
+			g_free (line->first_coords);
+			line->first_coords = NULL;
+		}
+
+		if (line->last_coords) {
+			g_free (line->last_coords);
+			line->last_coords = NULL;
+		}
+
+		/* Since the line's points have changed, we need to re-generate arrowheads in
+		 * addition to recalculating the bounds.
+		 */
+		foo_canvas_item_request_update (item);
+		break;
+
+	case PROP_FILL_COLOR:
+		if (g_value_get_string (value))
+			gdk_color_parse (g_value_get_string (value), &color);
+		line->fill_rgba = ((color.red & 0xff00) << 16 |
+				   (color.green & 0xff00) << 8 |
+				   (color.blue & 0xff00) |
+				   0xff);
+		color_changed = TRUE;
+		break;
+
+	case PROP_FILL_COLOR_GDK:
+		pcolor = g_value_get_boxed (value);
+		if (pcolor) {
+			GdkColormap *colormap;
+			color = *pcolor;
+
+			colormap = gtk_widget_get_colormap (GTK_WIDGET (item->canvas));
+			gdk_rgb_find_color (colormap, &color);
+
+			have_pixel = TRUE;
+		}
+
+		line->fill_rgba = ((color.red & 0xff00) << 16 |
+				   (color.green & 0xff00) << 8 |
+				   (color.blue & 0xff00) |
+				   0xff);
+		color_changed = TRUE;
+		break;
+
+	case PROP_FILL_COLOR_RGBA:
+		line->fill_rgba = g_value_get_uint (value);
+		color_changed = TRUE;
+		break;
+
+	case PROP_FILL_STIPPLE:
+		set_stipple (line, (GdkBitmap *) g_value_get_object (value), FALSE);
+		foo_canvas_item_request_redraw (item);		
+		break;
+
+	case PROP_WIDTH_PIXELS:
+		line->width = g_value_get_uint (value);
+		line->width_pixels = TRUE;
+		set_line_gc_width (line);
+		foo_canvas_item_request_update (item);
+		break;
+
+	case PROP_WIDTH_UNITS:
+		line->width = fabs (g_value_get_double (value));
+		line->width_pixels = FALSE;
+		set_line_gc_width (line);
+		foo_canvas_item_request_update (item);
+		break;
+
+	case PROP_CAP_STYLE:
+		line->cap = g_value_get_enum (value);
+		foo_canvas_item_request_update (item);
+		break;
+
+	case PROP_JOIN_STYLE:
+		line->join = g_value_get_enum (value);
+		foo_canvas_item_request_update (item);
+		break;
+
+	case PROP_LINE_STYLE:
+		line->line_style = g_value_get_enum (value);
+		set_line_gc_width (line);
+		foo_canvas_item_request_update (item);
+		break;
+
+	case PROP_FIRST_ARROWHEAD:
+		line->first_arrow = g_value_get_boolean (value);
+		foo_canvas_item_request_update (item);
+		break;
+
+	case PROP_LAST_ARROWHEAD:
+		line->last_arrow = g_value_get_boolean (value);
+		foo_canvas_item_request_update (item);
+		break;
+
+	case PROP_SMOOTH:
+		/* FIXME */
+		break;
+
+	case PROP_SPLINE_STEPS:
+		/* FIXME */
+		break;
+
+	case PROP_ARROW_SHAPE_A:
+		line->shape_a = fabs (g_value_get_double (value));
+		foo_canvas_item_request_update (item);
+		break;
+
+	case PROP_ARROW_SHAPE_B:
+		line->shape_b = fabs (g_value_get_double (value));
+		foo_canvas_item_request_update (item);
+		break;
+
+	case PROP_ARROW_SHAPE_C:
+		line->shape_c = fabs (g_value_get_double (value));
+		foo_canvas_item_request_update (item);
+		break;
+
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	}
+
+	if (color_changed) {
+		if (have_pixel)
+			line->fill_pixel = color.pixel;
+		else
+			line->fill_pixel = foo_canvas_get_color_pixel (item->canvas,
+									 line->fill_rgba);
+
+		set_line_gc_foreground (line);
+
+		foo_canvas_item_request_redraw (item);		
+	}
+}
+
+/* Returns a copy of the line's points without the endpoint adjustments for
+ * arrowheads.
+ */
+static FooCanvasPoints *
+get_points (FooCanvasLine *line)
+{
+	FooCanvasPoints *points;
+	int start_ofs, end_ofs;
+
+	if (line->num_points == 0)
+		return NULL;
+
+	start_ofs = end_ofs = 0;
+
+	points = foo_canvas_points_new (line->num_points);
+
+	/* Invariant:  if first_coords or last_coords exist, then the line's
+	 * endpoints have been adjusted.
+	 */
+
+	if (line->first_coords) {
+		start_ofs = 1;
+
+		points->coords[0] = line->first_coords[0];
+		points->coords[1] = line->first_coords[1];
+	}
+
+	if (line->last_coords) {
+		end_ofs = 1;
+
+		points->coords[2 * (line->num_points - 1)] = line->last_coords[0];
+		points->coords[2 * (line->num_points - 1) + 1] = line->last_coords[1];
+	}
+
+	memcpy (points->coords + 2 * start_ofs,
+		line->coords + 2 * start_ofs,
+		2 * (line->num_points - (start_ofs + end_ofs)) * sizeof (double));
+
+	return points;
+}
+
+static void
+foo_canvas_line_get_property (GObject              *object,
+				guint                 param_id,
+				GValue               *value,
+				GParamSpec           *pspec)
+{
+	FooCanvasLine *line;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (FOO_IS_CANVAS_LINE (object));
+
+	line = FOO_CANVAS_LINE (object);
+
+	switch (param_id) {
+	case PROP_POINTS:
+		g_value_set_boxed (value, get_points (line));
+		break;
+
+	case PROP_FILL_COLOR:
+		g_value_take_string (value,
+				     g_strdup_printf ("#%02x%02x%02x",
+						      line->fill_rgba >> 24,
+						      (line->fill_rgba >> 16) & 0xff,
+						      (line->fill_rgba >> 8) & 0xff));
+		break;
+
+	case PROP_FILL_COLOR_GDK: {
+		FooCanvas *canvas = FOO_CANVAS_ITEM (line)->canvas;
+		GdkColormap *colormap = gtk_widget_get_colormap (GTK_WIDGET (canvas));
+		GdkColor color;
+
+		gdk_colormap_query_color (colormap, line->fill_pixel, &color);
+		g_value_set_boxed (value, &color);
+		break;
+	}
+
+	case PROP_FILL_COLOR_RGBA:
+		g_value_set_uint (value, line->fill_rgba);
+		break;
+
+	case PROP_FILL_STIPPLE:
+		g_value_set_object (value, line->stipple);
+		break;
+
+	case PROP_WIDTH_PIXELS:
+		g_value_set_uint (value, line->width);
+		break;
+		
+	case PROP_WIDTH_UNITS:
+		g_value_set_double (value, line->width);
+		break;
+		
+	case PROP_CAP_STYLE:
+		g_value_set_enum (value, line->cap);
+		break;
+
+	case PROP_JOIN_STYLE:
+		g_value_set_enum (value, line->join);
+		break;
+
+	case PROP_LINE_STYLE:
+		g_value_set_enum (value, line->line_style);
+		break;
+
+	case PROP_FIRST_ARROWHEAD:
+		g_value_set_boolean (value, line->first_arrow);
+		break;
+
+	case PROP_LAST_ARROWHEAD:
+		g_value_set_boolean (value, line->last_arrow);
+		break;
+
+	case PROP_SMOOTH:
+		g_value_set_boolean (value, line->smooth);
+		break;
+
+	case PROP_SPLINE_STEPS:
+		g_value_set_uint (value, line->spline_steps);
+		break;
+
+	case PROP_ARROW_SHAPE_A:
+		g_value_set_double (value, line->shape_a);
+		break;
+
+	case PROP_ARROW_SHAPE_B:
+		g_value_set_double (value, line->shape_b);
+		break;
+
+	case PROP_ARROW_SHAPE_C:
+		g_value_set_double (value, line->shape_c);
+		break;
+
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	}
+}
+
+static void
+foo_canvas_line_update (FooCanvasItem *item, double i2w_dx, double i2w_dy, int flags)
+{
+	FooCanvasLine *line;
+	double x1, y1, x2, y2;
+
+	line = FOO_CANVAS_LINE (item);
+
+	if (parent_class->update)
+		(* parent_class->update) (item, i2w_dx, i2w_dy, flags);
+
+	reconfigure_arrows (line);
+
+	set_line_gc_foreground (line);
+	set_line_gc_width (line);
+	set_stipple (line, line->stipple, TRUE);
+	
+	get_bounds_canvas (line, &x1, &y1, &x2, &y2, i2w_dx, i2w_dy);
+	foo_canvas_update_bbox (item, x1, y1, x2, y2);
+}
+
+static void
+foo_canvas_line_realize (FooCanvasItem *item)
+{
+	FooCanvasLine *line;
+
+	line = FOO_CANVAS_LINE (item);
+
+	if (parent_class->realize)
+		(* parent_class->realize) (item);
+
+	line->gc = gdk_gc_new (item->canvas->layout.bin_window);
+/* FIXME FIXME FIXME Need to recalc pixel values, set colours, etc. */
+
+#if 0
+	(* FOO_CANVAS_ITEM_CLASS (item->object.klass)->update) (item, NULL, NULL, 0);
+#endif
+}
+
+static void
+foo_canvas_line_unrealize (FooCanvasItem *item)
+{
+	FooCanvasLine *line;
+
+	line = FOO_CANVAS_LINE (item);
+
+	g_object_unref (line->gc);
+	line->gc = NULL;
+
+	if (parent_class->unrealize)
+		(* parent_class->unrealize) (item);
+}
+
+static void
+item_to_canvas (FooCanvas *canvas, double *item_coords, GdkPoint *canvas_coords, int num_points,
+		int *num_drawn_points, double i2w_dx, double i2w_dy)
+{
+	int i;
+	int old_cx, old_cy;
+	int cx, cy;
+
+	/* the first point is always drawn */
+	foo_canvas_w2c (canvas,
+			  item_coords[0] + i2w_dx,
+			  item_coords[1] + i2w_dy,
+			  &canvas_coords->x, &canvas_coords->y);
+	old_cx = canvas_coords->x;
+	old_cy = canvas_coords->y;
+	canvas_coords++;
+	*num_drawn_points = 1;
+
+	for (i = 1; i < num_points; i++) {
+		foo_canvas_w2c (canvas,
+				  item_coords[i*2] + i2w_dx,
+				  item_coords[i*2+1] + i2w_dy,
+				  &cx, &cy);
+		if (old_cx != cx || old_cy != cy) {
+			canvas_coords->x = cx;
+			canvas_coords->y = cy;
+			old_cx = cx;
+			old_cy = cy;
+			canvas_coords++;
+			(*num_drawn_points)++;
+		}
+	}
+}
+
+static void
+foo_canvas_line_draw (FooCanvasItem *item, GdkDrawable *drawable,
+			GdkEventExpose *event)
+{
+	FooCanvasLine *line;
+	GdkPoint static_points[NUM_STATIC_POINTS];
+	GdkPoint *points;
+	int actual_num_points_drawn;
+	double i2w_dx, i2w_dy;
+	
+	line = FOO_CANVAS_LINE (item);
+
+	if (line->num_points == 0)
+		return;
+
+	/* Build array of canvas pixel coordinates */
+
+	if (line->num_points <= NUM_STATIC_POINTS)
+		points = static_points;
+	else
+		points = g_new (GdkPoint, line->num_points);
+
+	i2w_dx = 0.0;
+	i2w_dy = 0.0;
+	foo_canvas_item_i2w (item, &i2w_dx, &i2w_dy);
+ 
+	item_to_canvas (item->canvas, line->coords, points, line->num_points,
+			&actual_num_points_drawn, i2w_dx, i2w_dy);
+
+	if (line->stipple)
+		foo_canvas_set_stipple_origin (item->canvas, line->gc);
+
+	gdk_draw_lines (drawable, line->gc, points, actual_num_points_drawn);
+
+	if (points != static_points)
+		g_free (points);
+
+	/* Draw arrowheads */
+
+	points = static_points;
+
+	if (line->first_arrow) {
+		item_to_canvas (item->canvas, line->first_coords, points, NUM_ARROW_POINTS,
+				&actual_num_points_drawn, i2w_dx, i2w_dy);
+		gdk_draw_polygon (drawable, line->gc, TRUE, points, actual_num_points_drawn );
+	}
+
+	if (line->last_arrow) {
+		item_to_canvas (item->canvas, line->last_coords, points, NUM_ARROW_POINTS,
+				&actual_num_points_drawn, i2w_dx, i2w_dy);
+		gdk_draw_polygon (drawable, line->gc, TRUE, points, actual_num_points_drawn );
+	}
+}
+
+static double
+foo_canvas_line_point (FooCanvasItem *item, double x, double y,
+			 int cx, int cy, FooCanvasItem **actual_item)
+{
+	FooCanvasLine *line;
+	double *line_points = NULL, *coords;
+	double static_points[2 * NUM_STATIC_POINTS];
+	double poly[10];
+	double best, dist;
+	double dx, dy;
+	double width;
+	int num_points = 0, i;
+	int changed_miter_to_bevel;
+
+#ifdef VERBOSE
+	g_print ("foo_canvas_line_point x, y = (%g, %g); cx, cy = (%d, %d)\n", x, y, cx, cy);
+#endif
+
+	line = FOO_CANVAS_LINE (item);
+
+	*actual_item = item;
+
+	best = 1.0e36;
+
+	/* Handle smoothed lines by generating an expanded set ot points */
+
+	if (line->smooth && (line->num_points > 2)) {
+		/* FIXME */
+	} else {
+		num_points = line->num_points;
+		line_points = line->coords;
+	}
+
+	/* Compute a polygon for each edge of the line and test the point against it.  The effective
+	 * width of the line is adjusted so that it will be at least one pixel thick (so that zero
+	 * pixel-wide lines can be pickedup as well).
+	 */
+
+	if (line->width_pixels)
+		width = line->width / item->canvas->pixels_per_unit;
+	else
+		width = line->width;
+
+	if (width < (1.0 / item->canvas->pixels_per_unit))
+		width = 1.0 / item->canvas->pixels_per_unit;
+
+	changed_miter_to_bevel = 0;
+
+	for (i = num_points, coords = line_points; i >= 2; i--, coords += 2) {
+		/* If rounding is done around the first point, then compute distance between the
+		 * point and the first point.
+		 */
+
+		if (((line->cap == GDK_CAP_ROUND) && (i == num_points))
+		    || ((line->join == GDK_JOIN_ROUND) && (i != num_points))) {
+			dx = coords[0] - x;
+			dy = coords[1] - y;
+			dist = sqrt (dx * dx + dy * dy) - width / 2.0;
+			if (dist < FOO_CANVAS_EPSILON) {
+				best = 0.0;
+				goto done;
+			} else if (dist < best)
+				best = dist;
+		}
+
+		/* Compute the polygonal shape corresponding to this edge, with two points for the
+		 * first point of the edge and two points for the last point of the edge.
+		 */
+
+		if (i == num_points)
+			foo_canvas_get_butt_points (coords[2], coords[3], coords[0], coords[1],
+						      width, (line->cap == GDK_CAP_PROJECTING),
+						      poly, poly + 1, poly + 2, poly + 3);
+		else if ((line->join == GDK_JOIN_MITER) && !changed_miter_to_bevel) {
+			poly[0] = poly[6];
+			poly[1] = poly[7];
+			poly[2] = poly[4];
+			poly[3] = poly[5];
+		} else {
+			foo_canvas_get_butt_points (coords[2], coords[3], coords[0], coords[1],
+						      width, FALSE,
+						      poly, poly + 1, poly + 2, poly + 3);
+
+			/* If this line uses beveled joints, then check the distance to a polygon
+			 * comprising the last two points of the previous polygon and the first two
+			 * from this polygon; this checks the wedges that fill the mitered point.
+			 */
+
+			if ((line->join == GDK_JOIN_BEVEL) || changed_miter_to_bevel) {
+				poly[8] = poly[0];
+				poly[9] = poly[1];
+
+				dist = foo_canvas_polygon_to_point (poly, 5, x, y);
+				if (dist < FOO_CANVAS_EPSILON) {
+					best = 0.0;
+					goto done;
+				} else if (dist < best)
+					best = dist;
+
+				changed_miter_to_bevel = FALSE;
+			}
+		}
+
+		if (i == 2)
+			foo_canvas_get_butt_points (coords[0], coords[1], coords[2], coords[3],
+						      width, (line->cap == GDK_CAP_PROJECTING),
+						      poly + 4, poly + 5, poly + 6, poly + 7);
+		else if (line->join == GDK_JOIN_MITER) {
+			if (!foo_canvas_get_miter_points (coords[0], coords[1],
+							    coords[2], coords[3],
+							    coords[4], coords[5],
+							    width,
+							    poly + 4, poly + 5, poly + 6, poly + 7)) {
+				changed_miter_to_bevel = TRUE;
+				foo_canvas_get_butt_points (coords[0], coords[1], coords[2], coords[3],
+							      width, FALSE,
+							      poly + 4, poly + 5, poly + 6, poly + 7);
+			}
+		} else
+			foo_canvas_get_butt_points (coords[0], coords[1], coords[2], coords[3],
+						      width, FALSE,
+						      poly + 4, poly + 5, poly + 6, poly + 7);
+
+		poly[8] = poly[0];
+		poly[9] = poly[1];
+
+		dist = foo_canvas_polygon_to_point (poly, 5, x, y);
+		if (dist < FOO_CANVAS_EPSILON) {
+			best = 0.0;
+			goto done;
+		} else if (dist < best)
+			best = dist;
+	}
+
+	/* If caps are rounded, check the distance to the cap around the final end point of the line */
+
+	if (line->cap == GDK_CAP_ROUND) {
+		dx = coords[0] - x;
+		dy = coords[1] - y;
+		dist = sqrt (dx * dx + dy * dy) - width / 2.0;
+		if (dist < FOO_CANVAS_EPSILON) {
+			best = 0.0;
+			goto done;
+		} else
+			best = dist;
+	}
+
+	/* sometimes the FooCanvasItem::update signal will not have
+           been processed between deleting the arrow points and a call
+           to this routine -- this can cause a segfault here */
+	if ((line->first_arrow && !line->first_coords) ||
+	    (line->last_arrow && !line->last_coords))
+		reconfigure_arrows(line);
+
+	/* If there are arrowheads, check the distance to them */
+
+	if (line->first_arrow) {
+		dist = foo_canvas_polygon_to_point (line->first_coords, NUM_ARROW_POINTS, x, y);
+		if (dist < FOO_CANVAS_EPSILON) {
+			best = 0.0;
+			goto done;
+		} else
+			best = dist;
+	}
+
+	if (line->last_arrow) {
+		dist = foo_canvas_polygon_to_point (line->last_coords, NUM_ARROW_POINTS, x, y);
+		if (dist < FOO_CANVAS_EPSILON) {
+			best = 0.0;
+			goto done;
+		} else
+			best = dist;
+	}
+
+done:
+
+	if ((line_points != static_points) && (line_points != line->coords))
+		g_free (line_points);
+
+	return best;
+}
+
+static void
+foo_canvas_line_translate (FooCanvasItem *item, double dx, double dy)
+{
+        FooCanvasLine *line;
+        int i;
+        double *coords;
+
+        line = FOO_CANVAS_LINE (item);
+
+        for (i = 0, coords = line->coords; i < line->num_points; i++, coords += 2) {
+                coords[0] += dx;
+                coords[1] += dy;
+        }
+
+        if (line->first_arrow)
+                for (i = 0, coords = line->first_coords; i < NUM_ARROW_POINTS; i++, coords += 2) {
+                        coords[0] += dx;
+                        coords[1] += dy;
+                }
+
+        if (line->last_arrow)
+                for (i = 0, coords = line->last_coords; i < NUM_ARROW_POINTS; i++, coords += 2) {
+                        coords[0] += dx;
+                        coords[1] += dy;
+                }
+}
+
+static void
+foo_canvas_line_bounds (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2)
+{
+	FooCanvasLine *line;
+
+	line = FOO_CANVAS_LINE (item);
+
+	if (line->num_points == 0) {
+		*x1 = *y1 = *x2 = *y2 = 0.0;
+		return;
+	}
+
+	get_bounds (line, x1, y1, x2, y2);
+}
diff --git a/widgets/libfoocanvas/foo-canvas-line.h b/widgets/libfoocanvas/foo-canvas-line.h
new file mode 100644
index 0000000..42dfd74
--- /dev/null
+++ b/widgets/libfoocanvas/foo-canvas-line.h
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * The Gnome Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+/* Line/curve item type for FooCanvas widget
+ *
+ * FooCanvas is basically a port of the Tk toolkit's most excellent canvas widget.  Tk is
+ * copyrighted by the Regents of the University of California, Sun Microsystems, and other parties.
+ *
+ *
+ * Author: Federico Mena <federico nuclecu unam mx>
+ */
+
+#ifndef FOO_CANVAS_LINE_H
+#define FOO_CANVAS_LINE_H
+
+
+#include <libfoocanvas/foo-canvas.h>
+
+
+G_BEGIN_DECLS
+
+
+/* Line item for the canvas.  This is a polyline with configurable width, cap/join styles, and arrowheads.
+ * If arrowheads are enabled, then three values are used to specify their shape:
+ *
+ *	arrow_shape_a:  Distance from tip of arrowhead to the center point.
+ *	arrow_shape_b:  Distance from tip of arrowhead to trailing point, measured along the shaft.
+ *	arrow_shape_c:	Distance of trailing point from outside edge of shaft.
+ *
+ * The following object arguments are available:
+ *
+ * name			type			read/write	description
+ * ------------------------------------------------------------------------------------------
+ * points		FooCanvasPoints*	RW		Pointer to a FooCanvasPoints structure.
+ *								This can be created by a call to
+ *								foo_canvas_points_new() (in foo-canvas-util.h).
+ *								X coordinates are in the even indices of the
+ *								points->coords array, Y coordinates are in
+ *								the odd indices.
+ * fill_color		string			W		X color specification for line
+ * fill_color_gdk	GdkColor*		RW		Pointer to an allocated GdkColor
+ * fill_stipple		GdkBitmap*		RW		Stipple pattern for the line
+ * width_pixels		uint			R		Width of the line in pixels.  The line width
+ *								will not be scaled when the canvas zoom factor changes.
+ * width_units		double			R		Width of the line in canvas units.  The line width
+ *								will be scaled when the canvas zoom factor changes.
+ * cap_style		GdkCapStyle		RW		Cap ("endpoint") style for the line.
+ * join_style		GdkJoinStyle		RW		Join ("vertex") style for the line.
+ * line_style		GdkLineStyle		RW		Line dash style
+ * first_arrowhead	boolean			RW		Specifies whether to draw an arrowhead on the
+ *								first point of the line.
+ * last_arrowhead	boolean			RW		Specifies whether to draw an arrowhead on the
+ *								last point of the line.
+ * smooth		boolean			RW		Specifies whether to smooth the line using
+ *								parabolic splines.
+ * spline_steps		uint			RW		Specifies the number of steps to use when rendering curves.
+ * arrow_shape_a	double			RW		First arrow shape specifier.
+ * arrow_shape_b	double			RW		Second arrow shape specifier.
+ * arrow_shape_c	double			RW		Third arrow shape specifier.
+ */
+
+
+#define FOO_TYPE_CANVAS_LINE            (foo_canvas_line_get_type ())
+#define FOO_CANVAS_LINE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), FOO_TYPE_CANVAS_LINE, FooCanvasLine))
+#define FOO_CANVAS_LINE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), FOO_TYPE_CANVAS_LINE, FooCanvasLineClass))
+#define FOO_IS_CANVAS_LINE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FOO_TYPE_CANVAS_LINE))
+#define FOO_IS_CANVAS_LINE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FOO_TYPE_CANVAS_LINE))
+#define FOO_CANVAS_LINE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), FOO_TYPE_CANVAS_LINE, FooCanvasLineClass))
+
+
+typedef struct _FooCanvasLine FooCanvasLine;
+typedef struct _FooCanvasLineClass FooCanvasLineClass;
+
+struct _FooCanvasLine {
+	FooCanvasItem item;
+
+	double *coords;		/* Array of coordinates for the line's points.  X coords are in the
+				 * even indices, Y coords are in the odd indices.  If the line has
+				 * arrowheads then the first and last points have been adjusted to
+				 * refer to the necks of the arrowheads rather than their tips.  The
+				 * actual endpoints are stored in the first_arrow and last_arrow
+				 * arrays, if they exist.
+				 */
+
+	double *first_coords;	/* Array of points describing polygon for the first arrowhead */
+	double *last_coords;	/* Array of points describing polygon for the last arrowhead */
+
+	GdkGC *gc;		/* GC for drawing line */
+
+	GdkBitmap *stipple;	/* Stipple pattern */
+
+	double width;		/* Width of the line */
+
+	double shape_a;		/* Distance from tip of arrowhead to center */
+	double shape_b;		/* Distance from tip of arrowhead to trailing point, measured along shaft */
+	double shape_c;		/* Distance of trailing points from outside edge of shaft */
+
+	GdkCapStyle cap;	/* Cap style for line */
+	GdkJoinStyle join;	/* Join style for line */
+	GdkLineStyle line_style;/* Style for the line */
+
+	gulong fill_pixel;	/* Color for line */
+
+	guint32 fill_rgba;		/* RGBA color for outline */ /*AA*/
+
+	int num_points;		/* Number of points in the line */
+	guint fill_color;	/* Fill color, RGBA */
+
+	int spline_steps;	/* Number of steps in each spline segment */
+
+	guint width_pixels : 1;	/* Is the width specified in pixels or units? */
+	guint first_arrow : 1;	/* Draw first arrowhead? */
+	guint last_arrow : 1;	/* Draw last arrowhead? */
+	guint smooth : 1;	/* Smooth line (with parabolic splines)? */
+};
+
+struct _FooCanvasLineClass {
+	FooCanvasItemClass parent_class;
+};
+
+
+/* Standard Gtk function */
+GType foo_canvas_line_get_type (void) G_GNUC_CONST;
+
+
+G_END_DECLS
+
+#endif
diff --git a/widgets/libfoocanvas/foo-canvas-marshal.list b/widgets/libfoocanvas/foo-canvas-marshal.list
new file mode 100644
index 0000000..86f67df
--- /dev/null
+++ b/widgets/libfoocanvas/foo-canvas-marshal.list
@@ -0,0 +1,2 @@
+VOID:INT,INT,INT,INT
+BOOLEAN:BOXED
diff --git a/widgets/libfoocanvas/foo-canvas-pixbuf.c b/widgets/libfoocanvas/foo-canvas-pixbuf.c
new file mode 100644
index 0000000..186e0d7
--- /dev/null
+++ b/widgets/libfoocanvas/foo-canvas-pixbuf.c
@@ -0,0 +1,825 @@
+/* GNOME libraries - GdkPixbuf item for the GNOME canvas
+ *
+ * Copyright (C) 1999 The Free Software Foundation
+ *
+ * Author: Federico Mena-Quintero <federico gimp org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <math.h>
+#include <libfoocanvas/foo-canvas.h>
+#include <libfoocanvas/foo-canvas-util.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include "foo-canvas-pixbuf.h"
+
+/* Private part of the FooCanvasPixbuf structure */
+typedef struct {
+	/* Our gdk-pixbuf */
+	GdkPixbuf *pixbuf, *pixbuf_scaled;
+
+	/* Width value */
+	double width;
+
+	/* Height value */
+	double height;
+
+	/* X translation */
+	double x;
+
+	/* Y translation */
+	double y;
+
+	/* Whether dimensions are set and whether they are in pixels or units */
+	guint width_set : 1;
+	guint width_in_pixels : 1;
+	guint height_set : 1;
+	guint height_in_pixels : 1;
+	guint x_in_pixels : 1;
+	guint y_in_pixels : 1;
+
+	/* Whether the pixbuf has changed */
+	guint need_pixbuf_update : 1;
+
+	/* Whether the transformation or size have changed */
+	guint need_xform_update : 1;
+
+	/* Should the point method ignore transparent areas */
+	guint point_ignores_alpha : 1;
+
+	/* Anchor */
+	GtkAnchorType anchor;
+
+	/* Approximation method used for transformations */
+	GdkInterpType interp_type;
+
+} PixbufPrivate;
+
+/* Object argument IDs */
+enum {
+	PROP_0,
+	PROP_PIXBUF,
+	PROP_WIDTH,
+	PROP_WIDTH_SET,
+	PROP_WIDTH_IN_PIXELS,
+	PROP_HEIGHT,
+	PROP_HEIGHT_SET,
+	PROP_HEIGHT_IN_PIXELS,
+	PROP_X,
+	PROP_X_IN_PIXELS,
+	PROP_Y,
+	PROP_Y_IN_PIXELS,
+	PROP_ANCHOR,
+	PROP_INTERP_TYPE,
+	PROP_POINT_IGNORES_ALPHA
+};
+
+static void foo_canvas_pixbuf_class_init (FooCanvasPixbufClass *klass);
+static void foo_canvas_pixbuf_init (FooCanvasPixbuf *cpb);
+static void foo_canvas_pixbuf_destroy (GtkObject *object);
+static void foo_canvas_pixbuf_set_property (GObject *object,
+					    guint param_id,
+					    const GValue *value,
+					    GParamSpec *pspec);
+static void foo_canvas_pixbuf_get_property (GObject *object,
+					    guint param_id,
+					    GValue *value,
+					    GParamSpec *pspec);
+
+static void foo_canvas_pixbuf_update    (FooCanvasItem *item,
+					 double i2w_dx, double i2w_dy,
+					 int flags);
+static void foo_canvas_pixbuf_draw      (FooCanvasItem *item, GdkDrawable *drawable,
+					 GdkEventExpose *expose);
+static double foo_canvas_pixbuf_point   (FooCanvasItem *item, double x, double y, int cx, int cy,
+					 FooCanvasItem **actual_item);
+static void foo_canvas_pixbuf_translate (FooCanvasItem *item, double dx, double dy);
+static void foo_canvas_pixbuf_bounds    (FooCanvasItem *item,
+					 double *x1, double *y1, double *x2, double *y2);
+
+static FooCanvasItemClass *parent_class;
+
+G_DEFINE_TYPE (FooCanvasPixbuf, foo_canvas_pixbuf, FOO_TYPE_CANVAS_ITEM)
+
+/* Class initialization function for the pixbuf canvas item */
+static void
+foo_canvas_pixbuf_class_init (FooCanvasPixbufClass *klass)
+{
+        GObjectClass *gobject_class;
+	GtkObjectClass *object_class;
+	FooCanvasItemClass *item_class;
+
+        gobject_class = (GObjectClass *) klass;
+	object_class = (GtkObjectClass *) klass;
+	item_class = (FooCanvasItemClass *) klass;
+
+	parent_class = gtk_type_class (foo_canvas_item_get_type ());
+
+	gobject_class->set_property = foo_canvas_pixbuf_set_property;
+	gobject_class->get_property = foo_canvas_pixbuf_get_property;
+
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_PIXBUF,
+                 g_param_spec_object ("pixbuf", NULL, NULL,
+                                      GDK_TYPE_PIXBUF,
+                                      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_WIDTH,
+                 g_param_spec_double ("width", NULL, NULL,
+				      -G_MAXDOUBLE, G_MAXDOUBLE, 0,
+				      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_WIDTH_SET,
+                 g_param_spec_boolean ("width-set", NULL, NULL,
+				       FALSE,
+				       G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_WIDTH_IN_PIXELS,
+                 g_param_spec_boolean ("width-in-pixels", NULL, NULL,
+				       FALSE,
+				       G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_HEIGHT,
+                 g_param_spec_double ("height", NULL, NULL,
+				      -G_MAXDOUBLE, G_MAXDOUBLE, 0,
+				      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_HEIGHT_SET,
+                 g_param_spec_boolean ("height-set", NULL, NULL,
+				       FALSE,
+				       G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_HEIGHT_IN_PIXELS,
+                 g_param_spec_boolean ("height-in-pixels", NULL, NULL,
+				       FALSE,
+				       G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_X,
+                 g_param_spec_double ("x", NULL, NULL,
+				      -G_MAXDOUBLE, G_MAXDOUBLE, 0,
+                                    G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_X_IN_PIXELS,
+                 g_param_spec_boolean ("x-in-pixels", NULL, NULL,
+				       FALSE,
+				       G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_Y,
+                 g_param_spec_double ("y", NULL, NULL,
+				      -G_MAXDOUBLE, G_MAXDOUBLE, 0,
+				      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_Y_IN_PIXELS,
+                 g_param_spec_boolean ("y-in-pixels", NULL, NULL,
+				       FALSE,
+				       G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_ANCHOR,
+                 g_param_spec_enum ("anchor", NULL, NULL,
+                                    GTK_TYPE_ANCHOR_TYPE,
+                                    GTK_ANCHOR_NW,
+                                    G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_INTERP_TYPE,
+                 g_param_spec_enum ("interp-type", NULL, NULL,
+                                    GDK_TYPE_INTERP_TYPE,
+                                    GDK_INTERP_BILINEAR,
+                                    G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+		 PROP_POINT_IGNORES_ALPHA,
+                 g_param_spec_boolean ("point-ignores-alpha", NULL, NULL,
+				       FALSE,
+				       G_PARAM_READWRITE));
+
+	object_class->destroy = foo_canvas_pixbuf_destroy;
+
+	item_class->update = foo_canvas_pixbuf_update;
+	item_class->draw = foo_canvas_pixbuf_draw;
+	item_class->point = foo_canvas_pixbuf_point;
+	item_class->translate = foo_canvas_pixbuf_translate;
+	item_class->bounds = foo_canvas_pixbuf_bounds;
+}
+
+/* Object initialization function for the pixbuf canvas item */
+static void
+foo_canvas_pixbuf_init (FooCanvasPixbuf *gcp)
+{
+	PixbufPrivate *priv;
+
+	priv = g_new0 (PixbufPrivate, 1);
+	gcp->priv = priv;
+
+	priv->width = 0.0;
+	priv->height = 0.0;
+	priv->x = 0.0;
+	priv->y = 0.0;
+	priv->anchor = GTK_ANCHOR_NW;
+	priv->interp_type = GDK_INTERP_BILINEAR;
+	priv->point_ignores_alpha = FALSE;
+}
+
+/* Destroy handler for the pixbuf canvas item */
+static void
+foo_canvas_pixbuf_destroy (GtkObject *object)
+{
+	FooCanvasItem *item;
+	FooCanvasPixbuf *gcp;
+	PixbufPrivate *priv;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (FOO_IS_CANVAS_PIXBUF (object));
+
+	item = FOO_CANVAS_ITEM (object);
+	gcp = (FOO_CANVAS_PIXBUF (object));
+	priv = gcp->priv;
+
+	/* remember, destroy can be run multiple times! */
+
+	if (priv) {
+	    foo_canvas_item_request_redraw (item);
+
+	    if (priv->pixbuf)
+		g_object_unref (priv->pixbuf);
+	    if (priv->pixbuf_scaled)
+		g_object_unref (priv->pixbuf_scaled);
+
+	    g_free (priv);
+	    gcp->priv = NULL;
+	}
+
+	if (GTK_OBJECT_CLASS (parent_class)->destroy)
+		(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+
+
+/* Set_property handler for the pixbuf canvas item */
+static void
+foo_canvas_pixbuf_set_property (GObject            *object,
+				guint               param_id,
+				const GValue       *value,
+				GParamSpec         *pspec)
+{
+	FooCanvasItem *item;
+	FooCanvasPixbuf *gcp;
+	PixbufPrivate *priv;
+	GdkPixbuf *pixbuf;
+	double val;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (FOO_IS_CANVAS_PIXBUF (object));
+
+	item = FOO_CANVAS_ITEM (object);
+	gcp = FOO_CANVAS_PIXBUF (object);
+	priv = gcp->priv;
+
+	switch (param_id) {
+	case PROP_PIXBUF:
+		if (g_value_get_object (value))
+			pixbuf = GDK_PIXBUF (g_value_get_object (value));
+		else
+			pixbuf = NULL;
+		if (pixbuf != priv->pixbuf) {
+			if (pixbuf) {
+				g_return_if_fail
+				    (gdk_pixbuf_get_colorspace (pixbuf) == GDK_COLORSPACE_RGB);
+				g_return_if_fail
+				    (gdk_pixbuf_get_n_channels (pixbuf) == 3
+				     || gdk_pixbuf_get_n_channels (pixbuf) == 4);
+				g_return_if_fail
+				    (gdk_pixbuf_get_bits_per_sample (pixbuf) == 8);
+
+				g_object_ref (pixbuf);
+			}
+
+			if (priv->pixbuf)
+				g_object_unref (priv->pixbuf);
+			priv->pixbuf = pixbuf;
+
+			if (priv->pixbuf_scaled) {
+				g_object_unref (priv->pixbuf_scaled);
+				priv->pixbuf_scaled = NULL;
+			}
+		}
+
+		priv->need_pixbuf_update = TRUE;
+		foo_canvas_item_request_update (item);
+		break;
+
+	case PROP_WIDTH:
+		val = g_value_get_double (value);
+		g_return_if_fail (val >= 0.0);
+		priv->width = val;
+		priv->need_xform_update = TRUE;
+		foo_canvas_item_request_update (item);
+		break;
+
+	case PROP_WIDTH_SET:
+		priv->width_set = g_value_get_boolean (value);
+		priv->need_xform_update = TRUE;
+		foo_canvas_item_request_update (item);
+		break;
+
+	case PROP_WIDTH_IN_PIXELS:
+		priv->width_in_pixels = g_value_get_boolean (value);
+		priv->need_xform_update = TRUE;
+		foo_canvas_item_request_update (item);
+		break;
+
+	case PROP_HEIGHT:
+		val = g_value_get_double (value);
+		g_return_if_fail (val >= 0.0);
+		priv->height = val;
+		priv->need_xform_update = TRUE;
+		foo_canvas_item_request_update (item);
+		break;
+
+	case PROP_HEIGHT_SET:
+		priv->height_set = g_value_get_boolean (value);
+		priv->need_xform_update = TRUE;
+		foo_canvas_item_request_update (item);
+		break;
+
+	case PROP_HEIGHT_IN_PIXELS:
+		priv->height_in_pixels = g_value_get_boolean (value);
+		priv->need_xform_update = TRUE;
+		foo_canvas_item_request_update (item);
+		break;
+
+	case PROP_X:
+		priv->x = g_value_get_double (value);
+		priv->need_xform_update = TRUE;
+		foo_canvas_item_request_update (item);
+		break;
+
+	case PROP_X_IN_PIXELS:
+		priv->x_in_pixels = g_value_get_boolean (value);
+		priv->need_xform_update = TRUE;
+		foo_canvas_item_request_update (item);
+		break;
+
+	case PROP_Y:
+		priv->y = g_value_get_double (value);
+		priv->need_xform_update = TRUE;
+		foo_canvas_item_request_update (item);
+		break;
+
+	case PROP_Y_IN_PIXELS:
+		priv->y_in_pixels = g_value_get_boolean (value);
+		priv->need_xform_update = TRUE;
+		foo_canvas_item_request_update (item);
+		break;
+
+	case PROP_ANCHOR:
+		priv->anchor = g_value_get_enum (value);
+		priv->need_xform_update = TRUE;
+		foo_canvas_item_request_update (item);
+		break;
+
+	case PROP_INTERP_TYPE:
+		priv->interp_type = g_value_get_enum (value);
+		priv->need_xform_update = TRUE;
+		foo_canvas_item_request_update (item);
+		break;
+
+	case PROP_POINT_IGNORES_ALPHA:
+		priv->point_ignores_alpha = g_value_get_boolean (value);
+		break;
+
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	}
+}
+
+/* Get_property handler for the pixbuf canvasi item */
+static void
+foo_canvas_pixbuf_get_property (GObject            *object,
+				guint               param_id,
+				GValue             *value,
+				GParamSpec         *pspec)
+{
+	FooCanvasPixbuf *gcp;
+	PixbufPrivate *priv;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (FOO_IS_CANVAS_PIXBUF (object));
+
+	gcp = FOO_CANVAS_PIXBUF (object);
+	priv = gcp->priv;
+
+	switch (param_id) {
+	case PROP_PIXBUF:
+		g_value_set_object (value, G_OBJECT (priv->pixbuf));
+		break;
+
+	case PROP_WIDTH:
+		g_value_set_double (value, priv->width);
+		break;
+
+	case PROP_WIDTH_SET:
+		g_value_set_boolean (value, priv->width_set);
+		break;
+
+	case PROP_WIDTH_IN_PIXELS:
+		g_value_set_boolean (value, priv->width_in_pixels);
+		break;
+
+	case PROP_HEIGHT:
+		g_value_set_double (value, priv->height);
+		break;
+
+	case PROP_HEIGHT_SET:
+		g_value_set_boolean (value, priv->height_set);
+		break;
+
+	case PROP_HEIGHT_IN_PIXELS:
+		g_value_set_boolean (value, priv->height_in_pixels);
+		break;
+
+	case PROP_X:
+		g_value_set_double (value, priv->x);
+		break;
+
+	case PROP_X_IN_PIXELS:
+		g_value_set_boolean (value, priv->x_in_pixels);
+		break;
+
+	case PROP_Y:
+		g_value_set_double (value, priv->y);
+		break;
+
+	case PROP_Y_IN_PIXELS:
+		g_value_set_boolean (value, priv->y_in_pixels);
+		break;
+
+	case PROP_ANCHOR:
+		g_value_set_enum (value, priv->anchor);
+		break;
+
+	case PROP_INTERP_TYPE:
+		g_value_set_enum (value, priv->interp_type);
+		break;
+
+	case PROP_POINT_IGNORES_ALPHA:
+		g_value_set_boolean (value, priv->point_ignores_alpha);
+		break;
+
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	}
+}
+
+
+
+/* Bounds and utilities */
+
+
+/* Recomputes the bounding box of a pixbuf canvas item.  The horizontal and
+ * vertical dimensions may be specified in units or pixels, separately, so we
+ * have to compute the components individually for each dimension.
+ *
+ * Returns the coordinates with respect to the parent items coordinates.
+ */
+static void
+compute_bounding_box (FooCanvasPixbuf *gcp,
+		      double i2w_dx, double i2w_dy,
+		      double *bbox_x0, double *bbox_y0,
+		      double *bbox_x1, double *bbox_y1)
+{
+	FooCanvasItem *item;
+	PixbufPrivate *priv;
+	double x, y;
+	double width, height;
+
+	item = FOO_CANVAS_ITEM (gcp);
+	priv = gcp->priv;
+
+	if (!priv->pixbuf) {
+		*bbox_x0 = *bbox_y0 = *bbox_x1 = *bbox_y1 = 0.0;
+		return;
+	}
+
+	if (priv->x_in_pixels) {
+		x = i2w_dx + priv->x / item->canvas->pixels_per_unit;
+	} else {
+		x = i2w_dx + priv->x;
+	}
+
+	if (priv->y_in_pixels) {
+		y = i2w_dy + priv->y / item->canvas->pixels_per_unit;
+	} else {
+		y = i2w_dy + priv->y;
+	}
+
+	if (priv->width_set) {
+		width = priv->width;
+	} else {
+		width = gdk_pixbuf_get_width (priv->pixbuf);
+	}
+
+	if (priv->width_in_pixels)
+		width /= item->canvas->pixels_per_unit;
+
+	if (priv->height_set) {
+		height = priv->height;
+	} else {
+		height = gdk_pixbuf_get_height (priv->pixbuf);
+	}
+
+	if (priv->height_in_pixels)
+		height /= item->canvas->pixels_per_unit;
+
+
+	switch (priv->anchor) {
+	case GTK_ANCHOR_NW:
+	case GTK_ANCHOR_W:
+	case GTK_ANCHOR_SW:
+		break;
+
+	case GTK_ANCHOR_N:
+	case GTK_ANCHOR_CENTER:
+	case GTK_ANCHOR_S:
+		x -= width / 2.0;
+		break;
+
+	case GTK_ANCHOR_NE:
+	case GTK_ANCHOR_E:
+	case GTK_ANCHOR_SE:
+		x -= width;
+		break;
+
+        default:
+                break;
+	}
+
+	switch (priv->anchor) {
+	case GTK_ANCHOR_NW:
+	case GTK_ANCHOR_N:
+	case GTK_ANCHOR_NE:
+		break;
+
+	case GTK_ANCHOR_W:
+	case GTK_ANCHOR_CENTER:
+	case GTK_ANCHOR_E:
+		y -= height / 2.0;
+		break;
+
+	case GTK_ANCHOR_SW:
+	case GTK_ANCHOR_S:
+	case GTK_ANCHOR_SE:
+		y -= height;
+		break;
+
+        default:
+                break;
+	}
+
+	*bbox_x0 = x;
+	*bbox_y0 = y;
+	*bbox_x1 = x + width;
+	*bbox_y1 = y + height;
+}
+
+
+
+/* Update sequence */
+
+/* Update handler for the pixbuf canvas item */
+static void
+foo_canvas_pixbuf_update (FooCanvasItem *item,
+			    double i2w_dx, double i2w_dy,
+			    int flags)
+{
+	FooCanvasPixbuf *gcp;
+	PixbufPrivate *priv;
+	double bbox_x0, bbox_y0, bbox_x1, bbox_y1;
+	int w, h;
+
+	gcp = FOO_CANVAS_PIXBUF (item);
+	priv = gcp->priv;
+
+	if (parent_class->update)
+		(* parent_class->update) (item, i2w_dx, i2w_dy, flags);
+
+	/* If we need a pixbuf update, or if the item changed visibility to
+	 * shown, recompute the bounding box.
+	 */
+	if (priv->need_pixbuf_update || priv->need_xform_update ||
+	    (flags & FOO_CANVAS_UPDATE_DEEP)) {
+
+		foo_canvas_item_request_redraw (item);
+
+		compute_bounding_box (gcp, i2w_dx, i2w_dy,
+				      &bbox_x0, &bbox_y0,
+				      &bbox_x1, &bbox_y1);
+
+		foo_canvas_w2c_d (item->canvas,
+				    bbox_x0, bbox_y0,
+				    &item->x1, &item->y1);
+
+		foo_canvas_w2c_d (item->canvas,
+				    bbox_x1, bbox_y1,
+				    &item->x2, &item->y2);
+
+		item->x1 = floor (item->x1 + .5);
+		item->y1 = floor (item->y1 + .5);
+		item->x2 = floor (item->x2 + .5);
+		item->y2 = floor (item->y2 + .5);
+
+#ifdef FOO_CANVAS_PIXBUF_VERBOSE
+		g_print ("BBox is %g %g %g %g\n", item->x1, item->y1, item->x2, item->y2);
+#endif
+
+		if (priv->pixbuf) {
+			w = item->x2 - item->x1;
+			h = item->y2 - item->y1;
+
+			if (priv->pixbuf_scaled)
+				g_object_unref (priv->pixbuf_scaled);
+			if (gdk_pixbuf_get_width (priv->pixbuf) != w ||
+			    gdk_pixbuf_get_height (priv->pixbuf) != h)
+				priv->pixbuf_scaled = gdk_pixbuf_scale_simple (
+					priv->pixbuf, w, h, priv->interp_type);
+			else
+				priv->pixbuf_scaled = g_object_ref (priv->pixbuf);
+		}
+
+		foo_canvas_item_request_redraw (item);
+
+		priv->need_pixbuf_update = FALSE;
+		priv->need_xform_update = FALSE;
+	}
+}
+
+
+
+/* Draw handler for the pixbuf canvas item */
+static void
+foo_canvas_pixbuf_draw (FooCanvasItem *item, GdkDrawable *drawable,
+			  GdkEventExpose *expose)
+{
+	FooCanvasPixbuf *gcp;
+	PixbufPrivate *priv;
+	GdkRectangle display_rect, draw_rect;
+	GdkRegion *draw_region;
+	int w, h;
+
+	gcp = FOO_CANVAS_PIXBUF (item);
+	priv = gcp->priv;
+
+	if (!priv->pixbuf)
+		return;
+
+	/* Compute the area we need to repaint */
+
+	w = item->x2 - item->x1;
+	h = item->y2 - item->y1;
+
+	display_rect.x = item->x1;
+	display_rect.y = item->y1;
+	display_rect.width  = w;
+	display_rect.height = h;
+	draw_region = gdk_region_rectangle (&display_rect);
+	gdk_region_intersect (draw_region, expose->region);
+	if (!gdk_region_empty (draw_region)) {
+		gdk_region_get_clipbox (draw_region, &draw_rect);
+		gdk_draw_pixbuf (drawable, NULL, priv->pixbuf_scaled,
+			/* pixbuf 0, 0 is at pix_rect.x, pix_rect.y */
+			     draw_rect.x - display_rect.x,
+			     draw_rect.y - display_rect.y,
+			     draw_rect.x,
+			     draw_rect.y,
+			     draw_rect.width,
+			     draw_rect.height,
+			     GDK_RGB_DITHER_NORMAL, 0, 0);
+	}
+	gdk_region_destroy (draw_region);
+}
+
+
+
+
+/* Point handler for the pixbuf canvas item */
+static double
+foo_canvas_pixbuf_point (FooCanvasItem *item, double x, double y, int cx, int cy,
+			   FooCanvasItem **actual_item)
+{
+	FooCanvasPixbuf *gcp;
+	PixbufPrivate *priv;
+	double x1, y1, x2, y2;
+	int px, py;
+	double no_hit;
+	guchar *src;
+	GdkPixbuf *pixbuf;
+
+	gcp = FOO_CANVAS_PIXBUF (item);
+	priv = gcp->priv;
+	pixbuf = priv->pixbuf;
+
+	*actual_item = item;
+
+	no_hit = item->canvas->pixels_per_unit * 2 + 10;
+
+	if (!priv->pixbuf)
+		return no_hit;
+
+	compute_bounding_box (gcp, 0.0, 0.0,
+			      &x1, &y1, &x2, &y2);
+
+
+	if (x < x1 || x >= x2 ||
+	    y < y1 || y >= y2)
+		return no_hit;
+
+	if (!gdk_pixbuf_get_has_alpha (pixbuf) || priv->point_ignores_alpha)
+		return 0.0;
+
+	px = (x - x1) * gdk_pixbuf_get_width (pixbuf) / (x2 - x1);
+	py = (y - y1) * gdk_pixbuf_get_height (pixbuf) / (y2 - y1);
+
+	src = gdk_pixbuf_get_pixels (pixbuf) +
+		py * gdk_pixbuf_get_rowstride (pixbuf) +
+		px * gdk_pixbuf_get_n_channels (pixbuf);
+
+	if (src[3] < 128)
+		return no_hit;
+	else
+		return 0.0;
+}
+
+
+
+static void
+foo_canvas_pixbuf_translate (FooCanvasItem *item, double dx, double dy)
+{
+	FooCanvasPixbuf *gcp;
+	PixbufPrivate *priv;
+
+	gcp = FOO_CANVAS_PIXBUF (item);
+	priv = gcp->priv;
+
+	if (priv->x_in_pixels) {
+		priv->x += dx * item->canvas->pixels_per_unit;
+	} else {
+		priv->x += dx;
+	}
+
+	if (priv->y_in_pixels) {
+		priv->y += dy * item->canvas->pixels_per_unit;
+	} else {
+		priv->y += dy;
+	}
+
+	priv->need_xform_update = TRUE;
+}
+
+
+
+/* Bounds handler for the pixbuf canvas item */
+static void
+foo_canvas_pixbuf_bounds (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2)
+{
+	FooCanvasPixbuf *gcp;
+	PixbufPrivate *priv;
+
+	gcp = FOO_CANVAS_PIXBUF (item);
+	priv = gcp->priv;
+
+	if (!priv->pixbuf) {
+		*x1 = *y1 = *x2 = *y2 = 0.0;
+		return;
+	}
+
+	compute_bounding_box (gcp, 0.0, 0.0,
+			      x1, y1, x2, y2);
+}
diff --git a/widgets/libfoocanvas/foo-canvas-pixbuf.h b/widgets/libfoocanvas/foo-canvas-pixbuf.h
new file mode 100644
index 0000000..c477445
--- /dev/null
+++ b/widgets/libfoocanvas/foo-canvas-pixbuf.h
@@ -0,0 +1,62 @@
+/* GNOME libraries - GdkPixbuf item for the GNOME canvas
+ *
+ * Copyright (C) 1999 The Free Software Foundation
+ *
+ * Author: Federico Mena-Quintero <federico gimp org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef FOO_CANVAS_PIXBUF_H
+#define FOO_CANVAS_PIXBUF_H
+
+
+#include <libfoocanvas/foo-canvas.h>
+
+G_BEGIN_DECLS
+
+
+
+#define FOO_TYPE_CANVAS_PIXBUF            (foo_canvas_pixbuf_get_type ())
+#define FOO_CANVAS_PIXBUF(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), FOO_TYPE_CANVAS_PIXBUF, FooCanvasPixbuf))
+#define FOO_CANVAS_PIXBUF_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), FOO_TYPE_CANVAS_PIXBUF, FooCanvasPixbufClass))
+#define FOO_IS_CANVAS_PIXBUF(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FOO_TYPE_CANVAS_PIXBUF))
+#define FOO_IS_CANVAS_PIXBUF_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FOO_TYPE_CANVAS_PIXBUF))
+#define FOO_CANVAS_PIXBUF_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), FOO_TYPE_CANVAS_PIXBUF, FooCanvasPixbufClass))
+
+
+typedef struct _FooCanvasPixbuf FooCanvasPixbuf;
+typedef struct _FooCanvasPixbufClass FooCanvasPixbufClass;
+
+struct _FooCanvasPixbuf {
+	FooCanvasItem item;
+
+	/* Private data */
+	gpointer priv;
+};
+
+struct _FooCanvasPixbufClass {
+	FooCanvasItemClass parent_class;
+};
+
+
+GType foo_canvas_pixbuf_get_type (void) G_GNUC_CONST;
+
+
+
+G_END_DECLS
+
+#endif
diff --git a/widgets/libfoocanvas/foo-canvas-polygon.c b/widgets/libfoocanvas/foo-canvas-polygon.c
new file mode 100644
index 0000000..679d7bb
--- /dev/null
+++ b/widgets/libfoocanvas/foo-canvas-polygon.c
@@ -0,0 +1,826 @@
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * The Gnome Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+/* Polygon item type for FooCanvas widget
+ *
+ * FooCanvas is basically a port of the Tk toolkit's most excellent canvas widget.  Tk is
+ * copyrighted by the Regents of the University of California, Sun Microsystems, and other parties.
+ *
+ * Author: Federico Mena <federico nuclecu unam mx>
+ */
+
+#include <config.h>
+#include <math.h>
+#include <string.h>
+#include "libfoocanvas.h"
+
+
+#define NUM_STATIC_POINTS 256	/* Number of static points to use to avoid allocating arrays */
+
+
+#define GROW_BOUNDS(bx1, by1, bx2, by2, x, y) {	\
+	if (x < bx1)				\
+		bx1 = x;			\
+						\
+	if (x > bx2)				\
+		bx2 = x;			\
+						\
+	if (y < by1)				\
+		by1 = y;			\
+						\
+	if (y > by2)				\
+		by2 = y;			\
+}
+
+
+enum {
+	PROP_0,
+	PROP_POINTS,
+	PROP_FILL_COLOR,
+	PROP_FILL_COLOR_GDK,
+	PROP_FILL_COLOR_RGBA,
+	PROP_OUTLINE_COLOR,
+	PROP_OUTLINE_COLOR_GDK,
+	PROP_OUTLINE_COLOR_RGBA,
+	PROP_FILL_STIPPLE,
+	PROP_OUTLINE_STIPPLE,
+	PROP_WIDTH_PIXELS,
+	PROP_WIDTH_UNITS
+};
+
+
+static void foo_canvas_polygon_class_init (FooCanvasPolygonClass *klass);
+static void foo_canvas_polygon_init       (FooCanvasPolygon      *poly);
+static void foo_canvas_polygon_destroy    (GtkObject               *object);
+static void foo_canvas_polygon_set_property (GObject              *object,
+					       guint                 param_id,
+					       const GValue         *value,
+					       GParamSpec           *pspec);
+static void foo_canvas_polygon_get_property (GObject              *object,
+					       guint                 param_id,
+					       GValue               *value,
+					       GParamSpec           *pspec);
+
+static void   foo_canvas_polygon_update      (FooCanvasItem *item,
+						double i2w_dx, double i2w_dy,
+						int flags);
+static void   foo_canvas_polygon_realize     (FooCanvasItem *item);
+static void   foo_canvas_polygon_unrealize   (FooCanvasItem *item);
+static void   foo_canvas_polygon_draw        (FooCanvasItem *item, GdkDrawable *drawable,
+						GdkEventExpose *expose);
+static double foo_canvas_polygon_point       (FooCanvasItem *item, double x, double y,
+						int cx, int cy, FooCanvasItem **actual_item);
+static void   foo_canvas_polygon_translate   (FooCanvasItem *item, double dx, double dy);
+static void   foo_canvas_polygon_bounds      (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2);
+
+
+static FooCanvasItemClass *parent_class;
+
+G_DEFINE_TYPE (FooCanvasPolygon, foo_canvas_polygon, FOO_TYPE_CANVAS_ITEM)
+
+static void
+foo_canvas_polygon_class_init (FooCanvasPolygonClass *klass)
+{
+	GObjectClass *gobject_class;
+	GtkObjectClass *object_class;
+	FooCanvasItemClass *item_class;
+
+	gobject_class = (GObjectClass *) klass;
+	object_class = (GtkObjectClass *) klass;
+	item_class = (FooCanvasItemClass *) klass;
+
+	parent_class = g_type_class_peek_parent (klass);
+
+	gobject_class->set_property = foo_canvas_polygon_set_property;
+	gobject_class->get_property = foo_canvas_polygon_get_property;
+
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_POINTS,
+                 g_param_spec_boxed ("points", NULL, NULL,
+				     FOO_TYPE_CANVAS_POINTS,
+				     G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_FILL_COLOR,
+                 g_param_spec_string ("fill-color", NULL, NULL,
+                                      NULL,
+                                      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_FILL_COLOR_GDK,
+                 g_param_spec_boxed ("fill-color-gdk", NULL, NULL,
+				     GDK_TYPE_COLOR,
+				     G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_FILL_COLOR_RGBA,
+                 g_param_spec_uint ("fill-color-rgba", NULL, NULL,
+				    0, G_MAXUINT, 0,
+				    G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_OUTLINE_COLOR,
+                 g_param_spec_string ("outline-color", NULL, NULL,
+                                      NULL,
+                                      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_OUTLINE_COLOR_GDK,
+                 g_param_spec_boxed ("outline-color-gdk", NULL, NULL,
+				     GDK_TYPE_COLOR,
+				     G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_OUTLINE_COLOR_RGBA,
+                 g_param_spec_uint ("outline-color-rgba", NULL, NULL,
+				    0, G_MAXUINT, 0,
+				    G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_FILL_STIPPLE,
+                 g_param_spec_object ("fill-stipple", NULL, NULL,
+                                      GDK_TYPE_DRAWABLE,
+                                      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_OUTLINE_STIPPLE,
+                 g_param_spec_object ("outline-stipple", NULL, NULL,
+                                      GDK_TYPE_DRAWABLE,
+                                      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_WIDTH_PIXELS,
+                 g_param_spec_uint ("width-pixels", NULL, NULL,
+				    0, G_MAXUINT, 0,
+				    G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_WIDTH_UNITS,
+                 g_param_spec_double ("width-units", NULL, NULL,
+				      0.0, G_MAXDOUBLE, 0.0,
+				      G_PARAM_READWRITE));
+
+	object_class->destroy = foo_canvas_polygon_destroy;
+
+	item_class->update = foo_canvas_polygon_update;
+	item_class->realize = foo_canvas_polygon_realize;
+	item_class->unrealize = foo_canvas_polygon_unrealize;
+	item_class->draw = foo_canvas_polygon_draw;
+	item_class->point = foo_canvas_polygon_point;
+	item_class->translate = foo_canvas_polygon_translate;
+	item_class->bounds = foo_canvas_polygon_bounds;
+}
+
+static void
+foo_canvas_polygon_init (FooCanvasPolygon *poly)
+{
+	poly->width = 0.0;
+}
+
+static void
+foo_canvas_polygon_destroy (GtkObject *object)
+{
+	FooCanvasPolygon *poly;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (FOO_IS_CANVAS_POLYGON (object));
+
+	poly = FOO_CANVAS_POLYGON (object);
+
+	/* remember, destroy can be run multiple times! */
+
+	if (poly->coords)
+		g_free (poly->coords);
+	poly->coords = NULL;
+
+	if (poly->fill_stipple)
+		g_object_unref (poly->fill_stipple);
+	poly->fill_stipple = NULL;
+
+	if (poly->outline_stipple)
+		g_object_unref (poly->outline_stipple);
+	poly->outline_stipple = NULL;
+
+	if (GTK_OBJECT_CLASS (parent_class)->destroy)
+		(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+/* Computes the bounding box of the polygon.  Assumes that the number of points in the polygon is
+ * not zero.
+ */
+static gboolean
+get_bounds (FooCanvasPolygon *poly, double *bx1, double *by1, double *bx2, double *by2)
+{
+	double *coords;
+	double x1, y1, x2, y2;
+	double width;
+	int i;
+
+	if (poly->num_points == 0)
+		return FALSE;
+
+	/* Compute bounds of vertices */
+
+	x1 = x2 = poly->coords[0];
+	y1 = y2 = poly->coords[1];
+
+	for (i = 1, coords = poly->coords + 2; i < poly->num_points; i++, coords += 2) {
+		GROW_BOUNDS (x1, y1, x2, y2, coords[0], coords[1]);
+	}
+
+	/* Add outline width */
+
+	if (poly->width_pixels)
+		width = poly->width / poly->item.canvas->pixels_per_unit;
+	else
+		width = poly->width;
+
+	width /= 2.0;
+
+	x1 -= width;
+	y1 -= width;
+	x2 += width;
+	y2 += width;
+
+	/* Done */
+
+	*bx1 = x1;
+	*by1 = y1;
+	*bx2 = x2;
+	*by2 = y2;
+	return TRUE;
+}
+
+/* Computes the bounding box of the polygon, in canvas coordinates.  Assumes that the number of points in the polygon is
+ * not zero.
+ */
+static gboolean
+get_bounds_canvas (FooCanvasPolygon *poly,
+		   double *bx1, double *by1, double *bx2, double *by2,
+		   double i2w_dx, double i2w_dy)
+{
+	FooCanvasItem *item;
+	double bbox_x0, bbox_y0, bbox_x1, bbox_y1;
+
+	item = FOO_CANVAS_ITEM (poly);
+
+	if (!get_bounds (poly, &bbox_x0, &bbox_y0, &bbox_x1, &bbox_y1))
+		return FALSE;
+
+	bbox_x0 += i2w_dx; 
+	bbox_y0 += i2w_dy; 
+	bbox_x1 += i2w_dx; 
+	bbox_y1 += i2w_dy; 
+
+	foo_canvas_w2c_rect_d (item->canvas,
+				 &bbox_x0, &bbox_y0, &bbox_x1, &bbox_y1);
+	
+	/* include 1 pixel of fudge */
+	*bx1 = bbox_x0 - 1;
+	*by1 = bbox_y0 - 1;
+	*bx2 = bbox_x1 + 1;
+	*by2 = bbox_y1 + 1;
+	return TRUE;
+}
+
+/* Sets the points of the polygon item to the specified ones.  If needed, it will add a point to
+ * close the polygon.
+ */
+static void
+set_points (FooCanvasPolygon *poly, FooCanvasPoints *points)
+{
+	int duplicate;
+
+	/* See if we need to duplicate the first point */
+
+	duplicate = ((points->coords[0] != points->coords[2 * points->num_points - 2])
+		     || (points->coords[1] != points->coords[2 * points->num_points - 1]));
+
+	if (duplicate)
+		poly->num_points = points->num_points + 1;
+	else
+		poly->num_points = points->num_points;
+
+	poly->coords = g_new (double, 2 * poly->num_points);
+	memcpy (poly->coords, points->coords, 2 * points->num_points * sizeof (double));
+
+	if (duplicate) {
+		poly->coords[2 * poly->num_points - 2] = poly->coords[0];
+		poly->coords[2 * poly->num_points - 1] = poly->coords[1];
+	}
+}
+
+/* Convenience function to set a GC's foreground color to the specified pixel value */
+static void
+set_gc_foreground (GdkGC *gc, gulong pixel)
+{
+	GdkColor c;
+
+	if (!gc)
+		return;
+
+	c.pixel = pixel;
+	gdk_gc_set_foreground (gc, &c);
+}
+
+/* Sets the stipple pattern for the specified gc */
+static void
+set_stipple (GdkGC *gc, GdkBitmap **internal_stipple, GdkBitmap *stipple, int reconfigure)
+{
+	if (*internal_stipple && !reconfigure)
+		g_object_unref (*internal_stipple);
+
+	*internal_stipple = stipple;
+	if (stipple && !reconfigure)
+		g_object_ref (stipple);
+
+	if (gc) {
+		if (stipple) {
+			gdk_gc_set_stipple (gc, stipple);
+			gdk_gc_set_fill (gc, GDK_STIPPLED);
+		} else
+			gdk_gc_set_fill (gc, GDK_SOLID);
+	}
+}
+
+/* Recalculate the outline width of the polygon and set it in its GC */
+static void
+set_outline_gc_width (FooCanvasPolygon *poly)
+{
+	int width;
+
+	if (!poly->outline_gc)
+		return;
+
+	if (poly->width_pixels)
+		width = (int) poly->width;
+	else
+		width = (int) (poly->width * poly->item.canvas->pixels_per_unit + 0.5);
+
+	gdk_gc_set_line_attributes (poly->outline_gc, width,
+				    GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
+}
+
+static void
+foo_canvas_polygon_set_property (GObject              *object,
+				   guint                 param_id,
+				   const GValue         *value,
+				   GParamSpec           *pspec)
+{
+	FooCanvasItem *item;
+	FooCanvasPolygon *poly;
+	FooCanvasPoints *points;
+	GdkColor color = { 0, 0, 0, 0, };
+	GdkColor *pcolor;
+	int have_pixel;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (FOO_IS_CANVAS_POLYGON (object));
+
+	item = FOO_CANVAS_ITEM (object);
+	poly = FOO_CANVAS_POLYGON (object);
+	have_pixel = FALSE;
+
+	switch (param_id) {
+	case PROP_POINTS:
+		points = g_value_get_boxed (value);
+
+		if (poly->coords) {
+			g_free (poly->coords);
+			poly->coords = NULL;
+		}
+
+		if (!points)
+			poly->num_points = 0;
+		else
+			set_points (poly, points);
+
+		foo_canvas_item_request_update (item);
+		break;
+
+        case PROP_FILL_COLOR:
+	case PROP_FILL_COLOR_GDK:
+	case PROP_FILL_COLOR_RGBA:
+		switch (param_id) {
+		case PROP_FILL_COLOR:
+			if (g_value_get_string (value) &&
+			    gdk_color_parse (g_value_get_string (value), &color))
+				poly->fill_set = TRUE;
+			else
+				poly->fill_set = FALSE;
+
+			poly->fill_color = ((color.red & 0xff00) << 16 |
+					    (color.green & 0xff00) << 8 |
+					    (color.blue & 0xff00) |
+					    0xff);
+			break;
+
+		case PROP_FILL_COLOR_GDK:
+			pcolor = g_value_get_boxed (value);
+			poly->fill_set = pcolor != NULL;
+
+			if (pcolor) {
+				GdkColormap *colormap;
+
+				color = *pcolor;
+				colormap = gtk_widget_get_colormap (GTK_WIDGET (item->canvas));
+				gdk_rgb_find_color (colormap, &color);
+				have_pixel = TRUE;
+			}
+
+			poly->fill_color = ((color.red & 0xff00) << 16 |
+					    (color.green & 0xff00) << 8 |
+					    (color.blue & 0xff00) |
+					    0xff);
+			break;
+
+		case PROP_FILL_COLOR_RGBA:
+			poly->fill_set = TRUE;
+			poly->fill_color = g_value_get_uint (value);
+			break;
+		}
+#ifdef VERBOSE
+		g_print ("poly fill color = %08x\n", poly->fill_color);
+#endif
+		if (have_pixel)
+			poly->fill_pixel = color.pixel;
+		else
+			poly->fill_pixel = foo_canvas_get_color_pixel (item->canvas,
+									 poly->fill_color);
+
+		set_gc_foreground (poly->fill_gc, poly->fill_pixel);
+		foo_canvas_item_request_redraw (item);		
+		break;
+
+        case PROP_OUTLINE_COLOR:
+	case PROP_OUTLINE_COLOR_GDK:
+	case PROP_OUTLINE_COLOR_RGBA:
+		switch (param_id) {
+		case PROP_OUTLINE_COLOR:
+			if (g_value_get_string (value) &&
+			    gdk_color_parse (g_value_get_string (value), &color))
+				poly->outline_set = TRUE;
+			else
+				poly->outline_set = FALSE;
+
+			poly->outline_color = ((color.red & 0xff00) << 16 |
+					       (color.green & 0xff00) << 8 |
+					       (color.blue & 0xff00) |
+					       0xff);
+			break;
+
+		case PROP_OUTLINE_COLOR_GDK:
+			pcolor = g_value_get_boxed (value);
+			poly->outline_set = pcolor != NULL;
+
+			if (pcolor) {
+				GdkColormap *colormap;
+
+				color = *pcolor;
+				colormap = gtk_widget_get_colormap (GTK_WIDGET (item->canvas));
+				gdk_rgb_find_color (colormap, &color);
+				have_pixel = TRUE;
+			}
+
+			poly->outline_color = ((color.red & 0xff00) << 16 |
+					       (color.green & 0xff00) << 8 |
+					       (color.blue & 0xff00) |
+					       0xff);
+			break;
+
+		case PROP_OUTLINE_COLOR_RGBA:
+			poly->outline_set = TRUE;
+			poly->outline_color = g_value_get_uint (value);
+			break;
+		}
+#ifdef VERBOSE
+		g_print ("poly outline color = %08x\n", poly->outline_color);
+#endif
+		if (have_pixel)
+			poly->outline_pixel = color.pixel;
+		else
+			poly->outline_pixel = foo_canvas_get_color_pixel (item->canvas,
+									    poly->outline_color);
+
+		set_gc_foreground (poly->outline_gc, poly->outline_pixel);
+		foo_canvas_item_request_redraw (item);		
+		break;
+
+	case PROP_FILL_STIPPLE:
+		set_stipple (poly->fill_gc, &poly->fill_stipple, (GdkBitmap *) g_value_get_object (value), FALSE);
+		foo_canvas_item_request_update (item);
+		break;
+
+	case PROP_OUTLINE_STIPPLE:
+		set_stipple (poly->outline_gc, &poly->outline_stipple, (GdkBitmap *) g_value_get_object (value), FALSE);
+		foo_canvas_item_request_update (item);
+		break;
+
+	case PROP_WIDTH_PIXELS:
+		poly->width = g_value_get_uint (value);
+		poly->width_pixels = TRUE;
+		set_outline_gc_width (poly);
+#ifdef OLD_XFORM
+		recalc_bounds (poly);
+#else
+		foo_canvas_item_request_update (item);
+#endif
+		break;
+
+	case PROP_WIDTH_UNITS:
+		poly->width = fabs (g_value_get_double (value));
+		poly->width_pixels = FALSE;
+		set_outline_gc_width (poly);
+#ifdef OLD_XFORM
+		recalc_bounds (poly);
+#else
+		foo_canvas_item_request_update (item);
+#endif
+		break;
+
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	}
+}
+
+/* Allocates a GdkColor structure filled with the specified pixel, and puts it into the specified
+ * value for returning it in the get_property method.
+ */
+static void
+get_color_value (FooCanvasPolygon *poly, gulong pixel, GValue *value)
+{
+	GdkColor *color;
+	GdkColormap *colormap;
+
+	color = g_new (GdkColor, 1);
+	color->pixel = pixel;
+
+	colormap = gtk_widget_get_colormap (GTK_WIDGET (poly));
+	gdk_rgb_find_color (colormap, color);
+	g_value_set_boxed (value, color);
+}
+
+static void
+foo_canvas_polygon_get_property (GObject              *object,
+				   guint                 param_id,
+				   GValue               *value,
+				   GParamSpec           *pspec)
+{
+	FooCanvasPolygon *poly;
+	FooCanvasPoints *points;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (FOO_IS_CANVAS_POLYGON (object));
+
+	poly = FOO_CANVAS_POLYGON (object);
+
+	switch (param_id) {
+	case PROP_POINTS:
+		if (poly->num_points != 0) {
+			points = foo_canvas_points_new (poly->num_points);
+			memcpy (points->coords, poly->coords, 2 * poly->num_points * sizeof (double));
+			g_value_set_boxed (value, points);
+		} else
+			g_value_set_boxed (value, NULL);
+		break;
+
+	case PROP_FILL_COLOR_GDK:
+		get_color_value (poly, poly->fill_pixel, value);
+		break;
+
+	case PROP_OUTLINE_COLOR_GDK:
+		get_color_value (poly, poly->outline_pixel, value);
+		break;
+
+	case PROP_FILL_COLOR_RGBA:
+		g_value_set_uint (value, poly->fill_color);
+		break;
+
+	case PROP_OUTLINE_COLOR_RGBA:
+		g_value_set_uint (value, poly->outline_color);
+		break;
+
+	case PROP_FILL_STIPPLE:
+		g_value_set_object (value, (GObject *) poly->fill_stipple);
+		break;
+
+	case PROP_OUTLINE_STIPPLE:
+		g_value_set_object (value, (GObject *) poly->outline_stipple);
+		break;
+
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	}
+}
+
+static void
+foo_canvas_polygon_update (FooCanvasItem *item,
+			     double i2w_dx, double i2w_dy,
+			     int flags)
+{
+	FooCanvasPolygon *poly;
+	double x1, y1, x2, y2;
+
+	poly = FOO_CANVAS_POLYGON (item);
+
+	if (parent_class->update)
+		(* parent_class->update) (item, i2w_dx, i2w_dy, flags);
+
+	set_outline_gc_width (poly);
+	set_gc_foreground (poly->fill_gc, poly->fill_pixel);
+	set_gc_foreground (poly->outline_gc, poly->outline_pixel);
+	set_stipple (poly->fill_gc, &poly->fill_stipple, poly->fill_stipple, TRUE);
+	set_stipple (poly->outline_gc, &poly->outline_stipple, poly->outline_stipple, TRUE);
+	
+	if (get_bounds_canvas (poly, &x1, &y1, &x2, &y2, i2w_dx, i2w_dy))
+		foo_canvas_update_bbox (item, x1, y1, x2, y2);
+}
+
+static void
+foo_canvas_polygon_realize (FooCanvasItem *item)
+{
+	FooCanvasPolygon *poly;
+
+	poly = FOO_CANVAS_POLYGON (item);
+
+	if (parent_class->realize)
+		(* parent_class->realize) (item);
+
+	poly->fill_gc = gdk_gc_new (item->canvas->layout.bin_window);
+	poly->outline_gc = gdk_gc_new (item->canvas->layout.bin_window);
+/* FIXME FIXME FIXME Need to recalc pixel values, set colours, etc. */
+
+#ifdef OLD_XFORM
+	(* FOO_CANVAS_ITEM_CLASS (item->object.klass)->update) (item, NULL, NULL, 0);
+#endif
+}
+
+static void
+foo_canvas_polygon_unrealize (FooCanvasItem *item)
+{
+	FooCanvasPolygon *poly;
+
+	poly = FOO_CANVAS_POLYGON (item);
+
+	g_object_unref (poly->fill_gc);
+	poly->fill_gc = NULL;
+	g_object_unref (poly->outline_gc);
+	poly->outline_gc = NULL;
+
+	if (parent_class->unrealize)
+		(* parent_class->unrealize) (item);
+}
+
+/* Converts an array of world coordinates into an array of canvas pixel coordinates.  Takes in the
+ * item->world deltas and the drawable deltas.
+ */
+static void
+item_to_canvas (FooCanvas *canvas, double *item_coords, GdkPoint *canvas_coords, int num_points,
+		double i2w_dx, double i2w_dy)
+{
+	int i;
+
+	for (i = 0; i < num_points; i++) {
+		foo_canvas_w2c (canvas,
+				  item_coords[i*2] + i2w_dx,
+				  item_coords[i*2+1] + i2w_dy,
+				  &canvas_coords->x, &canvas_coords->y);
+		canvas_coords++;
+	}
+}
+
+static void
+foo_canvas_polygon_draw (FooCanvasItem *item, GdkDrawable *drawable,
+			   GdkEventExpose *expose)
+{
+	FooCanvasPolygon *poly;
+	GdkPoint static_points[NUM_STATIC_POINTS];
+	GdkPoint *points;
+	double i2w_dx, i2w_dy;
+
+	poly = FOO_CANVAS_POLYGON (item);
+
+	if (poly->num_points == 0)
+		return;
+
+	/* Build array of canvas pixel coordinates */
+
+	if (poly->num_points <= NUM_STATIC_POINTS)
+		points = static_points;
+	else
+		points = g_new (GdkPoint, poly->num_points);
+
+	i2w_dx = 0.0;
+	i2w_dy = 0.0;
+	foo_canvas_item_i2w (item, &i2w_dx, &i2w_dy);
+
+	item_to_canvas (item->canvas,
+			poly->coords, points, poly->num_points,
+			i2w_dx, i2w_dy);
+
+	if (poly->fill_set) {
+		if (poly->fill_stipple)
+			foo_canvas_set_stipple_origin (item->canvas, poly->fill_gc);
+
+		gdk_draw_polygon (drawable, poly->fill_gc, TRUE, points, poly->num_points);
+	}
+
+	if (poly->outline_set) {
+		if (poly->outline_stipple)
+			foo_canvas_set_stipple_origin (item->canvas, poly->outline_gc);
+
+		gdk_draw_polygon (drawable, poly->outline_gc, FALSE, points, poly->num_points);
+	}
+
+	/* Done */
+
+	if (points != static_points)
+		g_free (points);
+}
+
+static double
+foo_canvas_polygon_point (FooCanvasItem *item, double x, double y,
+			    int cx, int cy, FooCanvasItem **actual_item)
+{
+	FooCanvasPolygon *poly;
+	double dist;
+	double width;
+
+	poly = FOO_CANVAS_POLYGON (item);
+
+	*actual_item = item;
+
+	dist = foo_canvas_polygon_to_point (poly->coords, poly->num_points, x, y);
+
+	if (poly->outline_set) {
+		if (poly->width_pixels)
+			width = poly->width / item->canvas->pixels_per_unit;
+		else
+			width = poly->width;
+
+		dist -= width / 2.0;
+
+		if (dist < 0.0)
+			dist = 0.0;
+	}
+
+	return dist;
+}
+
+static void
+foo_canvas_polygon_translate (FooCanvasItem *item, double dx, double dy)
+{
+        FooCanvasPolygon *poly;
+        int i;
+        double *coords;
+
+        poly = FOO_CANVAS_POLYGON (item);
+
+        for (i = 0, coords = poly->coords; i < poly->num_points; i++, coords += 2) {
+                coords[0] += dx;
+                coords[1] += dy;
+        }
+
+}
+
+static void
+foo_canvas_polygon_bounds (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2)
+{
+	FooCanvasPolygon *poly;
+
+	g_return_if_fail (item != NULL);
+	g_return_if_fail (FOO_IS_CANVAS_POLYGON (item));
+
+	poly = FOO_CANVAS_POLYGON (item);
+
+	if (poly->num_points == 0) {
+		*x1 = *y1 = *x2 = *y2 = 0.0;
+		return;
+	}
+
+	get_bounds (poly, x1, y1, x2, y2);
+}
diff --git a/widgets/libfoocanvas/foo-canvas-polygon.h b/widgets/libfoocanvas/foo-canvas-polygon.h
new file mode 100644
index 0000000..d56fd45
--- /dev/null
+++ b/widgets/libfoocanvas/foo-canvas-polygon.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * The Gnome Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+/* Polygon item type for FooCanvas widget
+ *
+ * FooCanvas is basically a port of the Tk toolkit's most excellent canvas widget.  Tk is
+ * copyrighted by the Regents of the University of California, Sun Microsystems, and other parties.
+ *
+ *
+ * Author: Federico Mena <federico nuclecu unam mx>
+ */
+
+#ifndef FOO_CANVAS_POLYGON_H
+#define FOO_CANVAS_POLYGON_H
+
+
+#include <libfoocanvas/foo-canvas.h>
+
+G_BEGIN_DECLS
+
+
+/* Polygon item for the canvas.  A polygon is a bit different from rectangles and ellipses in that
+ * points inside it will always be considered "inside", even if the fill color is not set.  If you
+ * want to have a hollow polygon, use a line item instead.
+ *
+ * The following object arguments are available:
+ *
+ * name			type			read/write	description
+ * ------------------------------------------------------------------------------------------
+ * points		FooCanvasPoints*	RW		Pointer to a FooCanvasPoints structure.
+ *								This can be created by a call to
+ *								foo_canvas_points_new() (in foo-canvas-util.h).
+ *								X coordinates are in the even indices of the
+ *								points->coords array, Y coordinates are in
+ *								the odd indices.
+ * fill_color		string			W		X color specification for fill color,
+ *								or NULL pointer for no color (transparent).
+ * fill_color_gdk	GdkColor*		RW		Allocated GdkColor for fill.
+ * outline_color	string			W		X color specification for outline color,
+ *								or NULL pointer for no color (transparent).
+ * outline_color_gdk	GdkColor*		RW		Allocated GdkColor for outline.
+ * fill_stipple		GdkBitmap*		RW		Stipple pattern for fill
+ * outline_stipple	GdkBitmap*		RW		Stipple pattern for outline
+ * width_pixels		uint			RW		Width of the outline in pixels.  The outline will
+ *								not be scaled when the canvas zoom factor is changed.
+ * width_units		double			RW		Width of the outline in canvas units.  The outline
+ *								will be scaled when the canvas zoom factor is changed.
+ */
+
+#define FOO_TYPE_CANVAS_POLYGON            (foo_canvas_polygon_get_type ())
+#define FOO_CANVAS_POLYGON(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), FOO_TYPE_CANVAS_POLYGON, FooCanvasPolygon))
+#define FOO_CANVAS_POLYGON_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), FOO_TYPE_CANVAS_POLYGON, FooCanvasPolygonClass))
+#define FOO_IS_CANVAS_POLYGON(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FOO_TYPE_CANVAS_POLYGON))
+#define FOO_IS_CANVAS_POLYGON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FOO_TYPE_CANVAS_POLYGON))
+#define FOO_CANVAS_POLYGON_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), FOO_TYPE_CANVAS_POLYGON, FooCanvasPolygonClass))
+
+
+typedef struct _FooCanvasPolygon FooCanvasPolygon;
+typedef struct _FooCanvasPolygonClass FooCanvasPolygonClass;
+
+struct _FooCanvasPolygon {
+	FooCanvasItem item;
+
+	double *coords;			/* Array of coordinates for the polygon's points.  X coords
+					 * are in the even indices, Y coords are in the odd indices.
+					 */
+	GdkBitmap *fill_stipple;	/* Stipple for fill */
+	GdkBitmap *outline_stipple;	/* Stipple for outline */
+
+	GdkGC *fill_gc;			/* GC for filling */
+	GdkGC *outline_gc;		/* GC for outline */
+
+	gulong fill_pixel;		/* Color for fill */
+	gulong outline_pixel;		/* Color for outline */
+	double width;			/* Width of polygon's outline */
+
+	int num_points;			/* Number of points in the polygon */
+	guint fill_color;		/* Fill color, RGBA */
+	guint outline_color;		/* Outline color, RGBA */
+
+        guint32 fill_rgba;		/* RGBA color for filling */ /*AA*/
+	guint32 outline_rgba;		/* RGBA color for outline */ /*AA*/
+
+	guint fill_set : 1;		/* Is fill color set? */
+	guint outline_set : 1;		/* Is outline color set? */
+	guint width_pixels : 1;		/* Is outline width specified in pixels or units? */
+};
+
+struct _FooCanvasPolygonClass {
+	FooCanvasItemClass parent_class;
+};
+
+
+/* Standard Gtk function */
+GType foo_canvas_polygon_get_type (void) G_GNUC_CONST;
+
+
+G_END_DECLS
+
+#endif
diff --git a/widgets/libfoocanvas/foo-canvas-rect-ellipse.c b/widgets/libfoocanvas/foo-canvas-rect-ellipse.c
new file mode 100644
index 0000000..1c18949
--- /dev/null
+++ b/widgets/libfoocanvas/foo-canvas-rect-ellipse.c
@@ -0,0 +1,1489 @@
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * The Gnome Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+/* Rectangle and ellipse item types for FooCanvas widget
+ *
+ * FooCanvas is basically a port of the Tk toolkit's most excellent canvas widget.  Tk is
+ * copyrighted by the Regents of the University of California, Sun Microsystems, and other parties.
+ *
+ *
+ * Author: Federico Mena <federico nuclecu unam mx>
+ */
+
+#include <config.h>
+#include <math.h>
+#include "foo-canvas-rect-ellipse.h"
+#include "foo-canvas-util.h"
+#include <string.h>
+
+#ifdef HAVE_RENDER
+#include <gdk/gdkx.h>
+#include <X11/extensions/Xrender.h>
+#endif
+
+/* Base class for rectangle and ellipse item types */
+
+#define noVERBOSE
+
+enum {
+	PROP_0,
+	PROP_X1,
+	PROP_Y1,
+	PROP_X2,
+	PROP_Y2,
+	PROP_FILL_COLOR,
+	PROP_FILL_COLOR_GDK,
+	PROP_FILL_COLOR_RGBA,
+	PROP_OUTLINE_COLOR,
+	PROP_OUTLINE_COLOR_GDK,
+	PROP_OUTLINE_COLOR_RGBA,
+	PROP_FILL_STIPPLE,
+	PROP_OUTLINE_STIPPLE,
+	PROP_WIDTH_PIXELS,
+	PROP_WIDTH_UNITS
+};
+
+
+static void foo_canvas_re_class_init (FooCanvasREClass *klass);
+static void foo_canvas_re_init       (FooCanvasRE      *re);
+static void foo_canvas_re_destroy    (GtkObject          *object);
+static void foo_canvas_re_set_property (GObject              *object,
+					  guint                 param_id,
+					  const GValue         *value,
+					  GParamSpec           *pspec);
+static void foo_canvas_re_get_property (GObject              *object,
+					  guint                 param_id,
+					  GValue               *value,
+					  GParamSpec           *pspec);
+
+static void foo_canvas_re_update_shared (FooCanvasItem *item,
+					   double i2w_dx, double i2w_dy, int flags);
+static void foo_canvas_re_realize     (FooCanvasItem *item);
+static void foo_canvas_re_unrealize   (FooCanvasItem *item);
+static void foo_canvas_re_bounds      (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2);
+static void foo_canvas_re_translate   (FooCanvasItem *item, double dx, double dy);
+static void foo_canvas_rect_update      (FooCanvasItem *item, double i2w_dx, double i2w_dy, int flags);
+static void foo_canvas_ellipse_update      (FooCanvasItem *item, double i2w_dx, double i2w_dy, int flags);
+
+typedef struct {
+  /*< public >*/
+  int x0, y0, x1, y1;
+}  Rect;
+
+static Rect make_rect (int x0, int y0, int x1, int y1);
+static void  diff_rects (Rect r1, Rect r2, int *count, Rect result[4]);
+
+static FooCanvasItemClass *re_parent_class;
+static FooCanvasREClass *rect_parent_class;
+
+
+GType
+foo_canvas_re_get_type (void)
+{
+	static GType re_type = 0;
+
+	if (!re_type) {
+		GTypeInfo re_info = {
+		  sizeof (FooCanvasREClass),
+		  (GBaseInitFunc) NULL,
+		  (GBaseFinalizeFunc) NULL,
+		  (GClassInitFunc) foo_canvas_re_class_init,
+		  NULL,           /* class_finalize */
+		  NULL,           /* class_data */
+		  sizeof (FooCanvasRE),
+		  0,              /* n_preallocs */
+		  (GInstanceInitFunc) foo_canvas_re_init
+		};
+
+		re_type = g_type_register_static (foo_canvas_item_get_type (),
+						  "FooCanvasRE",
+						  &re_info,
+						  0);
+	}
+
+	return re_type;
+}
+
+static void
+foo_canvas_re_class_init (FooCanvasREClass *klass)
+{
+	GObjectClass *gobject_class;
+	GtkObjectClass *object_class;
+	FooCanvasItemClass *item_class;
+
+	gobject_class = (GObjectClass *) klass;
+	object_class = (GtkObjectClass *) klass;
+	item_class = (FooCanvasItemClass *) klass;
+
+	re_parent_class = g_type_class_peek_parent (klass);
+
+	gobject_class->set_property = foo_canvas_re_set_property;
+	gobject_class->get_property = foo_canvas_re_get_property;
+
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_X1,
+                 g_param_spec_double ("x1", NULL, NULL,
+				      -G_MAXDOUBLE, G_MAXDOUBLE, 0,
+				      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_Y1,
+                 g_param_spec_double ("y1", NULL, NULL,
+				      -G_MAXDOUBLE, G_MAXDOUBLE, 0,
+				      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_X2,
+                 g_param_spec_double ("x2", NULL, NULL,
+				      -G_MAXDOUBLE, G_MAXDOUBLE, 0,
+				      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_Y2,
+                 g_param_spec_double ("y2", NULL, NULL,
+				      -G_MAXDOUBLE, G_MAXDOUBLE, 0,
+				      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_FILL_COLOR,
+                 g_param_spec_string ("fill-color", NULL, NULL,
+                                      NULL,
+                                      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_FILL_COLOR_GDK,
+                 g_param_spec_boxed ("fill-color-gdk", NULL, NULL,
+				     GDK_TYPE_COLOR,
+				     G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_FILL_COLOR_RGBA,
+                 g_param_spec_uint ("fill-color-rgba", NULL, NULL,
+				    0, G_MAXUINT, 0,
+				    G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_FILL_STIPPLE,
+                 g_param_spec_object ("fill-stipple", NULL, NULL,
+                                      GDK_TYPE_DRAWABLE,
+                                      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_OUTLINE_COLOR,
+                 g_param_spec_string ("outline-color", NULL, NULL,
+                                      NULL,
+                                      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_OUTLINE_COLOR_GDK,
+                 g_param_spec_boxed ("outline-color-gdk", NULL, NULL,
+				     GDK_TYPE_COLOR,
+				     G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_OUTLINE_COLOR_RGBA,
+                 g_param_spec_uint ("outline-color-rgba", NULL, NULL,
+				    0, G_MAXUINT, 0,
+				    G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_OUTLINE_STIPPLE,
+                 g_param_spec_object ("outline-stipple", NULL, NULL,
+                                      GDK_TYPE_DRAWABLE,
+                                      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_WIDTH_PIXELS,
+                 g_param_spec_uint ("width-pixels", NULL, NULL,
+				    0, G_MAXUINT, 0,
+				    G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_WIDTH_UNITS,
+                 g_param_spec_double ("width-units", NULL, NULL,
+				      0.0, G_MAXDOUBLE, 0.0,
+				      G_PARAM_READWRITE));
+
+	object_class->destroy = foo_canvas_re_destroy;
+
+	item_class->realize = foo_canvas_re_realize;
+	item_class->unrealize = foo_canvas_re_unrealize;
+	item_class->translate = foo_canvas_re_translate;
+	item_class->bounds = foo_canvas_re_bounds;
+}
+
+static void
+foo_canvas_re_init (FooCanvasRE *re)
+{
+	re->x1 = 0.0;
+	re->y1 = 0.0;
+	re->x2 = 0.0;
+	re->y2 = 0.0;
+	re->width = 0.0;
+}
+
+static void
+foo_canvas_re_destroy (GtkObject *object)
+{
+	FooCanvasRE *re;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (FOO_IS_CANVAS_RE (object));
+
+	re = FOO_CANVAS_RE (object);
+
+	/* remember, destroy can be run multiple times! */
+
+	if (re->fill_stipple)
+		g_object_unref (re->fill_stipple);
+	re->fill_stipple = NULL;
+
+	if (re->outline_stipple)
+		g_object_unref (re->outline_stipple);
+	re->outline_stipple = NULL;
+
+	if (GTK_OBJECT_CLASS (re_parent_class)->destroy)
+		(* GTK_OBJECT_CLASS (re_parent_class)->destroy) (object);
+}
+
+static void get_bounds (FooCanvasRE *re, double *px1, double *py1, double *px2, double *py2)
+{
+	FooCanvasItem *item;
+	double x1, y1, x2, y2;
+	int cx1, cy1, cx2, cy2;
+	double hwidth;
+
+#ifdef VERBOSE
+	g_print ("re get_bounds\n");
+#endif
+	item = FOO_CANVAS_ITEM (re);
+
+	if (re->width_pixels)
+		hwidth = (re->width / item->canvas->pixels_per_unit) / 2.0;
+	else
+		hwidth = re->width / 2.0;
+
+	x1 = re->x1;
+	y1 = re->y1;
+	x2 = re->x2;
+	y2 = re->y2;
+
+	foo_canvas_item_i2w (item, &x1, &y1);
+	foo_canvas_item_i2w (item, &x2, &y2);
+	foo_canvas_w2c (item->canvas, x1 - hwidth, y1 - hwidth, &cx1, &cy1);
+	foo_canvas_w2c (item->canvas, x2 + hwidth, y2 + hwidth, &cx2, &cy2);
+	*px1 = cx1;
+	*py1 = cy1;
+	*px2 = cx2;
+	*py2 = cy2;
+
+	/* Some safety fudging */
+
+	*px1 -= 2;
+	*py1 -= 2;
+	*px2 += 2;
+	*py2 += 2;
+}
+
+/* Convenience function to set a GC's foreground color to the specified pixel value */
+static void
+set_gc_foreground (GdkGC *gc, gulong pixel)
+{
+	GdkColor c;
+
+	if (!gc)
+		return;
+
+	c.pixel = pixel;
+	gdk_gc_set_foreground (gc, &c);
+}
+
+/* Sets the stipple pattern for the specified gc */
+static void
+set_stipple (GdkGC *gc, GdkBitmap **internal_stipple, GdkBitmap *stipple, int reconfigure)
+{
+	if (*internal_stipple && !reconfigure)
+		g_object_unref (*internal_stipple);
+
+	*internal_stipple = stipple;
+	if (stipple && !reconfigure)
+		g_object_ref (stipple);
+
+	if (gc) {
+		if (stipple) {
+			gdk_gc_set_stipple (gc, stipple);
+			gdk_gc_set_fill (gc, GDK_STIPPLED);
+		} else
+			gdk_gc_set_fill (gc, GDK_SOLID);
+	}
+}
+
+/* Recalculate the outline width of the rectangle/ellipse and set it in its GC */
+static void
+set_outline_gc_width (FooCanvasRE *re)
+{
+	int width;
+
+	if (!re->outline_gc)
+		return;
+
+	if (re->width_pixels)
+		width = (int) re->width;
+	else
+		width = (int) (re->width * re->item.canvas->pixels_per_unit + 0.5);
+
+	gdk_gc_set_line_attributes (re->outline_gc, width,
+				    GDK_LINE_SOLID, GDK_CAP_PROJECTING, GDK_JOIN_MITER);
+}
+
+static void
+foo_canvas_re_set_fill (FooCanvasRE *re, gboolean fill_set)
+{
+	if (re->fill_set != fill_set) {
+		re->fill_set = fill_set;
+		foo_canvas_item_request_update (FOO_CANVAS_ITEM (re));
+	}
+}
+
+static void
+foo_canvas_re_set_outline (FooCanvasRE *re, gboolean outline_set)
+{
+	if (re->outline_set != outline_set) {
+		re->outline_set = outline_set;
+		foo_canvas_item_request_update (FOO_CANVAS_ITEM (re));
+	}
+}
+
+static void
+foo_canvas_re_set_property (GObject              *object,
+			      guint                 param_id,
+			      const GValue         *value,
+			      GParamSpec           *pspec)
+{
+	FooCanvasItem *item;
+	FooCanvasRE *re;
+	GdkColor color = { 0, 0, 0, 0, };
+	GdkColor *pcolor;
+	int have_pixel;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (FOO_IS_CANVAS_RE (object));
+
+	item = FOO_CANVAS_ITEM (object);
+	re = FOO_CANVAS_RE (object);
+	have_pixel = FALSE;
+
+	switch (param_id) {
+	case PROP_X1:
+		re->x1 = g_value_get_double (value);
+
+		foo_canvas_item_request_update (item);
+		break;
+
+	case PROP_Y1:
+		re->y1 = g_value_get_double (value);
+
+		foo_canvas_item_request_update (item);
+		break;
+
+	case PROP_X2:
+		re->x2 = g_value_get_double (value);
+
+		foo_canvas_item_request_update (item);
+		break;
+
+	case PROP_Y2:
+		re->y2 = g_value_get_double (value);
+
+		foo_canvas_item_request_update (item);
+		break;
+
+	case PROP_FILL_COLOR:
+	case PROP_FILL_COLOR_GDK:
+	case PROP_FILL_COLOR_RGBA:
+		switch (param_id) {
+		case PROP_FILL_COLOR:
+			if (g_value_get_string (value) &&
+			    gdk_color_parse (g_value_get_string (value), &color))
+				foo_canvas_re_set_fill (re, TRUE);
+			else
+				foo_canvas_re_set_fill (re, FALSE);
+
+			re->fill_color = ((color.red & 0xff00) << 16 |
+					  (color.green & 0xff00) << 8 |
+					  (color.blue & 0xff00) |
+					  0xff);
+			break;
+
+		case PROP_FILL_COLOR_GDK:
+			pcolor = g_value_get_boxed (value);
+			foo_canvas_re_set_fill (re, pcolor != NULL);
+
+			if (pcolor) {
+				GdkColormap *colormap;
+
+				color = *pcolor;
+				colormap = gtk_widget_get_colormap (GTK_WIDGET (item->canvas));
+				gdk_rgb_find_color (colormap, &color);
+				have_pixel = TRUE;
+			}
+
+			re->fill_color = ((color.red & 0xff00) << 16 |
+					  (color.green & 0xff00) << 8 |
+					  (color.blue & 0xff00) |
+					  0xff);
+			break;
+
+		case PROP_FILL_COLOR_RGBA:
+			foo_canvas_re_set_fill (re, TRUE);
+			re->fill_color = g_value_get_uint (value);
+			break;
+		}
+#ifdef VERBOSE
+		g_print ("re fill color = %08x\n", re->fill_color);
+#endif
+		if (have_pixel)
+			re->fill_pixel = color.pixel;
+		else
+			re->fill_pixel = foo_canvas_get_color_pixel (item->canvas, re->fill_color);
+
+		set_gc_foreground (re->fill_gc, re->fill_pixel);
+
+		foo_canvas_item_request_redraw (item);		
+		break;
+
+	case PROP_OUTLINE_COLOR:
+	case PROP_OUTLINE_COLOR_GDK:
+	case PROP_OUTLINE_COLOR_RGBA:
+		switch (param_id) {
+		case PROP_OUTLINE_COLOR:
+			if (g_value_get_string (value) &&
+			    gdk_color_parse (g_value_get_string (value), &color))
+				foo_canvas_re_set_outline (re, TRUE);
+			else
+				foo_canvas_re_set_outline (re, FALSE);
+
+			re->outline_color = ((color.red & 0xff00) << 16 |
+					     (color.green & 0xff00) << 8 |
+					     (color.blue & 0xff00) |
+					     0xff);
+			break;
+
+		case PROP_OUTLINE_COLOR_GDK:
+			pcolor = g_value_get_boxed (value);
+			foo_canvas_re_set_outline (re, pcolor != NULL);
+
+			if (pcolor) {
+				GdkColormap *colormap;
+
+				color = *pcolor;
+				colormap = gtk_widget_get_colormap (GTK_WIDGET (item->canvas));
+				gdk_rgb_find_color (colormap, &color);
+
+				have_pixel = TRUE;
+			}
+
+			re->outline_color = ((color.red & 0xff00) << 16 |
+					     (color.green & 0xff00) << 8 |
+					     (color.blue & 0xff00) |
+					     0xff);
+			break;
+
+		case PROP_OUTLINE_COLOR_RGBA:
+			foo_canvas_re_set_outline (re, TRUE);
+			re->outline_color = g_value_get_uint (value);
+			break;
+		}
+#ifdef VERBOSE
+		g_print ("re outline color %x %x %x\n", color.red, color.green, color.blue);
+#endif
+		if (have_pixel)
+			re->outline_pixel = color.pixel;
+		else
+			re->outline_pixel = foo_canvas_get_color_pixel (item->canvas,
+									  re->outline_color);
+
+		set_gc_foreground (re->outline_gc, re->outline_pixel);
+
+		foo_canvas_item_request_redraw (item);		
+		break;
+
+	case PROP_FILL_STIPPLE:
+	        set_stipple (re->fill_gc, &re->fill_stipple, (GdkBitmap *) g_value_get_object (value), FALSE);
+
+		break;
+
+	case PROP_OUTLINE_STIPPLE:
+	        set_stipple (re->outline_gc, &re->outline_stipple, (GdkBitmap *) g_value_get_object (value), FALSE);
+		break;
+
+	case PROP_WIDTH_PIXELS:
+		re->width = g_value_get_uint (value);
+		re->width_pixels = TRUE;
+		set_outline_gc_width (re);
+
+		foo_canvas_item_request_update (item);
+		break;
+
+	case PROP_WIDTH_UNITS:
+		re->width = fabs (g_value_get_double (value));
+		re->width_pixels = FALSE;
+		set_outline_gc_width (re);
+
+		foo_canvas_item_request_update (item);
+		break;
+
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	}
+}
+
+/* Allocates a GdkColor structure filled with the specified pixel, and puts it into the specified
+ * value for returning it in the get_property method.
+ */
+static void
+get_color_value (FooCanvasRE *re, gulong pixel, GValue *value)
+{
+	GdkColor color;
+	FooCanvasItem *item = (FooCanvasItem *) re;
+	GdkColormap *colormap = gtk_widget_get_colormap (GTK_WIDGET (item->canvas));
+
+	gdk_colormap_query_color (colormap, pixel, &color);
+	g_value_set_boxed (value, &color);
+}
+
+static void
+foo_canvas_re_get_property (GObject              *object,
+			      guint                 param_id,
+			      GValue               *value,
+			      GParamSpec           *pspec)
+{
+	FooCanvasRE *re;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (FOO_IS_CANVAS_RE (object));
+
+	re = FOO_CANVAS_RE (object);
+
+	switch (param_id) {
+	case PROP_X1:
+		g_value_set_double (value,  re->x1);
+		break;
+
+	case PROP_Y1:
+		g_value_set_double (value,  re->y1);
+		break;
+
+	case PROP_X2:
+		g_value_set_double (value,  re->x2);
+		break;
+
+	case PROP_Y2:
+		g_value_set_double (value,  re->y2);
+		break;
+
+	case PROP_FILL_COLOR_GDK:
+		get_color_value (re, re->fill_pixel, value);
+		break;
+
+	case PROP_OUTLINE_COLOR_GDK:
+		get_color_value (re, re->outline_pixel, value);
+		break;
+
+	case PROP_FILL_COLOR_RGBA:
+		g_value_set_uint (value,  re->fill_color);
+		break;
+
+	case PROP_OUTLINE_COLOR_RGBA:
+		g_value_set_uint (value,  re->outline_color);
+		break;
+
+	case PROP_FILL_STIPPLE:
+		g_value_set_object (value,  (GObject *) re->fill_stipple);
+		break;
+
+	case PROP_OUTLINE_STIPPLE:
+		g_value_set_object (value,  (GObject *) re->outline_stipple);
+		break;
+
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	}
+}
+
+static void
+set_colors_and_stipples (FooCanvasRE *re)
+{
+	set_gc_foreground (re->fill_gc, re->fill_pixel);
+	set_gc_foreground (re->outline_gc, re->outline_pixel);
+	set_stipple (re->fill_gc, &re->fill_stipple, re->fill_stipple, TRUE);
+	set_stipple (re->outline_gc, &re->outline_stipple, re->outline_stipple, TRUE);
+	set_outline_gc_width (re);
+}
+
+static void
+foo_canvas_re_update_shared (FooCanvasItem *item, double i2w_dx, double i2w_dy, int flags)
+{
+	FooCanvasRE *re;
+
+#ifdef VERBOSE
+	g_print ("foo_canvas_re_update_shared\n");
+#endif
+	re = FOO_CANVAS_RE (item);
+
+	if (re_parent_class->update)
+		(* re_parent_class->update) (item, i2w_dx, i2w_dy, flags);
+
+	set_colors_and_stipples (re);
+
+#ifdef OLD_XFORM
+	recalc_bounds (re);
+#endif
+}
+
+static void
+foo_canvas_re_realize (FooCanvasItem *item)
+{
+	FooCanvasRE *re;
+
+#ifdef VERBOSE
+	g_print ("foo_canvas_re_realize\n");
+#endif
+	re = FOO_CANVAS_RE (item);
+
+	if (re_parent_class->realize)
+		(* re_parent_class->realize) (item);
+
+	re->fill_gc = gdk_gc_new (item->canvas->layout.bin_window);
+	re->fill_pixel = foo_canvas_get_color_pixel (item->canvas, re->fill_color);
+	re->outline_gc = gdk_gc_new (item->canvas->layout.bin_window);
+	re->outline_pixel = foo_canvas_get_color_pixel (item->canvas, re->outline_color);
+	set_colors_and_stipples (re);
+
+#ifdef OLD_XFORM
+	(* FOO_CANVAS_ITEM_CLASS (item->object.klass)->update) (item, NULL, NULL, 0);
+#endif
+}
+
+static void
+foo_canvas_re_unrealize (FooCanvasItem *item)
+{
+	FooCanvasRE *re;
+
+	re = FOO_CANVAS_RE (item);
+
+	g_object_unref (re->fill_gc);
+	re->fill_gc = NULL;
+	g_object_unref (re->outline_gc);
+	re->outline_gc = NULL;
+
+	if (re_parent_class->unrealize)
+		(* re_parent_class->unrealize) (item);
+}
+
+static void
+foo_canvas_re_translate (FooCanvasItem *item, double dx, double dy)
+{
+	FooCanvasRE *re;
+
+#ifdef VERBOSE
+	g_print ("foo_canvas_re_translate\n");
+#endif
+	re = FOO_CANVAS_RE (item);
+
+	re->x1 += dx;
+	re->y1 += dy;
+	re->x2 += dx;
+	re->y2 += dy;
+}
+
+
+static void
+foo_canvas_re_bounds (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2)
+{
+	FooCanvasRE *re;
+	double hwidth;
+
+#ifdef VERBOSE
+	g_print ("foo_canvas_re_bounds\n");
+#endif
+	re = FOO_CANVAS_RE (item);
+
+	if (re->width_pixels)
+		hwidth = (re->width / item->canvas->pixels_per_unit) / 2.0;
+	else
+		hwidth = re->width / 2.0;
+
+	*x1 = re->x1 - hwidth;
+	*y1 = re->y1 - hwidth;
+	*x2 = re->x2 + hwidth;
+	*y2 = re->y2 + hwidth;
+}
+
+/* Rectangle item */
+
+
+static void foo_canvas_rect_class_init (FooCanvasRectClass *klass);
+static void foo_canvas_rect_init (FooCanvasRect *rect);
+static void foo_canvas_rect_finalize (GObject *object);
+static void foo_canvas_rect_realize  (FooCanvasItem *item);
+
+static void   foo_canvas_rect_draw   (FooCanvasItem *item, GdkDrawable *drawable, GdkEventExpose *expose);
+static double foo_canvas_rect_point  (FooCanvasItem *item, double x, double y, int cx, int cy,
+				        FooCanvasItem **actual_item);
+
+struct _FooCanvasRectPrivate {
+	Rect last_update_rect;
+	Rect last_outline_update_rect;
+	int last_outline_update_width;
+
+#ifdef HAVE_RENDER
+	gboolean use_render;
+	XRenderPictFormat *format;
+#endif
+};
+
+GType
+foo_canvas_rect_get_type (void)
+{
+	static GType rect_type = 0;
+
+	if (!rect_type) {
+		GTypeInfo rect_info = {
+		  sizeof (FooCanvasRectClass),
+		  (GBaseInitFunc) NULL,
+		  (GBaseFinalizeFunc) NULL,
+		  (GClassInitFunc) foo_canvas_rect_class_init,
+		  NULL,           /* class_finalize */
+		  NULL,           /* class_data */
+		  sizeof (FooCanvasRect),
+		  0,              /* n_preallocs */
+		  (GInstanceInitFunc) foo_canvas_rect_init
+		};
+
+		rect_type = g_type_register_static (foo_canvas_re_get_type (),
+						    "FooCanvasRect",
+						    &rect_info,
+						    0);
+	}
+
+	return rect_type;
+}
+
+static void
+foo_canvas_rect_class_init (FooCanvasRectClass *klass)
+{
+	FooCanvasItemClass *item_class;
+
+	rect_parent_class = g_type_class_peek_parent (klass);
+
+	item_class = (FooCanvasItemClass *) klass;
+
+	item_class->draw = foo_canvas_rect_draw;
+	item_class->point = foo_canvas_rect_point;
+	item_class->update = foo_canvas_rect_update;
+	item_class->realize = foo_canvas_rect_realize;
+
+	G_OBJECT_CLASS (klass)->finalize = foo_canvas_rect_finalize;
+	
+}
+
+static void
+foo_canvas_rect_init (FooCanvasRect *rect)
+{
+	rect->priv = g_new0 (FooCanvasRectPrivate, 1);
+}
+
+static void
+foo_canvas_rect_finalize (GObject *object)
+{
+	FooCanvasRect *rect = FOO_CANVAS_RECT (object);
+
+	if (rect->priv) {
+		g_free (rect->priv);
+	}
+
+	G_OBJECT_CLASS (rect_parent_class)->finalize (object);
+}
+
+static void
+foo_canvas_rect_realize  (FooCanvasItem *item)
+{
+#ifdef HAVE_RENDER
+	FooCanvasRectPrivate *priv;
+	int event_base, error_base;
+	Display *dpy;
+
+	priv = FOO_CANVAS_RECT (item)->priv;
+
+	dpy = gdk_x11_drawable_get_xdisplay (GTK_WIDGET (item->canvas)->window);
+	priv->use_render = XRenderQueryExtension (dpy, &event_base, &error_base);
+
+	if (priv->use_render) {
+		GdkVisual *gdk_visual;
+		Visual *visual;
+
+		gdk_visual = gtk_widget_get_visual (GTK_WIDGET (item->canvas));
+		visual = gdk_x11_visual_get_xvisual (gdk_visual);
+
+		priv->format = XRenderFindVisualFormat (dpy, visual);
+	}
+#endif
+	
+	if (FOO_CANVAS_ITEM_CLASS (rect_parent_class)->realize) {
+		(* FOO_CANVAS_ITEM_CLASS (rect_parent_class)->realize) (item);
+	}
+}
+
+
+static void
+render_rect_alpha (FooCanvasRect *rect,
+		   GdkDrawable *drawable,
+		   int x, int y,
+		   int width, int height,
+		   guint32 rgba)
+{
+	GdkPixbuf *pixbuf;
+	guchar *data;
+	int rowstride, i;
+	guchar r, g, b, a;
+	FooCanvasRectPrivate *priv;
+
+	if (width <= 0 || height <= 0 ) {
+		return;
+	}
+	
+	priv = rect->priv;
+
+	r = (rgba >> 24) & 0xff;
+	g = (rgba >> 16) & 0xff;
+	b = (rgba >> 8) & 0xff;
+	a = (rgba >> 0) & 0xff;
+
+#ifdef HAVE_RENDER
+	/* Every visual is not guaranteed to have a matching
+	 * XRenderPictFormat. So make sure that format is not null before
+	 * trying to render using Xrender calls.
+	 */
+	if (priv->use_render && (priv->format != NULL)) {
+		GdkDrawable *real_drawable;
+		int x_offset, y_offset;
+
+		Display *dpy;
+		Picture  pict;
+		XRenderPictureAttributes attributes;
+		XRenderColor color;
+
+		gdk_window_get_internal_paint_info (drawable, &real_drawable,
+						    &x_offset, &y_offset);
+
+		dpy = gdk_x11_drawable_get_xdisplay (real_drawable);
+
+		pict = XRenderCreatePicture (dpy,
+					     gdk_x11_drawable_get_xid (real_drawable),
+					     priv->format,
+					     0,
+					     &attributes);
+
+
+		/* Convert to premultiplied alpha: */
+		r = r * a / 255;
+		g = g * a / 255;
+		b = b * a / 255;
+		
+		color.red = (r << 8) + r;
+		color.green = (g << 8) + g;
+		color.blue = (b << 8) + b;
+		color.alpha = (a << 8) + a;
+		
+		XRenderFillRectangle (dpy,
+				      PictOpOver,
+				      pict,
+				      &color,
+				      x - x_offset, y - y_offset,
+				      width, height);
+		
+		XRenderFreePicture (dpy, pict);
+
+		return;
+	}
+#endif
+	pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, width, height);
+	data = gdk_pixbuf_get_pixels (pixbuf);
+	rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+	
+	r = (rgba >> 24) & 0xff;
+	g = (rgba >> 16) & 0xff;
+	b = (rgba >> 8) & 0xff;
+	a = (rgba >> 0) & 0xff;
+	
+	for (i = 0; i < width*4; ) {
+		data[i++] = r;
+		data[i++] = g;
+		data[i++] = b;
+		data[i++] = a;
+	}
+	
+	for (i = 1; i < height; i++) {
+		memcpy (data + i*rowstride, data, width*4);
+	}
+	
+	gdk_draw_pixbuf (drawable, NULL, pixbuf,
+			 0, 0, x, y, width, height,
+			 GDK_RGB_DITHER_NONE, 0, 0);
+	g_object_unref (pixbuf);
+}
+
+
+static void
+foo_canvas_rect_draw (FooCanvasItem *item, GdkDrawable *drawable, GdkEventExpose *expose)
+{
+	FooCanvasRE *re;
+	double x1, y1, x2, y2;
+	int cx1, cy1, cx2, cy2;
+	double i2w_dx, i2w_dy;
+
+	re = FOO_CANVAS_RE (item);
+
+	/* Get canvas pixel coordinates */
+	i2w_dx = 0.0;
+	i2w_dy = 0.0;
+	foo_canvas_item_i2w (item, &i2w_dx, &i2w_dy);
+	
+	x1 = re->x1 + i2w_dx;
+	y1 = re->y1 + i2w_dy;
+	x2 = re->x2 + i2w_dx;
+	y2 = re->y2 + i2w_dy;
+
+	foo_canvas_w2c (item->canvas, x1, y1, &cx1, &cy1);
+	foo_canvas_w2c (item->canvas, x2, y2, &cx2, &cy2);
+	
+	if (re->fill_set) {
+		if ((re->fill_color & 0xff) != 255) {
+			GdkRectangle *rectangles;
+			gint i, n_rectangles;
+			GdkRectangle draw_rect;
+			GdkRectangle part;
+
+			draw_rect.x = cx1;
+			draw_rect.y = cy1;
+			draw_rect.width = cx2 - cx1 + 1;
+			draw_rect.height = cy2 - cy1 + 1;
+			
+			/* For alpha mode, only render the parts of the region
+			   that are actually exposed */
+			gdk_region_get_rectangles (expose->region,
+						   &rectangles,
+						   &n_rectangles);
+
+			for (i = 0; i < n_rectangles; i++) {
+				if (gdk_rectangle_intersect (&rectangles[i],
+							     &draw_rect,
+							     &part)) {
+					render_rect_alpha (FOO_CANVAS_RECT (item),
+							   drawable,
+							   part.x, part.y,
+							   part.width, part.height,
+							   re->fill_color);
+				}
+			}
+			
+			g_free (rectangles);
+		} else {
+			if (re->fill_stipple)
+				foo_canvas_set_stipple_origin (item->canvas, re->fill_gc);
+
+			gdk_draw_rectangle (drawable,
+					    re->fill_gc,
+					    TRUE,
+					    cx1, cy1,
+					    cx2 - cx1 + 1,
+					    cy2 - cy1 + 1);
+		}
+	}
+
+	if (re->outline_set) {
+		if (re->outline_stipple)
+			foo_canvas_set_stipple_origin (item->canvas, re->outline_gc);
+
+		gdk_draw_rectangle (drawable,
+				    re->outline_gc,
+				    FALSE,
+				    cx1,
+				    cy1,
+				    cx2 - cx1,
+				    cy2 - cy1);
+	}
+}
+
+static double
+foo_canvas_rect_point (FooCanvasItem *item, double x, double y, int cx, int cy, FooCanvasItem **actual_item)
+{
+	FooCanvasRE *re;
+	double x1, y1, x2, y2;
+	double hwidth;
+	double dx, dy;
+	double tmp;
+
+#ifdef VERBOSE
+	g_print ("foo_canvas_rect_point\n");
+#endif
+	re = FOO_CANVAS_RE (item);
+
+	*actual_item = item;
+
+	/* Find the bounds for the rectangle plus its outline width */
+
+	x1 = re->x1;
+	y1 = re->y1;
+	x2 = re->x2;
+	y2 = re->y2;
+
+	if (re->outline_set) {
+		if (re->width_pixels)
+			hwidth = (re->width / item->canvas->pixels_per_unit) / 2.0;
+		else
+			hwidth = re->width / 2.0;
+
+		x1 -= hwidth;
+		y1 -= hwidth;
+		x2 += hwidth;
+		y2 += hwidth;
+	} else
+		hwidth = 0.0;
+
+	/* Is point inside rectangle (which can be hollow if it has no fill set)? */
+
+	if ((x >= x1) && (y >= y1) && (x <= x2) && (y <= y2)) {
+		if (re->fill_set || !re->outline_set)
+			return 0.0;
+
+		dx = x - x1;
+		tmp = x2 - x;
+		if (tmp < dx)
+			dx = tmp;
+
+		dy = y - y1;
+		tmp = y2 - y;
+		if (tmp < dy)
+			dy = tmp;
+
+		if (dy < dx)
+			dx = dy;
+
+		dx -= 2.0 * hwidth;
+
+		if (dx < 0.0)
+			return 0.0;
+		else
+			return dx;
+	}
+
+	/* Point is outside rectangle */
+
+	if (x < x1)
+		dx = x1 - x;
+	else if (x > x2)
+		dx = x - x2;
+	else
+		dx = 0.0;
+
+	if (y < y1)
+		dy = y1 - y;
+	else if (y > y2)
+		dy = y - y2;
+	else
+		dy = 0.0;
+
+	return sqrt (dx * dx + dy * dy);
+}
+
+static void
+request_redraw_borders (FooCanvas *canvas,
+			Rect     *update_rect,
+			int     width)
+{
+	foo_canvas_request_redraw (canvas,
+				   update_rect->x0, update_rect->y0,
+				   update_rect->x1, update_rect->y0 + width);
+	foo_canvas_request_redraw (canvas,
+				   update_rect->x0, update_rect->y1-width,
+				   update_rect->x1, update_rect->y1);
+	foo_canvas_request_redraw (canvas,
+				   update_rect->x0,       update_rect->y0,
+				   update_rect->x0+width, update_rect->y1);
+	foo_canvas_request_redraw (canvas,
+				   update_rect->x1-width, update_rect->y0,
+				   update_rect->x1,       update_rect->y1);
+}
+
+
+static void
+foo_canvas_rect_update (FooCanvasItem *item, double i2w_dx, double i2w_dy, gint flags)
+{
+	FooCanvasRE *re;
+	double x1, y1, x2, y2;
+	int cx1, cy1, cx2, cy2;
+	int repaint_rects_count, i;
+	int width_pixels;
+	int width_lt, width_rb;
+	Rect update_rect, repaint_rects[4];
+	FooCanvasRectPrivate *priv;
+
+	foo_canvas_re_update_shared (item, i2w_dx, i2w_dy, flags);
+
+	re = FOO_CANVAS_RE (item);
+	priv = FOO_CANVAS_RECT (item)->priv;
+	
+	x1 = re->x1 + i2w_dx;
+	y1 = re->y1 + i2w_dy;
+	x2 = re->x2 + i2w_dx;
+	y2 = re->y2 + i2w_dy;
+
+	foo_canvas_w2c (item->canvas, x1, y1, &cx1, &cy1);
+	foo_canvas_w2c (item->canvas, x2, y2, &cx2, &cy2);
+
+	update_rect = make_rect (cx1, cy1, cx2+1, cy2+1);
+#if 0
+	foo_canvas_request_redraw (item->canvas,
+				   update_rect.x0, update_rect.y0,
+				   update_rect.x1, update_rect.y1);
+	foo_canvas_request_redraw (item->canvas,
+				   priv->last_update_rect.x0, priv->last_update_rect.y0,
+				   priv->last_update_rect.x1, priv->last_update_rect.y1);
+#else
+	diff_rects (update_rect, priv->last_update_rect,
+		    &repaint_rects_count, repaint_rects);
+	for (i = 0; i < repaint_rects_count; i++) {
+		foo_canvas_request_redraw (item->canvas,
+					   repaint_rects[i].x0, repaint_rects[i].y0,
+					   repaint_rects[i].x1, repaint_rects[i].y1);
+	}
+#endif
+	priv->last_update_rect = update_rect;
+
+	if (re->outline_set) {
+		/* Outline and bounding box */
+		if (re->width_pixels)
+			width_pixels = (int) re->width;
+		else
+			width_pixels = (int) floor (re->width * re->item.canvas->pixels_per_unit + 0.5);
+
+		width_lt = width_pixels / 2;
+		width_rb = (width_pixels + 1) / 2;
+		
+		cx1 -= width_lt;
+		cy1 -= width_lt;
+		cx2 += width_rb;
+		cy2 += width_rb;
+
+		update_rect = make_rect (cx1, cy1, cx2, cy2);
+		request_redraw_borders (item->canvas, &update_rect,
+					(width_lt + width_rb));
+		request_redraw_borders (item->canvas, &priv->last_outline_update_rect,
+					priv->last_outline_update_width);
+		priv->last_outline_update_rect = update_rect;
+		priv->last_outline_update_width = width_lt + width_rb;
+		
+		item->x1 = cx1;
+		item->y1 = cy1;
+		item->x2 = cx2+1;
+		item->y2 = cy2+1;
+	} else {
+		item->x1 = cx1;
+		item->y1 = cy1;
+		item->x2 = cx2+1;
+		item->y2 = cy2+1;
+	}
+}
+
+/* Ellipse item */
+
+
+static void foo_canvas_ellipse_class_init (FooCanvasEllipseClass *klass);
+
+static void   foo_canvas_ellipse_draw   (FooCanvasItem *item, GdkDrawable *drawable, GdkEventExpose *expose);
+static double foo_canvas_ellipse_point  (FooCanvasItem *item, double x, double y, int cx, int cy,
+					   FooCanvasItem **actual_item);
+
+
+GType
+foo_canvas_ellipse_get_type (void)
+{
+	static GType ellipse_type = 0;
+
+	if (!ellipse_type) {
+		GTypeInfo ellipse_info = {
+		  sizeof (FooCanvasEllipseClass),
+		  (GBaseInitFunc) NULL,
+		  (GBaseFinalizeFunc) NULL,
+		  (GClassInitFunc) foo_canvas_ellipse_class_init,
+		  NULL,           /* class_finalize */
+		  NULL,           /* class_data */
+		  sizeof (FooCanvasEllipse),
+		  0,              /* n_preallocs */
+		  (GInstanceInitFunc) NULL
+
+		};
+
+		ellipse_type = g_type_register_static (foo_canvas_re_get_type (),
+						       "FooCanvasEllipse",
+						       &ellipse_info,
+						       0);
+	}
+
+	return ellipse_type;
+}
+
+static void
+foo_canvas_ellipse_class_init (FooCanvasEllipseClass *klass)
+{
+	FooCanvasItemClass *item_class;
+
+	item_class = (FooCanvasItemClass *) klass;
+
+	item_class->draw = foo_canvas_ellipse_draw;
+	item_class->point = foo_canvas_ellipse_point;
+	item_class->update = foo_canvas_ellipse_update;
+}
+
+static void
+foo_canvas_ellipse_draw (FooCanvasItem *item, GdkDrawable *drawable, GdkEventExpose *expose)
+{
+	FooCanvasRE *re;
+	int x1, y1, x2, y2;
+	double i2w_dx, i2w_dy;
+
+	re = FOO_CANVAS_RE (item);
+
+	/* Get canvas pixel coordinates */
+
+	i2w_dx = 0.0;
+	i2w_dy = 0.0;
+	foo_canvas_item_i2w (item, &i2w_dx, &i2w_dy);
+	
+	foo_canvas_w2c (item->canvas,
+			  re->x1 + i2w_dx,
+			  re->y1 + i2w_dy,
+			  &x1, &y1);
+	foo_canvas_w2c (item->canvas,
+			  re->x2 + i2w_dx,
+			  re->y2 + i2w_dy,
+			  &x2, &y2);
+
+	if (re->fill_set) {
+		if (re->fill_stipple)
+			foo_canvas_set_stipple_origin (item->canvas, re->fill_gc);
+
+		gdk_draw_arc (drawable,
+			      re->fill_gc,
+			      TRUE,
+			      x1,
+			      y1,
+			      x2 - x1,
+			      y2 - y1,
+			      0 * 64,
+			      360 * 64);
+	}
+
+	if (re->outline_set) {
+		if (re->outline_stipple)
+			foo_canvas_set_stipple_origin (item->canvas, re->outline_gc);
+
+		gdk_draw_arc (drawable,
+			      re->outline_gc,
+			      FALSE,
+			      x1,
+			      y1,
+			      x2 - x1,
+			      y2 - y1,
+			      0 * 64,
+			      360 * 64);
+	}
+}
+
+static double
+foo_canvas_ellipse_point (FooCanvasItem *item, double x, double y, int cx, int cy, FooCanvasItem **actual_item)
+{
+	FooCanvasRE *re;
+	double dx, dy;
+	double scaled_dist;
+	double outline_dist;
+	double center_dist;
+	double width;
+	double a, b;
+	double diamx, diamy;
+
+	re = FOO_CANVAS_RE (item);
+
+	*actual_item = item;
+
+	if (re->outline_set) {
+		if (re->width_pixels)
+			width = re->width / item->canvas->pixels_per_unit;
+		else
+			width = re->width;
+	} else
+		width = 0.0;
+
+	/* Compute the distance between the center of the ellipse and the point, with the ellipse
+	 * considered as being scaled to a circle.
+	 */
+
+	dx = x - (re->x1 + re->x2) / 2.0;
+	dy = y - (re->y1 + re->y2) / 2.0;
+	center_dist = sqrt (dx * dx + dy * dy);
+
+	a = dx / ((re->x2 + width - re->x1) / 2.0);
+	b = dy / ((re->y2 + width - re->y1) / 2.0);
+	scaled_dist = sqrt (a * a + b * b);
+
+	/* If the scaled distance is greater than 1, then we are outside.  Compute the distance from
+	 * the point to the edge of the circle, then scale back to the original un-scaled coordinate
+	 * system.
+	 */
+
+	if (scaled_dist > 1.0)
+		return (center_dist / scaled_dist) * (scaled_dist - 1.0);
+
+	/* We are inside the outer edge of the ellipse.  If it is filled, then we are "inside".
+	 * Otherwise, do the same computation as above, but also check whether we are inside the
+	 * outline.
+	 */
+
+	if (re->fill_set)
+		return 0.0;
+
+	if (scaled_dist > FOO_CANVAS_EPSILON)
+		outline_dist = (center_dist / scaled_dist) * (1.0 - scaled_dist) - width;
+	else {
+		/* Handle very small distance */
+
+		diamx = re->x2 - re->x1;
+		diamy = re->y2 - re->y1;
+
+		if (diamx < diamy)
+			outline_dist = (diamx - width) / 2.0;
+		else
+			outline_dist = (diamy - width) / 2.0;
+	}
+
+	if (outline_dist < 0.0)
+		return 0.0;
+
+	return outline_dist;
+}
+
+static void
+foo_canvas_ellipse_update (FooCanvasItem *item, double i2w_dx, double i2w_dy, gint flags)
+{
+	FooCanvasRE *re;
+	double x0, y0, x1, y1;
+
+#ifdef VERBOSE
+	g_print ("foo_canvas_sllipse_update item %x\n", item);
+#endif
+
+	foo_canvas_re_update_shared (item, i2w_dx, i2w_dy, flags);
+	re = FOO_CANVAS_RE (item);
+
+	get_bounds (re, &x0, &y0, &x1, &y1);
+	foo_canvas_update_bbox (item, x0, y0, x1, y1);
+}
+
+static int
+rect_empty (const Rect *src) {
+  return (src->x1 <= src->x0 || src->y1 <= src->y0);
+}
+
+static Rect
+make_rect (int x0, int y0, int x1, int y1)
+{
+	Rect r;
+
+	r.x0 = x0;
+	r.y0 = y0;
+	r.x1 = x1;
+	r.y1 = y1;
+	return r;
+}
+
+static gboolean
+rects_intersect (Rect r1, Rect r2)
+{
+	if (r1.x0 >= r2.x1) {
+		return FALSE;
+	}
+	if (r2.x0 >= r1.x1) {
+		return FALSE;
+	}
+	if (r1.y0 >= r2.y1) {
+		return FALSE;
+	}
+	if (r2.y0 >= r1.y1) {
+		return FALSE;
+	}
+	return TRUE;
+}
+
+static void
+diff_rects_guts (Rect ra, Rect rb, int *count, Rect result[4])
+{
+	if (ra.x0 < rb.x0) {
+		result[(*count)++] = make_rect (ra.x0, ra.y0, rb.x0, ra.y1);
+	}
+	if (ra.y0 < rb.y0) {
+		result[(*count)++] = make_rect (ra.x0, ra.y0, ra.x1, rb.y0);
+	}
+	if (ra.x1 < rb.x1) {
+		result[(*count)++] = make_rect (ra.x1, rb.y0, rb.x1, rb.y1);
+	}
+	if (ra.y1 < rb.y1) {
+		result[(*count)++] = make_rect (rb.x0, ra.y1, rb.x1, rb.y1);
+	}
+}
+
+static void
+diff_rects (Rect r1, Rect r2, int *count, Rect result[4])
+{
+	g_assert (count != NULL);
+	g_assert (result != NULL);
+
+	*count = 0;
+
+	if (rects_intersect (r1, r2)) {
+		diff_rects_guts (r1, r2, count, result);
+		diff_rects_guts (r2, r1, count, result);
+	} else {
+		if (!rect_empty (&r1)) {
+			result[(*count)++] = r1;
+		}
+		if (!rect_empty (&r2)) {
+			result[(*count)++] = r2;
+		}
+	}
+}
diff --git a/widgets/libfoocanvas/foo-canvas-rect-ellipse.h b/widgets/libfoocanvas/foo-canvas-rect-ellipse.h
new file mode 100644
index 0000000..5ee8a25
--- /dev/null
+++ b/widgets/libfoocanvas/foo-canvas-rect-ellipse.h
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * The Gnome Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+/* Rectangle and ellipse item types for FooCanvas widget
+ *
+ * FooCanvas is basically a port of the Tk toolkit's most excellent canvas widget.  Tk is
+ * copyrighted by the Regents of the University of California, Sun Microsystems, and other parties.
+ *
+ *
+ * Author: Federico Mena <federico nuclecu unam mx>
+ */
+
+#ifndef FOO_CANVAS_RECT_ELLIPSE_H
+#define FOO_CANVAS_RECT_ELLIPSE_H
+
+
+#include <libfoocanvas/foo-canvas.h>
+
+G_BEGIN_DECLS
+
+
+/* Base class for rectangle and ellipse item types.  These are defined by their top-left and
+ * bottom-right corners.  Rectangles and ellipses share the following arguments:
+ *
+ * name			type		read/write	description
+ * ------------------------------------------------------------------------------------------
+ * x1			double		RW		Leftmost coordinate of rectangle or ellipse
+ * y1			double		RW		Topmost coordinate of rectangle or ellipse
+ * x2			double		RW		Rightmost coordinate of rectangle or ellipse
+ * y2			double		RW		Bottommost coordinate of rectangle or ellipse
+ * fill_color		string		W		X color specification for fill color,
+ *							or NULL pointer for no color (transparent)
+ * fill_color_gdk	GdkColor*	RW		Allocated GdkColor for fill
+ * outline_color	string		W		X color specification for outline color,
+ *							or NULL pointer for no color (transparent)
+ * outline_color_gdk	GdkColor*	RW		Allocated GdkColor for outline
+ * fill_stipple		GdkBitmap*	RW		Stipple pattern for fill
+ * outline_stipple	GdkBitmap*	RW		Stipple pattern for outline
+ * width_pixels		uint		RW		Width of the outline in pixels.  The outline will
+ *							not be scaled when the canvas zoom factor is changed.
+ * width_units		double		RW		Width of the outline in canvas units.  The outline
+ *							will be scaled when the canvas zoom factor is changed.
+ */
+
+
+#define FOO_TYPE_CANVAS_RE            (foo_canvas_re_get_type ())
+#define FOO_CANVAS_RE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), FOO_TYPE_CANVAS_RE, FooCanvasRE))
+#define FOO_CANVAS_RE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), FOO_TYPE_CANVAS_RE, FooCanvasREClass))
+#define FOO_IS_CANVAS_RE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FOO_TYPE_CANVAS_RE))
+#define FOO_IS_CANVAS_RE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FOO_TYPE_CANVAS_RE))
+#define FOO_CANVAS_RE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), FOO_TYPE_CANVAS_RE, FooCanvasREClass))
+
+
+typedef struct _FooCanvasRE      FooCanvasRE;
+typedef struct _FooCanvasREClass FooCanvasREClass;
+
+struct _FooCanvasRE {
+	FooCanvasItem item;
+
+	GdkBitmap *fill_stipple;	/* Stipple for fill */
+	GdkBitmap *outline_stipple;	/* Stipple for outline */
+
+	GdkGC *fill_gc;			/* GC for filling */
+	GdkGC *outline_gc;		/* GC for outline */
+
+	gulong fill_pixel;		/* Fill color */
+	gulong outline_pixel;		/* Outline color */
+
+	double x1, y1, x2, y2;		/* Corners of item */
+	double width;			/* Outline width */
+
+	guint fill_color;		/* Fill color, RGBA */
+	guint outline_color;		/* Outline color, RGBA */
+
+	/* Configuration flags */
+
+	unsigned int fill_set : 1;	/* Is fill color set? */
+	unsigned int outline_set : 1;	/* Is outline color set? */
+	unsigned int width_pixels : 1;	/* Is outline width specified in pixels or units? */
+};
+
+struct _FooCanvasREClass {
+	FooCanvasItemClass parent_class;
+};
+
+
+/* Standard Gtk function */
+GType foo_canvas_re_get_type (void) G_GNUC_CONST;
+
+
+/* Rectangle item.  No configurable or queryable arguments are available (use those in
+ * FooCanvasRE).
+ */
+
+
+#define FOO_TYPE_CANVAS_RECT            (foo_canvas_rect_get_type ())
+#define FOO_CANVAS_RECT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), FOO_TYPE_CANVAS_RECT, FooCanvasRect))
+#define FOO_CANVAS_RECT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), FOO_TYPE_CANVAS_RECT, FooCanvasRectClass))
+#define FOO_IS_CANVAS_RECT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FOO_TYPE_CANVAS_RECT))
+#define FOO_IS_CANVAS_RECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FOO_TYPE_CANVAS_RECT))
+#define FOO_CANVAS_RECT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), FOO_TYPE_CANVAS_RECT, FooCanvasRectClass))
+
+
+typedef struct _FooCanvasRect FooCanvasRect;
+typedef struct _FooCanvasRectPrivate FooCanvasRectPrivate;
+typedef struct _FooCanvasRectClass FooCanvasRectClass;
+
+struct _FooCanvasRect {
+	FooCanvasRE re;
+	FooCanvasRectPrivate *priv;
+};
+
+struct _FooCanvasRectClass {
+	FooCanvasREClass parent_class;
+};
+
+
+/* Standard Gtk function */
+GType foo_canvas_rect_get_type (void) G_GNUC_CONST;
+
+
+/* Ellipse item.  No configurable or queryable arguments are available (use those in
+ * FooCanvasRE).
+ */
+
+
+#define FOO_TYPE_CANVAS_ELLIPSE            (foo_canvas_ellipse_get_type ())
+#define FOO_CANVAS_ELLIPSE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), FOO_TYPE_CANVAS_ELLIPSE, FooCanvasEllipse))
+#define FOO_CANVAS_ELLIPSE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), FOO_TYPE_CANVAS_ELLIPSE, FooCanvasEllipseClass))
+#define FOO_IS_CANVAS_ELLIPSE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FOO_TYPE_CANVAS_ELLIPSE))
+#define FOO_IS_CANVAS_ELLIPSE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FOO_TYPE_CANVAS_ELLIPSE))
+#define FOO_CANVAS_ELLIPSE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), FOO_TYPE_CANVAS_ELLIPSE, FooCanvasEllipseClass))
+
+
+typedef struct _FooCanvasEllipse FooCanvasEllipse;
+typedef struct _FooCanvasEllipseClass FooCanvasEllipseClass;
+
+struct _FooCanvasEllipse {
+	FooCanvasRE re;
+};
+
+struct _FooCanvasEllipseClass {
+	FooCanvasREClass parent_class;
+};
+
+
+/* Standard Gtk function */
+GType foo_canvas_ellipse_get_type (void) G_GNUC_CONST;
+
+
+G_END_DECLS
+
+#endif
diff --git a/widgets/libfoocanvas/foo-canvas-text.c b/widgets/libfoocanvas/foo-canvas-text.c
new file mode 100644
index 0000000..ca876db
--- /dev/null
+++ b/widgets/libfoocanvas/foo-canvas-text.c
@@ -0,0 +1,1587 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * $Id$
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * The Gnome Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+/* Text item type for FooCanvas widget
+ *
+ * FooCanvas is basically a port of the Tk toolkit's most excellent canvas
+ * widget.  Tk is copyrighted by the Regents of the University of California,
+ * Sun Microsystems, and other parties.
+ *
+ *
+ * Author: Federico Mena <federico nuclecu unam mx>
+ * Port to Pango co-done by Gergõ Érdi <cactus cactus rulez org>
+ */
+
+#include <config.h>
+#include <math.h>
+#include <string.h>
+#include "foo-canvas-text.h"
+
+#include "foo-canvas-util.h"
+#include "foo-canvas-i18n.h"
+
+
+
+/* Object argument IDs */
+enum {
+	PROP_0,
+
+	/* Text contents */
+	PROP_TEXT,
+	PROP_MARKUP,
+
+	/* Position */
+	PROP_X,
+	PROP_Y,
+
+	/* Font */
+	PROP_FONT,
+	PROP_FONT_DESC,
+	PROP_FAMILY, PROP_FAMILY_SET,
+
+	/* Style */
+	PROP_ATTRIBUTES,
+	PROP_STYLE,         PROP_STYLE_SET,
+	PROP_VARIANT,       PROP_VARIANT_SET,
+	PROP_WEIGHT,        PROP_WEIGHT_SET,
+	PROP_STRETCH,	    PROP_STRETCH_SET,
+	PROP_SIZE,          PROP_SIZE_SET,
+	PROP_SIZE_POINTS,
+	PROP_STRIKETHROUGH, PROP_STRIKETHROUGH_SET,
+	PROP_UNDERLINE,     PROP_UNDERLINE_SET,
+	PROP_RISE,          PROP_RISE_SET,
+	PROP_SCALE,         PROP_SCALE_SET,
+
+	/* Clipping */
+	PROP_ANCHOR,
+	PROP_JUSTIFICATION,
+	PROP_CLIP_WIDTH,
+	PROP_CLIP_HEIGHT,
+	PROP_CLIP,
+	PROP_WRAP_WIDTH,
+	PROP_X_OFFSET,
+	PROP_Y_OFFSET,
+
+	/* Coloring */
+	PROP_FILL_COLOR,
+	PROP_FILL_COLOR_GDK,
+	PROP_FILL_COLOR_RGBA,
+	PROP_FILL_STIPPLE,
+
+	/* Rendered size accessors */
+	PROP_TEXT_WIDTH,
+	PROP_TEXT_HEIGHT
+};
+
+struct _FooCanvasTextPrivate {
+	gint placeholder;
+};
+
+static void foo_canvas_text_class_init (FooCanvasTextClass *klass);
+static void foo_canvas_text_init (FooCanvasText *text);
+static void foo_canvas_text_destroy (GtkObject *object);
+static void foo_canvas_text_set_property (GObject            *object,
+					    guint               param_id,
+					    const GValue       *value,
+					    GParamSpec         *pspec);
+static void foo_canvas_text_get_property (GObject            *object,
+					    guint               param_id,
+					    GValue             *value,
+					    GParamSpec         *pspec);
+
+static void   foo_canvas_text_update    (FooCanvasItem  *item,
+					   double            i2w_dx,
+					   double            i2w_dy,
+					   int               flags);
+static void   foo_canvas_text_realize   (FooCanvasItem  *item);
+static void   foo_canvas_text_unrealize (FooCanvasItem  *item);
+static void   foo_canvas_text_draw      (FooCanvasItem  *item,
+					   GdkDrawable      *drawable,
+					   GdkEventExpose   *expose);
+static double foo_canvas_text_point     (FooCanvasItem  *item,
+					   double            x,
+					   double            y,
+					   int               cx,
+					   int               cy,
+					   FooCanvasItem **actual_item);
+static void   foo_canvas_text_translate (FooCanvasItem  *item,
+					   double            dx,
+					   double            dy);
+static void   foo_canvas_text_bounds    (FooCanvasItem  *item,
+					   double           *x1,
+					   double           *y1,
+					   double           *x2,
+					   double           *y2);
+
+static void foo_canvas_text_set_markup (FooCanvasText *textitem,
+					  const gchar     *markup);
+
+static void foo_canvas_text_set_font_desc    (FooCanvasText *textitem,
+					        PangoFontDescription *font_desc);
+
+static void foo_canvas_text_apply_font_desc  (FooCanvasText *textitem);
+static void foo_canvas_text_apply_attributes (FooCanvasText *textitem);
+
+static void add_attr (PangoAttrList  *attr_list,
+		      PangoAttribute *attr);
+
+static FooCanvasItemClass *parent_class;
+
+G_DEFINE_TYPE (FooCanvasText, foo_canvas_text, FOO_TYPE_CANVAS_ITEM)
+
+/* Class initialization function for the text item */
+static void
+foo_canvas_text_class_init (FooCanvasTextClass *klass)
+{
+	GObjectClass *gobject_class;
+	GtkObjectClass *object_class;
+	FooCanvasItemClass *item_class;
+
+	gobject_class = (GObjectClass *) klass;
+	object_class = (GtkObjectClass *) klass;
+	item_class = (FooCanvasItemClass *) klass;
+
+	parent_class = g_type_class_peek_parent (klass);
+
+	gobject_class->set_property = foo_canvas_text_set_property;
+	gobject_class->get_property = foo_canvas_text_get_property;
+
+	/* Text */
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_TEXT,
+                 g_param_spec_string ("text",
+				      _("Text"),
+				      _("Text to render"),
+                                      NULL,
+                                      G_PARAM_READWRITE));
+
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_MARKUP,
+                 g_param_spec_string ("markup",
+				      _("Markup"),
+				      _("Marked up text to render"),
+				      NULL,
+                                      (G_PARAM_WRITABLE)));
+
+	/* Position */
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_X,
+                 g_param_spec_double ("x", NULL, NULL,
+				      -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
+				      G_PARAM_READWRITE));
+
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_Y,
+                 g_param_spec_double ("y", NULL, NULL,
+				      -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
+				      G_PARAM_READWRITE));
+
+
+	/* Font */
+	g_object_class_install_property
+                (gobject_class,
+                 PROP_FONT,
+                 g_param_spec_string ("font",
+				      _("Font"),
+				      _("Font description as a string"),
+                                      NULL,
+                                      G_PARAM_READWRITE));
+
+        g_object_class_install_property
+		(gobject_class,
+		 PROP_FONT_DESC,
+		 g_param_spec_boxed ("font-desc",
+				     _("Font description"),
+				     _("Font description as a PangoFontDescription struct"),
+				     PANGO_TYPE_FONT_DESCRIPTION,
+				     G_PARAM_READWRITE));
+
+	g_object_class_install_property
+		(gobject_class,
+		 PROP_FAMILY,
+		 g_param_spec_string ("family",
+				      _("Font family"),
+				      _("Name of the font family, e.g. Sans, Helvetica, Times, Monospace"),
+				      NULL,
+				      G_PARAM_READWRITE));
+
+	/* Style */
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_ATTRIBUTES,
+                 g_param_spec_boxed ("attributes", NULL, NULL,
+				     PANGO_TYPE_ATTR_LIST,
+				     G_PARAM_READWRITE));
+
+	g_object_class_install_property
+		(gobject_class,
+		 PROP_STYLE,
+		 g_param_spec_enum ("style",
+				    _("Font style"),
+				    _("Font style"),
+				    PANGO_TYPE_STYLE,
+				    PANGO_STYLE_NORMAL,
+				    G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+	g_object_class_install_property
+		(gobject_class,
+		 PROP_VARIANT,
+		 g_param_spec_enum ("variant",
+				    _("Font variant"),
+				    _("Font variant"),
+				    PANGO_TYPE_VARIANT,
+				    PANGO_VARIANT_NORMAL,
+				    G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+	g_object_class_install_property
+		(gobject_class,
+		 PROP_WEIGHT,
+		 g_param_spec_int ("weight",
+				   _("Font weight"),
+				   _("Font weight"),
+				   0,
+				   G_MAXINT,
+				   PANGO_WEIGHT_NORMAL,
+				   G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+
+	g_object_class_install_property
+		(gobject_class,
+		 PROP_STRETCH,
+		 g_param_spec_enum ("stretch",
+				    _("Font stretch"),
+				    _("Font stretch"),
+				    PANGO_TYPE_STRETCH,
+				    PANGO_STRETCH_NORMAL,
+				    G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+	g_object_class_install_property
+		(gobject_class,
+		 PROP_SIZE,
+		 g_param_spec_int ("size",
+				   _("Font size"),
+				   _("Font size"),
+				   0,
+				   G_MAXINT,
+				   0,
+				   G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+	g_object_class_install_property
+		(gobject_class,
+		PROP_SIZE_POINTS,
+		g_param_spec_double ("size-points",
+				     _("Font points"),
+				     _("Font size in points"),
+				     0.0,
+				     G_MAXDOUBLE,
+				     0.0,
+				     G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+	g_object_class_install_property
+		(gobject_class,
+		 PROP_RISE,
+		 g_param_spec_int ("rise",
+				   _("Rise"),
+				   _("Offset of text above the baseline (below the baseline if rise is negative)"),
+				   -G_MAXINT,
+				   G_MAXINT,
+				   0,
+				   G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+	g_object_class_install_property
+		(gobject_class,
+		 PROP_STRIKETHROUGH,
+		 g_param_spec_boolean ("strikethrough",
+				       _("Strikethrough"),
+				       _("Whether to strike through the text"),
+				       FALSE,
+				       G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+	g_object_class_install_property
+		(gobject_class,
+		 PROP_UNDERLINE,
+		 g_param_spec_enum ("underline",
+				    _("Underline"),
+				    _("Style of underline for this text"),
+				    PANGO_TYPE_UNDERLINE,
+				    PANGO_UNDERLINE_NONE,
+				    G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+	g_object_class_install_property
+		(gobject_class,
+		 PROP_SCALE,
+		 g_param_spec_double ("scale",
+				      _("Scale"),
+				      _("Size of font, relative to default size"),
+				      0.0,
+				      G_MAXDOUBLE,
+				      1.0,
+				      G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+        g_object_class_install_property
+		(gobject_class,
+                 PROP_ANCHOR,
+                 g_param_spec_enum ("anchor", NULL, NULL,
+                                    GTK_TYPE_ANCHOR_TYPE,
+                                    GTK_ANCHOR_CENTER,
+                                    G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_JUSTIFICATION,
+                 g_param_spec_enum ("justification", NULL, NULL,
+                                    GTK_TYPE_JUSTIFICATION,
+                                    GTK_JUSTIFY_LEFT,
+                                    G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_CLIP_WIDTH,
+                 g_param_spec_double ("clip-width", NULL, NULL,
+				      -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
+				      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_CLIP_HEIGHT,
+                 g_param_spec_double ("clip-height", NULL, NULL,
+				      -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
+				      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_CLIP,
+                 g_param_spec_boolean ("clip", NULL, NULL,
+				       FALSE,
+				       G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_WRAP_WIDTH,
+                 g_param_spec_double ("wrap-width", NULL, NULL,
+				      -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
+				      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_X_OFFSET,
+                 g_param_spec_double ("x-offset", NULL, NULL,
+				      -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
+				      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_Y_OFFSET,
+                 g_param_spec_double ("y-offset", NULL, NULL,
+				      -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
+				      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_FILL_COLOR,
+                 g_param_spec_string ("fill-color",
+				      _("Color"),
+				      _("Text color, as string"),
+                                      NULL,
+                                      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_FILL_COLOR_GDK,
+                 g_param_spec_boxed ("fill-color-gdk",
+				     _("Color"),
+				     _("Text color, as a GdkColor"),
+				     GDK_TYPE_COLOR,
+				     G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_FILL_COLOR_RGBA,
+                 g_param_spec_uint ("fill-color-rgba",
+				    _("Color"),
+				    _("Text color, as an R/G/B/A combined integer"),
+				    0, G_MAXUINT, 0,
+				    G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_FILL_STIPPLE,
+                 g_param_spec_object ("fill-stipple", NULL, NULL,
+                                      GDK_TYPE_DRAWABLE,
+                                      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_TEXT_WIDTH,
+                 g_param_spec_double ("text-width",
+				      _("Text width"),
+				      _("Width of the rendered text"),
+				      0.0, G_MAXDOUBLE, 0.0,
+				      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_TEXT_HEIGHT,
+                 g_param_spec_double ("text-height",
+				      _("Text height"),
+				      _("Height of the rendered text"),
+				      0.0, G_MAXDOUBLE, 0.0,
+				      G_PARAM_READWRITE));
+
+	/* Style props are set (explicitly applied) or not */
+#define ADD_SET_PROP(propname, propval, nick, blurb) g_object_class_install_property (gobject_class, propval, g_param_spec_boolean (propname, nick, blurb, FALSE, G_PARAM_READABLE | G_PARAM_WRITABLE))
+
+	ADD_SET_PROP ("family-set", PROP_FAMILY_SET,
+		      _("Font family set"),
+		      _("Whether this tag affects the font family"));
+
+	ADD_SET_PROP ("style-set", PROP_STYLE_SET,
+		      _("Font style set"),
+		      _("Whether this tag affects the font style"));
+
+	ADD_SET_PROP ("variant-set", PROP_VARIANT_SET,
+		      _("Font variant set"),
+		      _("Whether this tag affects the font variant"));
+
+	ADD_SET_PROP ("weight-set", PROP_WEIGHT_SET,
+		      _("Font weight set"),
+		      _("Whether this tag affects the font weight"));
+
+	ADD_SET_PROP ("stretch-set", PROP_STRETCH_SET,
+		      _("Font stretch set"),
+		      _("Whether this tag affects the font stretch"));
+
+	ADD_SET_PROP ("size-set", PROP_SIZE_SET,
+		      _("Font size set"),
+		      _("Whether this tag affects the font size"));
+
+	ADD_SET_PROP ("rise-set", PROP_RISE_SET,
+		      _("Rise set"),
+		      _("Whether this tag affects the rise"));
+
+	ADD_SET_PROP ("strikethrough-set", PROP_STRIKETHROUGH_SET,
+		      _("Strikethrough set"),
+		      _("Whether this tag affects strikethrough"));
+
+	ADD_SET_PROP ("underline-set", PROP_UNDERLINE_SET,
+		      _("Underline set"),
+		      _("Whether this tag affects underlining"));
+
+	ADD_SET_PROP ("scale-set", PROP_SCALE_SET,
+		      _("Scale set"),
+		      _("Whether this tag affects font scaling"));
+#undef ADD_SET_PROP
+
+	object_class->destroy = foo_canvas_text_destroy;
+
+	item_class->update = foo_canvas_text_update;
+	item_class->realize = foo_canvas_text_realize;
+	item_class->unrealize = foo_canvas_text_unrealize;
+	item_class->draw = foo_canvas_text_draw;
+	item_class->point = foo_canvas_text_point;
+	item_class->translate = foo_canvas_text_translate;
+	item_class->bounds = foo_canvas_text_bounds;
+}
+
+/* Object initialization function for the text item */
+static void
+foo_canvas_text_init (FooCanvasText *text)
+{
+	text->x = 0.0;
+	text->y = 0.0;
+	text->anchor = GTK_ANCHOR_CENTER;
+	text->justification = GTK_JUSTIFY_LEFT;
+	text->clip_width = 0.0;
+	text->clip_height = 0.0;
+	text->xofs = 0.0;
+	text->yofs = 0.0;
+	text->layout = NULL;
+
+	text->font_desc = NULL;
+
+	text->underline     = PANGO_UNDERLINE_NONE;
+	text->strikethrough = FALSE;
+	text->rise          = 0;
+
+	text->underline_set = FALSE;
+	text->strike_set    = FALSE;
+	text->rise_set      = FALSE;
+
+	text->priv = g_new (FooCanvasTextPrivate, 1);
+}
+
+/* Destroy handler for the text item */
+static void
+foo_canvas_text_destroy (GtkObject *object)
+{
+	FooCanvasText *text;
+
+	g_return_if_fail (FOO_IS_CANVAS_TEXT (object));
+
+	text = FOO_CANVAS_TEXT (object);
+
+	/* remember, destroy can be run multiple times! */
+
+	g_free (text->text);
+	text->text = NULL;
+
+	if (text->layout)
+	    g_object_unref (G_OBJECT (text->layout));
+	text->layout = NULL;
+
+	if (text->font_desc) {
+		pango_font_description_free (text->font_desc);
+		text->font_desc = NULL;
+	}
+
+	if (text->attr_list)
+		pango_attr_list_unref (text->attr_list);
+	text->attr_list = NULL;
+
+	if (text->stipple)
+		g_object_unref (text->stipple);
+	text->stipple = NULL;
+
+	g_free (text->priv);
+	text->priv = NULL;
+
+	if (GTK_OBJECT_CLASS (parent_class)->destroy)
+		(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+get_bounds (FooCanvasText *text, double *px1, double *py1, double *px2, double *py2)
+{
+	FooCanvasItem *item;
+	double wx, wy;
+
+	item = FOO_CANVAS_ITEM (text);
+
+	/* Get canvas pixel coordinates for text position */
+
+
+	wx = text->x;
+	wy = text->y;
+	foo_canvas_item_i2w (item, &wx, &wy);
+	foo_canvas_w2c (item->canvas, wx + text->xofs, wy + text->yofs, &text->cx, &text->cy);
+
+	/* Get canvas pixel coordinates for clip rectangle position */
+
+	foo_canvas_w2c (item->canvas, wx, wy, &text->clip_cx, &text->clip_cy);
+	text->clip_cwidth = text->clip_width * item->canvas->pixels_per_unit;
+	text->clip_cheight = text->clip_height * item->canvas->pixels_per_unit;
+
+	/* Anchor text */
+
+	switch (text->anchor) {
+	case GTK_ANCHOR_NW:
+	case GTK_ANCHOR_W:
+	case GTK_ANCHOR_SW:
+		break;
+
+	case GTK_ANCHOR_N:
+	case GTK_ANCHOR_CENTER:
+	case GTK_ANCHOR_S:
+		text->cx -= text->max_width / 2;
+		text->clip_cx -= text->clip_cwidth / 2;
+		break;
+
+	case GTK_ANCHOR_NE:
+	case GTK_ANCHOR_E:
+	case GTK_ANCHOR_SE:
+		text->cx -= text->max_width;
+		text->clip_cx -= text->clip_cwidth;
+		break;
+
+	default:
+		break;
+	}
+
+	switch (text->anchor) {
+	case GTK_ANCHOR_NW:
+	case GTK_ANCHOR_N:
+	case GTK_ANCHOR_NE:
+		break;
+
+	case GTK_ANCHOR_W:
+	case GTK_ANCHOR_CENTER:
+	case GTK_ANCHOR_E:
+		text->cy -= text->height / 2;
+		text->clip_cy -= text->clip_cheight / 2;
+		break;
+
+	case GTK_ANCHOR_SW:
+	case GTK_ANCHOR_S:
+	case GTK_ANCHOR_SE:
+		text->cy -= text->height;
+		text->clip_cy -= text->clip_cheight;
+		break;
+
+	default:
+		break;
+	}
+
+	/* Bounds */
+
+	if (text->clip) {
+		*px1 = text->clip_cx;
+		*py1 = text->clip_cy;
+		*px2 = text->clip_cx + text->clip_cwidth;
+		*py2 = text->clip_cy + text->clip_cheight;
+	} else {
+		*px1 = text->cx;
+		*py1 = text->cy;
+		*px2 = text->cx + text->max_width;
+		*py2 = text->cy + text->height;
+	}
+}
+
+/* Convenience function to set the text's GC's foreground color */
+static void
+set_text_gc_foreground (FooCanvasText *text)
+{
+	GdkColor c;
+
+	if (!text->gc)
+		return;
+
+	c.pixel = text->pixel;
+	gdk_gc_set_foreground (text->gc, &c);
+}
+
+/* Sets the stipple pattern for the text */
+static void
+set_stipple (FooCanvasText *text, GdkBitmap *stipple, int reconfigure)
+{
+	if (text->stipple && !reconfigure)
+		g_object_unref (text->stipple);
+
+	text->stipple = stipple;
+	if (stipple && !reconfigure)
+		g_object_ref (stipple);
+
+	if (text->gc) {
+		if (stipple) {
+			gdk_gc_set_stipple (text->gc, stipple);
+			gdk_gc_set_fill (text->gc, GDK_STIPPLED);
+		} else
+			gdk_gc_set_fill (text->gc, GDK_SOLID);
+	}
+}
+
+static PangoFontMask
+get_property_font_set_mask (guint prop_id)
+{
+  switch (prop_id)
+    {
+    case PROP_FAMILY_SET:
+      return PANGO_FONT_MASK_FAMILY;
+    case PROP_STYLE_SET:
+      return PANGO_FONT_MASK_STYLE;
+    case PROP_VARIANT_SET:
+      return PANGO_FONT_MASK_VARIANT;
+    case PROP_WEIGHT_SET:
+      return PANGO_FONT_MASK_WEIGHT;
+    case PROP_STRETCH_SET:
+      return PANGO_FONT_MASK_STRETCH;
+    case PROP_SIZE_SET:
+      return PANGO_FONT_MASK_SIZE;
+    }
+
+  return 0;
+}
+
+static void
+ensure_font (FooCanvasText *text)
+{
+	if (!text->font_desc)
+		text->font_desc = pango_font_description_new ();
+}
+
+/* Set_arg handler for the text item */
+static void
+foo_canvas_text_set_property (GObject            *object,
+				guint               param_id,
+				const GValue       *value,
+				GParamSpec         *pspec)
+{
+	FooCanvasItem *item;
+	FooCanvasText *text;
+	GdkColor color = { 0, 0, 0, 0, };
+	GdkColor *pcolor;
+	gboolean color_changed;
+	int have_pixel;
+	PangoAlignment align;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (FOO_IS_CANVAS_TEXT (object));
+
+	item = FOO_CANVAS_ITEM (object);
+	text = FOO_CANVAS_TEXT (object);
+
+	color_changed = FALSE;
+	have_pixel = FALSE;
+
+
+	if (!text->layout) {
+		text->layout = gtk_widget_create_pango_layout  (GTK_WIDGET (item->canvas), NULL);
+	}
+
+	switch (param_id) {
+	case PROP_TEXT:
+		if (text->text)
+			g_free (text->text);
+
+		text->text = g_value_dup_string (value);
+		pango_layout_set_text (text->layout, text->text, -1);
+
+		break;
+
+	case PROP_MARKUP:
+		foo_canvas_text_set_markup (text,
+					      g_value_get_string (value));
+		break;
+
+	case PROP_X:
+		text->x = g_value_get_double (value);
+		break;
+
+	case PROP_Y:
+		text->y = g_value_get_double (value);
+		break;
+
+	case PROP_FONT: {
+		const char *font_name;
+		PangoFontDescription *font_desc;
+
+		font_name = g_value_get_string (value);
+		if (font_name)
+			font_desc = pango_font_description_from_string (font_name);
+		else
+			font_desc = NULL;
+
+		foo_canvas_text_set_font_desc (text, font_desc);
+		if (font_desc)
+			pango_font_description_free (font_desc);
+
+		break;
+	}
+
+	case PROP_FONT_DESC:
+		foo_canvas_text_set_font_desc (text, g_value_peek_pointer (value));
+		break;
+
+	case PROP_FAMILY:
+	case PROP_STYLE:
+	case PROP_VARIANT:
+	case PROP_WEIGHT:
+	case PROP_STRETCH:
+	case PROP_SIZE:
+	case PROP_SIZE_POINTS:
+		ensure_font (text);
+
+		switch (param_id) {
+		case PROP_FAMILY:
+			pango_font_description_set_family (text->font_desc,
+							   g_value_get_string (value));
+			break;
+		case PROP_STYLE:
+			pango_font_description_set_style (text->font_desc,
+							  g_value_get_enum (value));
+			break;
+		case PROP_VARIANT:
+			pango_font_description_set_variant (text->font_desc,
+							    g_value_get_enum (value));
+			break;
+		case PROP_WEIGHT:
+			pango_font_description_set_weight (text->font_desc,
+							   g_value_get_int (value));
+			break;
+		case PROP_STRETCH:
+			pango_font_description_set_stretch (text->font_desc,
+							    g_value_get_enum (value));
+			break;
+		case PROP_SIZE:
+			/* FIXME: This is bogus! It should be pixels, not points/PANGO_SCALE! */
+			pango_font_description_set_size (text->font_desc,
+							 g_value_get_int (value));
+			break;
+		case PROP_SIZE_POINTS:
+			pango_font_description_set_size (text->font_desc,
+							 g_value_get_double (value) * PANGO_SCALE);
+			break;
+		}
+
+		foo_canvas_text_apply_font_desc (text);
+		break;
+
+	case PROP_FAMILY_SET:
+	case PROP_STYLE_SET:
+	case PROP_VARIANT_SET:
+	case PROP_WEIGHT_SET:
+	case PROP_STRETCH_SET:
+	case PROP_SIZE_SET:
+		if (!g_value_get_boolean (value) && text->font_desc)
+			pango_font_description_unset_fields (text->font_desc,
+							     get_property_font_set_mask (param_id));
+		break;
+
+	case PROP_SCALE:
+		text->scale = g_value_get_double (value);
+		text->scale_set = TRUE;
+
+		foo_canvas_text_apply_font_desc (text);
+		break;
+
+	case PROP_SCALE_SET:
+		text->scale_set = g_value_get_boolean (value);
+
+		foo_canvas_text_apply_font_desc (text);
+		break;
+
+	case PROP_UNDERLINE:
+		text->underline = g_value_get_enum (value);
+		text->underline_set = TRUE;
+
+		foo_canvas_text_apply_attributes (text);
+		break;
+
+	case PROP_UNDERLINE_SET:
+		text->underline_set = g_value_get_boolean (value);
+
+		foo_canvas_text_apply_attributes (text);
+		break;
+
+	case PROP_STRIKETHROUGH:
+		text->strikethrough = g_value_get_boolean (value);
+		text->strike_set = TRUE;
+
+		foo_canvas_text_apply_attributes (text);
+		break;
+
+	case PROP_STRIKETHROUGH_SET:
+		text->strike_set = g_value_get_boolean (value);
+
+		foo_canvas_text_apply_attributes (text);
+		break;
+
+	case PROP_RISE:
+		text->rise = g_value_get_int (value);
+		text->rise_set = TRUE;
+
+		foo_canvas_text_apply_attributes (text);
+		break;
+
+	case PROP_RISE_SET:
+		text->rise_set = TRUE;
+
+		foo_canvas_text_apply_attributes (text);
+		break;
+
+	case PROP_ATTRIBUTES:
+		if (text->attr_list)
+			pango_attr_list_unref (text->attr_list);
+
+		text->attr_list = g_value_peek_pointer (value);
+		if (text->attr_list)
+			pango_attr_list_ref (text->attr_list);
+
+		foo_canvas_text_apply_attributes (text);
+		break;
+
+	case PROP_ANCHOR:
+		text->anchor = g_value_get_enum (value);
+		break;
+
+	case PROP_JUSTIFICATION:
+		text->justification = g_value_get_enum (value);
+
+		switch (text->justification) {
+		case GTK_JUSTIFY_LEFT:
+		        align = PANGO_ALIGN_LEFT;
+			break;
+		case GTK_JUSTIFY_CENTER:
+		        align = PANGO_ALIGN_CENTER;
+			break;
+		case GTK_JUSTIFY_RIGHT:
+		        align = PANGO_ALIGN_RIGHT;
+			break;
+		default:
+		        /* GTK_JUSTIFY_FILL isn't supported yet. */
+		        align = PANGO_ALIGN_LEFT;
+			break;
+		}
+		pango_layout_set_alignment (text->layout, align);
+		break;
+
+	case PROP_CLIP_WIDTH:
+		text->clip_width = fabs (g_value_get_double (value));
+		break;
+
+	case PROP_CLIP_HEIGHT:
+		text->clip_height = fabs (g_value_get_double (value));
+		break;
+
+	case PROP_CLIP:
+		text->clip = g_value_get_boolean (value);
+		break;
+
+	case PROP_WRAP_WIDTH: {
+		double w = fabs (g_value_get_double (value));
+		pango_layout_set_width (text->layout,
+			w * text->item.canvas->pixels_per_unit * PANGO_SCALE);
+
+		break;
+	}
+
+	case PROP_X_OFFSET:
+		text->xofs = g_value_get_double (value);
+		break;
+
+	case PROP_Y_OFFSET:
+		text->yofs = g_value_get_double (value);
+		break;
+
+        case PROP_FILL_COLOR: {
+		const char *color_name;
+
+		color_name = g_value_get_string (value);
+		if (color_name) {
+			gdk_color_parse (color_name, &color);
+
+			text->rgba = ((color.red & 0xff00) << 16 |
+				      (color.green & 0xff00) << 8 |
+				      (color.blue & 0xff00) |
+				      0xff);
+			color_changed = TRUE;
+		}
+		break;
+	}
+
+	case PROP_FILL_COLOR_GDK:
+		pcolor = g_value_get_boxed (value);
+		if (pcolor) {
+		    GdkColormap *colormap;
+
+		    color = *pcolor;
+		    colormap = gtk_widget_get_colormap (GTK_WIDGET (item->canvas));
+		    gdk_rgb_find_color (colormap, &color);
+		    have_pixel = TRUE;
+		}
+
+		text->rgba = ((color.red & 0xff00) << 16 |
+			      (color.green & 0xff00) << 8|
+			      (color.blue & 0xff00) |
+			      0xff);
+		color_changed = TRUE;
+		break;
+
+        case PROP_FILL_COLOR_RGBA:
+		text->rgba = g_value_get_uint (value);
+		color_changed = TRUE;
+		break;
+
+	case PROP_FILL_STIPPLE:
+		set_stipple (text, (GdkBitmap *)g_value_get_object (value), FALSE);
+		break;
+
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	}
+
+	if (color_changed) {
+		if (have_pixel)
+			text->pixel = color.pixel;
+		else
+			text->pixel = foo_canvas_get_color_pixel (item->canvas, text->rgba);
+
+		set_text_gc_foreground (text);
+	}
+
+	/* Calculate text dimensions */
+
+	if (text->layout)
+	        pango_layout_get_pixel_size (text->layout,
+					     &text->max_width,
+					     &text->height);
+	else {
+		text->max_width = 0;
+		text->height = 0;
+	}
+
+	foo_canvas_item_request_update (item);
+}
+
+/* Get_arg handler for the text item */
+static void
+foo_canvas_text_get_property (GObject            *object,
+				guint               param_id,
+				GValue             *value,
+				GParamSpec         *pspec)
+{
+	FooCanvasText *text;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (FOO_IS_CANVAS_TEXT (object));
+
+	text = FOO_CANVAS_TEXT (object);
+
+	switch (param_id) {
+	case PROP_TEXT:
+		g_value_set_string (value, text->text);
+		break;
+
+	case PROP_X:
+		g_value_set_double (value, text->x);
+		break;
+
+	case PROP_Y:
+		g_value_set_double (value, text->y);
+		break;
+
+	case PROP_FONT:
+	case PROP_FONT_DESC:
+	case PROP_FAMILY:
+	case PROP_STYLE:
+	case PROP_VARIANT:
+	case PROP_WEIGHT:
+	case PROP_STRETCH:
+	case PROP_SIZE:
+	case PROP_SIZE_POINTS:
+		ensure_font (text);
+
+		switch (param_id) {
+		case PROP_FONT:
+		{
+			/* FIXME GValue imposes a totally gratuitous string copy
+			 * here, we could just hand off string ownership
+			 */
+			gchar *str;
+
+			str = pango_font_description_to_string (text->font_desc);
+			g_value_set_string (value, str);
+			g_free (str);
+
+			break;
+		}
+
+		case PROP_FONT_DESC:
+			g_value_set_boxed (value, text->font_desc);
+			break;
+
+		case PROP_FAMILY:
+			g_value_set_string (value, pango_font_description_get_family (text->font_desc));
+			break;
+
+		case PROP_STYLE:
+			g_value_set_enum (value, pango_font_description_get_style (text->font_desc));
+			break;
+
+		case PROP_VARIANT:
+			g_value_set_enum (value, pango_font_description_get_variant (text->font_desc));
+			break;
+
+		case PROP_WEIGHT:
+			g_value_set_int (value, pango_font_description_get_weight (text->font_desc));
+			break;
+
+		case PROP_STRETCH:
+			g_value_set_enum (value, pango_font_description_get_stretch (text->font_desc));
+			break;
+
+		case PROP_SIZE:
+			g_value_set_int (value, pango_font_description_get_size (text->font_desc));
+			break;
+
+		case PROP_SIZE_POINTS:
+			g_value_set_double (value, ((double)pango_font_description_get_size (text->font_desc)) / (double)PANGO_SCALE);
+			break;
+		}
+		break;
+
+	case PROP_FAMILY_SET:
+	case PROP_STYLE_SET:
+	case PROP_VARIANT_SET:
+	case PROP_WEIGHT_SET:
+	case PROP_STRETCH_SET:
+	case PROP_SIZE_SET:
+	{
+		PangoFontMask set_mask = text->font_desc ? pango_font_description_get_set_fields (text->font_desc) : 0;
+		PangoFontMask test_mask = get_property_font_set_mask (param_id);
+		g_value_set_boolean (value, (set_mask & test_mask) != 0);
+
+		break;
+	}
+
+	case PROP_SCALE:
+		g_value_set_double (value, text->scale);
+		break;
+	case PROP_SCALE_SET:
+		g_value_set_boolean (value, text->scale_set);
+		break;
+
+	case PROP_UNDERLINE:
+		g_value_set_enum (value, text->underline);
+		break;
+	case PROP_UNDERLINE_SET:
+		g_value_set_boolean (value, text->underline_set);
+		break;
+
+	case PROP_STRIKETHROUGH:
+		g_value_set_boolean (value, text->strikethrough);
+		break;
+	case PROP_STRIKETHROUGH_SET:
+		g_value_set_boolean (value, text->strike_set);
+		break;
+
+	case PROP_RISE:
+		g_value_set_int (value, text->rise);
+		break;
+	case PROP_RISE_SET:
+		g_value_set_boolean (value, text->rise_set);
+		break;
+
+	case PROP_ATTRIBUTES:
+		g_value_set_boxed (value, text->attr_list);
+		break;
+
+	case PROP_ANCHOR:
+		g_value_set_enum (value, text->anchor);
+		break;
+
+	case PROP_JUSTIFICATION:
+		g_value_set_enum (value, text->justification);
+		break;
+
+	case PROP_CLIP_WIDTH:
+		g_value_set_double (value, text->clip_width);
+		break;
+
+	case PROP_CLIP_HEIGHT:
+		g_value_set_double (value, text->clip_height);
+		break;
+
+	case PROP_CLIP:
+		g_value_set_boolean (value, text->clip);
+		break;
+
+	case PROP_WRAP_WIDTH:
+		g_value_set_double (value,
+			pango_layout_get_width (text->layout) / PANGO_SCALE);
+		break;
+
+	case PROP_X_OFFSET:
+		g_value_set_double (value, text->xofs);
+		break;
+
+	case PROP_Y_OFFSET:
+		g_value_set_double (value, text->yofs);
+		break;
+
+	case PROP_FILL_COLOR:
+                g_value_take_string (value,
+				     g_strdup_printf ("#%02x%02x%02x",
+						      text->rgba >> 24,
+						      (text->rgba >> 16) & 0xff,
+						      (text->rgba >> 8) & 0xff));
+		break;
+
+	case PROP_FILL_COLOR_GDK: {
+		FooCanvas *canvas = FOO_CANVAS_ITEM (text)->canvas;
+		GdkColormap *colormap = gtk_widget_get_colormap (GTK_WIDGET (canvas));
+		GdkColor color;
+
+		gdk_colormap_query_color (colormap, text->pixel, &color);
+		g_value_set_boxed (value, &color);
+		break;
+	}
+	case PROP_FILL_COLOR_RGBA:
+		g_value_set_uint (value, text->rgba);
+		break;
+
+	case PROP_FILL_STIPPLE:
+		g_value_set_object (value, text->stipple);
+		break;
+
+	case PROP_TEXT_WIDTH:
+		g_value_set_double (value, text->max_width / text->item.canvas->pixels_per_unit);
+		break;
+
+	case PROP_TEXT_HEIGHT:
+		g_value_set_double (value, text->height / text->item.canvas->pixels_per_unit);
+		break;
+
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	}
+}
+
+/* */
+static void
+foo_canvas_text_apply_font_desc (FooCanvasText *text)
+{
+	PangoFontDescription *font_desc =
+		pango_font_description_copy (
+			GTK_WIDGET (FOO_CANVAS_ITEM (text)->canvas)->style->font_desc);
+
+	if (text->font_desc)
+		pango_font_description_merge (font_desc, text->font_desc, TRUE);
+
+	pango_layout_set_font_description (text->layout, font_desc);
+	pango_font_description_free (font_desc);
+}
+
+static void
+add_attr (PangoAttrList  *attr_list,
+	  PangoAttribute *attr)
+{
+	attr->start_index = 0;
+	attr->end_index = G_MAXINT;
+
+	pango_attr_list_insert (attr_list, attr);
+}
+
+/* */
+static void
+foo_canvas_text_apply_attributes (FooCanvasText *text)
+{
+	PangoAttrList *attr_list;
+	double zoom;
+
+	if (text->attr_list)
+		attr_list = pango_attr_list_copy (text->attr_list);
+	else
+		attr_list = pango_attr_list_new ();
+
+	if (text->underline_set)
+		add_attr (attr_list, pango_attr_underline_new (text->underline));
+	if (text->strike_set)
+		add_attr (attr_list, pango_attr_strikethrough_new (text->strikethrough));
+	if (text->rise_set)
+		add_attr (attr_list, pango_attr_rise_new (text->rise));
+
+	zoom = text->item.canvas->pixels_per_unit;
+	if (fabs (zoom - 1.) > 1e-4) {
+		PangoAttribute *attr = pango_attr_scale_new (zoom);
+		attr->start_index = 0;
+		attr->end_index = -1;
+		pango_attr_list_insert_before (attr_list, attr);
+	}
+
+	pango_layout_set_attributes (text->layout, attr_list);
+	pango_attr_list_unref (attr_list);
+}
+
+static void
+foo_canvas_text_set_font_desc (FooCanvasText      *text,
+				 PangoFontDescription *font_desc)
+{
+	if (text->font_desc)
+		pango_font_description_free (text->font_desc);
+
+	if (font_desc)
+		text->font_desc = pango_font_description_copy (font_desc);
+	else
+		text->font_desc = NULL;
+
+	foo_canvas_text_apply_font_desc (text);
+}
+
+/* Setting the text from a Pango markup string */
+static void
+foo_canvas_text_set_markup (FooCanvasText *textitem,
+			      const gchar     *markup)
+{
+	PangoAttrList *attr_list = NULL;
+	gchar         *text = NULL;
+	GError        *error = NULL;
+
+	if (textitem->text)
+		g_free (textitem->text);
+	if (textitem->attr_list)
+		pango_attr_list_unref (textitem->attr_list);
+
+	if (markup && !pango_parse_markup (markup, -1,
+					   0,
+					   &attr_list, &text, NULL,
+					   &error))
+	{
+		g_warning ("Failed to set cell text from markup due to error parsing markup: %s",
+			   error->message);
+		g_error_free (error);
+		return;
+	}
+
+	textitem->text = text;
+	textitem->attr_list = attr_list;
+
+	pango_layout_set_text (textitem->layout, text, -1);
+
+	foo_canvas_text_apply_attributes (textitem);
+}
+
+/* Update handler for the text item */
+static void
+foo_canvas_text_update (FooCanvasItem *item, double i2w_dx, double i2w_dy, int flags)
+{
+	FooCanvasText *text;
+	double x1, y1, x2, y2;
+
+	text = FOO_CANVAS_TEXT (item);
+
+	if (parent_class->update)
+		(* parent_class->update) (item, i2w_dx, i2w_dy, flags);
+
+	set_text_gc_foreground (text);
+	set_stipple (text, text->stipple, TRUE);
+	get_bounds (text, &x1, &y1, &x2, &y2);
+
+	foo_canvas_update_bbox (item,
+				floor (x1+.5), floor (y1+.5),
+				floor (x2+.5), floor (y2+.5));
+}
+
+/* Realize handler for the text item */
+static void
+foo_canvas_text_realize (FooCanvasItem *item)
+{
+	FooCanvasText *text;
+
+	text = FOO_CANVAS_TEXT (item);
+
+	if (parent_class->realize)
+		(* parent_class->realize) (item);
+
+	text->gc = gdk_gc_new (item->canvas->layout.bin_window);
+}
+
+/* Unrealize handler for the text item */
+static void
+foo_canvas_text_unrealize (FooCanvasItem *item)
+{
+	FooCanvasText *text;
+
+	text = FOO_CANVAS_TEXT (item);
+
+	g_object_unref (text->gc);
+	text->gc = NULL;
+
+	if (parent_class->unrealize)
+		(* parent_class->unrealize) (item);
+}
+
+/* Draw handler for the text item */
+static void
+foo_canvas_text_draw (FooCanvasItem *item, GdkDrawable *drawable,
+			GdkEventExpose   *expose)
+{
+	FooCanvasText *text;
+	GdkRectangle rect;
+
+	text = FOO_CANVAS_TEXT (item);
+
+	if (!text->text)
+		return;
+
+	if (text->clip) {
+		rect.x = text->clip_cx;
+		rect.y = text->clip_cy;
+		rect.width = text->clip_cwidth;
+		rect.height = text->clip_cheight;
+
+		gdk_gc_set_clip_rectangle (text->gc, &rect);
+	}
+
+	if (text->stipple)
+		foo_canvas_set_stipple_origin (item->canvas, text->gc);
+
+
+	gdk_draw_layout (drawable, text->gc, text->cx, text->cy, text->layout);
+
+	if (text->clip)
+		gdk_gc_set_clip_rectangle (text->gc, NULL);
+}
+
+/* Point handler for the text item */
+static double
+foo_canvas_text_point (FooCanvasItem *item, double x, double y,
+			 int cx, int cy, FooCanvasItem **actual_item)
+{
+	FooCanvasText *text;
+	PangoLayoutIter *iter;
+	int x1, y1, x2, y2;
+	int dx, dy;
+	double dist, best;
+
+	text = FOO_CANVAS_TEXT (item);
+
+	*actual_item = item;
+
+	/* The idea is to build bounding rectangles for each of the lines of
+	 * text (clipped by the clipping rectangle, if it is activated) and see
+	 * whether the point is inside any of these.  If it is, we are done.
+	 * Otherwise, calculate the distance to the nearest rectangle.
+	 */
+
+	best = 1.0e36;
+
+	iter = pango_layout_get_iter (text->layout);
+	do {
+ 	        PangoRectangle log_rect;
+
+		pango_layout_iter_get_line_extents (iter, NULL, &log_rect);
+
+		if (text->clip) {
+			x1 = PANGO_PIXELS (log_rect.x);
+			y1 = PANGO_PIXELS (log_rect.y);
+			x2 = PANGO_PIXELS (log_rect.x+log_rect.width);
+			y2 = PANGO_PIXELS (log_rect.y+log_rect.height);
+
+
+			if (x1 < text->clip_cx)
+				x1 = text->clip_cx;
+
+			if (y1 < text->clip_cy)
+				y1 = text->clip_cy;
+
+			if (x2 > (text->clip_cx + text->clip_width))
+				x2 = text->clip_cx + text->clip_width;
+
+			if (y2 > (text->clip_cy + text->clip_height))
+				y2 = text->clip_cy + text->clip_height;
+
+			if ((x1 >= x2) || (y1 >= y2))
+				continue;
+		} else {
+			x1 = text->x;
+			y1 = text->y;
+			x2 = log_rect.width;
+			y2 = log_rect.height;
+		}
+
+		/* Calculate distance from point to rectangle */
+
+		if (cx < x1)
+			dx = x1 - cx;
+		else if (cx >= x2)
+			dx = cx - x2 + 1;
+		else
+			dx = 0;
+
+		if (cy < y1)
+			dy = y1 - cy;
+		else if (cy >= y2)
+			dy = cy - y2 + 1;
+		else
+			dy = 0;
+
+		if ((dx == 0) && (dy == 0)) {
+			pango_layout_iter_free(iter);
+			return 0.0;
+		}
+
+		dist = sqrt (dx * dx + dy * dy);
+		if (dist < best)
+			best = dist;
+
+	} while (pango_layout_iter_next_line(iter));
+
+	pango_layout_iter_free(iter);
+
+	return best / item->canvas->pixels_per_unit;
+}
+
+static void
+foo_canvas_text_translate (FooCanvasItem *item, double dx, double dy)
+{
+	FooCanvasText *text;
+
+	text = FOO_CANVAS_TEXT (item);
+
+	text->x += dx;
+	text->y += dy;
+}
+
+/* Bounds handler for the text item */
+static void
+foo_canvas_text_bounds (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2)
+{
+	FooCanvasText *text;
+	double width, height;
+
+	text = FOO_CANVAS_TEXT (item);
+
+	*x1 = text->x;
+	*y1 = text->y;
+
+	if (text->clip) {
+		width = text->clip_width;
+		height = text->clip_height;
+	} else {
+		width = text->max_width / item->canvas->pixels_per_unit;
+		height = text->height / item->canvas->pixels_per_unit;
+	}
+
+	switch (text->anchor) {
+	case GTK_ANCHOR_NW:
+	case GTK_ANCHOR_W:
+	case GTK_ANCHOR_SW:
+		break;
+
+	case GTK_ANCHOR_N:
+	case GTK_ANCHOR_CENTER:
+	case GTK_ANCHOR_S:
+		*x1 -= width / 2.0;
+		break;
+
+	case GTK_ANCHOR_NE:
+	case GTK_ANCHOR_E:
+	case GTK_ANCHOR_SE:
+		*x1 -= width;
+		break;
+
+	default:
+		break;
+	}
+
+	switch (text->anchor) {
+	case GTK_ANCHOR_NW:
+	case GTK_ANCHOR_N:
+	case GTK_ANCHOR_NE:
+		break;
+
+	case GTK_ANCHOR_W:
+	case GTK_ANCHOR_CENTER:
+	case GTK_ANCHOR_E:
+		*y1 -= height / 2.0;
+		break;
+
+	case GTK_ANCHOR_SW:
+	case GTK_ANCHOR_S:
+	case GTK_ANCHOR_SE:
+		*y1 -= height;
+		break;
+
+	default:
+		break;
+	}
+
+	*x2 = *x1 + width;
+	*y2 = *y1 + height;
+}
diff --git a/widgets/libfoocanvas/foo-canvas-text.h b/widgets/libfoocanvas/foo-canvas-text.h
new file mode 100644
index 0000000..571c642
--- /dev/null
+++ b/widgets/libfoocanvas/foo-canvas-text.h
@@ -0,0 +1,168 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * The Gnome Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+/* Text item type for FooCanvas widget
+ *
+ * FooCanvas is basically a port of the Tk toolkit's most excellent canvas widget.  Tk is
+ * copyrighted by the Regents of the University of California, Sun Microsystems, and other parties.
+ *
+ *
+ * Author: Federico Mena <federico nuclecu unam mx>
+ * Port to Pango co-done by Gergõ Érdi <cactus cactus rulez org>
+ */
+
+#ifndef FOO_CANVAS_TEXT_H
+#define FOO_CANVAS_TEXT_H
+
+
+#include <libfoocanvas/foo-canvas.h>
+
+
+G_BEGIN_DECLS
+
+
+/* Text item for the canvas.  Text items are positioned by an anchor point and an anchor direction.
+ *
+ * A clipping rectangle may be specified for the text.  The rectangle is anchored at the text's anchor
+ * point, and is specified by clipping width and height parameters.  If the clipping rectangle is
+ * enabled, it will clip the text.
+ *
+ * In addition, x and y offset values may be specified.  These specify an offset from the anchor
+ * position.  If used in conjunction with the clipping rectangle, these could be used to implement
+ * simple scrolling of the text within the clipping rectangle.
+ *
+ * Properties marked with [*] also have _set properties associated
+ * with them, that determine if the specified value should be used
+ * instead of the default (style-defined) values
+ *
+ * The following object arguments are available:
+ *
+ * name			type			read/write	description
+ * ------------------------------------------------------------------------------------------
+ * text			string			RW		The string of the text label
+ * markup		string			 W		A Pango markup string for the text label
+ *
+ * x			double			RW		X coordinate of anchor point
+ * y			double			RW		Y coordinate of anchor point
+ *
+ * font			string			 W		A string describing the font
+ * font_desc	        PangoFontDescription*	RW		Pointer to a PangoFontDescriptor
+ * attributes           PangoAttrList*          RW		Pointer to a Pango attribute list
+ * style		PangoStyle		RW		Pango style of font to use	[*]
+ * variant		PangoVariant		RW		Pango variant of font to use	[*]
+ * weight		int			RW		Pango weight of font to use	[*]
+ * stretch		PangoStretch		RW		Pango stretch of font to use	[*]
+ * size			int			RW		Size (in pixels) of font	[*]
+ * size_points		double			RW		Size (in points) of font
+ * scale                double                  RW              Ratio to scale font		[*]
+ *
+ * anchor		GtkAnchorType		RW		Anchor side for the text
+ * justification	GtkJustification	RW		Justification for multiline text
+ * clip_width		double			RW		Width of clip rectangle
+ * clip_height		double			RW		Height of clip rectangle
+ * clip			boolean			RW		Use clipping rectangle?
+ * x_offset		double			RW		Horizontal offset distance from anchor position
+ * y_offset		double			RW		Vertical offset distance from anchor position
+ *
+ * text_width		double			R		Used to query the width of the rendered text
+ * text_height		double			R		Used to query the rendered height of the text
+ *
+ * fill_color		string			 W		X color specification for text
+ * fill_color_gdk	GdkColor*		RW		Pointer to an allocated GdkColor
+ * fill_color_rgba	guint   		RW		RGBA value used for AA color.
+ * fill_stipple		GdkBitmap*		RW		Stipple pattern for filling the text
+ */
+
+#define FOO_TYPE_CANVAS_TEXT            (foo_canvas_text_get_type ())
+#define FOO_CANVAS_TEXT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), FOO_TYPE_CANVAS_TEXT, FooCanvasText))
+#define FOO_CANVAS_TEXT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), FOO_TYPE_CANVAS_TEXT, FooCanvasTextClass))
+#define FOO_IS_CANVAS_TEXT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FOO_TYPE_CANVAS_TEXT))
+#define FOO_IS_CANVAS_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FOO_TYPE_CANVAS_TEXT))
+#define FOO_CANVAS_TEXT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), FOO_TYPE_CANVAS_TEXT, FooCanvasTextClass))
+
+
+typedef struct _FooCanvasText FooCanvasText;
+typedef struct _FooCanvasTextClass FooCanvasTextClass;
+
+typedef struct _FooCanvasTextPrivate FooCanvasTextPrivate;
+
+struct _FooCanvasText {
+	FooCanvasItem item;
+
+	PangoFontDescription *font_desc; /* Font description for text */
+	PangoAttrList *attr_list;        /* Attribute list of the text (caching) */
+	PangoUnderline underline;
+	gboolean       strikethrough;
+	int            rise;
+	double         scale;
+	
+	char *text;			/* Text to display */
+	GdkBitmap *stipple;		/* Stipple for text */
+	GdkGC *gc;			/* GC for drawing text */
+        PangoLayout *layout;            /* The PangoLayout containing the text */
+
+	gulong pixel;			/* Fill color */
+
+	double x, y;			/* Position at anchor */
+
+	double clip_width;		/* Width of optional clip rectangle */
+	double clip_height;		/* Height of optional clip rectangle */
+
+	double xofs, yofs;		/* Text offset distance from anchor position */
+
+	GtkAnchorType anchor;		/* Anchor side for text */
+	GtkJustification justification;	/* Justification for text */
+
+	int cx, cy;			/* Top-left canvas coordinates for text */
+	int clip_cx, clip_cy;		/* Top-left canvas coordinates for clip rectangle */
+	int clip_cwidth, clip_cheight;	/* Size of clip rectangle in pixels */
+	int max_width;			/* Maximum width of text lines */
+	int height;			/* Rendered text height in pixels */
+
+        guint32 rgba;			/* RGBA color for text */ /*AA*/
+
+	guint clip : 1;			/* Use clip rectangle? */
+
+	guint underline_set : 1;        /* Apply specified underline style? */
+	guint strike_set    : 1;        /* Apply specified strikethrough style? */
+	guint rise_set      : 1;        /* Apply specified ascension/descension? */
+
+	guint scale_set     : 1;        /* Apply specified font scaling ratio? */
+
+	FooCanvasTextPrivate *priv;	
+};
+
+struct _FooCanvasTextClass {
+	FooCanvasItemClass parent_class;
+};
+
+
+/* Standard Gtk function */
+GType foo_canvas_text_get_type (void) G_GNUC_CONST;
+
+
+G_END_DECLS
+
+#endif
diff --git a/widgets/libfoocanvas/foo-canvas-util.c b/widgets/libfoocanvas/foo-canvas-util.c
new file mode 100644
index 0000000..879db57
--- /dev/null
+++ b/widgets/libfoocanvas/foo-canvas-util.c
@@ -0,0 +1,399 @@
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * The Gnome Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+/* Miscellaneous utility functions for the FooCanvas widget
+ *
+ * FooCanvas is basically a port of the Tk toolkit's most excellent canvas widget.  Tk is
+ * copyrighted by the Regents of the University of California, Sun Microsystems, and other parties.
+ *
+ *
+ * Author: Federico Mena <federico nuclecu unam mx>
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <glib.h>
+#include <math.h>
+#include "foo-canvas.h"
+#include "foo-canvas-util.h"
+
+/*
+ * Ok, so some systems require magic incantations for M_PI to be defined.
+ * It's not important enough to worry about.
+ */
+#ifndef M_PI
+#define M_PI 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117
+#endif
+
+/**
+ * foo_canvas_points_new:
+ * @num_points: The number of points to allocate space for in the array.
+ * 
+ * Creates a structure that should be used to pass an array of points to
+ * items.
+ * 
+ * Return value: A newly-created array of points.  It should be filled in
+ * by the user.
+ **/
+FooCanvasPoints *
+foo_canvas_points_new (int num_points)
+{
+	FooCanvasPoints *points;
+
+	g_return_val_if_fail (num_points > 1, NULL);
+
+	points = g_new (FooCanvasPoints, 1);
+	points->num_points = num_points;
+	points->coords = g_new (double, 2 * num_points);
+	points->ref_count = 1;
+
+	return points;
+}
+
+/**
+ * foo_canvas_points_ref:
+ * @points: A canvas points structure.
+ * 
+ * Increases the reference count of the specified points structure.
+ * 
+ * Return value: The canvas points structure itself.
+ **/
+FooCanvasPoints *
+foo_canvas_points_ref (FooCanvasPoints *points)
+{
+	g_return_val_if_fail (points != NULL, NULL);
+
+	points->ref_count += 1;
+	return points;
+}
+
+/**
+ * foo_canvas_points_free:
+ * @points: A canvas points structure.
+ * 
+ * Decreases the reference count of the specified points structure.  If it
+ * reaches zero, then the structure is freed.
+ **/
+void
+foo_canvas_points_free (FooCanvasPoints *points)
+{
+	g_return_if_fail (points != NULL);
+
+	points->ref_count -= 1;
+	if (points->ref_count == 0) {
+		g_free (points->coords);
+		g_free (points);
+	}
+}
+
+/**
+ * foo_canvas_get_miter_points:
+ * @x1: X coordinate of the first point
+ * @y1: Y coordinate of the first point
+ * @x2: X coordinate of the second (angle) point
+ * @y2: Y coordinate of the second (angle) point
+ * @x3: X coordinate of the third point
+ * @y3: Y coordinate of the third point
+ * @width: Width of the line
+ * @mx1: The X coordinate of the first miter point is returned here.
+ * @my1: The Y coordinate of the first miter point is returned here.
+ * @mx2: The X coordinate of the second miter point is returned here.
+ * @my2: The Y coordinate of the second miter point is returned here.
+ * 
+ * Given three points forming an angle, computes the coordinates of the inside
+ * and outside points of the mitered corner formed by a line of a given width at
+ * that angle.
+ * 
+ * Return value: FALSE if the angle is less than 11 degrees (this is the same
+ * threshold as X uses.  If this occurs, the return points are not modified.
+ * Otherwise, returns TRUE.
+ **/
+int
+foo_canvas_get_miter_points (double x1, double y1, double x2, double y2, double x3, double y3,
+			     double width,
+			     double *mx1, double *my1, double *mx2, double *my2)
+{
+	double theta1;		/* angle of segment p2-p1 */
+	double theta2;		/* angle of segment p2-p3 */
+	double theta;		/* angle between line segments */
+	double theta3;		/* angle that bisects theta1 and theta2 and points to p1 */
+	double dist;		/* distance of miter points from p2 */
+	double dx, dy;		/* x and y offsets corresponding to dist */
+
+	double ELEVEN_DEGREES = 11.0 * M_PI / 180.0;
+
+	/* Degenerate cases.  */
+	if ((x1 == x2 && y1 == y2) || (x2 == x3 && y2 == y3))
+		return FALSE;
+
+	theta1 = atan2 (y1 - y2, x1 - x2);
+	theta2 = atan2 (y3 - y2, x3 - x2);
+	theta = theta1 - theta2;
+
+	/* Normalize to (-pi; pi].  */
+	if (theta > M_PI)
+		theta -= 2.0 * M_PI;
+	else if (theta <= -M_PI)
+		theta += 2.0 * M_PI;
+
+	if (fabs (theta) < ELEVEN_DEGREES)
+		return FALSE;
+
+	dist = fabs (0.5 * width / sin (0.5 * theta));
+
+	theta3 = (theta1 + theta2) / 2.0;
+	if (sin (theta3 - theta1) > 0.0)
+		theta3 += M_PI;
+
+	dx = dist * cos (theta3);
+	dy = dist * sin (theta3);
+
+	*mx1 = x2 + dx;
+	*mx2 = x2 - dx;
+	*my1 = y2 + dy;
+	*my2 = y2 - dy;
+
+	return TRUE;
+}
+
+/**
+ * foo_canvas_get_butt_points:
+ * @x1: X coordinate of first point in the line
+ * @y1: Y cooordinate of first point in the line
+ * @x2: X coordinate of second point (endpoint) of the line
+ * @y2: Y coordinate of second point (endpoint) of the line
+ * @width: Width of the line
+ * @project: Whether the butt points should project out by width/2 distance
+ * @bx1: X coordinate of first butt point is returned here
+ * @by1: Y coordinate of first butt point is returned here
+ * @bx2: X coordinate of second butt point is returned here
+ * @by2: Y coordinate of second butt point is returned here
+ * 
+ * Computes the butt points of a line segment.
+ **/
+void
+foo_canvas_get_butt_points (double x1, double y1, double x2, double y2,
+			      double width, int project,
+			      double *bx1, double *by1, double *bx2, double *by2)
+{
+	double length;
+	double dx, dy;
+
+	width *= 0.5;
+	dx = x2 - x1;
+	dy = y2 - y1;
+	length = sqrt (dx * dx + dy * dy);
+
+	if (length < FOO_CANVAS_EPSILON) {
+		*bx1 = *bx2 = x2;
+		*by1 = *by2 = y2;
+	} else {
+		dx = -width * (y2 - y1) / length;
+		dy = width * (x2 - x1) / length;
+
+		*bx1 = x2 + dx;
+		*bx2 = x2 - dx;
+		*by1 = y2 + dy;
+		*by2 = y2 - dy;
+
+		if (project) {
+			*bx1 += dy;
+			*bx2 += dy;
+			*by1 -= dx;
+			*by2 -= dx;
+		}
+	}
+}
+
+/**
+ * foo_canvas_polygon_to_point:
+ * @poly: Vertices of the polygon.  X coordinates are in the even indices, and Y
+ * coordinates are in the odd indices
+ * @num_points: Number of points in the polygon
+ * @x: X coordinate of the point
+ * @y: Y coordinate of the point
+ * 
+ * Computes the distance between a point and a polygon.
+ * 
+ * Return value: The distance from the point to the polygon, or zero if the
+ * point is inside the polygon.
+ **/
+double
+foo_canvas_polygon_to_point (double *poly, int num_points, double x, double y)
+{
+	double best;
+	int intersections;
+	int i;
+	double *p;
+	double dx, dy;
+
+	/* Iterate through all the edges in the polygon, updating best and intersections.
+	 *
+	 * When computing intersections, include left X coordinate of line within its range, but not
+	 * Y coordinate.  Otherwise if the point lies exactly below a vertex we'll count it as two
+	 * intersections.
+	 */
+
+	best = 1.0e36;
+	if (poly == NULL)
+		return best;
+
+	intersections = 0;
+
+	for (i = num_points, p = poly; i > 1; i--, p += 2) {
+		double px, py, dist;
+
+		/* Compute the point on the current edge closest to the point and update the
+		 * intersection count.  This must be done separately for vertical edges, horizontal
+		 * edges, and others.
+		 */
+
+		if (p[2] == p[0]) {
+			/* Vertical edge */
+
+			px = p[0];
+
+			if (p[1] >= p[3]) {
+				py = MIN (p[1], y);
+				py = MAX (py, p[3]);
+			} else {
+				py = MIN (p[3], y);
+				py = MAX (py, p[1]);
+			}
+		} else if (p[3] == p[1]) {
+			/* Horizontal edge */
+
+			py = p[1];
+
+			if (p[0] >= p[2]) {
+				px = MIN (p[0], x);
+				px = MAX (px, p[2]);
+
+				if ((y < py) && (x < p[0]) && (x >= p[2]))
+					intersections++;
+			} else {
+				px = MIN (p[2], x);
+				px = MAX (px, p[0]);
+
+				if ((y < py) && (x < p[2]) && (x >= p[0]))
+					intersections++;
+			}
+		} else {
+			double m1, b1, m2, b2;
+			int lower;
+
+			/* Diagonal edge.  Convert the edge to a line equation (y = m1*x + b1), then
+			 * compute a line perpendicular to this edge but passing through the point,
+			 * (y = m2*x + b2).
+			 */
+
+			m1 = (p[3] - p[1]) / (p[2] - p[0]);
+			b1 = p[1] - m1 * p[0];
+
+			m2 = -1.0 / m1;
+			b2 = y - m2 * x;
+
+			px = (b2 - b1) / (m1 - m2);
+			py = m1 * px + b1;
+
+			if (p[0] > p[2]) {
+				if (px > p[0]) {
+					px = p[0];
+					py = p[1];
+				} else if (px < p[2]) {
+					px = p[2];
+					py = p[3];
+				}
+			} else {
+				if (px > p[2]) {
+					px = p[2];
+					py = p[3];
+				} else if (px < p[0]) {
+					px = p[0];
+					py = p[1];
+				}
+			}
+
+			lower = (m1 * x + b1) > y;
+
+			if (lower && (x >= MIN (p[0], p[2])) && (x < MAX (p[0], p[2])))
+				intersections++;
+		}
+
+		/* Compute the distance to the closest point, and see if that is the best so far */
+
+		dx = x - px;
+		dy = y - py;
+		dist = sqrt (dx * dx + dy * dy);
+		if (dist < best)
+			best = dist;
+	}
+
+	/* We've processed all the points.  If the number of intersections is odd, the point is
+	 * inside the polygon.
+	 */
+
+	if (intersections & 0x1)
+		return 0.0;
+	else
+		return best;
+}
+
+/**
+ * foo_canvas_item_reset_bounds:
+ * @item: A canvas item
+ * 
+ * Resets the bounding box of a canvas item to an empty rectangle.
+ **/
+void
+foo_canvas_item_reset_bounds (FooCanvasItem *item)
+{
+	item->x1 = 0.0;
+	item->y1 = 0.0;
+	item->x2 = 0.0;
+	item->y2 = 0.0;
+}
+
+/**
+ * foo_canvas_update_bbox:
+ * @canvas: the canvas needing update
+ * @x1: Left coordinate of the new bounding box
+ * @y1: Top coordinate of the new bounding box
+ * @x2: Right coordinate of the new bounding box
+ * @y2: Bottom coordinate of the new bounding box
+ *
+ * Sets the bbox to the new value, requesting full repaint.
+ **/
+void
+foo_canvas_update_bbox (FooCanvasItem *item, int x1, int y1, int x2, int y2)
+{
+	foo_canvas_item_request_redraw (item);
+	item->x1 = x1;
+	item->y1 = y1;
+	item->x2 = x2;
+	item->y2 = y2;
+	foo_canvas_item_request_redraw (item);
+}
+
diff --git a/widgets/libfoocanvas/foo-canvas-util.h b/widgets/libfoocanvas/foo-canvas-util.h
new file mode 100644
index 0000000..63fc3ac
--- /dev/null
+++ b/widgets/libfoocanvas/foo-canvas-util.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * The Gnome Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+/* Miscellaneous utility functions for the FooCanvas widget
+ *
+ * FooCanvas is basically a port of the Tk toolkit's most excellent canvas widget.  Tk is
+ * copyrighted by the Regents of the University of California, Sun Microsystems, and other parties.
+ *
+ * Author: Federico Mena <federico nuclecu unam mx>
+ */
+
+#ifndef FOO_CANVAS_UTIL_H
+#define FOO_CANVAS_UTIL_H
+
+
+G_BEGIN_DECLS
+
+
+/* This structure defines an array of points.  X coordinates are stored in the even-numbered
+ * indices, and Y coordinates are stored in the odd-numbered indices.  num_points indicates the
+ * number of points, so the array is 2*num_points elements big.
+ */
+typedef struct {
+	double *coords;
+	int num_points;
+	int ref_count;
+} FooCanvasPoints;
+
+
+/* Allocate a new FooCanvasPoints structure with enough space for the specified number of points */
+FooCanvasPoints *foo_canvas_points_new (int num_points);
+
+/* Increate ref count */
+FooCanvasPoints *foo_canvas_points_ref (FooCanvasPoints *points);
+#define foo_canvas_points_unref foo_canvas_points_free
+
+/* Decrease ref count and free structure if it has reached zero */
+void foo_canvas_points_free (FooCanvasPoints *points);
+
+/* Given three points forming an angle, compute the coordinates of the inside and outside points of
+ * the mitered corner formed by a line of a given width at that angle.
+ *
+ * If the angle is less than 11 degrees, then FALSE is returned and the return points are not
+ * modified.  Otherwise, TRUE is returned.
+ */
+int foo_canvas_get_miter_points (double x1, double y1, double x2, double y2, double x3, double y3,
+				   double width,
+				   double *mx1, double *my1, double *mx2, double *my2);
+
+/* Compute the butt points of a line segment.  If project is FALSE, then the results are as follows:
+ *
+ *            -------------------* (bx1, by1)
+ *                               |
+ *   (x1, y1) *------------------* (x2, y2)
+ *                               |
+ *            -------------------* (bx2, by2)
+ *
+ * that is, the line is not projected beyond (x2, y2).  If project is TRUE, then the results are as
+ * follows:
+ *
+ *            -------------------* (bx1, by1)
+ *                      (x2, y2) |
+ *   (x1, y1) *-------------*    |
+ *                               |
+ *            -------------------* (bx2, by2)
+ */
+void foo_canvas_get_butt_points (double x1, double y1, double x2, double y2,
+				   double width, int project,
+				   double *bx1, double *by1, double *bx2, double *by2);
+
+/* Calculate the distance from a polygon to a point.  The polygon's X coordinates are in the even
+ * indices of the poly array, and the Y coordinates are in the odd indices.
+ */
+double foo_canvas_polygon_to_point (double *poly, int num_points, double x, double y);
+
+
+void foo_canvas_item_reset_bounds (FooCanvasItem *item);
+
+/* Sets the bbox to the new value, requesting full repaint. */
+void foo_canvas_update_bbox (FooCanvasItem *item, int x1, int y1, int x2, int y2);
+
+G_END_DECLS
+
+#endif
diff --git a/widgets/libfoocanvas/foo-canvas-widget.c b/widgets/libfoocanvas/foo-canvas-widget.c
new file mode 100644
index 0000000..9e5d337
--- /dev/null
+++ b/widgets/libfoocanvas/foo-canvas-widget.c
@@ -0,0 +1,589 @@
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * The Gnome Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+/* Widget item type for FooCanvas widget
+ *
+ * FooCanvas is basically a port of the Tk toolkit's most excellent canvas widget.  Tk is
+ * copyrighted by the Regents of the University of California, Sun Microsystems, and other parties.
+ *
+ *
+ * Author: Federico Mena <federico nuclecu unam mx>
+ */
+
+#include <config.h>
+#include <math.h>
+#include <glib-object.h>
+#include "foo-canvas-widget.h"
+
+enum {
+	PROP_0,
+	PROP_WIDGET,
+	PROP_X,
+	PROP_Y,
+	PROP_WIDTH,
+	PROP_HEIGHT,
+	PROP_ANCHOR,
+	PROP_SIZE_PIXELS
+};
+
+
+static void foo_canvas_widget_class_init (FooCanvasWidgetClass *klass);
+static void foo_canvas_widget_init       (FooCanvasWidget      *witem);
+static void foo_canvas_widget_destroy    (GtkObject              *object);
+static void foo_canvas_widget_get_property (GObject            *object,
+					      guint               param_id,
+					      GValue             *value,
+					      GParamSpec         *pspec);
+static void foo_canvas_widget_set_property (GObject            *object,
+					      guint               param_id,
+					      const GValue       *value,
+					      GParamSpec         *pspec);
+
+static void   foo_canvas_widget_update      (FooCanvasItem *item, double i2w_dx, double i2w_dy, int flags);
+static double foo_canvas_widget_point       (FooCanvasItem *item, double x, double y,
+					       int cx, int cy, FooCanvasItem **actual_item);
+static void   foo_canvas_widget_translate   (FooCanvasItem *item, double dx, double dy);
+static void   foo_canvas_widget_bounds      (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2);
+
+static void foo_canvas_widget_draw (FooCanvasItem *item,
+				      GdkDrawable *drawable,
+				      GdkEventExpose   *event);
+static void foo_canvas_widget_map   (FooCanvasItem *item);
+static void foo_canvas_widget_unmap (FooCanvasItem *item);
+
+static FooCanvasItemClass *parent_class;
+
+G_DEFINE_TYPE (FooCanvasWidget, foo_canvas_widget, FOO_TYPE_CANVAS_ITEM)
+
+static void
+foo_canvas_widget_class_init (FooCanvasWidgetClass *klass)
+{
+	GObjectClass *gobject_class;
+	GtkObjectClass *object_class;
+	FooCanvasItemClass *item_class;
+
+	gobject_class = (GObjectClass *) klass;
+	object_class = (GtkObjectClass *) klass;
+	item_class = (FooCanvasItemClass *) klass;
+
+	parent_class = g_type_class_peek_parent (klass);
+
+	gobject_class->set_property = foo_canvas_widget_set_property;
+	gobject_class->get_property = foo_canvas_widget_get_property;
+
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_WIDGET,
+                 g_param_spec_object ("widget", NULL, NULL,
+                                      GTK_TYPE_WIDGET,
+                                      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_X,
+                 g_param_spec_double ("x", NULL, NULL,
+				      -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
+				      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_Y,
+                 g_param_spec_double ("y", NULL, NULL,
+				      -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
+				      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_WIDTH,
+                 g_param_spec_double ("width", NULL, NULL,
+				      -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
+				      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_HEIGHT,
+                 g_param_spec_double ("height", NULL, NULL,
+				      -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
+				      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_ANCHOR,
+                 g_param_spec_enum ("anchor", NULL, NULL,
+                                    GTK_TYPE_ANCHOR_TYPE,
+                                    GTK_ANCHOR_NW,
+                                    G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_SIZE_PIXELS,
+                 g_param_spec_boolean ("size-pixels", NULL, NULL,
+				       FALSE,
+				       G_PARAM_READWRITE));
+
+	object_class->destroy = foo_canvas_widget_destroy;
+
+	item_class->update = foo_canvas_widget_update;
+	item_class->point = foo_canvas_widget_point;
+	item_class->translate = foo_canvas_widget_translate;
+	item_class->bounds = foo_canvas_widget_bounds;
+	item_class->draw = foo_canvas_widget_draw;
+	item_class->map   = foo_canvas_widget_map;
+	item_class->unmap = foo_canvas_widget_unmap;
+}
+
+static void
+foo_canvas_widget_init (FooCanvasWidget *witem)
+{
+	witem->x = 0.0;
+	witem->y = 0.0;
+	witem->width = 0.0;
+	witem->height = 0.0;
+	witem->anchor = GTK_ANCHOR_NW;
+	witem->size_pixels = FALSE;
+}
+
+static void
+foo_canvas_widget_destroy (GtkObject *object)
+{
+	FooCanvasWidget *witem;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (FOO_IS_CANVAS_WIDGET (object));
+
+	witem = FOO_CANVAS_WIDGET (object);
+
+	if (witem->widget && !witem->in_destroy) {
+		g_signal_handler_disconnect (G_OBJECT (witem->widget), witem->destroy_id);
+		gtk_widget_destroy (witem->widget);
+		witem->widget = NULL;
+	}
+
+	if (GTK_OBJECT_CLASS (parent_class)->destroy)
+		(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+recalc_bounds (FooCanvasWidget *witem)
+{
+	FooCanvasItem *item;
+	double wx, wy;
+
+	item = FOO_CANVAS_ITEM (witem);
+
+	/* Get world coordinates */
+
+	wx = witem->x;
+	wy = witem->y;
+	foo_canvas_item_i2w (item, &wx, &wy);
+
+	/* Get canvas pixel coordinates */
+
+	foo_canvas_w2c (item->canvas, wx, wy, &witem->cx, &witem->cy);
+
+	/* Anchor widget item */
+
+	switch (witem->anchor) {
+	case GTK_ANCHOR_NW:
+	case GTK_ANCHOR_W:
+	case GTK_ANCHOR_SW:
+		break;
+
+	case GTK_ANCHOR_N:
+	case GTK_ANCHOR_CENTER:
+	case GTK_ANCHOR_S:
+		witem->cx -= witem->cwidth / 2;
+		break;
+
+	case GTK_ANCHOR_NE:
+	case GTK_ANCHOR_E:
+	case GTK_ANCHOR_SE:
+		witem->cx -= witem->cwidth;
+		break;
+
+        default:
+                break;
+	}
+
+	switch (witem->anchor) {
+	case GTK_ANCHOR_NW:
+	case GTK_ANCHOR_N:
+	case GTK_ANCHOR_NE:
+		break;
+
+	case GTK_ANCHOR_W:
+	case GTK_ANCHOR_CENTER:
+	case GTK_ANCHOR_E:
+		witem->cy -= witem->cheight / 2;
+		break;
+
+	case GTK_ANCHOR_SW:
+	case GTK_ANCHOR_S:
+	case GTK_ANCHOR_SE:
+		witem->cy -= witem->cheight;
+		break;
+
+        default:
+                break;
+	}
+
+	/* Bounds */
+
+	item->x1 = witem->cx;
+	item->y1 = witem->cy;
+	item->x2 = witem->cx + witem->cwidth;
+	item->y2 = witem->cy + witem->cheight;
+
+	if (witem->widget)
+		gtk_layout_move (GTK_LAYOUT (item->canvas), witem->widget,
+				 witem->cx,
+				 witem->cy);
+}
+
+static void
+do_destroy (GtkObject *object, gpointer data)
+{
+	FooCanvasWidget *witem;
+
+	witem = data;
+
+	witem->in_destroy = TRUE;
+
+	gtk_object_destroy (data);
+}
+
+static void
+foo_canvas_widget_set_property (GObject            *object,
+				  guint               param_id,
+				  const GValue       *value,
+				  GParamSpec         *pspec)
+{
+	FooCanvasItem *item;
+	FooCanvasWidget *witem;
+	GObject *obj;
+	int update;
+	int calc_bounds;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (FOO_IS_CANVAS_WIDGET (object));
+
+	item = FOO_CANVAS_ITEM (object);
+	witem = FOO_CANVAS_WIDGET (object);
+
+	update = FALSE;
+	calc_bounds = FALSE;
+
+	switch (param_id) {
+	case PROP_WIDGET:
+		if (witem->widget) {
+			g_signal_handler_disconnect (G_OBJECT (witem->widget), witem->destroy_id);
+			gtk_container_remove (GTK_CONTAINER (item->canvas), witem->widget);
+		}
+
+		obj = g_value_get_object (value);
+		if (obj) {
+			witem->widget = GTK_WIDGET (obj);
+			witem->destroy_id = g_signal_connect (G_OBJECT (obj),
+				"destroy", G_CALLBACK (do_destroy), witem);
+			gtk_layout_put (GTK_LAYOUT (item->canvas), witem->widget,
+					witem->cx + item->canvas->zoom_xofs,
+					witem->cy + item->canvas->zoom_yofs);
+		}
+
+		update = TRUE;
+		break;
+
+	case PROP_X:
+	        if (witem->x != g_value_get_double (value))
+		{
+		        witem->x = g_value_get_double (value);
+			calc_bounds = TRUE;
+		}
+		break;
+
+	case PROP_Y:
+	        if (witem->y != g_value_get_double (value))
+		{
+		        witem->y = g_value_get_double (value);
+			calc_bounds = TRUE;
+		}
+		break;
+
+	case PROP_WIDTH:
+	        if (witem->width != fabs (g_value_get_double (value)))
+		{
+		        witem->width = fabs (g_value_get_double (value));
+			update = TRUE;
+		}
+		break;
+
+	case PROP_HEIGHT:
+	        if (witem->height != fabs (g_value_get_double (value)))
+		{
+		        witem->height = fabs (g_value_get_double (value));
+			update = TRUE;
+		}
+		break;
+
+	case PROP_ANCHOR:
+	        if (witem->anchor != (GtkAnchorType)g_value_get_enum (value))
+		{
+		        witem->anchor = g_value_get_enum (value);
+			update = TRUE;
+		}
+		break;
+
+	case PROP_SIZE_PIXELS:
+	        if (witem->size_pixels != g_value_get_boolean (value))
+		{
+		        witem->size_pixels = g_value_get_boolean (value);
+			update = TRUE;
+		}
+		break;
+
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	}
+
+	if (update)
+		(* FOO_CANVAS_ITEM_GET_CLASS (item)->update) (item, 0, 0, 0);
+
+	if (calc_bounds)
+		recalc_bounds (witem);
+}
+
+static void
+foo_canvas_widget_get_property (GObject            *object,
+				  guint               param_id,
+				  GValue             *value,
+				  GParamSpec         *pspec)
+{
+	FooCanvasWidget *witem;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (FOO_IS_CANVAS_WIDGET (object));
+
+	witem = FOO_CANVAS_WIDGET (object);
+
+	switch (param_id) {
+	case PROP_WIDGET:
+		g_value_set_object (value, (GObject *) witem->widget);
+		break;
+
+	case PROP_X:
+		g_value_set_double (value, witem->x);
+		break;
+
+	case PROP_Y:
+		g_value_set_double (value, witem->y);
+		break;
+
+	case PROP_WIDTH:
+		g_value_set_double (value, witem->width);
+		break;
+
+	case PROP_HEIGHT:
+		g_value_set_double (value, witem->height);
+		break;
+
+	case PROP_ANCHOR:
+		g_value_set_enum (value, witem->anchor);
+		break;
+
+	case PROP_SIZE_PIXELS:
+		g_value_set_boolean (value, witem->size_pixels);
+		break;
+
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	}
+}
+
+static void
+foo_canvas_widget_update (FooCanvasItem *item, double i2w_dx, double i2w_dy, int flags)
+{
+	FooCanvasWidget *witem;
+
+	witem = FOO_CANVAS_WIDGET (item);
+
+	if (parent_class->update)
+		(* parent_class->update) (item, i2w_dx, i2w_dy, flags);
+
+	if (witem->widget) {
+		if (witem->size_pixels) {
+			witem->cwidth = (int) (witem->width + 0.5);
+			witem->cheight = (int) (witem->height + 0.5);
+		} else {
+			witem->cwidth = (int) (witem->width * item->canvas->pixels_per_unit + 0.5);
+			witem->cheight = (int) (witem->height * item->canvas->pixels_per_unit + 0.5);
+		}
+
+		gtk_widget_set_usize (witem->widget, witem->cwidth, witem->cheight);
+	} else {
+		witem->cwidth = 0.0;
+		witem->cheight = 0.0;
+	}
+
+	recalc_bounds (witem);
+}
+
+static void
+foo_canvas_widget_draw (FooCanvasItem *item,
+			  GdkDrawable *drawable,
+			  GdkEventExpose *event)
+{
+#if 0
+	FooCanvasWidget *witem;
+
+	witem = FOO_CANVAS_WIDGET (item);
+
+	if (witem->widget)
+		gtk_widget_queue_draw (witem->widget);
+#endif
+}
+static void
+foo_canvas_widget_map (FooCanvasItem *item)
+{
+	FooCanvasWidget *witem = FOO_CANVAS_WIDGET (item);
+	if (parent_class->map)
+		(* parent_class->map) (item);
+	if (witem->widget && GTK_WIDGET_VISIBLE (witem->widget))
+		gtk_widget_map (witem->widget);
+}
+
+static void
+foo_canvas_widget_unmap (FooCanvasItem *item)
+{
+	FooCanvasWidget *witem = FOO_CANVAS_WIDGET (item);
+	if (parent_class->unmap)
+		(* parent_class->unmap) (item);
+	gtk_widget_unmap (witem->widget);
+}
+
+static double
+foo_canvas_widget_point (FooCanvasItem *item, double x, double y,
+			   int cx, int cy, FooCanvasItem **actual_item)
+{
+	FooCanvasWidget *witem;
+	double x1, y1, x2, y2;
+	double dx, dy;
+
+	witem = FOO_CANVAS_WIDGET (item);
+
+	*actual_item = item;
+
+	foo_canvas_c2w (item->canvas, witem->cx, witem->cy, &x1, &y1);
+
+	x2 = x1 + (witem->cwidth - 1) / item->canvas->pixels_per_unit;
+	y2 = y1 + (witem->cheight - 1) / item->canvas->pixels_per_unit;
+
+	/* Is point inside widget bounds? */
+
+	if ((x >= x1) && (y >= y1) && (x <= x2) && (y <= y2))
+		return 0.0;
+
+	/* Point is outside widget bounds */
+
+	if (x < x1)
+		dx = x1 - x;
+	else if (x > x2)
+		dx = x - x2;
+	else
+		dx = 0.0;
+
+	if (y < y1)
+		dy = y1 - y;
+	else if (y > y2)
+		dy = y - y2;
+	else
+		dy = 0.0;
+
+	return sqrt (dx * dx + dy * dy);
+}
+
+static void
+foo_canvas_widget_translate (FooCanvasItem *item, double dx, double dy)
+{
+	FooCanvasWidget *witem;
+
+	witem = FOO_CANVAS_WIDGET (item);
+
+	witem->x += dx;
+	witem->y += dy;
+}
+
+
+static void
+foo_canvas_widget_bounds (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2)
+{
+	FooCanvasWidget *witem;
+
+	witem = FOO_CANVAS_WIDGET (item);
+
+	*x1 = witem->x;
+	*y1 = witem->y;
+
+	switch (witem->anchor) {
+	case GTK_ANCHOR_NW:
+	case GTK_ANCHOR_W:
+	case GTK_ANCHOR_SW:
+		break;
+
+	case GTK_ANCHOR_N:
+	case GTK_ANCHOR_CENTER:
+	case GTK_ANCHOR_S:
+		*x1 -= witem->width / 2.0;
+		break;
+
+	case GTK_ANCHOR_NE:
+	case GTK_ANCHOR_E:
+	case GTK_ANCHOR_SE:
+		*x1 -= witem->width;
+		break;
+
+        default:
+                break;
+	}
+
+	switch (witem->anchor) {
+	case GTK_ANCHOR_NW:
+	case GTK_ANCHOR_N:
+	case GTK_ANCHOR_NE:
+		break;
+
+	case GTK_ANCHOR_W:
+	case GTK_ANCHOR_CENTER:
+	case GTK_ANCHOR_E:
+		*y1 -= witem->height / 2.0;
+		break;
+
+	case GTK_ANCHOR_SW:
+	case GTK_ANCHOR_S:
+	case GTK_ANCHOR_SE:
+		*y1 -= witem->height;
+		break;
+
+        default:
+                break;
+	}
+
+	*x2 = *x1 + witem->width;
+	*y2 = *y1 + witem->height;
+}
diff --git a/widgets/libfoocanvas/foo-canvas-widget.h b/widgets/libfoocanvas/foo-canvas-widget.h
new file mode 100644
index 0000000..09612ee
--- /dev/null
+++ b/widgets/libfoocanvas/foo-canvas-widget.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * The Gnome Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+/* Widget item type for FooCanvas widget
+ *
+ * FooCanvas is basically a port of the Tk toolkit's most excellent canvas widget.  Tk is
+ * copyrighted by the Regents of the University of California, Sun Microsystems, and other parties.
+ *
+ *
+ * Author: Federico Mena <federico nuclecu unam mx>
+ */
+
+#ifndef FOO_CANVAS_WIDGET_H
+#define FOO_CANVAS_WIDGET_H
+
+
+#include <libfoocanvas/foo-canvas.h>
+
+
+G_BEGIN_DECLS
+
+
+/* Widget item for canvas.  The widget is positioned with respect to an anchor point.
+ * The following object arguments are available:
+ *
+ * name			type			read/write	description
+ * ------------------------------------------------------------------------------------------
+ * widget		GtkWidget*		RW		Pointer to the widget
+ * x			double			RW		X coordinate of anchor point
+ * y			double			RW		Y coordinate of anchor point
+ * width		double			RW		Width of widget (see below)
+ * height		double			RW		Height of widget (see below)
+ * anchor		GtkAnchorType		RW		Anchor side for widget
+ * size_pixels		boolean			RW		Specifies whether the widget size
+ *								is specified in pixels or canvas units.
+ *								If it is in pixels, then the widget will not
+ *								be scaled when the canvas zoom factor changes.
+ *								Otherwise, it will be scaled.
+ */
+
+
+#define FOO_TYPE_CANVAS_WIDGET            (foo_canvas_widget_get_type ())
+#define FOO_CANVAS_WIDGET(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), FOO_TYPE_CANVAS_WIDGET, FooCanvasWidget))
+#define FOO_CANVAS_WIDGET_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), FOO_TYPE_CANVAS_WIDGET, FooCanvasWidgetClass))
+#define FOO_IS_CANVAS_WIDGET(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FOO_TYPE_CANVAS_WIDGET))
+#define FOO_IS_CANVAS_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FOO_TYPE_CANVAS_WIDGET))
+#define FOO_CANVAS_WIDGET_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), FOO_TYPE_CANVAS_WIDGET, FooCanvasWidgetClass))
+
+
+typedef struct _FooCanvasWidget FooCanvasWidget;
+typedef struct _FooCanvasWidgetClass FooCanvasWidgetClass;
+
+struct _FooCanvasWidget {
+	FooCanvasItem item;
+
+	GtkWidget *widget;		/* The child widget */
+
+	double x, y;			/* Position at anchor */
+	double width, height;		/* Dimensions of widget */
+	GtkAnchorType anchor;		/* Anchor side for widget */
+
+	int cx, cy;			/* Top-left canvas coordinates for widget */
+	int cwidth, cheight;		/* Size of widget in pixels */
+
+	guint destroy_id;		/* Signal connection id for destruction of child widget */
+
+	guint size_pixels : 1;		/* Is size specified in (unchanging) pixels or units (get scaled)? */
+	guint in_destroy : 1;		/* Is child widget being destroyed? */
+};
+
+struct _FooCanvasWidgetClass {
+	FooCanvasItemClass parent_class;
+};
+
+
+/* Standard Gtk function */
+GType foo_canvas_widget_get_type (void) G_GNUC_CONST;
+
+
+G_END_DECLS
+
+#endif
diff --git a/widgets/libfoocanvas/foo-canvas.c b/widgets/libfoocanvas/foo-canvas.c
new file mode 100644
index 0000000..65eb103
--- /dev/null
+++ b/widgets/libfoocanvas/foo-canvas.c
@@ -0,0 +1,4060 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: 8; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * The Gnome Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+/*
+ * FooCanvas widget - Tk-like canvas widget for Gnome
+ *
+ * FooCanvas is basically a port of the Tk toolkit's most excellent canvas widget.  Tk is
+ * copyrighted by the Regents of the University of California, Sun Microsystems, and other parties.
+ *
+ *
+ * Authors: Federico Mena <federico nuclecu unam mx>
+ *          Raph Levien <raph gimp org>
+ */
+
+/*
+ * TO-DO list for the canvas:
+ *
+ * - Allow to specify whether FooCanvasImage sizes are in units or pixels (scale or don't scale).
+ *
+ * - Implement a flag for foo_canvas_item_reparent() that tells the function to keep the item
+ *   visually in the same place, that is, to keep it in the same place with respect to the canvas
+ *   origin.
+ *
+ * - GC put functions for items.
+ *
+ * - Widget item (finish it).
+ *
+ * - GList *foo_canvas_gimme_all_items_contained_in_this_area (FooCanvas *canvas, Rectangle area);
+ *
+ * - Retrofit all the primitive items with microtile support.
+ *
+ * - Curve support for line item.
+ *
+ * - Arc item (Havoc has it; to be integrated in FooCanvasEllipse).
+ *
+ * - Sane font handling API.
+ *
+ * - Get_arg methods for items:
+ *   - How to fetch the outline width and know whether it is in pixels or units?
+ */
+
+#include <config.h>
+
+#include <math.h>
+#include <string.h>
+#include <stdio.h>
+#include <gdk/gdkprivate.h>
+#include <gtk/gtk.h>
+#include "foo-canvas.h"
+#include "foo-canvas-i18n.h"
+
+#include "foo-canvas-marshal.h"
+
+static void foo_canvas_request_update (FooCanvas      *canvas);
+static void group_add                   (FooCanvasGroup *group,
+					 FooCanvasItem  *item);
+static void group_remove                (FooCanvasGroup *group,
+					 FooCanvasItem  *item);
+static void redraw_and_repick_if_mapped (FooCanvasItem *item);
+
+/*** FooCanvasItem ***/
+
+/* Some convenience stuff */
+#define GCI_UPDATE_MASK (FOO_CANVAS_UPDATE_REQUESTED | FOO_CANVAS_UPDATE_DEEP)
+#define GCI_EPSILON 1e-18
+
+enum {
+	ITEM_PROP_0,
+	ITEM_PROP_PARENT,
+	ITEM_PROP_VISIBLE
+};
+
+enum {
+	ITEM_EVENT,
+	ITEM_LAST_SIGNAL
+};
+
+static void foo_canvas_item_class_init     (FooCanvasItemClass *klass);
+static void foo_canvas_item_init           (FooCanvasItem      *item);
+static int  emit_event                       (FooCanvas *canvas, GdkEvent *event);
+
+static guint item_signals[ITEM_LAST_SIGNAL];
+
+static GtkObjectClass *item_parent_class;
+
+static gpointer accessible_item_parent_class;
+static gpointer accessible_parent_class;
+
+
+/**
+ * foo_canvas_item_get_type:
+ *
+ * Registers the &FooCanvasItem class if necessary, and returns the type ID
+ * associated to it.
+ *
+ * Return value:  The type ID of the &FooCanvasItem class.
+ **/
+GType
+foo_canvas_item_get_type (void)
+{
+	static GType canvas_item_type = 0;
+
+	if (!canvas_item_type) {
+		static const GTypeInfo canvas_item_info = {
+			sizeof (FooCanvasItemClass),
+			(GBaseInitFunc) NULL,
+			(GBaseFinalizeFunc) NULL,
+			(GClassInitFunc) foo_canvas_item_class_init,
+			NULL,           /* class_finalize */
+			NULL,           /* class_data */
+			sizeof (FooCanvasItem),
+			0,              /* n_preallocs */
+			(GInstanceInitFunc) foo_canvas_item_init
+		};
+
+		canvas_item_type = g_type_register_static (gtk_object_get_type (),
+							   "FooCanvasItem",
+							   &canvas_item_info,
+							   0);
+	}
+
+	return canvas_item_type;
+}
+
+/* Object initialization function for FooCanvasItem */
+static void
+foo_canvas_item_init (FooCanvasItem *item)
+{
+	item->object.flags |= FOO_CANVAS_ITEM_VISIBLE;
+}
+
+/**
+ * foo_canvas_item_new:
+ * @parent: The parent group for the new item.
+ * @type: The object type of the item.
+ * @first_arg_name: A list of object argument name/value pairs, NULL-terminated,
+ * used to configure the item.  For example, "fill_color", "black",
+ * "width_units", 5.0, NULL.
+ * @Varargs:
+ *
+ * Creates a new canvas item with @parent as its parent group.  The item is
+ * created at the top of its parent's stack, and starts up as visible.  The item
+ * is of the specified @type, for example, it can be
+ * foo_canvas_rect_get_type().  The list of object arguments/value pairs is
+ * used to configure the item.
+ *
+ * Return value: The newly-created item.
+ **/
+FooCanvasItem *
+foo_canvas_item_new (FooCanvasGroup *parent, GType type, const gchar *first_arg_name, ...)
+{
+	FooCanvasItem *item;
+	va_list args;
+
+	g_return_val_if_fail (FOO_IS_CANVAS_GROUP (parent), NULL);
+	g_return_val_if_fail (g_type_is_a (type, foo_canvas_item_get_type ()), NULL);
+
+	item = FOO_CANVAS_ITEM (g_object_new (type, NULL));
+
+	va_start (args, first_arg_name);
+	foo_canvas_item_construct (item, parent, first_arg_name, args);
+	va_end (args);
+
+	return item;
+}
+
+
+/* Performs post-creation operations on a canvas item (adding it to its parent
+ * group, etc.)
+ */
+static void
+item_post_create_setup (FooCanvasItem *item)
+{
+	group_add (FOO_CANVAS_GROUP (item->parent), item);
+
+	redraw_and_repick_if_mapped (item);
+}
+
+/* Set_property handler for canvas items */
+static void
+foo_canvas_item_set_property (GObject *gobject, guint param_id,
+			      const GValue *value, GParamSpec *pspec)
+{
+	FooCanvasItem *item;
+
+	g_return_if_fail (FOO_IS_CANVAS_ITEM (gobject));
+
+	item = FOO_CANVAS_ITEM (gobject);
+
+	switch (param_id) {
+	case ITEM_PROP_PARENT:
+		if (item->parent != NULL) {
+		    g_warning ("Cannot set `parent' argument after item has "
+			       "already been constructed.");
+		} else if (g_value_get_object (value)) {
+			item->parent = FOO_CANVAS_ITEM (g_value_get_object (value));
+			item->canvas = item->parent->canvas;
+			item_post_create_setup (item);
+		}
+		break;
+	case ITEM_PROP_VISIBLE:
+		if (g_value_get_boolean (value)) {
+			foo_canvas_item_show (item);
+		} else {
+			foo_canvas_item_hide (item);
+		}
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec);
+		break;
+	}
+}
+
+/* Get_property handler for canvas items */
+static void
+foo_canvas_item_get_property (GObject *gobject, guint param_id,
+			      GValue *value, GParamSpec *pspec)
+{
+	FooCanvasItem *item;
+
+	g_return_if_fail (FOO_IS_CANVAS_ITEM (gobject));
+
+	item = FOO_CANVAS_ITEM (gobject);
+
+	switch (param_id) {
+	case ITEM_PROP_VISIBLE:
+		g_value_set_boolean (value, item->object.flags & FOO_CANVAS_ITEM_VISIBLE);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec);
+		break;
+	}
+}
+
+/**
+ * foo_canvas_item_construct:
+ * @item: An unconstructed canvas item.
+ * @parent: The parent group for the item.
+ * @first_arg_name: The name of the first argument for configuring the item.
+ * @args: The list of arguments used to configure the item.
+ *
+ * Constructs a canvas item; meant for use only by item implementations.
+ **/
+void
+foo_canvas_item_construct (FooCanvasItem *item, FooCanvasGroup *parent,
+			   const gchar *first_arg_name, va_list args)
+{
+	g_return_if_fail (FOO_IS_CANVAS_GROUP (parent));
+	g_return_if_fail (FOO_IS_CANVAS_ITEM (item));
+
+	item->parent = FOO_CANVAS_ITEM (parent);
+	item->canvas = item->parent->canvas;
+
+	g_object_set_valist (G_OBJECT (item), first_arg_name, args);
+
+	item_post_create_setup (item);
+}
+
+
+static void
+redraw_and_repick_if_mapped (FooCanvasItem *item)
+{
+	if (item->object.flags & FOO_CANVAS_ITEM_MAPPED) {
+		foo_canvas_item_request_redraw (item);
+		item->canvas->need_repick = TRUE;
+	}
+}
+
+/* Dispose handler for canvas items */
+static void
+foo_canvas_item_dispose (GObject *object)
+{
+	FooCanvasItem *item;
+
+	g_return_if_fail (FOO_IS_CANVAS_ITEM (object));
+
+	item = FOO_CANVAS_ITEM (object);
+
+	if (item->canvas) {
+		foo_canvas_item_request_redraw (item);
+
+		/* Make the canvas forget about us */
+
+		if (item == item->canvas->current_item) {
+			item->canvas->current_item = NULL;
+			item->canvas->need_repick = TRUE;
+		}
+
+		if (item == item->canvas->new_current_item) {
+			item->canvas->new_current_item = NULL;
+			item->canvas->need_repick = TRUE;
+		}
+
+		if (item == item->canvas->grabbed_item) {
+			GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (item->canvas));
+			item->canvas->grabbed_item = NULL;
+			gdk_display_pointer_ungrab (display, GDK_CURRENT_TIME);
+		}
+
+		if (item == item->canvas->focused_item)
+			item->canvas->focused_item = NULL;
+
+		/* Normal destroy stuff */
+
+		if (item->object.flags & FOO_CANVAS_ITEM_MAPPED)
+			(* FOO_CANVAS_ITEM_GET_CLASS (item)->unmap) (item);
+
+		if (item->object.flags & FOO_CANVAS_ITEM_REALIZED)
+			(* FOO_CANVAS_ITEM_GET_CLASS (item)->unrealize) (item);
+
+		if (item->parent)
+			group_remove (FOO_CANVAS_GROUP (item->parent), item);
+
+		item->canvas = NULL;
+	}
+
+	G_OBJECT_CLASS (item_parent_class)->dispose (object);
+}
+
+
+/* Realize handler for canvas items */
+static void
+foo_canvas_item_realize (FooCanvasItem *item)
+{
+	if (item->parent && !(item->parent->object.flags & FOO_CANVAS_ITEM_REALIZED))
+		(* FOO_CANVAS_ITEM_GET_CLASS (item->parent)->realize) (item->parent);
+	
+	if (item->parent == NULL && !GTK_WIDGET_REALIZED (GTK_WIDGET (item->canvas)))
+		gtk_widget_realize (GTK_WIDGET (item->canvas));
+	
+	GTK_OBJECT_SET_FLAGS (item, FOO_CANVAS_ITEM_REALIZED);
+
+	foo_canvas_item_request_update (item);
+}
+
+/* Unrealize handler for canvas items */
+static void
+foo_canvas_item_unrealize (FooCanvasItem *item)
+{
+	if (item->object.flags & FOO_CANVAS_ITEM_MAPPED)
+		(* FOO_CANVAS_ITEM_GET_CLASS (item)->unmap) (item);
+	
+	GTK_OBJECT_UNSET_FLAGS (item, FOO_CANVAS_ITEM_REALIZED);
+}
+
+/* Map handler for canvas items */
+static void
+foo_canvas_item_map (FooCanvasItem *item)
+{
+	GTK_OBJECT_SET_FLAGS (item, FOO_CANVAS_ITEM_MAPPED);
+}
+
+/* Unmap handler for canvas items */
+static void
+foo_canvas_item_unmap (FooCanvasItem *item)
+{
+	GTK_OBJECT_UNSET_FLAGS (item, FOO_CANVAS_ITEM_MAPPED);
+}
+
+/* Update handler for canvas items */
+static void
+foo_canvas_item_update (FooCanvasItem *item, double i2w_dx, double i2w_dy, int flags)
+{
+	GTK_OBJECT_UNSET_FLAGS (item, FOO_CANVAS_ITEM_NEED_UPDATE);
+	GTK_OBJECT_UNSET_FLAGS (item, FOO_CANVAS_ITEM_NEED_DEEP_UPDATE);
+}
+
+/*
+ * This routine invokes the update method of the item
+ * Please notice, that we take parent to canvas pixel matrix as argument
+ * unlike virtual method ::update, whose argument is item 2 canvas pixel
+ * matrix
+ *
+ * I will try to force somewhat meaningful naming for affines (Lauris)
+ * General naming rule is FROM2TO, where FROM and TO are abbreviations
+ * So p2cpx is Parent2CanvasPixel and i2cpx is Item2CanvasPixel
+ * I hope that this helps to keep track of what really happens
+ *
+ */
+
+static void
+foo_canvas_item_invoke_update (FooCanvasItem *item,
+			       double i2w_dx,
+			       double i2w_dy,
+			       int flags)
+{
+	int child_flags;
+
+	child_flags = flags;
+
+	/* apply object flags to child flags */
+	child_flags &= ~FOO_CANVAS_UPDATE_REQUESTED;
+
+	if (item->object.flags & FOO_CANVAS_ITEM_NEED_UPDATE)
+		child_flags |= FOO_CANVAS_UPDATE_REQUESTED;
+
+	if (item->object.flags & FOO_CANVAS_ITEM_NEED_DEEP_UPDATE)
+		child_flags |= FOO_CANVAS_UPDATE_DEEP;
+
+	if (child_flags & GCI_UPDATE_MASK) {
+		if (FOO_CANVAS_ITEM_GET_CLASS (item)->update)
+			FOO_CANVAS_ITEM_GET_CLASS (item)->update (item, i2w_dx, i2w_dy, child_flags);
+	}
+ 
+	/* If this fail you probably forgot to chain up to
+	 * FooCanvasItem::update from a derived class */
+ 	g_return_if_fail (!(item->object.flags & FOO_CANVAS_ITEM_NEED_UPDATE));
+}
+
+/*
+ * This routine invokes the point method of the item.
+ * The arguments x, y should be in the parent item local coordinates.
+ */
+
+static double
+foo_canvas_item_invoke_point (FooCanvasItem *item, double x, double y, int cx, int cy, FooCanvasItem **actual_item)
+{
+	/* Calculate x & y in item local coordinates */
+
+	if (FOO_CANVAS_ITEM_GET_CLASS (item)->point)
+		return FOO_CANVAS_ITEM_GET_CLASS (item)->point (item, x, y, cx, cy, actual_item);
+
+	return 1e18;
+}
+
+/**
+ * foo_canvas_item_set:
+ * @item: A canvas item.
+ * @first_arg_name: The list of object argument name/value pairs used to configure the item.
+ * @Varargs:
+ *
+ * Configures a canvas item.  The arguments in the item are set to the specified
+ * values, and the item is repainted as appropriate.
+ **/
+void
+foo_canvas_item_set (FooCanvasItem *item, const gchar *first_arg_name, ...)
+{
+	va_list args;
+
+	va_start (args, first_arg_name);
+	foo_canvas_item_set_valist (item, first_arg_name, args);
+	va_end (args);
+}
+
+
+/**
+ * foo_canvas_item_set_valist:
+ * @item: A canvas item.
+ * @first_arg_name: The name of the first argument used to configure the item.
+ * @args: The list of object argument name/value pairs used to configure the item.
+ *
+ * Configures a canvas item.  The arguments in the item are set to the specified
+ * values, and the item is repainted as appropriate.
+ **/
+void
+foo_canvas_item_set_valist (FooCanvasItem *item, const gchar *first_arg_name, va_list args)
+{
+	g_return_if_fail (FOO_IS_CANVAS_ITEM (item));
+
+	g_object_set_valist (G_OBJECT (item), first_arg_name, args);
+
+#if 0
+	/* I commented this out, because item implementations have to schedule update/redraw */
+	foo_canvas_item_request_redraw (item);
+#endif
+
+	item->canvas->need_repick = TRUE;
+}
+
+/**
+ * foo_canvas_item_move:
+ * @item: A canvas item.
+ * @dx: Horizontal offset.
+ * @dy: Vertical offset.
+ *
+ * Moves a canvas item by creating an affine transformation matrix for
+ * translation by using the specified values. This happens in item
+ * local coordinate system, so if you have nontrivial transform, it
+ * most probably does not do, what you want.
+ **/
+void
+foo_canvas_item_move (FooCanvasItem *item, double dx, double dy)
+{
+        g_return_if_fail (item != NULL);
+        g_return_if_fail (FOO_IS_CANVAS_ITEM (item));
+
+        if (!FOO_CANVAS_ITEM_GET_CLASS (item)->translate) {
+                g_warning ("Item type %s does not implement translate method.\n",
+                           g_type_name (GTK_OBJECT_TYPE (item)));
+                return;
+        }
+
+        (* FOO_CANVAS_ITEM_GET_CLASS (item)->translate) (item, dx, dy);
+
+	if (item->object.flags & FOO_CANVAS_ITEM_MAPPED) 
+		item->canvas->need_repick = TRUE;
+
+	if (!(item->object.flags & FOO_CANVAS_ITEM_NEED_DEEP_UPDATE)) {
+		item->object.flags |= FOO_CANVAS_ITEM_NEED_DEEP_UPDATE;
+		if (item->parent != NULL)
+			foo_canvas_item_request_update (item->parent);
+		else
+			foo_canvas_request_update (item->canvas);
+	}
+
+}
+
+/* Convenience function to reorder items in a group's child list.  This puts the
+ * specified link after the "before" link. Returns TRUE if the list was changed.
+ */
+static gboolean
+put_item_after (GList *link, GList *before)
+{
+	FooCanvasGroup *parent;
+
+	if (link == before)
+		return FALSE;
+
+	parent = FOO_CANVAS_GROUP (FOO_CANVAS_ITEM (link->data)->parent);
+
+	if (before == NULL) {
+		if (link == parent->item_list)
+			return FALSE;
+
+		link->prev->next = link->next;
+
+		if (link->next)
+			link->next->prev = link->prev;
+		else
+			parent->item_list_end = link->prev;
+
+		link->prev = before;
+		link->next = parent->item_list;
+		link->next->prev = link;
+		parent->item_list = link;
+	} else {
+		if ((link == parent->item_list_end) && (before == parent->item_list_end->prev))
+			return FALSE;
+
+		if (link->next)
+			link->next->prev = link->prev;
+
+		if (link->prev)
+			link->prev->next = link->next;
+		else {
+			parent->item_list = link->next;
+			parent->item_list->prev = NULL;
+		}
+
+		link->prev = before;
+		link->next = before->next;
+
+		link->prev->next = link;
+
+		if (link->next)
+			link->next->prev = link;
+		else
+			parent->item_list_end = link;
+	}
+	return TRUE;
+}
+
+
+/**
+ * foo_canvas_item_raise:
+ * @item: A canvas item.
+ * @positions: Number of steps to raise the item.
+ *
+ * Raises the item in its parent's stack by the specified number of positions.
+ * If the number of positions is greater than the distance to the top of the
+ * stack, then the item is put at the top.
+ **/
+void
+foo_canvas_item_raise (FooCanvasItem *item, int positions)
+{
+	GList *link, *before;
+	FooCanvasGroup *parent;
+
+	g_return_if_fail (FOO_IS_CANVAS_ITEM (item));
+	g_return_if_fail (positions >= 0);
+
+	if (!item->parent || positions == 0)
+		return;
+
+	parent = FOO_CANVAS_GROUP (item->parent);
+	link = g_list_find (parent->item_list, item);
+	g_assert (link != NULL);
+
+	for (before = link; positions && before; positions--)
+		before = before->next;
+
+	if (!before)
+		before = parent->item_list_end;
+
+	if (put_item_after (link, before)) {
+		redraw_and_repick_if_mapped (item);
+	}
+}
+
+
+/**
+ * foo_canvas_item_lower:
+ * @item: A canvas item.
+ * @positions: Number of steps to lower the item.
+ *
+ * Lowers the item in its parent's stack by the specified number of positions.
+ * If the number of positions is greater than the distance to the bottom of the
+ * stack, then the item is put at the bottom.
+ **/
+void
+foo_canvas_item_lower (FooCanvasItem *item, int positions)
+{
+	GList *link, *before;
+	FooCanvasGroup *parent;
+
+	g_return_if_fail (FOO_IS_CANVAS_ITEM (item));
+	g_return_if_fail (positions >= 1);
+
+	if (!item->parent || positions == 0)
+		return;
+
+	parent = FOO_CANVAS_GROUP (item->parent);
+	link = g_list_find (parent->item_list, item);
+	g_assert (link != NULL);
+
+	if (link->prev)
+		for (before = link->prev; positions && before; positions--)
+			before = before->prev;
+	else
+		before = NULL;
+
+	if (put_item_after (link, before)) {
+		redraw_and_repick_if_mapped (item);
+	}
+}
+
+
+/**
+ * foo_canvas_item_raise_to_top:
+ * @item: A canvas item.
+ *
+ * Raises an item to the top of its parent's stack.
+ **/
+void
+foo_canvas_item_raise_to_top (FooCanvasItem *item)
+{
+	GList *link;
+	FooCanvasGroup *parent;
+
+	g_return_if_fail (FOO_IS_CANVAS_ITEM (item));
+
+	if (!item->parent)
+		return;
+
+	parent = FOO_CANVAS_GROUP (item->parent);
+	link = g_list_find (parent->item_list, item);
+	g_assert (link != NULL);
+
+	if (put_item_after (link, parent->item_list_end)) {
+		redraw_and_repick_if_mapped (item);
+	}
+}
+
+
+/**
+ * foo_canvas_item_lower_to_bottom:
+ * @item: A canvas item.
+ *
+ * Lowers an item to the bottom of its parent's stack.
+ **/
+void
+foo_canvas_item_lower_to_bottom (FooCanvasItem *item)
+{
+	GList *link;
+	FooCanvasGroup *parent;
+
+	g_return_if_fail (FOO_IS_CANVAS_ITEM (item));
+
+	if (!item->parent)
+		return;
+
+	parent = FOO_CANVAS_GROUP (item->parent);
+	link = g_list_find (parent->item_list, item);
+	g_assert (link != NULL);
+
+	if (put_item_after (link, NULL)) {
+		redraw_and_repick_if_mapped (item);
+	}
+}
+
+/**
+ * foo_canvas_item_send_behind:
+ * @item: A canvas item.
+ * @behind_item: The canvas item to put item behind, or NULL
+ *
+ * Moves item to a in the position in the stacking order so that
+ * it is placed immediately below behind_item, or at the top if
+ * behind_item is NULL.
+ **/
+void
+foo_canvas_item_send_behind (FooCanvasItem *item,
+			     FooCanvasItem *behind_item)
+{
+	GList *item_list;
+	int item_position, behind_position;
+
+	g_return_if_fail (FOO_IS_CANVAS_ITEM (item));
+
+	if (behind_item == NULL) {
+		foo_canvas_item_raise_to_top (item);
+		return;
+	}
+
+	g_return_if_fail (FOO_IS_CANVAS_ITEM (behind_item));
+	g_return_if_fail (item->parent == behind_item->parent);
+
+	item_list = FOO_CANVAS_GROUP (item->parent)->item_list;
+
+	item_position = g_list_index (item_list, item);
+	g_assert (item_position != -1);
+	behind_position = g_list_index (item_list, behind_item);
+	g_assert (behind_position != -1);
+	g_assert (item_position != behind_position);
+
+	if (item_position == behind_position - 1) {
+		return;
+	}
+
+	if (item_position < behind_position) {
+		foo_canvas_item_raise (item, (behind_position - 1) - item_position);
+	} else {
+		foo_canvas_item_lower (item, item_position - behind_position);
+	}
+}
+
+/**
+ * foo_canvas_item_show:
+ * @item: A canvas item.
+ *
+ * Shows a canvas item.  If the item was already shown, then no action is taken.
+ **/
+void
+foo_canvas_item_show (FooCanvasItem *item)
+{
+	g_return_if_fail (FOO_IS_CANVAS_ITEM (item));
+
+	if (!(item->object.flags & FOO_CANVAS_ITEM_VISIBLE)) {
+		item->object.flags |= FOO_CANVAS_ITEM_VISIBLE;
+		
+		if (!(item->object.flags & FOO_CANVAS_ITEM_REALIZED))
+			(* FOO_CANVAS_ITEM_GET_CLASS (item)->realize) (item);
+
+		if (item->parent != NULL) {
+			if (!(item->object.flags & FOO_CANVAS_ITEM_MAPPED) &&
+			    item->parent->object.flags & FOO_CANVAS_ITEM_MAPPED)
+				(* FOO_CANVAS_ITEM_GET_CLASS (item)->map) (item);
+		} else {
+			if (!(item->object.flags & FOO_CANVAS_ITEM_MAPPED) &&
+			    GTK_WIDGET_MAPPED (GTK_WIDGET (item->canvas)))
+				(* FOO_CANVAS_ITEM_GET_CLASS (item)->map) (item);
+		}
+
+		redraw_and_repick_if_mapped (item);
+	}
+}
+
+
+/**
+ * foo_canvas_item_hide:
+ * @item: A canvas item.
+ *
+ * Hides a canvas item.  If the item was already hidden, then no action is
+ * taken.
+ **/
+void
+foo_canvas_item_hide (FooCanvasItem *item)
+{
+	g_return_if_fail (FOO_IS_CANVAS_ITEM (item));
+
+	if (item->object.flags & FOO_CANVAS_ITEM_VISIBLE) {
+		item->object.flags &= ~FOO_CANVAS_ITEM_VISIBLE;
+
+		redraw_and_repick_if_mapped (item);
+		
+		if (item->object.flags & FOO_CANVAS_ITEM_MAPPED)
+			(* FOO_CANVAS_ITEM_GET_CLASS (item)->unmap) (item);
+
+		/* No need to unrealize when we just want to hide */
+	}
+}
+
+
+/**
+ * foo_canvas_item_grab:
+ * @item: A canvas item.
+ * @event_mask: Mask of events that will be sent to this item.
+ * @cursor: If non-NULL, the cursor that will be used while the grab is active.
+ * @etime: The timestamp required for grabbing the mouse, or GDK_CURRENT_TIME.
+ *
+ * Specifies that all events that match the specified event mask should be sent
+ * to the specified item, and also grabs the mouse by calling
+ * gdk_pointer_grab().  The event mask is also used when grabbing the pointer.
+ * If @cursor is not NULL, then that cursor is used while the grab is active.
+ * The @etime parameter is the timestamp required for grabbing the mouse.
+ *
+ * Return value: If an item was already grabbed, it returns %GDK_GRAB_ALREADY_GRABBED.  If
+ * the specified item was hidden by calling foo_canvas_item_hide(), then it
+ * returns %GDK_GRAB_NOT_VIEWABLE.  Else, it returns the result of calling
+ * gdk_pointer_grab().
+ **/
+int
+foo_canvas_item_grab (FooCanvasItem *item, guint event_mask, GdkCursor *cursor, guint32 etime)
+{
+	int retval;
+
+	g_return_val_if_fail (FOO_IS_CANVAS_ITEM (item), GDK_GRAB_NOT_VIEWABLE);
+	g_return_val_if_fail (GTK_WIDGET_MAPPED (item->canvas), GDK_GRAB_NOT_VIEWABLE);
+
+	if (item->canvas->grabbed_item)
+		return GDK_GRAB_ALREADY_GRABBED;
+
+	if (!(item->object.flags & FOO_CANVAS_ITEM_MAPPED))
+		return GDK_GRAB_NOT_VIEWABLE;
+
+	retval = gdk_pointer_grab (item->canvas->layout.bin_window,
+				   FALSE,
+				   event_mask,
+				   NULL,
+				   cursor,
+				   etime);
+
+	if (retval != GDK_GRAB_SUCCESS)
+		return retval;
+
+	item->canvas->grabbed_item = item;
+	item->canvas->grabbed_event_mask = event_mask;
+	item->canvas->current_item = item; /* So that events go to the grabbed item */
+
+	return retval;
+}
+
+
+/**
+ * foo_canvas_item_ungrab:
+ * @item: A canvas item that holds a grab.
+ * @etime: The timestamp for ungrabbing the mouse.
+ *
+ * Ungrabs the item, which must have been grabbed in the canvas, and ungrabs the
+ * mouse.
+ **/
+void
+foo_canvas_item_ungrab (FooCanvasItem *item, guint32 etime)
+{
+	GdkDisplay *display;
+
+	g_return_if_fail (FOO_IS_CANVAS_ITEM (item));
+
+	if (item->canvas->grabbed_item != item)
+		return;
+
+	display = gtk_widget_get_display (GTK_WIDGET (item->canvas));
+	item->canvas->grabbed_item = NULL;
+	gdk_display_pointer_ungrab (display, etime);
+}
+
+
+/**
+ * foo_canvas_item_i2w_affine:
+ * @item: A canvas item
+ * @affine: An affine transformation matrix (return value).
+ *
+ * Gets the affine transform that converts from the item's coordinate system to
+ * world coordinates.
+ **/
+void
+foo_canvas_item_i2w_affine (FooCanvasItem *item, double affine[6])
+{
+	g_return_if_fail (FOO_IS_CANVAS_ITEM (item));
+	g_return_if_fail (affine != NULL);
+
+	art_affine_identity (affine);
+}
+
+/**
+ * foo_canvas_item_w2i:
+ * @item: A canvas item.
+ * @x: X coordinate to convert (input/output value).
+ * @y: Y coordinate to convert (input/output value).
+ *
+ * Converts a coordinate pair from world coordinates to item-relative
+ * coordinates.
+ **/
+void
+foo_canvas_item_w2i (FooCanvasItem *item, double *x, double *y)
+{
+	g_return_if_fail (FOO_IS_CANVAS_ITEM (item));
+	g_return_if_fail (x != NULL);
+	g_return_if_fail (y != NULL);
+
+	item = item->parent;
+	while (item) {
+		if (FOO_IS_CANVAS_GROUP (item)) {
+			*x -= FOO_CANVAS_GROUP (item)->xpos;
+			*y -= FOO_CANVAS_GROUP (item)->ypos;
+		}
+
+		item = item->parent;
+	}
+}
+
+
+/**
+ * foo_canvas_item_i2w:
+ * @item: A canvas item.
+ * @x: X coordinate to convert (input/output value).
+ * @y: Y coordinate to convert (input/output value).
+ *
+ * Converts a coordinate pair from item-relative coordinates to world
+ * coordinates.
+ **/
+void
+foo_canvas_item_i2w (FooCanvasItem *item, double *x, double *y)
+{
+	g_return_if_fail (FOO_IS_CANVAS_ITEM (item));
+	g_return_if_fail (x != NULL);
+	g_return_if_fail (y != NULL);
+
+	item = item->parent;
+	while (item) {
+		if (FOO_IS_CANVAS_GROUP (item)) {
+			*x += FOO_CANVAS_GROUP (item)->xpos;
+			*y += FOO_CANVAS_GROUP (item)->ypos;
+		}
+
+		item = item->parent;
+	}
+}
+
+/**
+ * foo_canvas_item_i2c_affine:
+ * @item: A canvas item.
+ * @affine: An affine transformation matrix (return value).
+ *
+ * Gets the affine transform that converts from item-relative coordinates to
+ * canvas pixel coordinates.
+ **/
+void
+foo_canvas_item_i2c_affine (FooCanvasItem *item, double affine[6])
+{
+	double i2w[6], w2c[6];
+
+	foo_canvas_item_i2w_affine (item, i2w);
+	foo_canvas_w2c_affine (item->canvas, w2c);
+	art_affine_multiply (affine, i2w, w2c);
+}
+
+/* Returns whether the item is an inferior of or is equal to the parent. */
+static int
+is_descendant (FooCanvasItem *item, FooCanvasItem *parent)
+{
+	for (; item; item = item->parent)
+		if (item == parent)
+			return TRUE;
+
+	return FALSE;
+}
+
+/**
+ * foo_canvas_item_reparent:
+ * @item: A canvas item.
+ * @new_group: A canvas group.
+ *
+ * Changes the parent of the specified item to be the new group.  The item keeps
+ * its group-relative coordinates as for its old parent, so the item may change
+ * its absolute position within the canvas.
+ **/
+void
+foo_canvas_item_reparent (FooCanvasItem *item, FooCanvasGroup *new_group)
+{
+	g_return_if_fail (FOO_IS_CANVAS_ITEM (item));
+	g_return_if_fail (FOO_IS_CANVAS_GROUP (new_group));
+
+	/* Both items need to be in the same canvas */
+	g_return_if_fail (item->canvas == FOO_CANVAS_ITEM (new_group)->canvas);
+
+	/* The group cannot be an inferior of the item or be the item itself --
+	 * this also takes care of the case where the item is the root item of
+	 * the canvas.  */
+	g_return_if_fail (!is_descendant (FOO_CANVAS_ITEM (new_group), item));
+
+	/* Everything is ok, now actually reparent the item */
+
+	g_object_ref (G_OBJECT (item)); /* protect it from the unref in group_remove */
+
+	foo_canvas_item_request_redraw (item);
+
+	group_remove (FOO_CANVAS_GROUP (item->parent), item);
+	item->parent = FOO_CANVAS_ITEM (new_group);
+	/* item->canvas is unchanged.  */
+	group_add (new_group, item);
+
+	/* Redraw and repick */
+
+	redraw_and_repick_if_mapped (item);
+
+	g_object_unref (G_OBJECT (item));
+}
+
+/**
+ * foo_canvas_item_grab_focus:
+ * @item: A canvas item.
+ *
+ * Makes the specified item take the keyboard focus, so all keyboard events will
+ * be sent to it.  If the canvas widget itself did not have the focus, it grabs
+ * it as well.
+ **/
+void
+foo_canvas_item_grab_focus (FooCanvasItem *item)
+{
+	FooCanvasItem *focused_item;
+	GdkEvent ev;
+
+	g_return_if_fail (FOO_IS_CANVAS_ITEM (item));
+	g_return_if_fail (GTK_WIDGET_CAN_FOCUS (GTK_WIDGET (item->canvas)));
+
+	focused_item = item->canvas->focused_item;
+
+	if (focused_item) {
+		ev.focus_change.type = GDK_FOCUS_CHANGE;
+		ev.focus_change.window = GTK_LAYOUT (item->canvas)->bin_window;
+		ev.focus_change.send_event = FALSE;
+		ev.focus_change.in = FALSE;
+
+		emit_event (item->canvas, &ev);
+	}
+
+	item->canvas->focused_item = item;
+	gtk_widget_grab_focus (GTK_WIDGET (item->canvas));
+
+	if (focused_item) {                                                     
+		ev.focus_change.type = GDK_FOCUS_CHANGE;                        
+		ev.focus_change.window = GTK_LAYOUT (item->canvas)->bin_window;
+		ev.focus_change.send_event = FALSE;                             
+		ev.focus_change.in = TRUE;                                      
+
+		emit_event (item->canvas, &ev);                          
+	}                               
+}
+
+
+/**
+ * foo_canvas_item_get_bounds:
+ * @item: A canvas item.
+ * @x1: Leftmost edge of the bounding box (return value).
+ * @y1: Upper edge of the bounding box (return value).
+ * @x2: Rightmost edge of the bounding box (return value).
+ * @y2: Lower edge of the bounding box (return value).
+ *
+ * Queries the bounding box of a canvas item.  The bounds are returned in the
+ * coordinate system of the item's parent.
+ **/
+void
+foo_canvas_item_get_bounds (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2)
+{
+	double tx1, ty1, tx2, ty2;
+
+	g_return_if_fail (FOO_IS_CANVAS_ITEM (item));
+
+	tx1 = ty1 = tx2 = ty2 = 0.0;
+
+	/* Get the item's bounds in its coordinate system */
+
+	if (FOO_CANVAS_ITEM_GET_CLASS (item)->bounds)
+		(* FOO_CANVAS_ITEM_GET_CLASS (item)->bounds) (item, &tx1, &ty1, &tx2, &ty2);
+
+	/* Return the values */
+
+	if (x1)
+		*x1 = tx1;
+
+	if (y1)
+		*y1 = ty1;
+
+	if (x2)
+		*x2 = tx2;
+
+	if (y2)
+		*y2 = ty2;
+}
+
+
+/**
+ * foo_canvas_item_request_update
+ * @item: A canvas item.
+ *
+ * To be used only by item implementations.  Requests that the canvas queue an
+ * update for the specified item.
+ **/
+void
+foo_canvas_item_request_update (FooCanvasItem *item)
+{
+	if (NULL == item->canvas)
+		return;
+
+	g_return_if_fail (!item->canvas->doing_update);
+
+	if (item->object.flags & FOO_CANVAS_ITEM_NEED_UPDATE)
+		return;
+
+	item->object.flags |= FOO_CANVAS_ITEM_NEED_UPDATE;
+
+	if (item->parent != NULL) {
+		/* Recurse up the tree */
+		foo_canvas_item_request_update (item->parent);
+	} else {
+		/* Have reached the top of the tree, make sure the update call gets scheduled. */
+		foo_canvas_request_update (item->canvas);
+	}
+}
+
+/**
+ * foo_canvas_item_request_update
+ * @item: A canvas item.
+ *
+ * Convenience function that informs a canvas that the specified item needs
+ * to be repainted. To be used by item implementations
+ **/
+void
+foo_canvas_item_request_redraw (FooCanvasItem *item)
+{
+	if (item->object.flags & FOO_CANVAS_ITEM_MAPPED)
+		foo_canvas_request_redraw (item->canvas,
+					   item->x1, item->y1,
+					   item->x2 + 1, item->y2 + 1);
+}
+
+
+
+/*** FooCanvasGroup ***/
+
+
+enum {
+	GROUP_PROP_0,
+	GROUP_PROP_X,
+	GROUP_PROP_Y
+};
+
+
+static void foo_canvas_group_class_init  (FooCanvasGroupClass *klass);
+static void foo_canvas_group_init        (FooCanvasGroup      *group);
+static void foo_canvas_group_set_property(GObject               *object, 
+					    guint                  param_id,
+					    const GValue          *value,
+					    GParamSpec            *pspec);
+static void foo_canvas_group_get_property(GObject               *object,
+					    guint                  param_id,
+					    GValue                *value,
+					    GParamSpec            *pspec);
+
+static void foo_canvas_group_destroy     (GtkObject             *object);
+
+static void   foo_canvas_group_update      (FooCanvasItem *item,
+					      double           i2w_dx,
+					      double           i2w_dy,
+					      int              flags);
+static void   foo_canvas_group_unrealize   (FooCanvasItem *item);
+static void   foo_canvas_group_map         (FooCanvasItem *item);
+static void   foo_canvas_group_unmap       (FooCanvasItem *item);
+static void   foo_canvas_group_draw        (FooCanvasItem *item, GdkDrawable *drawable,
+					      GdkEventExpose *expose);
+static double foo_canvas_group_point       (FooCanvasItem *item, double x, double y,
+					      int cx, int cy,
+					      FooCanvasItem **actual_item);
+static void   foo_canvas_group_translate   (FooCanvasItem *item, double dx, double dy);
+static void   foo_canvas_group_bounds      (FooCanvasItem *item, double *x1, double *y1,
+					      double *x2, double *y2);
+
+
+static FooCanvasItemClass *group_parent_class;
+
+
+/**
+ * foo_canvas_group_get_type:
+ *
+ * Registers the &FooCanvasGroup class if necessary, and returns the type ID
+ * associated to it.
+ *
+ * Return value:  The type ID of the &FooCanvasGroup class.
+ **/
+GType
+foo_canvas_group_get_type (void)
+{
+	static GType group_type = 0;
+
+	if (!group_type) {
+		static const GTypeInfo group_info = {
+			sizeof (FooCanvasGroupClass),
+			(GBaseInitFunc) NULL,
+			(GBaseFinalizeFunc) NULL,
+			(GClassInitFunc) foo_canvas_group_class_init,
+			NULL,           /* class_finalize */
+			NULL,           /* class_data */
+			sizeof (FooCanvasGroup),
+			0,              /* n_preallocs */
+			(GInstanceInitFunc) foo_canvas_group_init
+
+	
+		};
+
+		group_type = g_type_register_static (foo_canvas_item_get_type (),
+						     "FooCanvasGroup",
+						     &group_info,
+						     0);
+	}
+
+	return group_type;
+}
+
+/* Class initialization function for FooCanvasGroupClass */
+static void
+foo_canvas_group_class_init (FooCanvasGroupClass *klass)
+{
+	GObjectClass *gobject_class;
+	GtkObjectClass *object_class;
+	FooCanvasItemClass *item_class;
+
+	gobject_class = (GObjectClass *) klass;
+	object_class = (GtkObjectClass *) klass;
+	item_class = (FooCanvasItemClass *) klass;
+
+	group_parent_class = g_type_class_peek_parent (klass);
+
+	gobject_class->set_property = foo_canvas_group_set_property;
+	gobject_class->get_property = foo_canvas_group_get_property;
+
+	g_object_class_install_property
+		(gobject_class, GROUP_PROP_X,
+		 g_param_spec_double ("x",
+				      _("X"),
+				      _("X"),
+				      -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
+				      G_PARAM_READWRITE));
+	g_object_class_install_property
+		(gobject_class, GROUP_PROP_Y,
+		 g_param_spec_double ("y",
+				      _("Y"),
+				      _("Y"),
+				      -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
+				      G_PARAM_READWRITE));
+
+	object_class->destroy = foo_canvas_group_destroy;
+
+	item_class->update = foo_canvas_group_update;
+	item_class->unrealize = foo_canvas_group_unrealize;
+	item_class->map = foo_canvas_group_map;
+	item_class->unmap = foo_canvas_group_unmap;
+	item_class->draw = foo_canvas_group_draw;
+	item_class->point = foo_canvas_group_point;
+	item_class->translate = foo_canvas_group_translate;
+	item_class->bounds = foo_canvas_group_bounds;
+}
+
+/* Object initialization function for FooCanvasGroup */
+static void
+foo_canvas_group_init (FooCanvasGroup *group)
+{
+	group->xpos = 0.0;
+	group->ypos = 0.0;
+}
+
+/* Set_property handler for canvas groups */
+static void
+foo_canvas_group_set_property (GObject *gobject, guint param_id,
+			       const GValue *value, GParamSpec *pspec)
+{
+	FooCanvasItem *item;
+	FooCanvasGroup *group;
+	double old;
+	gboolean moved;
+
+	g_return_if_fail (FOO_IS_CANVAS_GROUP (gobject));
+
+	item = FOO_CANVAS_ITEM (gobject);
+	group = FOO_CANVAS_GROUP (gobject);
+
+	moved = FALSE;
+	switch (param_id) {
+	case GROUP_PROP_X:
+		old = group->xpos;
+		group->xpos = g_value_get_double (value);
+		if (old != group->xpos)
+			moved = TRUE;
+		break;
+
+	case GROUP_PROP_Y:
+		old = group->ypos;
+		group->ypos = g_value_get_double (value);
+		if (old != group->ypos)
+			moved = TRUE;
+		break;
+
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec);
+		break;
+	}
+
+	if (moved) {
+		item->object.flags |= FOO_CANVAS_ITEM_NEED_DEEP_UPDATE;
+		if (item->parent != NULL)
+			foo_canvas_item_request_update (item->parent);
+		else
+			foo_canvas_request_update (item->canvas);
+	}
+}
+
+/* Get_property handler for canvas groups */
+static void
+foo_canvas_group_get_property (GObject *gobject, guint param_id,
+				 GValue *value, GParamSpec *pspec)
+{
+	FooCanvasItem *item;
+	FooCanvasGroup *group;
+
+	g_return_if_fail (FOO_IS_CANVAS_GROUP (gobject));
+
+	item = FOO_CANVAS_ITEM (gobject);
+	group = FOO_CANVAS_GROUP (gobject);
+
+	switch (param_id) {
+	case GROUP_PROP_X:
+		g_value_set_double (value, group->xpos);
+		break;
+
+	case GROUP_PROP_Y:
+		g_value_set_double (value, group->ypos);
+		break;
+
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec);
+		break;
+	}
+}
+
+/* Destroy handler for canvas groups */
+static void
+foo_canvas_group_destroy (GtkObject *object)
+{
+	FooCanvasGroup *group;
+	FooCanvasItem *child;
+	GList *list;
+
+	g_return_if_fail (FOO_IS_CANVAS_GROUP (object));
+
+	group = FOO_CANVAS_GROUP (object);
+
+	list = group->item_list;
+	while (list) {
+		child = list->data;
+		list = list->next;
+
+		gtk_object_destroy (GTK_OBJECT (child));
+	}
+
+	if (GTK_OBJECT_CLASS (group_parent_class)->destroy)
+		(* GTK_OBJECT_CLASS (group_parent_class)->destroy) (object);
+}
+
+/* Update handler for canvas groups */
+static void
+foo_canvas_group_update (FooCanvasItem *item, double i2w_dx, double i2w_dy, int flags)
+{
+	FooCanvasGroup *group;
+	GList *list;
+	FooCanvasItem *i;
+	double bbox_x0, bbox_y0, bbox_x1, bbox_y1;
+	gboolean first = TRUE;
+
+	group = FOO_CANVAS_GROUP (item);
+
+	(* group_parent_class->update) (item, i2w_dx, i2w_dy, flags);
+
+	bbox_x0 = 0;
+	bbox_y0 = 0;
+	bbox_x1 = 0;
+	bbox_y1 = 0;
+
+	for (list = group->item_list; list; list = list->next) {
+		i = list->data;
+
+		foo_canvas_item_invoke_update (i, i2w_dx + group->xpos, i2w_dy + group->ypos, flags);
+
+		if (first) {
+			first = FALSE;
+			bbox_x0 = i->x1;
+			bbox_y0 = i->y1;
+			bbox_x1 = i->x2;
+			bbox_y1 = i->y2;
+		} else {
+			bbox_x0 = MIN (bbox_x0, i->x1);
+			bbox_y0 = MIN (bbox_y0, i->y1);
+			bbox_x1 = MAX (bbox_x1, i->x2);
+			bbox_y1 = MAX (bbox_y1, i->y2);
+		}
+	}
+	item->x1 = bbox_x0;
+	item->y1 = bbox_y0;
+	item->x2 = bbox_x1;
+	item->y2 = bbox_y1;
+}
+
+/* Unrealize handler for canvas groups */
+static void
+foo_canvas_group_unrealize (FooCanvasItem *item)
+{
+	FooCanvasGroup *group;
+	GList *list;
+	FooCanvasItem *i;
+
+	group = FOO_CANVAS_GROUP (item);
+
+	/* Unmap group before children to avoid flash */
+	if (item->object.flags & FOO_CANVAS_ITEM_MAPPED)
+		(* FOO_CANVAS_ITEM_GET_CLASS (item)->unmap) (item);
+
+	for (list = group->item_list; list; list = list->next) {
+		i = list->data;
+
+		if (i->object.flags & FOO_CANVAS_ITEM_REALIZED)
+			(* FOO_CANVAS_ITEM_GET_CLASS (i)->unrealize) (i);
+	}
+
+	(* group_parent_class->unrealize) (item);
+}
+
+/* Map handler for canvas groups */
+static void
+foo_canvas_group_map (FooCanvasItem *item)
+{
+	FooCanvasGroup *group;
+	GList *list;
+	FooCanvasItem *i;
+
+	group = FOO_CANVAS_GROUP (item);
+
+	for (list = group->item_list; list; list = list->next) {
+		i = list->data;
+
+		if (i->object.flags & FOO_CANVAS_ITEM_VISIBLE &&
+		    !(i->object.flags & FOO_CANVAS_ITEM_MAPPED)) {
+			if (!(i->object.flags & FOO_CANVAS_ITEM_REALIZED))
+				(* FOO_CANVAS_ITEM_GET_CLASS (i)->realize) (i);
+				
+			(* FOO_CANVAS_ITEM_GET_CLASS (i)->map) (i);
+		}
+	}
+
+	(* group_parent_class->map) (item);
+}
+
+/* Unmap handler for canvas groups */
+static void
+foo_canvas_group_unmap (FooCanvasItem *item)
+{
+	FooCanvasGroup *group;
+	GList *list;
+	FooCanvasItem *i;
+
+	group = FOO_CANVAS_GROUP (item);
+
+	for (list = group->item_list; list; list = list->next) {
+		i = list->data;
+
+		if (i->object.flags & FOO_CANVAS_ITEM_MAPPED)
+			(* FOO_CANVAS_ITEM_GET_CLASS (i)->unmap) (i);
+	}
+
+	(* group_parent_class->unmap) (item);
+}
+
+/* Draw handler for canvas groups */
+static void
+foo_canvas_group_draw (FooCanvasItem *item, GdkDrawable *drawable,
+			 GdkEventExpose *expose)
+{
+	FooCanvasGroup *group;
+	GList *list;
+	FooCanvasItem *child = NULL;
+
+	group = FOO_CANVAS_GROUP (item);
+
+	for (list = group->item_list; list; list = list->next) {
+		child = list->data;
+
+		if ((child->object.flags & FOO_CANVAS_ITEM_MAPPED) &&
+		    (FOO_CANVAS_ITEM_GET_CLASS (child)->draw)) {
+			GdkRectangle child_rect;
+			
+			child_rect.x = child->x1;
+			child_rect.y = child->y1;
+			child_rect.width = child->x2 - child->x1 + 1;
+			child_rect.height = child->y2 - child->y1 + 1;
+
+			if (gdk_region_rect_in (expose->region, &child_rect) != GDK_OVERLAP_RECTANGLE_OUT)
+				(* FOO_CANVAS_ITEM_GET_CLASS (child)->draw) (child, drawable, expose);
+		}
+	}
+}
+
+/* Point handler for canvas groups */
+static double
+foo_canvas_group_point (FooCanvasItem *item, double x, double y, int cx, int cy,
+			FooCanvasItem **actual_item)
+{
+	FooCanvasGroup *group;
+	GList *list;
+	FooCanvasItem *child, *point_item;
+	int x1, y1, x2, y2;
+	double gx, gy;
+	double dist, best;
+	int has_point;
+
+	group = FOO_CANVAS_GROUP (item);
+
+	x1 = cx - item->canvas->close_enough;
+	y1 = cy - item->canvas->close_enough;
+	x2 = cx + item->canvas->close_enough;
+	y2 = cy + item->canvas->close_enough;
+
+	best = 0.0;
+	*actual_item = NULL;
+
+	gx = x - group->xpos;
+	gy = y - group->ypos;
+
+	dist = 0.0; /* keep gcc happy */
+
+	for (list = group->item_list; list; list = list->next) {
+		child = list->data;
+
+		if ((child->x1 > x2) || (child->y1 > y2) || (child->x2 < x1) || (child->y2 < y1))
+			continue;
+
+		point_item = NULL; /* cater for incomplete item implementations */
+
+		if ((child->object.flags & FOO_CANVAS_ITEM_MAPPED)
+		    && FOO_CANVAS_ITEM_GET_CLASS (child)->point) {
+			dist = foo_canvas_item_invoke_point (child, gx, gy, cx, cy, &point_item);
+			has_point = TRUE;
+		} else
+			has_point = FALSE;
+
+		if (has_point
+		    && point_item
+		    && ((int) (dist * item->canvas->pixels_per_unit + 0.5)
+			<= item->canvas->close_enough)) {
+			best = dist;
+			*actual_item = point_item;
+		}
+	}
+
+	return best;
+}
+
+void
+foo_canvas_group_translate (FooCanvasItem *item, double dx, double dy)
+{
+        FooCanvasGroup *group;
+
+        group = FOO_CANVAS_GROUP (item);
+
+        group->xpos += dx;
+        group->ypos += dy;
+}
+
+/* Bounds handler for canvas groups */
+static void
+foo_canvas_group_bounds (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2)
+{
+	FooCanvasGroup *group;
+	FooCanvasItem *child;
+	GList *list;
+	double tx1, ty1, tx2, ty2;
+	double minx, miny, maxx, maxy;
+	int set;
+
+	group = FOO_CANVAS_GROUP (item);
+
+	/* Get the bounds of the first visible item */
+
+	child = NULL; /* Unnecessary but eliminates a warning. */
+
+	set = FALSE;
+
+	for (list = group->item_list; list; list = list->next) {
+		child = list->data;
+
+		if (child->object.flags & FOO_CANVAS_ITEM_MAPPED) {
+			set = TRUE;
+			foo_canvas_item_get_bounds (child, &minx, &miny, &maxx, &maxy);
+			break;
+		}
+	}
+
+	/* If there were no visible items, return an empty bounding box */
+
+	if (!set) {
+		*x1 = *y1 = *x2 = *y2 = 0.0;
+		return;
+	}
+
+	/* Now we can grow the bounds using the rest of the items */
+
+	list = list->next;
+
+	for (; list; list = list->next) {
+		child = list->data;
+
+		if (!(child->object.flags & FOO_CANVAS_ITEM_MAPPED))
+			continue;
+
+		foo_canvas_item_get_bounds (child, &tx1, &ty1, &tx2, &ty2);
+
+		if (tx1 < minx)
+			minx = tx1;
+
+		if (ty1 < miny)
+			miny = ty1;
+
+		if (tx2 > maxx)
+			maxx = tx2;
+
+		if (ty2 > maxy)
+			maxy = ty2;
+	}
+
+	/* Make the bounds be relative to our parent's coordinate system */
+
+	if (item->parent) {
+		minx += group->xpos;
+		miny += group->ypos;
+		maxx += group->xpos;
+		maxy += group->ypos;
+	}
+	
+	*x1 = minx;
+	*y1 = miny;
+	*x2 = maxx;
+	*y2 = maxy;
+}
+
+/* Adds an item to a group */
+static void
+group_add (FooCanvasGroup *group, FooCanvasItem *item)
+{
+#if GLIB_CHECK_VERSION(2,10,0) && GTK_CHECK_VERSION(2,8,14)
+	g_object_ref_sink (item);
+#else
+	g_object_ref (item);
+	gtk_object_sink (GTK_OBJECT (item));
+#endif
+
+	if (!group->item_list) {
+		group->item_list = g_list_append (group->item_list, item);
+		group->item_list_end = group->item_list;
+	} else
+		group->item_list_end = g_list_append (group->item_list_end, item)->next;
+
+	if (item->object.flags & FOO_CANVAS_ITEM_VISIBLE &&
+	    group->item.object.flags & FOO_CANVAS_ITEM_MAPPED) {
+		if (!(item->object.flags & FOO_CANVAS_ITEM_REALIZED))
+			(* FOO_CANVAS_ITEM_GET_CLASS (item)->realize) (item);
+		
+		if (!(item->object.flags & FOO_CANVAS_ITEM_MAPPED))
+			(* FOO_CANVAS_ITEM_GET_CLASS (item)->map) (item);
+	}
+}
+
+/* Removes an item from a group */
+static void
+group_remove (FooCanvasGroup *group, FooCanvasItem *item)
+{
+	GList *children;
+
+	g_return_if_fail (FOO_IS_CANVAS_GROUP (group));
+	g_return_if_fail (FOO_IS_CANVAS_ITEM (item));
+
+	for (children = group->item_list; children; children = children->next)
+		if (children->data == item) {
+			if (item->object.flags & FOO_CANVAS_ITEM_MAPPED)
+				(* FOO_CANVAS_ITEM_GET_CLASS (item)->unmap) (item);
+
+			if (item->object.flags & FOO_CANVAS_ITEM_REALIZED)
+				(* FOO_CANVAS_ITEM_GET_CLASS (item)->unrealize) (item);
+
+			/* Unparent the child */
+
+			item->parent = NULL;
+			/* item->canvas = NULL; */
+			g_object_unref (G_OBJECT (item));
+
+			/* Remove it from the list */
+
+			if (children == group->item_list_end)
+				group->item_list_end = children->prev;
+
+			group->item_list = g_list_remove_link (group->item_list, children);
+			g_list_free (children);
+			break;
+		}
+}
+
+
+/*** FooCanvas ***/
+
+
+enum {
+	DRAW_BACKGROUND,
+	LAST_SIGNAL
+};
+
+static void foo_canvas_class_init          (FooCanvasClass *klass);
+static void foo_canvas_init                (FooCanvas      *canvas);
+static void foo_canvas_destroy             (GtkObject        *object);
+static void foo_canvas_map                 (GtkWidget        *widget);
+static void foo_canvas_unmap               (GtkWidget        *widget);
+static void foo_canvas_realize             (GtkWidget        *widget);
+static void foo_canvas_unrealize           (GtkWidget        *widget);
+static void foo_canvas_size_allocate       (GtkWidget        *widget,
+					      GtkAllocation    *allocation);
+static gint foo_canvas_button              (GtkWidget        *widget,
+					      GdkEventButton   *event);
+static gint foo_canvas_motion              (GtkWidget        *widget,
+					      GdkEventMotion   *event);
+static gint foo_canvas_expose              (GtkWidget        *widget,
+					      GdkEventExpose   *event);
+static gint foo_canvas_key                 (GtkWidget        *widget,
+					      GdkEventKey      *event);
+static gint foo_canvas_crossing            (GtkWidget        *widget,
+					      GdkEventCrossing *event);
+static gint foo_canvas_focus_in            (GtkWidget        *widget,
+					      GdkEventFocus    *event);
+static gint foo_canvas_focus_out           (GtkWidget        *widget,
+					      GdkEventFocus    *event);
+static void foo_canvas_request_update_real (FooCanvas      *canvas);
+static void foo_canvas_draw_background     (FooCanvas      *canvas,
+					      int               x,
+					      int               y,
+					      int               width,
+					      int               height);
+
+
+static GtkLayoutClass *canvas_parent_class;
+
+static guint canvas_signals[LAST_SIGNAL];
+
+/**
+ * foo_canvas_get_type:
+ *
+ * Registers the &FooCanvas class if necessary, and returns the type ID
+ * associated to it.
+ *
+ * Return value:  The type ID of the &FooCanvas class.
+ **/
+GType
+foo_canvas_get_type (void)
+{
+	static GType canvas_type = 0;
+
+	if (!canvas_type) {
+		static const GTypeInfo canvas_info = {
+			sizeof (FooCanvasClass),
+			(GBaseInitFunc) NULL,
+			(GBaseFinalizeFunc) NULL,
+			(GClassInitFunc) foo_canvas_class_init,
+			NULL,           /* class_finalize */
+			NULL,           /* class_data */
+			sizeof (FooCanvas),
+			0,              /* n_preallocs */
+			(GInstanceInitFunc) foo_canvas_init
+		};
+
+		canvas_type = g_type_register_static (gtk_layout_get_type (),
+						      "FooCanvas",
+						      &canvas_info,
+						      0);
+	}
+
+	return canvas_type;
+}
+
+static void
+foo_canvas_get_property (GObject    *object, 
+			   guint       prop_id,
+			   GValue     *value,
+			   GParamSpec *pspec)
+{
+	switch (prop_id) {
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+foo_canvas_set_property (GObject      *object, 
+			   guint         prop_id,
+			   const GValue *value,
+			   GParamSpec   *pspec)
+{
+	switch (prop_id) {
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+foo_canvas_accessible_adjustment_changed (GtkAdjustment *adjustment,
+					  gpointer       data)
+{
+	AtkObject *atk_obj;
+
+	/* The scrollbars have changed */
+	atk_obj = ATK_OBJECT (data);
+
+	g_signal_emit_by_name (atk_obj, "visible_data_changed");
+}
+
+static void
+foo_canvas_accessible_initialize (AtkObject *obj, 
+				  gpointer   data)
+{
+	FooCanvas *canvas;
+
+	if (ATK_OBJECT_CLASS (accessible_parent_class)->initialize != NULL) 
+		ATK_OBJECT_CLASS (accessible_parent_class)->initialize (obj, data);
+
+	canvas = FOO_CANVAS (data);
+	g_signal_connect (canvas->layout.hadjustment,
+			  "value_changed",
+			  G_CALLBACK (foo_canvas_accessible_adjustment_changed),
+			  obj);
+	g_signal_connect (canvas->layout.vadjustment,
+			  "value_changed",
+			  G_CALLBACK (foo_canvas_accessible_adjustment_changed),
+			  obj);
+	
+	obj->role = ATK_ROLE_LAYERED_PANE;
+}
+
+static gint
+foo_canvas_accessible_get_n_children (AtkObject* obj)
+{
+ 	GtkAccessible *accessible;
+	GtkWidget *widget;
+	FooCanvas *canvas;
+	FooCanvasGroup *root_group;
+
+	accessible = GTK_ACCESSIBLE (obj);
+	widget = accessible->widget;
+	if (widget == NULL) {
+		/* State is defunct */
+		return 0;
+	}
+
+	g_return_val_if_fail (FOO_IS_CANVAS (widget), 0);
+
+	canvas = FOO_CANVAS (widget);
+	root_group = foo_canvas_root (canvas);
+	g_return_val_if_fail (root_group, 0);
+	return 1;
+}
+
+static AtkObject*
+foo_canvas_accessible_ref_child (AtkObject *obj,
+                                 gint       i)
+{
+	GtkAccessible *accessible;
+	GtkWidget *widget;
+	FooCanvas *canvas;
+	FooCanvasGroup *root_group;
+	AtkObject *atk_object;
+
+	/* Canvas only has one child, so return NULL if index is non zero */
+	if (i != 0) {
+        	return NULL;
+	}
+
+	accessible = GTK_ACCESSIBLE (obj);
+	widget = accessible->widget;
+	if (widget == NULL) {
+		/* State is defunct */
+		return NULL;
+	}
+
+	canvas = FOO_CANVAS (widget);
+	root_group = foo_canvas_root (canvas);
+	g_return_val_if_fail (root_group, NULL);
+	atk_object = atk_gobject_accessible_for_object (G_OBJECT (root_group));
+	g_object_ref (atk_object);
+	
+	g_warning ("Accessible support for FooGroup needs to be implemented");
+	
+	return atk_object;
+}
+
+static void
+foo_canvas_accessible_class_init (AtkObjectClass *klass)
+{
+ 	accessible_parent_class = g_type_class_peek_parent (klass);
+
+	klass->initialize = foo_canvas_accessible_initialize;
+	klass->get_n_children = foo_canvas_accessible_get_n_children;
+	klass->ref_child = foo_canvas_accessible_ref_child;
+}
+
+static GType
+foo_canvas_accessible_get_type (void)
+{
+	static GType type = 0;
+
+	if (!type) {
+		AtkObjectFactory *factory;
+		GType parent_atk_type;
+		GTypeQuery query;
+		GTypeInfo tinfo = { 0 };
+
+		factory = atk_registry_get_factory (atk_get_default_registry(),
+						    GTK_TYPE_WIDGET);
+		if (!factory) {
+			return G_TYPE_INVALID;
+		}
+		parent_atk_type = atk_object_factory_get_accessible_type (factory);
+		if (!parent_atk_type) {
+			return G_TYPE_INVALID;
+		}
+		g_type_query (parent_atk_type, &query);
+		tinfo.class_init = (GClassInitFunc) foo_canvas_accessible_class_init;
+		tinfo.class_size = query.class_size;
+		tinfo.instance_size = query.instance_size;
+		type = g_type_register_static (parent_atk_type,
+					       "FooCanvasAccessibility",
+					       &tinfo, 0);
+	}
+	return type;
+}
+
+static AtkObject *
+foo_canvas_accessible_create (GObject *for_object)
+{
+	GType type;
+	AtkObject *accessible;
+	FooCanvas *canvas;
+
+	canvas = FOO_CANVAS (for_object);
+	g_return_val_if_fail (canvas != NULL, NULL);
+
+	type = foo_canvas_accessible_get_type ();
+
+	if (type == G_TYPE_INVALID) {
+		return atk_no_op_object_new (for_object);
+	}
+
+	accessible = g_object_new (type, NULL);
+	atk_object_initialize (accessible, for_object);
+	return accessible;
+}
+
+static GType
+foo_canvas_accessible_factory_get_accessible_type (void)
+{
+	return foo_canvas_accessible_get_type ();
+}
+
+static AtkObject*
+foo_canvas_accessible_factory_create_accessible (GObject *obj)
+{
+	AtkObject *accessible;
+
+	g_return_val_if_fail (G_IS_OBJECT (obj), NULL);
+
+	accessible = foo_canvas_accessible_create (obj);
+
+	return accessible;
+}
+
+static void
+foo_canvas_accessible_factory_class_init (AtkObjectFactoryClass *klass)
+{
+	klass->create_accessible = foo_canvas_accessible_factory_create_accessible;
+	klass->get_accessible_type = foo_canvas_accessible_factory_get_accessible_type;
+}
+ 
+static GType
+foo_canvas_accessible_factory_get_type (void)
+{
+	static GType type = 0;
+
+	if (!type) {
+		static const GTypeInfo tinfo = {
+			sizeof (AtkObjectFactoryClass),
+			(GBaseInitFunc) NULL,
+			(GBaseFinalizeFunc) NULL,
+			(GClassInitFunc) foo_canvas_accessible_factory_class_init,
+			NULL,		/* class_finalize */
+			NULL,		/* class_data */
+			sizeof (AtkObjectFactory),
+			0,		/* n_preallocs */
+			NULL
+		};
+		type = g_type_register_static (ATK_TYPE_OBJECT_FACTORY,
+					       "FooCanvasAccessibilityFactory",
+					       &tinfo, 0);
+	}
+
+	return type;
+}
+
+
+/* Class initialization function for FooCanvasClass */
+static void
+foo_canvas_class_init (FooCanvasClass *klass)
+{
+	GObjectClass   *gobject_class;
+	GtkObjectClass *object_class;
+	GtkWidgetClass *widget_class;
+
+	gobject_class = (GObjectClass *)klass;
+	object_class  = (GtkObjectClass *) klass;
+	widget_class  = (GtkWidgetClass *) klass;
+
+	canvas_parent_class = g_type_class_peek_parent (klass);
+
+	gobject_class->set_property = foo_canvas_set_property;
+	gobject_class->get_property = foo_canvas_get_property;
+
+	object_class->destroy = foo_canvas_destroy;
+
+	widget_class->map = foo_canvas_map;
+	widget_class->unmap = foo_canvas_unmap;
+	widget_class->realize = foo_canvas_realize;
+	widget_class->unrealize = foo_canvas_unrealize;
+	widget_class->size_allocate = foo_canvas_size_allocate;
+	widget_class->button_press_event = foo_canvas_button;
+	widget_class->button_release_event = foo_canvas_button;
+	widget_class->motion_notify_event = foo_canvas_motion;
+	widget_class->expose_event = foo_canvas_expose;
+	widget_class->key_press_event = foo_canvas_key;
+	widget_class->key_release_event = foo_canvas_key;
+	widget_class->enter_notify_event = foo_canvas_crossing;
+	widget_class->leave_notify_event = foo_canvas_crossing;
+	widget_class->focus_in_event = foo_canvas_focus_in;
+	widget_class->focus_out_event = foo_canvas_focus_out;
+
+	klass->draw_background = foo_canvas_draw_background;
+	klass->request_update = foo_canvas_request_update_real;
+
+	canvas_signals[DRAW_BACKGROUND] =
+		g_signal_new ("draw_background",
+			      G_TYPE_FROM_CLASS (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (FooCanvasClass, draw_background),
+			      NULL, NULL,
+			      foo_canvas_marshal_VOID__INT_INT_INT_INT,
+			      G_TYPE_NONE, 4, 
+			      G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT);
+
+	atk_registry_set_factory_type (atk_get_default_registry (),
+				       FOO_TYPE_CANVAS,
+				       foo_canvas_accessible_factory_get_type ());
+}
+
+/* Callback used when the root item of a canvas is destroyed.  The user should
+ * never ever do this, so we panic if this happens.
+ */
+static void
+panic_root_destroyed (GtkObject *object, gpointer data)
+{
+	g_error ("Eeeek, root item %p of canvas %p was destroyed!", object, data);
+}
+
+/* Object initialization function for FooCanvas */
+static void
+foo_canvas_init (FooCanvas *canvas)
+{
+	GTK_WIDGET_SET_FLAGS (canvas, GTK_CAN_FOCUS);
+
+	gtk_widget_set_redraw_on_allocate (GTK_WIDGET (canvas), FALSE);
+
+	canvas->scroll_x1 = 0.0;
+	canvas->scroll_y1 = 0.0;
+	canvas->scroll_x2 = canvas->layout.width;
+	canvas->scroll_y2 = canvas->layout.height;
+
+	canvas->pixels_per_unit = 1.0;
+
+	canvas->pick_event.type = GDK_LEAVE_NOTIFY;
+	canvas->pick_event.crossing.x = 0;
+	canvas->pick_event.crossing.y = 0;
+
+	gtk_layout_set_hadjustment (GTK_LAYOUT (canvas), NULL);
+	gtk_layout_set_vadjustment (GTK_LAYOUT (canvas), NULL);
+
+	/* Create the root item as a special case */
+
+	canvas->root = FOO_CANVAS_ITEM (g_object_new (foo_canvas_group_get_type (), NULL));
+	canvas->root->canvas = canvas;
+
+#if GLIB_CHECK_VERSION(2,10,0) && GTK_CHECK_VERSION(2,8,14)
+	g_object_ref_sink (canvas->root);
+#else
+	g_object_ref (canvas->root);
+	gtk_object_sink (GTK_OBJECT (canvas->root));
+#endif
+
+	canvas->root_destroy_id = g_signal_connect (G_OBJECT (canvas->root),
+		"destroy", G_CALLBACK (panic_root_destroyed), canvas);
+
+	canvas->need_repick = TRUE;
+	canvas->doing_update = FALSE;
+}
+
+/* Convenience function to remove the idle handler of a canvas */
+static void
+remove_idle (FooCanvas *canvas)
+{
+	if (canvas->idle_id == 0)
+		return;
+
+	g_source_remove (canvas->idle_id);
+	canvas->idle_id = 0;
+}
+
+/* Removes the transient state of the canvas (idle handler, grabs). */
+static void
+shutdown_transients (FooCanvas *canvas)
+{
+	/* We turn off the need_redraw flag, since if the canvas is mapped again
+	 * it will request a redraw anyways.  We do not turn off the need_update
+	 * flag, though, because updates are not queued when the canvas remaps
+	 * itself.
+	 */
+	if (canvas->need_redraw) {
+		canvas->need_redraw = FALSE;
+	}
+
+	if (canvas->grabbed_item) {
+		GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (canvas));
+		canvas->grabbed_item = NULL;
+		gdk_display_pointer_ungrab (display, GDK_CURRENT_TIME);
+	}
+
+	remove_idle (canvas);
+}
+
+/* Destroy handler for FooCanvas */
+static void
+foo_canvas_destroy (GtkObject *object)
+{
+	FooCanvas *canvas;
+
+	g_return_if_fail (FOO_IS_CANVAS (object));
+
+	/* remember, destroy can be run multiple times! */
+
+	canvas = FOO_CANVAS (object);
+
+	if (canvas->root_destroy_id) {
+		g_signal_handler_disconnect (G_OBJECT (canvas->root), canvas->root_destroy_id);
+		canvas->root_destroy_id = 0;
+	}
+	if (canvas->root) {
+		FooCanvasItem *root = canvas->root;
+		canvas->root = NULL;
+		gtk_object_destroy (GTK_OBJECT (root));
+		g_object_unref (root);
+	}
+
+	shutdown_transients (canvas);
+
+	if (GTK_OBJECT_CLASS (canvas_parent_class)->destroy)
+		(* GTK_OBJECT_CLASS (canvas_parent_class)->destroy) (object);
+}
+
+/**
+ * foo_canvas_new:
+ * @void:
+ *
+ * Creates a new empty canvas.  If you wish to use the
+ * &FooCanvasImage item inside this canvas, then you must push the gdk_imlib
+ * visual and colormap before calling this function, and they can be popped
+ * afterwards.
+ *
+ * Return value: A newly-created canvas.
+ **/
+GtkWidget *
+foo_canvas_new (void)
+{
+	return GTK_WIDGET (g_object_new (foo_canvas_get_type (), NULL));
+}
+
+/* Map handler for the canvas */
+static void
+foo_canvas_map (GtkWidget *widget)
+{
+	FooCanvas *canvas;
+
+	g_return_if_fail (FOO_IS_CANVAS (widget));
+
+	/* Normal widget mapping stuff */
+
+	if (GTK_WIDGET_CLASS (canvas_parent_class)->map)
+		(* GTK_WIDGET_CLASS (canvas_parent_class)->map) (widget);
+
+	canvas = FOO_CANVAS (widget);
+
+	/* Map items */
+
+	if (canvas->root->object.flags & FOO_CANVAS_ITEM_VISIBLE &&
+	    !(canvas->root->object.flags & FOO_CANVAS_ITEM_MAPPED) &&
+	    FOO_CANVAS_ITEM_GET_CLASS (canvas->root)->map)
+		(* FOO_CANVAS_ITEM_GET_CLASS (canvas->root)->map) (canvas->root);
+}
+
+/* Unmap handler for the canvas */
+static void
+foo_canvas_unmap (GtkWidget *widget)
+{
+	FooCanvas *canvas;
+
+	g_return_if_fail (FOO_IS_CANVAS (widget));
+
+	canvas = FOO_CANVAS (widget);
+
+	shutdown_transients (canvas);
+
+	/* Unmap items */
+
+	if (FOO_CANVAS_ITEM_GET_CLASS (canvas->root)->unmap)
+		(* FOO_CANVAS_ITEM_GET_CLASS (canvas->root)->unmap) (canvas->root);
+
+	/* Normal widget unmapping stuff */
+
+	if (GTK_WIDGET_CLASS (canvas_parent_class)->unmap)
+		(* GTK_WIDGET_CLASS (canvas_parent_class)->unmap) (widget);
+}
+
+/* Realize handler for the canvas */
+static void
+foo_canvas_realize (GtkWidget *widget)
+{
+	FooCanvas *canvas;
+
+	g_return_if_fail (FOO_IS_CANVAS (widget));
+
+	/* Normal widget realization stuff */
+
+	if (GTK_WIDGET_CLASS (canvas_parent_class)->realize)
+		(* GTK_WIDGET_CLASS (canvas_parent_class)->realize) (widget);
+
+	canvas = FOO_CANVAS (widget);
+
+	gdk_window_set_events (canvas->layout.bin_window,
+			       (gdk_window_get_events (canvas->layout.bin_window)
+				 | GDK_EXPOSURE_MASK
+				 | GDK_BUTTON_PRESS_MASK
+				 | GDK_BUTTON_RELEASE_MASK
+				 | GDK_POINTER_MOTION_MASK
+				 | GDK_KEY_PRESS_MASK
+				 | GDK_KEY_RELEASE_MASK
+				 | GDK_ENTER_NOTIFY_MASK
+				 | GDK_LEAVE_NOTIFY_MASK
+				 | GDK_FOCUS_CHANGE_MASK));
+
+	/* Create our own temporary pixmap gc and realize all the items */
+
+	canvas->pixmap_gc = gdk_gc_new (canvas->layout.bin_window);
+
+	(* FOO_CANVAS_ITEM_GET_CLASS (canvas->root)->realize) (canvas->root);
+}
+
+/* Unrealize handler for the canvas */
+static void
+foo_canvas_unrealize (GtkWidget *widget)
+{
+	FooCanvas *canvas;
+
+	g_return_if_fail (FOO_IS_CANVAS (widget));
+
+	canvas = FOO_CANVAS (widget);
+
+	shutdown_transients (canvas);
+
+	/* Unrealize items and parent widget */
+
+	(* FOO_CANVAS_ITEM_GET_CLASS (canvas->root)->unrealize) (canvas->root);
+
+	g_object_unref (canvas->pixmap_gc);
+	canvas->pixmap_gc = NULL;
+
+	if (GTK_WIDGET_CLASS (canvas_parent_class)->unrealize)
+		(* GTK_WIDGET_CLASS (canvas_parent_class)->unrealize) (widget);
+}
+
+/* Handles scrolling of the canvas.  Adjusts the scrolling and zooming offset to
+ * keep as much as possible of the canvas scrolling region in view.
+ */
+static void
+scroll_to (FooCanvas *canvas, int cx, int cy)
+{
+	int scroll_width, scroll_height;
+	int right_limit, bottom_limit;
+	int old_zoom_xofs, old_zoom_yofs;
+	int changed_x = FALSE, changed_y = FALSE;
+	int canvas_width, canvas_height;
+
+	canvas_width = GTK_WIDGET (canvas)->allocation.width;
+	canvas_height = GTK_WIDGET (canvas)->allocation.height;
+
+	scroll_width = floor ((canvas->scroll_x2 - canvas->scroll_x1) * canvas->pixels_per_unit + 0.5);
+	scroll_height = floor ((canvas->scroll_y2 - canvas->scroll_y1) * canvas->pixels_per_unit + 0.5);
+
+	right_limit = scroll_width - canvas_width;
+	bottom_limit = scroll_height - canvas_height;
+
+	old_zoom_xofs = canvas->zoom_xofs;
+	old_zoom_yofs = canvas->zoom_yofs;
+
+	if (right_limit < 0) {
+		cx = 0;
+		if (canvas->center_scroll_region) {
+			canvas->zoom_xofs = (canvas_width - scroll_width) / 2;
+			scroll_width = canvas_width;
+		} else {
+			canvas->zoom_xofs = 0;
+		}
+	} else if (cx < 0) {
+		cx = 0;
+		canvas->zoom_xofs = 0;
+	} else if (cx > right_limit) {
+		cx = right_limit;
+		canvas->zoom_xofs = 0;
+	} else
+		canvas->zoom_xofs = 0;
+
+	if (bottom_limit < 0) {
+		cy = 0;
+		if (canvas->center_scroll_region) {
+			canvas->zoom_yofs = (canvas_height - scroll_height) / 2;
+			scroll_height = canvas_height;
+		} else {
+			canvas->zoom_yofs = 0;
+		}
+	} else if (cy < 0) {
+		cy = 0;
+		canvas->zoom_yofs = 0;
+	} else if (cy > bottom_limit) {
+		cy = bottom_limit;
+		canvas->zoom_yofs = 0;
+	} else
+		canvas->zoom_yofs = 0;
+
+	if ((canvas->zoom_xofs != old_zoom_xofs) || (canvas->zoom_yofs != old_zoom_yofs)) {
+		/* This can only occur, if either canvas size or widget size changes */
+		/* So I think we can request full redraw here */
+		/* More stuff - we have to mark root as needing fresh affine (Lauris) */
+		if (!(canvas->root->object.flags & FOO_CANVAS_ITEM_NEED_DEEP_UPDATE)) {
+			canvas->root->object.flags |= FOO_CANVAS_ITEM_NEED_DEEP_UPDATE;
+			foo_canvas_request_update (canvas);
+		}
+		gtk_widget_queue_draw (GTK_WIDGET (canvas));
+	}
+
+	if (((int) canvas->layout.hadjustment->value) != cx) {
+		canvas->layout.hadjustment->value = cx;
+		changed_x = TRUE;
+	}
+
+	if (((int) canvas->layout.vadjustment->value) != cy) {
+		canvas->layout.vadjustment->value = cy;
+		changed_y = TRUE;
+	}
+
+	if ((scroll_width != (int) canvas->layout.width) || (scroll_height != (int) canvas->layout.height)) {
+		gtk_layout_set_size (GTK_LAYOUT (canvas), scroll_width, scroll_height);
+	}
+	
+	/* Signal GtkLayout that it should do a redraw. */
+	if (changed_x)
+		g_signal_emit_by_name (G_OBJECT (canvas->layout.hadjustment), "value_changed");
+	if (changed_y)
+		g_signal_emit_by_name (G_OBJECT (canvas->layout.vadjustment), "value_changed");
+}
+
+/* Size allocation handler for the canvas */
+static void
+foo_canvas_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
+{
+	FooCanvas *canvas;
+
+	g_return_if_fail (FOO_IS_CANVAS (widget));
+	g_return_if_fail (allocation != NULL);
+
+	if (GTK_WIDGET_CLASS (canvas_parent_class)->size_allocate)
+		(* GTK_WIDGET_CLASS (canvas_parent_class)->size_allocate) (widget, allocation);
+
+	canvas = FOO_CANVAS (widget);
+
+	/* Recenter the view, if appropriate */
+
+	canvas->layout.hadjustment->page_size = allocation->width;
+	canvas->layout.hadjustment->page_increment = allocation->width / 2;
+
+	canvas->layout.vadjustment->page_size = allocation->height;
+	canvas->layout.vadjustment->page_increment = allocation->height / 2;
+
+	scroll_to (canvas,
+		   canvas->layout.hadjustment->value,
+		   canvas->layout.vadjustment->value);
+
+	g_signal_emit_by_name (G_OBJECT (canvas->layout.hadjustment), "changed");
+	g_signal_emit_by_name (G_OBJECT (canvas->layout.vadjustment), "changed");
+}
+
+/* Emits an event for an item in the canvas, be it the current item, grabbed
+ * item, or focused item, as appropriate.
+ */
+
+static int
+emit_event (FooCanvas *canvas, GdkEvent *event)
+{
+	GdkEvent ev;
+	gint finished;
+	FooCanvasItem *item;
+	FooCanvasItem *parent;
+	guint mask;
+
+	/* Could be an old pick event */
+	if (!GTK_WIDGET_REALIZED (canvas)) {
+		return FALSE;
+	}
+
+	/* Perform checks for grabbed items */
+
+	if (canvas->grabbed_item &&
+	    !is_descendant (canvas->current_item, canvas->grabbed_item)) {
+		return FALSE;
+        }
+
+	if (canvas->grabbed_item) {
+		switch (event->type) {
+		case GDK_ENTER_NOTIFY:
+			mask = GDK_ENTER_NOTIFY_MASK;
+			break;
+
+		case GDK_LEAVE_NOTIFY:
+			mask = GDK_LEAVE_NOTIFY_MASK;
+			break;
+
+		case GDK_MOTION_NOTIFY:
+			mask = GDK_POINTER_MOTION_MASK;
+			break;
+
+		case GDK_BUTTON_PRESS:
+		case GDK_2BUTTON_PRESS:
+		case GDK_3BUTTON_PRESS:
+			mask = GDK_BUTTON_PRESS_MASK;
+			break;
+
+		case GDK_BUTTON_RELEASE:
+			mask = GDK_BUTTON_RELEASE_MASK;
+			break;
+
+		case GDK_KEY_PRESS:
+			mask = GDK_KEY_PRESS_MASK;
+			break;
+
+		case GDK_KEY_RELEASE:
+			mask = GDK_KEY_RELEASE_MASK;
+			break;
+
+		default:
+			mask = 0;
+			break;
+		}
+
+		if (!(mask & canvas->grabbed_event_mask))
+			return FALSE;
+	}
+
+	/* Convert to world coordinates -- we have two cases because of diferent
+	 * offsets of the fields in the event structures.
+	 */
+
+	ev = *event;
+
+	switch (ev.type)
+        {
+	case GDK_ENTER_NOTIFY:
+	case GDK_LEAVE_NOTIFY:
+		foo_canvas_window_to_world (canvas,
+					      ev.crossing.x, ev.crossing.y,
+					      &ev.crossing.x, &ev.crossing.y);
+		break;
+
+	case GDK_MOTION_NOTIFY:
+                foo_canvas_window_to_world (canvas,
+                                              ev.motion.x, ev.motion.y,
+                                              &ev.motion.x, &ev.motion.y);
+                break;
+
+	case GDK_BUTTON_PRESS:
+	case GDK_2BUTTON_PRESS:
+	case GDK_3BUTTON_PRESS:
+                foo_canvas_window_to_world (canvas,
+                                              ev.motion.x, ev.motion.y,
+                                              &ev.motion.x, &ev.motion.y);
+                break;
+
+	case GDK_BUTTON_RELEASE:
+		foo_canvas_window_to_world (canvas,
+					      ev.motion.x, ev.motion.y,
+					      &ev.motion.x, &ev.motion.y);
+		break;
+
+	default:
+		break;
+	}
+
+	/* Choose where we send the event */
+
+	item = canvas->current_item;
+
+	if (canvas->focused_item
+	    && ((event->type == GDK_KEY_PRESS) ||
+		(event->type == GDK_KEY_RELEASE) ||
+		(event->type == GDK_FOCUS_CHANGE)))
+		item = canvas->focused_item;
+
+	/* The event is propagated up the hierarchy (for if someone connected to
+	 * a group instead of a leaf event), and emission is stopped if a
+	 * handler returns TRUE, just like for GtkWidget events.
+	 */
+
+	finished = FALSE;
+
+	while (item && !finished) {
+		g_object_ref (GTK_OBJECT (item));
+
+		g_signal_emit (
+		       G_OBJECT (item), item_signals[ITEM_EVENT], 0,
+			&ev, &finished);
+		
+		parent = item->parent;
+		g_object_unref (GTK_OBJECT (item));
+
+		item = parent;
+	}
+
+	return finished;
+}
+
+/* Re-picks the current item in the canvas, based on the event's coordinates.
+ * Also emits enter/leave events for items as appropriate.
+ */
+static int
+pick_current_item (FooCanvas *canvas, GdkEvent *event)
+{
+	int button_down;
+	double x, y;
+	int cx, cy;
+	int retval;
+
+	retval = FALSE;
+
+	/* If a button is down, we'll perform enter and leave events on the
+	 * current item, but not enter on any other item.  This is more or less
+	 * like X pointer grabbing for canvas items.
+	 */
+	button_down = canvas->state & (GDK_BUTTON1_MASK
+				       | GDK_BUTTON2_MASK
+				       | GDK_BUTTON3_MASK
+				       | GDK_BUTTON4_MASK
+				       | GDK_BUTTON5_MASK);
+	if (!button_down)
+		canvas->left_grabbed_item = FALSE;
+
+	/* Save the event in the canvas.  This is used to synthesize enter and
+	 * leave events in case the current item changes.  It is also used to
+	 * re-pick the current item if the current one gets deleted.  Also,
+	 * synthesize an enter event.
+	 */
+	if (event != &canvas->pick_event) {
+		if ((event->type == GDK_MOTION_NOTIFY) || (event->type == GDK_BUTTON_RELEASE)) {
+			/* these fields have the same offsets in both types of events */
+
+			canvas->pick_event.crossing.type       = GDK_ENTER_NOTIFY;
+			canvas->pick_event.crossing.window     = event->motion.window;
+			canvas->pick_event.crossing.send_event = event->motion.send_event;
+			canvas->pick_event.crossing.subwindow  = NULL;
+			canvas->pick_event.crossing.x          = event->motion.x;
+			canvas->pick_event.crossing.y          = event->motion.y;
+			canvas->pick_event.crossing.mode       = GDK_CROSSING_NORMAL;
+			canvas->pick_event.crossing.detail     = GDK_NOTIFY_NONLINEAR;
+			canvas->pick_event.crossing.focus      = FALSE;
+			canvas->pick_event.crossing.state      = event->motion.state;
+
+			/* these fields don't have the same offsets in both types of events */
+
+			if (event->type == GDK_MOTION_NOTIFY) {
+				canvas->pick_event.crossing.x_root = event->motion.x_root;
+				canvas->pick_event.crossing.y_root = event->motion.y_root;
+			} else {
+				canvas->pick_event.crossing.x_root = event->button.x_root;
+				canvas->pick_event.crossing.y_root = event->button.y_root;
+			}
+		} else
+			canvas->pick_event = *event;
+	}
+
+	/* Don't do anything else if this is a recursive call */
+
+	if (canvas->in_repick)
+		return retval;
+
+	/* LeaveNotify means that there is no current item, so we don't look for one */
+
+	if (canvas->pick_event.type != GDK_LEAVE_NOTIFY) {
+		/* these fields don't have the same offsets in both types of events */
+
+		if (canvas->pick_event.type == GDK_ENTER_NOTIFY) {
+			x = canvas->pick_event.crossing.x;
+			y = canvas->pick_event.crossing.y;
+		} else {
+			x = canvas->pick_event.motion.x;
+			y = canvas->pick_event.motion.y;
+		}
+
+		/* canvas pixel coords */
+
+		cx = (int) (x + 0.5);
+		cy = (int) (y + 0.5);
+
+		/* world coords */
+		foo_canvas_c2w (canvas, cx, cy, &x, &y);
+
+		/* find the closest item */
+		if (canvas->root->object.flags & FOO_CANVAS_ITEM_MAPPED)
+			foo_canvas_item_invoke_point (canvas->root, x, y, cx, cy,
+							&canvas->new_current_item);
+		else
+			canvas->new_current_item = NULL;
+	} else
+		canvas->new_current_item = NULL;
+
+	if ((canvas->new_current_item == canvas->current_item) && !canvas->left_grabbed_item)
+		return retval; /* current item did not change */
+
+	/* Synthesize events for old and new current items */
+
+	if ((canvas->new_current_item != canvas->current_item)
+	    && (canvas->current_item != NULL)
+	    && !canvas->left_grabbed_item) {
+		GdkEvent new_event;
+		FooCanvasItem *item;
+
+		item = canvas->current_item;
+
+		new_event = canvas->pick_event;
+		new_event.type = GDK_LEAVE_NOTIFY;
+
+		new_event.crossing.detail = GDK_NOTIFY_ANCESTOR;
+		new_event.crossing.subwindow = NULL;
+		canvas->in_repick = TRUE;
+		retval = emit_event (canvas, &new_event);
+		canvas->in_repick = FALSE;
+	}
+
+	/* new_current_item may have been set to NULL during the call to emit_event() above */
+
+	if ((canvas->new_current_item != canvas->current_item) && button_down) {
+		canvas->left_grabbed_item = TRUE;
+		return retval;
+	}
+
+	/* Handle the rest of cases */
+
+	canvas->left_grabbed_item = FALSE;
+	canvas->current_item = canvas->new_current_item;
+
+	if (canvas->current_item != NULL) {
+		GdkEvent new_event;
+
+		new_event = canvas->pick_event;
+		new_event.type = GDK_ENTER_NOTIFY;
+		new_event.crossing.detail = GDK_NOTIFY_ANCESTOR;
+		new_event.crossing.subwindow = NULL;
+		retval = emit_event (canvas, &new_event);
+	}
+
+	return retval;
+}
+
+/* Button event handler for the canvas */
+static gint
+foo_canvas_button (GtkWidget *widget, GdkEventButton *event)
+{
+	FooCanvas *canvas;
+	int mask;
+	int retval;
+
+	g_return_val_if_fail (FOO_IS_CANVAS (widget), FALSE);
+	g_return_val_if_fail (event != NULL, FALSE);
+
+	retval = FALSE;
+
+	canvas = FOO_CANVAS (widget);
+
+	/*
+	 * dispatch normally regardless of the event's window if an item has
+	 * has a pointer grab in effect
+	 */
+	if (!canvas->grabbed_item && event->window != canvas->layout.bin_window)
+		return retval;
+
+	switch (event->button) {
+	case 1:
+		mask = GDK_BUTTON1_MASK;
+		break;
+	case 2:
+		mask = GDK_BUTTON2_MASK;
+		break;
+	case 3:
+		mask = GDK_BUTTON3_MASK;
+		break;
+	case 4:
+		mask = GDK_BUTTON4_MASK;
+		break;
+	case 5:
+		mask = GDK_BUTTON5_MASK;
+		break;
+	default:
+		mask = 0;
+	}
+
+	switch (event->type) {
+	case GDK_BUTTON_PRESS:
+	case GDK_2BUTTON_PRESS:
+	case GDK_3BUTTON_PRESS:
+		/* Pick the current item as if the button were not pressed, and
+		 * then process the event.
+		 */
+		canvas->state = event->state;
+		pick_current_item (canvas, (GdkEvent *) event);
+		canvas->state ^= mask;
+		retval = emit_event (canvas, (GdkEvent *) event);
+		break;
+
+	case GDK_BUTTON_RELEASE:
+		/* Process the event as if the button were pressed, then repick
+		 * after the button has been released
+		 */
+		canvas->state = event->state;
+		retval = emit_event (canvas, (GdkEvent *) event);
+		event->state ^= mask;
+		canvas->state = event->state;
+		pick_current_item (canvas, (GdkEvent *) event);
+		event->state ^= mask;
+		break;
+
+	default:
+		g_assert_not_reached ();
+	}
+
+	return retval;
+}
+
+/* Motion event handler for the canvas */
+static gint
+foo_canvas_motion (GtkWidget *widget, GdkEventMotion *event)
+{
+	FooCanvas *canvas;
+
+	g_return_val_if_fail (FOO_IS_CANVAS (widget), FALSE);
+	g_return_val_if_fail (event != NULL, FALSE);
+
+	canvas = FOO_CANVAS (widget);
+
+	if (event->window != canvas->layout.bin_window)
+		return FALSE;
+
+	canvas->state = event->state;
+	pick_current_item (canvas, (GdkEvent *) event);
+	return emit_event (canvas, (GdkEvent *) event);
+}
+
+/* Key event handler for the canvas */
+static gint
+foo_canvas_key (GtkWidget *widget, GdkEventKey *event)
+{
+	FooCanvas *canvas;
+	
+	g_return_val_if_fail (FOO_IS_CANVAS (widget), FALSE);
+	g_return_val_if_fail (event != NULL, FALSE);
+
+	canvas = FOO_CANVAS (widget);
+	
+	if (emit_event (canvas, (GdkEvent *) event))
+		return TRUE;
+	if (event->type == GDK_KEY_RELEASE)
+		return GTK_WIDGET_CLASS (canvas_parent_class)->key_release_event (widget, event);
+	else
+		return GTK_WIDGET_CLASS (canvas_parent_class)->key_press_event (widget, event);
+}
+
+
+/* Crossing event handler for the canvas */
+static gint
+foo_canvas_crossing (GtkWidget *widget, GdkEventCrossing *event)
+{
+	FooCanvas *canvas;
+
+	g_return_val_if_fail (FOO_IS_CANVAS (widget), FALSE);
+	g_return_val_if_fail (event != NULL, FALSE);
+
+	canvas = FOO_CANVAS (widget);
+
+	if (event->window != canvas->layout.bin_window)
+		return FALSE;
+
+	canvas->state = event->state;
+	return pick_current_item (canvas, (GdkEvent *) event);
+}
+
+/* Focus in handler for the canvas */
+static gint
+foo_canvas_focus_in (GtkWidget *widget, GdkEventFocus *event)
+{
+	FooCanvas *canvas;
+
+	GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
+
+	canvas = FOO_CANVAS (widget);
+
+	if (canvas->focused_item)
+		return emit_event (canvas, (GdkEvent *) event);
+	else
+		return FALSE;
+}
+
+/* Focus out handler for the canvas */
+static gint
+foo_canvas_focus_out (GtkWidget *widget, GdkEventFocus *event)
+{
+	FooCanvas *canvas;
+
+	GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
+
+	canvas = FOO_CANVAS (widget);
+
+	if (canvas->focused_item)
+		return emit_event (canvas, (GdkEvent *) event);
+	else
+		return FALSE;
+}
+
+/* Expose handler for the canvas */
+static gint
+foo_canvas_expose (GtkWidget *widget, GdkEventExpose *event)
+{
+	FooCanvas *canvas;
+
+	canvas = FOO_CANVAS (widget);
+
+	if (!GTK_WIDGET_DRAWABLE (widget) || (event->window != canvas->layout.bin_window)) return FALSE;
+
+#ifdef VERBOSE
+	g_print ("Expose\n");
+#endif
+	/* If there are any outstanding items that need updating, do them now */
+	if (canvas->idle_id) {
+		g_source_remove (canvas->idle_id);
+		canvas->idle_id = 0;
+	}
+	if (canvas->need_update) {
+		g_return_val_if_fail (!canvas->doing_update, FALSE);
+
+		canvas->doing_update = TRUE;
+		foo_canvas_item_invoke_update (canvas->root, 0, 0, 0);
+
+		g_return_val_if_fail (canvas->doing_update, FALSE);
+
+		canvas->doing_update = FALSE;
+
+		canvas->need_update = FALSE;
+	}
+
+	/* Hmmm. Would like to queue antiexposes if the update marked
+	   anything that is gonna get redrawn as invalid */
+	
+	
+	g_signal_emit (G_OBJECT (canvas), canvas_signals[DRAW_BACKGROUND], 0, 
+		       event->area.x, event->area.y,
+		       event->area.width, event->area.height);
+	
+	if (canvas->root->object.flags & FOO_CANVAS_ITEM_MAPPED)
+		(* FOO_CANVAS_ITEM_GET_CLASS (canvas->root)->draw) (canvas->root,
+								      canvas->layout.bin_window,
+								      event);
+
+
+
+	/* Chain up to get exposes on child widgets */
+	GTK_WIDGET_CLASS (canvas_parent_class)->expose_event (widget, event);
+
+	return FALSE;
+}
+
+static void
+foo_canvas_draw_background (FooCanvas *canvas,
+			    int x, int y, int width, int height)
+{
+	/* By default, we use the style background. */
+	gdk_gc_set_foreground (canvas->pixmap_gc,
+			       &GTK_WIDGET (canvas)->style->bg[GTK_STATE_NORMAL]);
+	gdk_draw_rectangle (canvas->layout.bin_window,
+			    canvas->pixmap_gc,
+			    TRUE,
+			    x, y,
+			    width, height);
+}
+
+static void
+do_update (FooCanvas *canvas)
+{
+	/* Cause the update if necessary */
+
+update_again:
+	if (canvas->need_update) {
+		g_return_if_fail (!canvas->doing_update);
+
+		canvas->doing_update = TRUE;
+		foo_canvas_item_invoke_update (canvas->root, 0, 0, 0);
+
+		g_return_if_fail (canvas->doing_update);
+
+		canvas->doing_update = FALSE;
+
+		canvas->need_update = FALSE;
+	}
+
+	/* Pick new current item */
+
+	while (canvas->need_repick) {
+		canvas->need_repick = FALSE;
+		pick_current_item (canvas, &canvas->pick_event);
+	}
+
+	/* it is possible that during picking we emitted an event in which
+	   the user then called some function which then requested update
+	   of something.  Without this we'd be left in a state where
+	   need_update would have been left TRUE and the canvas would have
+	   been left unpainted. */
+	if (canvas->need_update) {
+		goto update_again;
+	}
+}
+
+/* Idle handler for the canvas.  It deals with pending updates and redraws. */
+static gint
+idle_handler (gpointer data)
+{
+	FooCanvas *canvas;
+
+	GDK_THREADS_ENTER ();
+
+	canvas = FOO_CANVAS (data);
+	do_update (canvas);
+
+	/* Reset idle id */
+	canvas->idle_id = 0;
+
+	GDK_THREADS_LEAVE ();
+
+	return FALSE;
+}
+
+/* Convenience function to add an idle handler to a canvas */
+static void
+add_idle (FooCanvas *canvas)
+{
+	if (!canvas->idle_id) {
+		/* We let the update idle handler have higher priority
+		 * than the redraw idle handler so the canvas state
+		 * will be updated during the expose event.  canvas in
+		 * expose_event.
+		 */
+		canvas->idle_id = g_idle_add_full (GDK_PRIORITY_REDRAW - 20,
+						   idle_handler, canvas, NULL);
+	}
+}
+
+/**
+ * foo_canvas_root:
+ * @canvas: A canvas.
+ *
+ * Queries the root group of a canvas.
+ *
+ * Return value: The root group of the specified canvas.
+ **/
+FooCanvasGroup *
+foo_canvas_root (FooCanvas *canvas)
+{
+	g_return_val_if_fail (FOO_IS_CANVAS (canvas), NULL);
+
+	return FOO_CANVAS_GROUP (canvas->root);
+}
+
+
+/**
+ * foo_canvas_set_scroll_region:
+ * @canvas: A canvas.
+ * @x1: Leftmost limit of the scrolling region.
+ * @y1: Upper limit of the scrolling region.
+ * @x2: Rightmost limit of the scrolling region.
+ * @y2: Lower limit of the scrolling region.
+ *
+ * Sets the scrolling region of a canvas to the specified rectangle.  The canvas
+ * will then be able to scroll only within this region.  The view of the canvas
+ * is adjusted as appropriate to display as much of the new region as possible.
+ **/
+void
+foo_canvas_set_scroll_region (FooCanvas *canvas, double x1, double y1, double x2, double y2)
+{
+	double wxofs, wyofs;
+	int xofs, yofs;
+
+	g_return_if_fail (FOO_IS_CANVAS (canvas));
+
+	if ((canvas->scroll_x1 == x1) && (canvas->scroll_y1 == y1) &&
+	    (canvas->scroll_x2 == x2) && (canvas->scroll_y2 == y2)) {
+		return;
+	}
+	
+	/*
+	 * Set the new scrolling region.  If possible, do not move the visible contents of the
+	 * canvas.
+	 */
+
+	foo_canvas_c2w (canvas,
+			  GTK_LAYOUT (canvas)->hadjustment->value + canvas->zoom_xofs,
+			  GTK_LAYOUT (canvas)->vadjustment->value + canvas->zoom_yofs,
+			  /*canvas->zoom_xofs,
+			  canvas->zoom_yofs,*/
+			  &wxofs, &wyofs);
+
+	canvas->scroll_x1 = x1;
+	canvas->scroll_y1 = y1;
+	canvas->scroll_x2 = x2;
+	canvas->scroll_y2 = y2;
+
+	foo_canvas_w2c (canvas, wxofs, wyofs, &xofs, &yofs);
+
+	scroll_to (canvas, xofs, yofs);
+
+	canvas->need_repick = TRUE;
+
+	if (!(canvas->root->object.flags & FOO_CANVAS_ITEM_NEED_DEEP_UPDATE)) {
+		canvas->root->object.flags |= FOO_CANVAS_ITEM_NEED_DEEP_UPDATE;
+		foo_canvas_request_update (canvas);
+	}
+}
+
+
+/**
+ * foo_canvas_get_scroll_region:
+ * @canvas: A canvas.
+ * @x1: Leftmost limit of the scrolling region (return value).
+ * @y1: Upper limit of the scrolling region (return value).
+ * @x2: Rightmost limit of the scrolling region (return value).
+ * @y2: Lower limit of the scrolling region (return value).
+ *
+ * Queries the scrolling region of a canvas.
+ **/
+void
+foo_canvas_get_scroll_region (FooCanvas *canvas, double *x1, double *y1, double *x2, double *y2)
+{
+	g_return_if_fail (FOO_IS_CANVAS (canvas));
+
+	if (x1)
+		*x1 = canvas->scroll_x1;
+
+	if (y1)
+		*y1 = canvas->scroll_y1;
+
+	if (x2)
+		*x2 = canvas->scroll_x2;
+
+	if (y2)
+		*y2 = canvas->scroll_y2;
+}
+
+void
+foo_canvas_set_center_scroll_region (FooCanvas *canvas,
+				     gboolean center_scroll_region)
+{
+	g_return_if_fail (FOO_IS_CANVAS (canvas));
+
+	canvas->center_scroll_region = center_scroll_region != 0;
+
+	scroll_to (canvas,
+		   canvas->layout.hadjustment->value,
+		   canvas->layout.vadjustment->value);
+}
+
+
+/**
+ * foo_canvas_set_pixels_per_unit:
+ * @canvas: A canvas.
+ * @n: The number of pixels that correspond to one canvas unit.
+ *
+ * Sets the zooming factor of a canvas by specifying the number of pixels that
+ * correspond to one canvas unit.
+ **/
+void
+foo_canvas_set_pixels_per_unit (FooCanvas *canvas, double n)
+{
+	GtkWidget *widget;
+	double cx, cy;
+	int x1, y1;
+	int center_x, center_y;
+	GdkWindow *window;
+	GdkWindowAttr attributes;
+	gint attributes_mask;
+
+	g_return_if_fail (FOO_IS_CANVAS (canvas));
+	g_return_if_fail (n > FOO_CANVAS_EPSILON);
+
+	widget = GTK_WIDGET (canvas);
+
+	center_x = widget->allocation.width / 2;
+	center_y = widget->allocation.height / 2;
+
+	/* Find the coordinates of the screen center in units. */
+	cx = (canvas->layout.hadjustment->value + center_x) / canvas->pixels_per_unit + canvas->scroll_x1 + canvas->zoom_xofs;
+	cy = (canvas->layout.vadjustment->value + center_y) / canvas->pixels_per_unit + canvas->scroll_y1 + canvas->zoom_yofs;
+
+	/* Now calculate the new offset of the upper left corner. (round not truncate) */
+	x1 = ((cx - canvas->scroll_x1) * n) - center_x + .5;
+	y1 = ((cy - canvas->scroll_y1) * n) - center_y + .5;
+
+	canvas->pixels_per_unit = n;
+
+	if (!(canvas->root->object.flags & FOO_CANVAS_ITEM_NEED_DEEP_UPDATE)) {
+		canvas->root->object.flags |= FOO_CANVAS_ITEM_NEED_DEEP_UPDATE;
+		foo_canvas_request_update (canvas);
+	}
+
+	/* Map a background None window over the bin_window to avoid
+	 * scrolling the window scroll causing exposes.
+	 */
+	window = NULL;
+	if (GTK_WIDGET_MAPPED (widget)) {
+		attributes.window_type = GDK_WINDOW_CHILD;
+		attributes.x = widget->allocation.x;
+		attributes.y = widget->allocation.y;
+		attributes.width = widget->allocation.width;
+		attributes.height = widget->allocation.height;
+		attributes.wclass = GDK_INPUT_OUTPUT;
+		attributes.visual = gtk_widget_get_visual (widget);
+		attributes.colormap = gtk_widget_get_colormap (widget);
+		attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK;
+		
+		attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+		
+		window = gdk_window_new (gtk_widget_get_parent_window (widget),
+					 &attributes, attributes_mask);
+		gdk_window_set_back_pixmap (window, NULL, FALSE);
+		gdk_window_set_user_data (window, widget);
+		
+		gdk_window_show (window);
+	}
+
+	scroll_to (canvas, x1, y1);
+
+	/* If we created a an overlapping background None window, remove it how.
+	 *
+	 * TODO: We would like to temporarily set the bin_window background to
+	 * None to avoid clearing the bin_window to the background, but gdk doesn't
+	 * expose enought to let us do this, so we get a flash-effect here. At least
+	 * it looks better than scroll + expose.
+	 */
+	if (window != NULL) {
+		gdk_window_hide (window);
+		gdk_window_set_user_data (window, NULL);
+		gdk_window_destroy (window);
+	}
+
+	canvas->need_repick = TRUE;
+}
+
+/**
+ * foo_canvas_scroll_to:
+ * @canvas: A canvas.
+ * @cx: Horizontal scrolling offset in canvas pixel units.
+ * @cy: Vertical scrolling offset in canvas pixel units.
+ *
+ * Makes a canvas scroll to the specified offsets, given in canvas pixel units.
+ * The canvas will adjust the view so that it is not outside the scrolling
+ * region.  This function is typically not used, as it is better to hook
+ * scrollbars to the canvas layout's scrolling adjusments.
+ **/
+void
+foo_canvas_scroll_to (FooCanvas *canvas, int cx, int cy)
+{
+	g_return_if_fail (FOO_IS_CANVAS (canvas));
+
+	scroll_to (canvas, cx, cy);
+}
+
+/**
+ * foo_canvas_get_scroll_offsets:
+ * @canvas: A canvas.
+ * @cx: Horizontal scrolling offset (return value).
+ * @cy: Vertical scrolling offset (return value).
+ *
+ * Queries the scrolling offsets of a canvas.  The values are returned in canvas
+ * pixel units.
+ **/
+void
+foo_canvas_get_scroll_offsets (FooCanvas *canvas, int *cx, int *cy)
+{
+	g_return_if_fail (FOO_IS_CANVAS (canvas));
+
+	if (cx)
+		*cx = canvas->layout.hadjustment->value;
+
+	if (cy)
+		*cy = canvas->layout.vadjustment->value;
+}
+
+/**
+ * foo_canvas_update_now:
+ * @canvas: A canvas.
+ *
+ * Forces an immediate update and redraw of a canvas.  If the canvas does not
+ * have any pending update or redraw requests, then no action is taken.  This is
+ * typically only used by applications that need explicit control of when the
+ * display is updated, like games.  It is not needed by normal applications.
+ */
+void
+foo_canvas_update_now (FooCanvas *canvas)
+{
+	g_return_if_fail (FOO_IS_CANVAS (canvas));
+
+	if (!(canvas->need_update || canvas->need_redraw))
+		return;
+	remove_idle (canvas);
+	do_update (canvas);
+}
+
+/**
+ * foo_canvas_get_item_at:
+ * @canvas: A canvas.
+ * @x: X position in world coordinates.
+ * @y: Y position in world coordinates.
+ *
+ * Looks for the item that is under the specified position, which must be
+ * specified in world coordinates.
+ *
+ * Return value: The sought item, or NULL if no item is at the specified
+ * coordinates.
+ **/
+FooCanvasItem *
+foo_canvas_get_item_at (FooCanvas *canvas, double x, double y)
+{
+	FooCanvasItem *item;
+	double dist;
+	int cx, cy;
+
+	g_return_val_if_fail (FOO_IS_CANVAS (canvas), NULL);
+
+	foo_canvas_w2c (canvas, x, y, &cx, &cy);
+
+	dist = foo_canvas_item_invoke_point (canvas->root, x, y, cx, cy, &item);
+	if ((int) (dist * canvas->pixels_per_unit + 0.5) <= canvas->close_enough)
+		return item;
+	else
+		return NULL;
+}
+
+/* Queues an update of the canvas */
+static void
+foo_canvas_request_update (FooCanvas *canvas)
+{
+	FOO_CANVAS_GET_CLASS (canvas)->request_update (canvas);
+}
+
+static void
+foo_canvas_request_update_real (FooCanvas *canvas)
+{
+	canvas->need_update = TRUE;
+	add_idle (canvas);
+}
+
+/**
+ * foo_canvas_request_redraw:
+ * @canvas: A canvas.
+ * @x1: Leftmost coordinate of the rectangle to be redrawn.
+ * @y1: Upper coordinate of the rectangle to be redrawn.
+ * @x2: Rightmost coordinate of the rectangle to be redrawn, plus 1.
+ * @y2: Lower coordinate of the rectangle to be redrawn, plus 1.
+ *
+ * Convenience function that informs a canvas that the specified rectangle needs
+ * to be repainted.  The rectangle includes @x1 and @y1, but not @x2 and @y2.
+ * To be used only by item implementations.
+ **/
+void
+foo_canvas_request_redraw (FooCanvas *canvas, int x1, int y1, int x2, int y2)
+{
+	GdkRectangle bbox;
+
+	g_return_if_fail (FOO_IS_CANVAS (canvas));
+
+	if (!GTK_WIDGET_DRAWABLE (canvas) || (x1 >= x2) || (y1 >= y2)) return;
+
+	bbox.x = x1;
+	bbox.y = y1;
+	bbox.width = x2 - x1;
+	bbox.height = y2 - y1;
+
+	gdk_window_invalidate_rect (canvas->layout.bin_window,
+				    &bbox, FALSE);
+}
+
+
+/**
+ * foo_canvas_w2c_affine:
+ * @canvas: A canvas.
+ * @affine: An affine transformation matrix (return value).
+ *
+ * Gets the affine transform that converts from world coordinates to canvas
+ * pixel coordinates.
+ **/
+void
+foo_canvas_w2c_affine (FooCanvas *canvas, double affine[6])
+{
+	double zooom;
+
+	g_return_if_fail (FOO_IS_CANVAS (canvas));
+	g_return_if_fail (affine != NULL);
+
+	zooom = canvas->pixels_per_unit;
+
+	affine[0] = zooom;
+	affine[1] = 0;
+	affine[2] = 0;
+	affine[3] = zooom;
+	affine[4] = -canvas->scroll_x1 * zooom;
+	affine[5] = -canvas->scroll_y1 * zooom;
+}
+
+/**
+ * foo_canvas_w2c:
+ * @canvas: A canvas.
+ * @wx: World X coordinate.
+ * @wy: World Y coordinate.
+ * @cx: X pixel coordinate (return value).
+ * @cy: Y pixel coordinate (return value).
+ *
+ * Converts world coordinates into canvas pixel coordinates.
+ **/
+void
+foo_canvas_w2c (FooCanvas *canvas, double wx, double wy, int *cx, int *cy)
+{
+	double zoom;
+
+	g_return_if_fail (FOO_IS_CANVAS (canvas));
+	
+	zoom = canvas->pixels_per_unit;
+	
+	if (cx)
+		*cx = floor ((wx - canvas->scroll_x1)*zoom + canvas->zoom_xofs + 0.5);
+	if (cy)
+		*cy = floor ((wy - canvas->scroll_y1)*zoom + canvas->zoom_yofs + 0.5);
+}
+
+/**
+ * foo_canvas_w2c:
+ * @canvas: A canvas.
+ * @world: rectangle in world coordinates.
+ * @canvas: rectangle in canvase coordinates.
+ *
+ * Converts rectangles in world coordinates into canvas pixel coordinates.
+ **/
+void
+foo_canvas_w2c_rect_d (FooCanvas *canvas,
+			 double *x1, double *y1,
+			 double *x2, double *y2)
+{
+	foo_canvas_w2c_d (canvas,
+			    *x1, *y1,
+			    x1, y1);
+	foo_canvas_w2c_d (canvas,
+			    *x2, *y2,
+			    x2, y2);
+}
+
+
+
+/**
+ * foo_canvas_w2c_d:
+ * @canvas: A canvas.
+ * @wx: World X coordinate.
+ * @wy: World Y coordinate.
+ * @cx: X pixel coordinate (return value).
+ * @cy: Y pixel coordinate (return value).
+ *
+ * Converts world coordinates into canvas pixel coordinates.  This version
+ * produces coordinates in floating point coordinates, for greater precision.
+ **/
+void
+foo_canvas_w2c_d (FooCanvas *canvas, double wx, double wy, double *cx, double *cy)
+{
+	double zoom;
+
+	g_return_if_fail (FOO_IS_CANVAS (canvas));
+
+	zoom = canvas->pixels_per_unit;
+	
+	if (cx)
+		*cx = (wx - canvas->scroll_x1)*zoom + canvas->zoom_xofs;
+	if (cy)
+		*cy = (wy - canvas->scroll_y1)*zoom + canvas->zoom_yofs;
+}
+
+
+/**
+ * foo_canvas_c2w:
+ * @canvas: A canvas.
+ * @cx: Canvas pixel X coordinate.
+ * @cy: Canvas pixel Y coordinate.
+ * @wx: X world coordinate (return value).
+ * @wy: Y world coordinate (return value).
+ *
+ * Converts canvas pixel coordinates to world coordinates.
+ **/
+void
+foo_canvas_c2w (FooCanvas *canvas, int cx, int cy, double *wx, double *wy)
+{
+	double zoom;
+
+	g_return_if_fail (FOO_IS_CANVAS (canvas));
+
+	zoom = canvas->pixels_per_unit;
+	
+	if (wx)
+		*wx = (cx - canvas->zoom_xofs)/zoom + canvas->scroll_x1;
+	if (wy)
+		*wy = (cy - canvas->zoom_yofs)/zoom + canvas->scroll_y1;
+}
+
+
+/**
+ * foo_canvas_window_to_world:
+ * @canvas: A canvas.
+ * @winx: Window-relative X coordinate.
+ * @winy: Window-relative Y coordinate.
+ * @worldx: X world coordinate (return value).
+ * @worldy: Y world coordinate (return value).
+ *
+ * Converts window-relative coordinates into world coordinates.  You can use
+ * this when you need to convert mouse coordinates into world coordinates, for
+ * example.
+ * Window coordinates are really the same as canvas coordinates now, but this
+ * function is here for backwards compatibility reasons.
+ **/
+void
+foo_canvas_window_to_world (FooCanvas *canvas, double winx, double winy,
+			      double *worldx, double *worldy)
+{
+	g_return_if_fail (FOO_IS_CANVAS (canvas));
+
+	if (worldx)
+		*worldx = canvas->scroll_x1 + ((winx - canvas->zoom_xofs)
+					       / canvas->pixels_per_unit);
+
+	if (worldy)
+		*worldy = canvas->scroll_y1 + ((winy - canvas->zoom_yofs)
+					       / canvas->pixels_per_unit);
+}
+
+
+/**
+ * foo_canvas_world_to_window:
+ * @canvas: A canvas.
+ * @worldx: World X coordinate.
+ * @worldy: World Y coordinate.
+ * @winx: X window-relative coordinate.
+ * @winy: Y window-relative coordinate.
+ *
+ * Converts world coordinates into window-relative coordinates.
+ * Window coordinates are really the same as canvas coordinates now, but this
+ * function is here for backwards compatibility reasons.
+ **/
+void
+foo_canvas_world_to_window (FooCanvas *canvas, double worldx, double worldy,
+			    double *winx, double *winy)
+{
+	g_return_if_fail (FOO_IS_CANVAS (canvas));
+
+	if (winx)
+		*winx = (canvas->pixels_per_unit)*(worldx - canvas->scroll_x1) + canvas->zoom_xofs;
+
+	if (winy)
+		*winy = (canvas->pixels_per_unit)*(worldy - canvas->scroll_y1) + canvas->zoom_yofs;
+}
+
+
+
+/**
+ * foo_canvas_get_color:
+ * @canvas: A canvas.
+ * @spec: X color specification, or NULL for "transparent".
+ * @color: Returns the allocated color.
+ *
+ * Allocates a color based on the specified X color specification.  As a
+ * convenience to item implementations, it returns TRUE if the color was
+ * allocated, or FALSE if the specification was NULL.  A NULL color
+ * specification is considered as "transparent" by the canvas.
+ *
+ * Return value: TRUE if @spec is non-NULL and the color is allocated.  If @spec
+ * is NULL, then returns FALSE.
+ **/
+int
+foo_canvas_get_color (FooCanvas *canvas, const char *spec, GdkColor *color)
+{
+	GdkColormap *colormap;
+
+	g_return_val_if_fail (FOO_IS_CANVAS (canvas), FALSE);
+	g_return_val_if_fail (color != NULL, FALSE);
+
+	if (!spec) {
+		color->pixel = 0;
+		color->red = 0;
+		color->green = 0;
+		color->blue = 0;
+		return FALSE;
+	}
+
+	gdk_color_parse (spec, color);
+
+	colormap = gtk_widget_get_colormap (GTK_WIDGET (canvas));
+
+	gdk_rgb_find_color (colormap, color);
+
+	return TRUE;
+}
+
+/**
+ * foo_canvas_get_color_pixel:
+ * @canvas: A canvas.
+ * @rgba: RGBA color specification.
+ *
+ * Allocates a color from the RGBA value passed into this function.  The alpha
+ * opacity value is discarded, since normal X colors do not support it.
+ *
+ * Return value: Allocated pixel value corresponding to the specified color.
+ **/
+gulong
+foo_canvas_get_color_pixel (FooCanvas *canvas, guint rgba)
+{
+	GdkColormap *colormap;
+	GdkColor color;
+
+	g_return_val_if_fail (FOO_IS_CANVAS (canvas), 0);
+
+	color.red = ((rgba & 0xff000000) >> 16) + ((rgba & 0xff000000) >> 24);
+	color.green = ((rgba & 0x00ff0000) >> 8) + ((rgba & 0x00ff0000) >> 16);
+	color.blue = (rgba & 0x0000ff00) + ((rgba & 0x0000ff00) >> 8);
+	color.pixel = 0;
+
+	colormap = gtk_widget_get_colormap (GTK_WIDGET (canvas));
+
+	gdk_rgb_find_color (colormap, &color);
+
+	return color.pixel;
+}
+
+
+/* FIXME: This function is not useful anymore */
+/**
+ * foo_canvas_set_stipple_origin:
+ * @canvas: A canvas.
+ * @gc: GC on which to set the stipple origin.
+ *
+ * Sets the stipple origin of the specified GC as is appropriate for the canvas,
+ * so that it will be aligned with other stipple patterns used by canvas items.
+ * This is typically only needed by item implementations.
+ **/
+void
+foo_canvas_set_stipple_origin (FooCanvas *canvas, GdkGC *gc)
+{
+	g_return_if_fail (FOO_IS_CANVAS (canvas));
+	g_return_if_fail (GDK_IS_GC (gc));
+
+	gdk_gc_set_ts_origin (gc, 0, 0);
+}
+
+static gboolean
+boolean_handled_accumulator (GSignalInvocationHint *ihint,
+			     GValue                *return_accu,
+			     const GValue          *handler_return,
+			     gpointer               dummy)
+{
+	gboolean continue_emission;
+	gboolean signal_handled;
+	
+	signal_handled = g_value_get_boolean (handler_return);
+	g_value_set_boolean (return_accu, signal_handled);
+	continue_emission = !signal_handled;
+	
+	return continue_emission;
+}
+
+static guint
+foo_canvas_item_accessible_add_focus_handler (AtkComponent    *component,
+                                              AtkFocusHandler handler)
+{
+ 	GSignalMatchType match_type;
+	guint signal_id;
+
+	match_type = G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC;
+	signal_id = g_signal_lookup ("focus-event", ATK_TYPE_OBJECT);
+
+	if (!g_signal_handler_find (component, match_type, signal_id, 0, NULL,
+                                    (gpointer) handler, NULL)) {
+		return g_signal_connect_closure_by_id (component,
+                                                       signal_id, 0,
+                                                       g_cclosure_new (
+                                                       G_CALLBACK (handler), NULL,
+                                                       (GClosureNotify) NULL),
+                                                       FALSE);
+	} 
+	return 0;
+}
+
+static void
+foo_canvas_item_accessible_get_item_extents (FooCanvasItem *item,
+                                             GdkRectangle  *rect)
+{
+ 	double bx1, bx2, by1, by2;
+	gint scroll_x, scroll_y;
+	gint x1, x2, y1, y2;
+
+	foo_canvas_item_get_bounds (item, &bx1, &by1, &bx2, &by2);
+	foo_canvas_w2c_rect_d (item->canvas, &bx1, &by1, &bx2, &by2);
+	foo_canvas_get_scroll_offsets (item->canvas, &scroll_x, &scroll_y);
+	x1 = floor (bx1 + .5);
+	y1 = floor (by1 + .5);
+	x2 = floor (bx2 + .5);
+	y2 = floor (by2 + .5);
+	rect->x = x1 - scroll_x;
+	rect->y = y1 - scroll_y;
+	rect->width = x2 - x1;
+	rect->height = y2 - y1;
+}
+
+static gboolean
+foo_canvas_item_accessible_is_item_in_window (FooCanvasItem *item,
+                                              GdkRectangle  *rect)
+{
+ 	GtkWidget *widget;
+	gboolean retval;
+
+	widget = GTK_WIDGET (item->canvas);
+	if (widget->window) {
+		int window_width, window_height;
+
+		gdk_window_get_geometry (widget->window, NULL, NULL,
+                                         &window_width, &window_height, NULL);
+		/*
+                 * Check whether rectangles intersect
+		 */
+                if (rect->x + rect->width < 0 ||
+                    rect->y + rect->height < 0 ||
+                    rect->x > window_width  ||
+                    rect->y > window_height) {
+			retval = FALSE;
+		} else {
+                        retval = TRUE;
+		}
+	} else {
+                retval = FALSE;
+	}
+        return retval;
+}
+
+
+static void
+foo_canvas_item_accessible_get_extents (AtkComponent *component,
+                                        gint		*x,
+                                        gint		*y,
+                                        gint		*width,
+                                        gint		*height,
+                                        AtkCoordType coord_type)
+{
+ 	AtkGObjectAccessible *atk_gobj;
+	GObject *obj;
+	FooCanvasItem *item;
+	gint window_x, window_y;
+	gint toplevel_x, toplevel_y;
+	GdkRectangle rect;
+	GdkWindow *window;
+	GtkWidget *canvas;
+
+	atk_gobj = ATK_GOBJECT_ACCESSIBLE (component);
+	obj = atk_gobject_accessible_get_object (atk_gobj);
+
+	if (obj == NULL) {
+		/* item is defunct */
+		return;
+	}
+
+        /* Get the CanvasItem */
+	item = FOO_CANVAS_ITEM (obj);
+
+	/* If this item has no parent canvas, something's broken */
+	g_return_if_fail (GTK_IS_WIDGET (item->canvas));
+
+	foo_canvas_item_accessible_get_item_extents (item, &rect);
+	*width = rect.width;
+	*height = rect.height;
+	if (!foo_canvas_item_accessible_is_item_in_window (item, &rect)) {
+		*x = G_MININT;
+		*y = G_MININT;
+		return;
+	}
+
+        canvas = GTK_WIDGET (item->canvas);
+	window = gtk_widget_get_parent_window (canvas);
+	gdk_window_get_origin (window, &window_x, &window_y);
+	*x = rect.x + window_x;
+	*y = rect.y + window_y;
+	if (coord_type == ATK_XY_WINDOW) {
+		window = gdk_window_get_toplevel (canvas->window);
+		gdk_window_get_origin (window, &toplevel_x, &toplevel_y);
+		*x -= toplevel_x;
+		*y -= toplevel_y;
+	}
+        return;
+}
+
+static gint
+foo_canvas_item_accessible_get_mdi_zorder (AtkComponent *component)
+{
+	AtkGObjectAccessible *atk_gobj;
+	GObject *g_obj;
+	FooCanvasItem *item;
+
+	atk_gobj = ATK_GOBJECT_ACCESSIBLE (component);
+	g_obj = atk_gobject_accessible_get_object (atk_gobj);
+	if (g_obj == NULL) {
+		/* Object is defunct */
+		return -1;
+	}
+
+	item = FOO_CANVAS_ITEM (g_obj);
+	if (item->parent) {
+       		return g_list_index (FOO_CANVAS_GROUP (item->parent)->item_list, item);
+	} else {
+		g_return_val_if_fail (item->canvas->root == item, -1);
+		return 0;
+	}
+}
+
+static gboolean
+foo_canvas_item_accessible_grab_focus (AtkComponent *component)
+{
+ 	AtkGObjectAccessible *atk_gobj;
+	GObject *obj;
+	FooCanvasItem *item;
+	GtkWidget *toplevel;
+
+	atk_gobj = ATK_GOBJECT_ACCESSIBLE (component);
+	obj = atk_gobject_accessible_get_object (atk_gobj);
+
+	item = FOO_CANVAS_ITEM (obj);
+	if (item == NULL) {
+		/* item is defunct */
+		return FALSE;
+	}
+
+        foo_canvas_item_grab_focus (item);
+	toplevel = gtk_widget_get_toplevel (GTK_WIDGET (item->canvas));
+	if (GTK_WIDGET_TOPLEVEL (toplevel)) {
+		gtk_window_present (GTK_WINDOW (toplevel));
+	}
+
+	return TRUE;
+}
+
+static void
+foo_canvas_item_accessible_remove_focus_handler (AtkComponent *component,
+                                                 guint		handler_id)
+{
+ 	g_signal_handler_disconnect (component, handler_id);
+}
+
+static void
+foo_canvas_item_accessible_component_interface_init (AtkComponentIface *iface)
+{
+	g_return_if_fail (iface != NULL);
+
+	iface->add_focus_handler = foo_canvas_item_accessible_add_focus_handler;
+	iface->get_extents = foo_canvas_item_accessible_get_extents;
+	iface->get_mdi_zorder = foo_canvas_item_accessible_get_mdi_zorder;
+	iface->grab_focus = foo_canvas_item_accessible_grab_focus;
+      	iface->remove_focus_handler = foo_canvas_item_accessible_remove_focus_handler;
+}
+
+static gboolean
+foo_canvas_item_accessible_is_item_on_screen (FooCanvasItem *item)
+{
+	GdkRectangle rect;
+
+	foo_canvas_item_accessible_get_item_extents (item, &rect);
+	return foo_canvas_item_accessible_is_item_in_window (item, &rect);
+}
+
+static void
+foo_canvas_item_accessible_initialize (AtkObject *obj, gpointer data)
+{
+	if (ATK_OBJECT_CLASS (accessible_item_parent_class)->initialize != NULL)
+		ATK_OBJECT_CLASS (accessible_item_parent_class)->initialize (obj, data);
+	g_object_set_data (G_OBJECT (obj), "atk-component-layer",
+			   GINT_TO_POINTER (ATK_LAYER_MDI));
+}
+
+static AtkStateSet*
+foo_canvas_item_accessible_ref_state_set (AtkObject *accessible)
+{
+ 	AtkGObjectAccessible *atk_gobj;
+	GObject *obj;
+ 	FooCanvasItem *item;
+	AtkStateSet *state_set;
+
+	state_set = ATK_OBJECT_CLASS (accessible_item_parent_class)->ref_state_set (accessible);
+	atk_gobj = ATK_GOBJECT_ACCESSIBLE (accessible);
+	obj = atk_gobject_accessible_get_object (atk_gobj);
+
+	item = FOO_CANVAS_ITEM (obj);
+	if (item == NULL) {
+		atk_state_set_add_state (state_set, ATK_STATE_DEFUNCT);
+	} else {
+                if (item->object.flags & FOO_CANVAS_ITEM_VISIBLE) {
+			atk_state_set_add_state (state_set, ATK_STATE_VISIBLE);
+			
+			if (foo_canvas_item_accessible_is_item_on_screen (item)) {
+  				atk_state_set_add_state (state_set, ATK_STATE_SHOWING);
+       			}
+		}
+        	if (GTK_WIDGET_CAN_FOCUS (GTK_WIDGET (item->canvas))) {
+			atk_state_set_add_state (state_set, ATK_STATE_FOCUSABLE);
+
+			if (item->canvas->focused_item == item) {
+				atk_state_set_add_state (state_set, ATK_STATE_FOCUSED);
+			}
+		}
+	}
+
+        return state_set;
+}
+
+static void
+foo_canvas_item_accessible_class_init (AtkObjectClass *klass)
+{
+ 	accessible_item_parent_class = g_type_class_peek_parent (klass);
+
+	klass->initialize = foo_canvas_item_accessible_initialize;
+	klass->ref_state_set = foo_canvas_item_accessible_ref_state_set;
+}
+
+static GType
+foo_canvas_item_accessible_get_type (void)
+{
+	static GType type = 0;
+
+	if (!type) {
+		static const GInterfaceInfo atk_component_info = {
+			(GInterfaceInitFunc) foo_canvas_item_accessible_component_interface_init,
+                 	(GInterfaceFinalizeFunc) NULL,
+			NULL
+		};
+		AtkObjectFactory *factory;
+		GType parent_atk_type;
+		GTypeQuery query;
+		GTypeInfo tinfo = { 0 };
+
+		factory = atk_registry_get_factory (atk_get_default_registry(),
+						    GTK_TYPE_OBJECT);
+		if (!factory) {
+			return G_TYPE_INVALID;
+		}
+		parent_atk_type = atk_object_factory_get_accessible_type (factory);
+		if (!parent_atk_type) {
+			return G_TYPE_INVALID;
+		}
+		g_type_query (parent_atk_type, &query);
+		tinfo.class_init = (GClassInitFunc) foo_canvas_item_accessible_class_init;
+		tinfo.class_size = query.class_size;
+		tinfo.instance_size = query.instance_size;
+		type = g_type_register_static (parent_atk_type,
+					       "FooCanvasItemAccessibility",
+					       &tinfo, 0);
+
+		g_type_add_interface_static (type, ATK_TYPE_COMPONENT,
+					     &atk_component_info);
+
+	}
+
+	return type;
+}
+
+static AtkObject *
+foo_canvas_item_accessible_create (GObject *for_object)
+{
+	GType type;
+	AtkObject *accessible;
+	FooCanvasItem *item;
+
+	item = FOO_CANVAS_ITEM (for_object);
+	g_return_val_if_fail (item != NULL, NULL);
+
+	type = foo_canvas_item_accessible_get_type ();
+	if (type == G_TYPE_INVALID) {
+		return atk_no_op_object_new (for_object);
+	}
+
+        accessible = g_object_new (type, NULL);
+	atk_object_initialize (accessible, for_object);
+	return accessible;
+}
+
+static GType
+foo_canvas_item_accessible_factory_get_accessible_type (void)
+{
+	return foo_canvas_item_accessible_get_type ();
+}
+
+static AtkObject*
+foo_canvas_item_accessible_factory_create_accessible (GObject *obj)
+{
+	AtkObject *accessible;
+
+	g_return_val_if_fail (G_IS_OBJECT (obj), NULL);
+
+	accessible = foo_canvas_item_accessible_create (obj);
+
+	return accessible;
+}
+
+static void
+foo_canvas_item_accessible_factory_class_init (AtkObjectFactoryClass *klass)
+{
+	klass->create_accessible = foo_canvas_item_accessible_factory_create_accessible;
+	klass->get_accessible_type = foo_canvas_item_accessible_factory_get_accessible_type;
+}
+ 
+static GType
+foo_canvas_item_accessible_factory_get_type (void)
+{
+	static GType type = 0;
+
+	if (!type) {
+		static const GTypeInfo tinfo = {
+			sizeof (AtkObjectFactoryClass),
+			(GBaseInitFunc) NULL,
+			(GBaseFinalizeFunc) NULL,
+			(GClassInitFunc) foo_canvas_item_accessible_factory_class_init,
+			NULL,		/* class_finalize */
+			NULL,		/* class_data */
+			sizeof (AtkObjectFactory),
+			0,		/* n_preallocs */
+			NULL
+		};
+		type = g_type_register_static (ATK_TYPE_OBJECT_FACTORY,
+					       "FooCanvasItemAccessibilityFactory",
+					       &tinfo, 0);
+	}
+
+	return type;
+}
+
+/* Class initialization function for FooCanvasItemClass */
+static void
+foo_canvas_item_class_init (FooCanvasItemClass *klass)
+{
+	GObjectClass *gobject_class = (GObjectClass *) klass;
+
+	item_parent_class = g_type_class_peek_parent (klass);
+
+	gobject_class->set_property = foo_canvas_item_set_property;
+	gobject_class->get_property = foo_canvas_item_get_property;
+	gobject_class->dispose = foo_canvas_item_dispose;
+
+	g_object_class_install_property
+		(gobject_class, ITEM_PROP_PARENT,
+		 g_param_spec_object ("parent", NULL, NULL,
+				      FOO_TYPE_CANVAS_ITEM,
+				      G_PARAM_READWRITE));
+	
+	g_object_class_install_property
+		(gobject_class, ITEM_PROP_VISIBLE,
+		 g_param_spec_boolean ("visible", NULL, NULL,
+				      TRUE,
+				      G_PARAM_READWRITE));
+
+	item_signals[ITEM_EVENT] =
+		g_signal_new ("event",
+			      G_TYPE_FROM_CLASS (klass),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (FooCanvasItemClass, event),
+			      boolean_handled_accumulator, NULL,
+			      foo_canvas_marshal_BOOLEAN__BOXED,
+			      G_TYPE_BOOLEAN, 1,
+			      GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+	klass->realize = foo_canvas_item_realize;
+	klass->unrealize = foo_canvas_item_unrealize;
+	klass->map = foo_canvas_item_map;
+	klass->unmap = foo_canvas_item_unmap;
+	klass->update = foo_canvas_item_update;
+
+	atk_registry_set_factory_type (atk_get_default_registry (),
+                                       FOO_TYPE_CANVAS_ITEM,
+                                       foo_canvas_item_accessible_factory_get_type ());
+}
diff --git a/widgets/libfoocanvas/foo-canvas.h b/widgets/libfoocanvas/foo-canvas.h
new file mode 100644
index 0000000..91ab8d8
--- /dev/null
+++ b/widgets/libfoocanvas/foo-canvas.h
@@ -0,0 +1,542 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: 8; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * The Gnome Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+/* FooCanvas widget - Tk-like canvas widget for Gnome
+ *
+ * FooCanvas is basically a port of the Tk toolkit's most excellent canvas
+ * widget.  Tk is copyrighted by the Regents of the University of California,
+ * Sun Microsystems, and other parties.
+ *
+ *
+ * Authors: Federico Mena <federico nuclecu unam mx>
+ *          Raph Levien <raph gimp org>
+ */
+
+#ifndef FOO_CANVAS_H
+#define FOO_CANVAS_H
+
+#include <gtk/gtk.h>
+#include <stdarg.h>
+
+G_BEGIN_DECLS
+
+/* "Small" value used by canvas stuff */
+#define FOO_CANVAS_EPSILON 1e-10
+
+
+/* Macros for building colors that fit in a 32-bit integer.  The values are in
+ * [0, 255].
+ */
+
+#define FOO_CANVAS_COLOR(r, g, b) ((((int) (r) & 0xff) << 24)	\
+				     | (((int) (g) & 0xff) << 16)	\
+				     | (((int) (b) & 0xff) << 8)	\
+				     | 0xff)
+
+#define FOO_CANVAS_COLOR_A(r, g, b, a) ((((int) (r) & 0xff) << 24)	\
+					  | (((int) (g) & 0xff) << 16)	\
+					  | (((int) (b) & 0xff) << 8)	\
+					  | ((int) (a) & 0xff))
+
+
+typedef struct _FooCanvas           FooCanvas;
+typedef struct _FooCanvasClass      FooCanvasClass;
+typedef struct _FooCanvasItem       FooCanvasItem;
+typedef struct _FooCanvasItemClass  FooCanvasItemClass;
+typedef struct _FooCanvasGroup      FooCanvasGroup;
+typedef struct _FooCanvasGroupClass FooCanvasGroupClass;
+
+
+/* FooCanvasItem - base item class for canvas items
+ *
+ * All canvas items are derived from FooCanvasItem.  The only information a
+ * FooCanvasItem contains is its parent canvas, its parent canvas item group,
+ * and its bounding box in world coordinates.
+ *
+ * Items inside a canvas are organized in a tree of FooCanvasItemGroup nodes
+ * and FooCanvasItem leaves.  Each canvas has a single root group, which can
+ * be obtained with the foo_canvas_get_root() function.
+ *
+ * The abstract FooCanvasItem class does not have any configurable or
+ * queryable attributes.
+ */
+
+/* Object flags for items */
+enum {
+	FOO_CANVAS_ITEM_REALIZED         = 1 << 4,
+	FOO_CANVAS_ITEM_MAPPED           = 1 << 5,
+	FOO_CANVAS_ITEM_ALWAYS_REDRAW    = 1 << 6,
+	FOO_CANVAS_ITEM_VISIBLE          = 1 << 7,
+	FOO_CANVAS_ITEM_NEED_UPDATE      = 1 << 8,
+	FOO_CANVAS_ITEM_NEED_DEEP_UPDATE = 1 << 9
+};
+
+/* Update flags for items */
+enum {
+	FOO_CANVAS_UPDATE_REQUESTED  = 1 << 0,
+	FOO_CANVAS_UPDATE_DEEP       = 1 << 1
+};
+
+#define FOO_TYPE_CANVAS_ITEM            (foo_canvas_item_get_type ())
+#define FOO_CANVAS_ITEM(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), FOO_TYPE_CANVAS_ITEM, FooCanvasItem))
+#define FOO_CANVAS_ITEM_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), FOO_TYPE_CANVAS_ITEM, FooCanvasItemClass))
+#define FOO_IS_CANVAS_ITEM(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FOO_TYPE_CANVAS_ITEM))
+#define FOO_IS_CANVAS_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FOO_TYPE_CANVAS_ITEM))
+#define FOO_CANVAS_ITEM_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), FOO_TYPE_CANVAS_ITEM, FooCanvasItemClass))
+
+struct _FooCanvasItem {
+	GtkObject object;
+
+	/* Parent canvas for this item */
+	FooCanvas *canvas;
+
+	/* Parent canvas group for this item (a FooCanvasGroup) */
+	FooCanvasItem *parent;
+
+	/* Bounding box for this item (in canvas coordinates) */
+	double x1, y1, x2, y2;
+};
+
+struct _FooCanvasItemClass {
+	GtkObjectClass parent_class;
+
+	/* Tell the item to update itself.  The flags are from the update flags
+	 * defined above.  The item should update its internal state from its
+	 * queued state, and recompute and request its repaint area. The
+	 * update method also recomputes the bounding box of the item.
+	 */
+	void (* update) (FooCanvasItem *item, double i2w_dx, double i2w_dy, int flags);
+
+	/* Realize an item -- create GCs, etc. */
+	void (* realize) (FooCanvasItem *item);
+
+	/* Unrealize an item */
+	void (* unrealize) (FooCanvasItem *item);
+
+	/* Map an item - normally only need by items with their own GdkWindows */
+	void (* map) (FooCanvasItem *item);
+
+	/* Unmap an item */
+	void (* unmap) (FooCanvasItem *item);
+
+	/* Draw an item of this type.  (x, y) are the upper-left canvas pixel
+	 * coordinates of the drawable, a temporary pixmap, where things get
+	 * drawn.  (width, height) are the dimensions of the drawable.
+	 */
+	void (* draw) (FooCanvasItem *item, GdkDrawable *drawable, GdkEventExpose *expose);
+
+	/* Calculate the distance from an item to the specified point.  It also
+         * returns a canvas item which is the item itself in the case of the
+         * object being an actual leaf item, or a child in case of the object
+         * being a canvas group.  (cx, cy) are the canvas pixel coordinates that
+         * correspond to the item-relative coordinates (x, y).
+	 */
+	double (* point) (FooCanvasItem *item, double x, double y, int cx, int cy,
+			  FooCanvasItem **actual_item);
+
+	void (* translate) (FooCanvasItem *item, double dx, double dy);
+	
+	/* Fetch the item's bounding box (need not be exactly tight).  This
+	 * should be in item-relative coordinates.
+	 */
+	void (* bounds) (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2);
+
+	/* Signal: an event ocurred for an item of this type.  The (x, y)
+	 * coordinates are in the canvas world coordinate system.
+	 */
+	gboolean (* event)                (FooCanvasItem *item, GdkEvent *event);
+
+	/* Reserved for future expansion */
+	gpointer spare_vmethods [4];
+};
+
+
+/* Standard Gtk function */
+GType foo_canvas_item_get_type (void) G_GNUC_CONST;
+
+/* Create a canvas item using the standard Gtk argument mechanism.  The item is
+ * automatically inserted at the top of the specified canvas group.  The last
+ * argument must be a NULL pointer.
+ */
+FooCanvasItem *foo_canvas_item_new (FooCanvasGroup *parent, GType type,
+				    const gchar *first_arg_name, ...);
+
+/* Constructors for use in derived classes and language wrappers */
+void foo_canvas_item_construct (FooCanvasItem *item, FooCanvasGroup *parent,
+				const gchar *first_arg_name, va_list args);
+
+/* Configure an item using the standard Gtk argument mechanism.  The last
+ * argument must be a NULL pointer.
+ */
+void foo_canvas_item_set (FooCanvasItem *item, const gchar *first_arg_name, ...);
+
+/* Used only for language wrappers and the like */
+void foo_canvas_item_set_valist (FooCanvasItem *item,
+				 const gchar *first_arg_name, va_list args);
+
+/* Move an item by the specified amount */
+void foo_canvas_item_move (FooCanvasItem *item, double dx, double dy);
+
+/* Raise an item in the z-order of its parent group by the specified number of
+ * positions.
+ */
+void foo_canvas_item_raise (FooCanvasItem *item, int positions);
+
+/* Lower an item in the z-order of its parent group by the specified number of
+ * positions.
+ */
+void foo_canvas_item_lower (FooCanvasItem *item, int positions);
+
+/* Raise an item to the top of its parent group's z-order. */
+void foo_canvas_item_raise_to_top (FooCanvasItem *item);
+
+/* Lower an item to the bottom of its parent group's z-order */
+void foo_canvas_item_lower_to_bottom (FooCanvasItem *item);
+
+/* Send an item behind another item */
+void foo_canvas_item_send_behind (FooCanvasItem *item,
+				  FooCanvasItem *behind_item);
+
+
+/* Show an item (make it visible).  If the item is already shown, it has no
+ * effect.
+ */
+void foo_canvas_item_show (FooCanvasItem *item);
+
+/* Hide an item (make it invisible).  If the item is already invisible, it has
+ * no effect.
+ */
+void foo_canvas_item_hide (FooCanvasItem *item);
+
+/* Grab the mouse for the specified item.  Only the events in event_mask will be
+ * reported.  If cursor is non-NULL, it will be used during the duration of the
+ * grab.  Time is a proper X event time parameter.  Returns the same values as
+ * XGrabPointer().
+ */
+int foo_canvas_item_grab (FooCanvasItem *item, unsigned int event_mask,
+			  GdkCursor *cursor, guint32 etime);
+
+/* Ungrabs the mouse -- the specified item must be the same that was passed to
+ * foo_canvas_item_grab().  Time is a proper X event time parameter.
+ */
+void foo_canvas_item_ungrab (FooCanvasItem *item, guint32 etime);
+
+/* These functions convert from a coordinate system to another.  "w" is world
+ * coordinates and "i" is item coordinates.
+ */
+void foo_canvas_item_w2i (FooCanvasItem *item, double *x, double *y);
+void foo_canvas_item_i2w (FooCanvasItem *item, double *x, double *y);
+
+/* Gets the affine transform that converts from item-relative coordinates to
+ * world coordinates.
+ */
+void foo_canvas_item_i2w_affine (FooCanvasItem *item, double affine[6]);
+
+/* Gets the affine transform that converts from item-relative coordinates to
+ * canvas pixel coordinates.
+ */
+void foo_canvas_item_i2c_affine (FooCanvasItem *item, double affine[6]);
+
+/* Remove the item from its parent group and make the new group its parent.  The
+ * item will be put on top of all the items in the new group.  The item's
+ * coordinates relative to its new parent to *not* change -- this means that the
+ * item could potentially move on the screen.
+ * 
+ * The item and the group must be in the same canvas.  An item cannot be
+ * reparented to a group that is the item itself or that is an inferior of the
+ * item.
+ */
+void foo_canvas_item_reparent (FooCanvasItem *item, FooCanvasGroup *new_group);
+
+/* Used to send all of the keystroke events to a specific item as well as
+ * GDK_FOCUS_CHANGE events.
+ */
+void foo_canvas_item_grab_focus (FooCanvasItem *item);
+
+/* Fetch the bounding box of the item.  The bounding box may not be exactly
+ * tight, but the canvas items will do the best they can.  The returned bounding
+ * box is in the coordinate system of the item's parent.
+ */
+void foo_canvas_item_get_bounds (FooCanvasItem *item,
+				 double *x1, double *y1, double *x2, double *y2);
+
+/* Request that the update method eventually get called.  This should be used
+ * only by item implementations.
+ */
+void foo_canvas_item_request_update (FooCanvasItem *item);
+
+/* Request a redraw of the bounding box of the canvas item */
+void foo_canvas_item_request_redraw (FooCanvasItem *item);
+
+/* FooCanvasGroup - a group of canvas items
+ *
+ * A group is a node in the hierarchical tree of groups/items inside a canvas.
+ * Groups serve to give a logical structure to the items.
+ *
+ * Consider a circuit editor application that uses the canvas for its schematic
+ * display.  Hierarchically, there would be canvas groups that contain all the
+ * components needed for an "adder", for example -- this includes some logic
+ * gates as well as wires.  You can move stuff around in a convenient way by
+ * doing a foo_canvas_item_move() of the hierarchical groups -- to move an
+ * adder, simply move the group that represents the adder.
+ *
+ * The following arguments are available:
+ *
+ * name		type		read/write	description
+ * --------------------------------------------------------------------------------
+ * x		double		RW		X coordinate of group's origin
+ * y		double		RW		Y coordinate of group's origin
+ */
+
+
+#define FOO_TYPE_CANVAS_GROUP            (foo_canvas_group_get_type ())
+#define FOO_CANVAS_GROUP(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), FOO_TYPE_CANVAS_GROUP, FooCanvasGroup))
+#define FOO_CANVAS_GROUP_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), FOO_TYPE_CANVAS_GROUP, FooCanvasGroupClass))
+#define FOO_IS_CANVAS_GROUP(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FOO_TYPE_CANVAS_GROUP))
+#define FOO_IS_CANVAS_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FOO_TYPE_CANVAS_GROUP))
+#define FOO_CANVAS_GROUP_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), FOO_TYPE_CANVAS_GROUP, FooCanvasGroupClass))
+
+
+struct _FooCanvasGroup {
+	FooCanvasItem item;
+
+	double xpos, ypos;
+	
+	/* Children of the group */
+	GList *item_list;
+	GList *item_list_end;
+};
+
+struct _FooCanvasGroupClass {
+	FooCanvasItemClass parent_class;
+};
+
+
+/* Standard Gtk function */
+GType foo_canvas_group_get_type (void) G_GNUC_CONST;
+
+
+/*** FooCanvas ***/
+
+
+#define FOO_TYPE_CANVAS            (foo_canvas_get_type ())
+#define FOO_CANVAS(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), FOO_TYPE_CANVAS, FooCanvas))
+#define FOO_CANVAS_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), FOO_TYPE_CANVAS, FooCanvasClass))
+#define FOO_IS_CANVAS(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FOO_TYPE_CANVAS))
+#define FOO_IS_CANVAS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FOO_TYPE_CANVAS))
+#define FOO_CANVAS_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), FOO_TYPE_CANVAS, FooCanvasClass))
+
+
+struct _FooCanvas {
+	GtkLayout layout;
+
+	/* Root canvas group */
+	FooCanvasItem *root;
+
+	/* The item containing the mouse pointer, or NULL if none */
+	FooCanvasItem *current_item;
+
+	/* Item that is about to become current (used to track deletions and such) */
+	FooCanvasItem *new_current_item;
+
+	/* Item that holds a pointer grab, or NULL if none */
+	FooCanvasItem *grabbed_item;
+
+	/* If non-NULL, the currently focused item */
+	FooCanvasItem *focused_item;
+
+	/* GC for temporary draw pixmap */
+	GdkGC *pixmap_gc;
+
+	/* Event on which selection of current item is based */
+	GdkEvent pick_event;
+
+	/* Scrolling region */
+	double scroll_x1, scroll_y1;
+	double scroll_x2, scroll_y2;
+
+	/* Scaling factor to be used for display */
+	double pixels_per_unit;
+
+	/* Idle handler ID */
+	guint idle_id;
+
+	/* Signal handler ID for destruction of the root item */
+	guint root_destroy_id;
+
+	/* Internal pixel offsets when zoomed out */
+	int zoom_xofs, zoom_yofs;
+
+	/* Last known modifier state, for deferred repick when a button is down */
+	int state;
+
+	/* Event mask specified when grabbing an item */
+	guint grabbed_event_mask;
+
+	/* Tolerance distance for picking items */
+	int close_enough;
+
+	/* Whether the canvas should center the canvas in the middle of
+	 * the window if the scroll region is smaller than the window */
+	unsigned int center_scroll_region : 1;
+
+	/* Whether items need update at next idle loop iteration */
+	unsigned int need_update : 1;
+
+	/* Are we in the midst of an update */
+	unsigned int doing_update : 1;
+
+	/* Whether the canvas needs redrawing at the next idle loop iteration */
+	unsigned int need_redraw : 1;
+
+	/* Whether current item will be repicked at next idle loop iteration */
+	unsigned int need_repick : 1;
+
+	/* For use by internal pick_current_item() function */
+	unsigned int left_grabbed_item : 1;
+
+	/* For use by internal pick_current_item() function */
+	unsigned int in_repick : 1;
+};
+
+struct _FooCanvasClass {
+	GtkLayoutClass parent_class;
+
+	/* Draw the background for the area given.
+	 */
+	void (* draw_background) (FooCanvas *canvas,
+				  int x, int y, int width, int height);
+
+	/* Private Virtual methods for groping the canvas inside bonobo */
+	void (* request_update) (FooCanvas *canvas);
+
+	/* Reserved for future expansion */
+	gpointer spare_vmethods [4];
+};
+
+
+/* Standard Gtk function */
+GType foo_canvas_get_type (void) G_GNUC_CONST;
+
+/* Creates a new canvas.  You should check that the canvas is created with the
+ * proper visual and colormap.  Any visual will do unless you intend to insert
+ * gdk_imlib images into it, in which case you should use the gdk_imlib visual.
+ *
+ * You should call foo_canvas_set_scroll_region() soon after calling this
+ * function to set the desired scrolling limits for the canvas.
+ */
+GtkWidget *foo_canvas_new (void);
+
+/* Returns the root canvas item group of the canvas */
+FooCanvasGroup *foo_canvas_root (FooCanvas *canvas);
+
+/* Sets the limits of the scrolling region, in world coordinates */
+void foo_canvas_set_scroll_region (FooCanvas *canvas,
+				   double x1, double y1, double x2, double y2);
+
+/* Gets the limits of the scrolling region, in world coordinates */
+void foo_canvas_get_scroll_region (FooCanvas *canvas,
+				   double *x1, double *y1, double *x2, double *y2);
+
+/* Sets the number of pixels that correspond to one unit in world coordinates */
+void foo_canvas_set_pixels_per_unit (FooCanvas *canvas, double n);
+
+/* Wether the canvas centers the scroll region if it is smaller than the window  */
+void foo_canvas_set_center_scroll_region (FooCanvas *canvas, gboolean center_scroll_region);
+
+/* Scrolls the canvas to the specified offsets, given in canvas pixel coordinates */
+void foo_canvas_scroll_to (FooCanvas *canvas, int cx, int cy);
+
+/* Returns the scroll offsets of the canvas in canvas pixel coordinates.  You
+ * can specify NULL for any of the values, in which case that value will not be
+ * queried.
+ */
+void foo_canvas_get_scroll_offsets (FooCanvas *canvas, int *cx, int *cy);
+
+/* Requests that the canvas be repainted immediately instead of in the idle
+ * loop.
+ */
+void foo_canvas_update_now (FooCanvas *canvas);
+
+/* Returns the item that is at the specified position in world coordinates, or
+ * NULL if no item is there.
+ */
+FooCanvasItem *foo_canvas_get_item_at (FooCanvas *canvas, double x, double y);
+
+/* For use only by item type implementations.  Request that the canvas
+ * eventually redraw the specified region, specified in canvas pixel
+ * coordinates.  The region contains (x1, y1) but not (x2, y2).
+ */
+void foo_canvas_request_redraw (FooCanvas *canvas, int x1, int y1, int x2, int y2);
+
+/* Gets the affine transform that converts world coordinates into canvas pixel
+ * coordinates.
+ */
+void foo_canvas_w2c_affine (FooCanvas *canvas, double affine[6]);
+
+/* These functions convert from a coordinate system to another.  "w" is world
+ * coordinates, "c" is canvas pixel coordinates (pixel coordinates that are
+ * (0,0) for the upper-left scrolling limit and something else for the
+ * lower-left scrolling limit).
+ */
+void foo_canvas_w2c_rect_d (FooCanvas *canvas,
+			    double *x1, double *y1,
+			    double *x2, double *y2);
+void foo_canvas_w2c (FooCanvas *canvas, double wx, double wy, int *cx, int *cy);
+void foo_canvas_w2c_d (FooCanvas *canvas, double wx, double wy, double *cx, double *cy);
+void foo_canvas_c2w (FooCanvas *canvas, int cx, int cy, double *wx, double *wy);
+
+/* This function takes in coordinates relative to the GTK_LAYOUT
+ * (canvas)->bin_window and converts them to world coordinates.
+ * These days canvas coordinates and window coordinates are the same, but
+ * these are left for backwards compat reasons.
+ */
+void foo_canvas_window_to_world (FooCanvas *canvas,
+				 double winx, double winy, double *worldx, double *worldy);
+
+/* This is the inverse of foo_canvas_window_to_world() */
+void foo_canvas_world_to_window (FooCanvas *canvas,
+				 double worldx, double worldy, double *winx, double *winy);
+
+/* Takes a string specification for a color and allocates it into the specified
+ * GdkColor.  If the string is null, then it returns FALSE. Otherwise, it
+ * returns TRUE.
+ */
+int foo_canvas_get_color (FooCanvas *canvas, const char *spec, GdkColor *color);
+
+/* Allocates a color from the RGB value passed into this function. */
+gulong foo_canvas_get_color_pixel (FooCanvas *canvas,
+				   guint        rgba);
+     
+
+/* Sets the stipple origin of the specified gc so that it will be aligned with
+ * all the stipples used in the specified canvas.  This is intended for use only
+ * by canvas item implementations.
+ */
+void foo_canvas_set_stipple_origin (FooCanvas *canvas, GdkGC *gc);
+
+G_END_DECLS
+
+#endif
diff --git a/widgets/libfoocanvas/libart-types.h b/widgets/libfoocanvas/libart-types.h
new file mode 100644
index 0000000..489c434
--- /dev/null
+++ b/widgets/libfoocanvas/libart-types.h
@@ -0,0 +1,18 @@
+#ifndef LIBART_TYPES_H
+#define LIBART_TYPES_H
+
+/* XXX Evolution still needs a few things from libart_lgpl.
+ *     Does GTK+ or GDK offer any equivalent structures? */
+
+typedef struct _ArtPoint ArtPoint;
+typedef struct _ArtDRect ArtDRect;
+
+struct _ArtPoint {
+	double x, y;
+};
+
+struct _ArtDRect {
+	double x0, y0, x1, y1;
+};
+
+#endif /* LIBART_TYPES_H */
diff --git a/widgets/libfoocanvas/libfoocanvas.h b/widgets/libfoocanvas/libfoocanvas.h
new file mode 100644
index 0000000..adce512
--- /dev/null
+++ b/widgets/libfoocanvas/libfoocanvas.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * The Gnome Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+#ifndef LIBFOOCANVAS_H
+#define LIBFOOCANVAS_H
+
+#include <libfoocanvas/foo-canvas.h>
+#include <libfoocanvas/foo-canvas-line.h>
+#include <libfoocanvas/foo-canvas-text.h>
+#include <libfoocanvas/foo-canvas-polygon.h>
+#include <libfoocanvas/foo-canvas-pixbuf.h>
+#include <libfoocanvas/foo-canvas-widget.h>
+#include <libfoocanvas/foo-canvas-rect-ellipse.h>
+#include <libfoocanvas/foo-canvas-util.h>
+
+G_BEGIN_DECLS
+
+GType foo_canvas_points_get_type (void);
+#define FOO_TYPE_CANVAS_POINTS foo_canvas_points_get_type()
+
+G_END_DECLS
+
+#endif /* LIBFOOCANVAS_H */
diff --git a/widgets/libfoocanvas/libfoocanvastypes.c b/widgets/libfoocanvas/libfoocanvastypes.c
new file mode 100644
index 0000000..bdf98dc
--- /dev/null
+++ b/widgets/libfoocanvas/libfoocanvastypes.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 1999, 2000 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * The Gnome Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+#include <config.h>
+#include <glib-object.h>
+
+#include <libfoocanvas/libfoocanvas.h>
+
+GType
+foo_canvas_points_get_type (void)
+{
+    static GType type_canvas_points = 0;
+
+    if (!type_canvas_points)
+	type_canvas_points = g_boxed_type_register_static
+	    ("FooCanvasPoints", 
+	     (GBoxedCopyFunc) foo_canvas_points_ref,
+	     (GBoxedFreeFunc) foo_canvas_points_unref);
+
+    return type_canvas_points;
+}
diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am
index ebd5562..b0a5a3e 100644
--- a/widgets/misc/Makefile.am
+++ b/widgets/misc/Makefile.am
@@ -153,13 +153,14 @@ libemiscwidgets_la_SOURCES =			\
 
 libemiscwidgets_la_LDFLAGS = $(NO_UNDEFINED)
 
-libemiscwidgets_la_LIBADD =				\
-	$(top_builddir)/e-util/libeutil.la		\
-	$(top_builddir)/filter/libfilter.la		\
-	$(top_builddir)/a11y/libevolution-a11y.la	\
-	$(EVOLUTION_MAIL_LIBS)				\
-	$(GNOME_PLATFORM_LIBS)				\
-	$(MATH_LIB)					\
+libemiscwidgets_la_LIBADD =					\
+	$(top_builddir)/e-util/libeutil.la			\
+	$(top_builddir)/filter/libfilter.la			\
+	$(top_builddir)/a11y/libevolution-a11y.la		\
+	$(top_builddir)/widgets/libfoocanvas/libfoocanvas.la	\
+	$(EVOLUTION_MAIL_LIBS)					\
+	$(GNOME_PLATFORM_LIBS)					\
+	$(MATH_LIB)						\
 	$(ICONV_LIBS)
 
 noinst_PROGRAMS = 			\
diff --git a/widgets/misc/e-calendar-item.c b/widgets/misc/e-calendar-item.c
index 41b5eea..93c0129 100644
--- a/widgets/misc/e-calendar-item.c
+++ b/widgets/misc/e-calendar-item.c
@@ -53,19 +53,16 @@ static void e_calendar_item_set_property(GObject	 *object,
 					 guint		  property_id,
 					 const GValue	 *value,
 					 GParamSpec	 *pspec);
-static void e_calendar_item_realize	(GnomeCanvasItem *item);
-static void e_calendar_item_unrealize	(GnomeCanvasItem *item);
-static void e_calendar_item_unmap	(GnomeCanvasItem *item);
-static void e_calendar_item_update	(GnomeCanvasItem *item,
-					 double		 *affine,
-					 ArtSVP		 *clip_path,
+static void e_calendar_item_realize	(FooCanvasItem *item);
+static void e_calendar_item_unrealize	(FooCanvasItem *item);
+static void e_calendar_item_unmap	(FooCanvasItem *item);
+static void e_calendar_item_update	(FooCanvasItem *item,
+					 double		 i2w_dx,
+					 double		 i2w_dy,
 					 gint		  flags);
-static void e_calendar_item_draw	(GnomeCanvasItem *item,
+static void e_calendar_item_draw	(FooCanvasItem *item,
 					 GdkDrawable	 *drawable,
-					 gint		  x,
-					 gint		  y,
-					 gint		  width,
-					 gint		  height);
+					 GdkEventExpose  *expose);
 static void e_calendar_item_draw_month	(ECalendarItem   *calitem,
 					 GdkDrawable	 *drawable,
 					 gint		  x,
@@ -85,12 +82,12 @@ static void e_calendar_item_draw_day_numbers (ECalendarItem	*calitem,
 					      gint		 start_weekday,
 					      gint		 cells_x,
 					      gint		 cells_y);
-static double e_calendar_item_point	(GnomeCanvasItem *item,
+static double e_calendar_item_point	(FooCanvasItem *item,
 					 double		  x,
 					 double		  y,
 					 gint		  cx,
 					 gint		  cy,
-					 GnomeCanvasItem **actual_item);
+					 FooCanvasItem **actual_item);
 static void e_calendar_item_stop_selecting (ECalendarItem *calitem,
 					    guint32 time);
 static void e_calendar_item_selection_add_days (ECalendarItem *calitem,
@@ -98,9 +95,9 @@ static void e_calendar_item_selection_add_days (ECalendarItem *calitem,
 						gboolean multi_selection);
 static gint e_calendar_item_key_press_event (ECalendarItem *item,
 					     GdkEvent *event);
-static gint e_calendar_item_event	(GnomeCanvasItem *item,
+static gint e_calendar_item_event	(FooCanvasItem *item,
 					 GdkEvent	 *event);
-static void e_calendar_item_bounds (GnomeCanvasItem *item, double *x1, double *y1,
+static void e_calendar_item_bounds (FooCanvasItem *item, double *x1, double *y1,
 				    double *x2, double *y2);
 
 static gboolean e_calendar_item_button_press	(ECalendarItem	*calitem,
@@ -228,20 +225,20 @@ enum {
 
 static guint e_calendar_item_signals[LAST_SIGNAL] = { 0 };
 
-G_DEFINE_TYPE (ECalendarItem, e_calendar_item, GNOME_TYPE_CANVAS_ITEM)
+G_DEFINE_TYPE (ECalendarItem, e_calendar_item, FOO_TYPE_CANVAS_ITEM)
 
 static void
 e_calendar_item_class_init (ECalendarItemClass *class)
 {
 	GObjectClass  *object_class;
-	GnomeCanvasItemClass *item_class;
+	FooCanvasItemClass *item_class;
 
 	object_class = G_OBJECT_CLASS (class);
 	object_class->dispose = e_calendar_item_dispose;
 	object_class->get_property = e_calendar_item_get_property;
 	object_class->set_property = e_calendar_item_set_property;
 
-	item_class = GNOME_CANVAS_ITEM_CLASS (class);
+	item_class = FOO_CANVAS_ITEM_CLASS (class);
 	item_class->realize = e_calendar_item_realize;
 	item_class->unrealize = e_calendar_item_unrealize;
 	item_class->unmap = e_calendar_item_unmap;
@@ -701,14 +698,14 @@ e_calendar_item_set_property (GObject *object,
                               const GValue *value,
                               GParamSpec *pspec)
 {
-	GnomeCanvasItem *item;
+	FooCanvasItem *item;
 	ECalendarItem *calitem;
 	PangoFontDescription *font_desc;
 	gdouble dvalue;
 	gint ivalue;
 	gboolean bvalue;
 
-	item = GNOME_CANVAS_ITEM (object);
+	item = FOO_CANVAS_ITEM (object);
 	calitem = E_CALENDAR_ITEM (object);
 
 	switch (property_id) {
@@ -726,28 +723,28 @@ e_calendar_item_set_property (GObject *object,
 		dvalue = g_value_get_double (value);
 		if (calitem->x1 != dvalue) {
 			calitem->x1 = dvalue;
-			gnome_canvas_item_request_update (item);
+			foo_canvas_item_request_update (item);
 		}
 		return;
 	case PROP_Y1:
 		dvalue = g_value_get_double (value);
 		if (calitem->y1 != dvalue) {
 			calitem->y1 = dvalue;
-			gnome_canvas_item_request_update (item);
+			foo_canvas_item_request_update (item);
 		}
 		return;
 	case PROP_X2:
 		dvalue = g_value_get_double (value);
 		if (calitem->x2 != dvalue) {
 			calitem->x2 = dvalue;
-			gnome_canvas_item_request_update (item);
+			foo_canvas_item_request_update (item);
 		}
 		return;
 	case PROP_Y2:
 		dvalue = g_value_get_double (value);
 		if (calitem->y2 != dvalue) {
 			calitem->y2 = dvalue;
-			gnome_canvas_item_request_update (item);
+			foo_canvas_item_request_update (item);
 		}
 		return;
 	case PROP_FONT_DESC:
@@ -755,21 +752,21 @@ e_calendar_item_set_property (GObject *object,
 		if (calitem->font_desc)
 			pango_font_description_free (calitem->font_desc);
 		calitem->font_desc = pango_font_description_copy (font_desc);
-		gnome_canvas_item_request_update (item);
+		foo_canvas_item_request_update (item);
 		return;
 	case PROP_WEEK_NUMBER_FONT_DESC:
 		font_desc = g_value_get_boxed (value);
 		if (calitem->week_number_font_desc)
 			pango_font_description_free (calitem->week_number_font_desc);
 		calitem->week_number_font_desc = pango_font_description_copy (font_desc);
-		gnome_canvas_item_request_update (item);
+		foo_canvas_item_request_update (item);
 		return;
 	case PROP_MINIMUM_ROWS:
 		ivalue = g_value_get_int (value);
 		ivalue = MAX (1, ivalue);
 		if (calitem->min_rows != ivalue) {
 			calitem->min_rows = ivalue;
-			gnome_canvas_item_request_update (item);
+			foo_canvas_item_request_update (item);
 		}
 		return;
 	case PROP_MINIMUM_COLUMNS:
@@ -777,35 +774,35 @@ e_calendar_item_set_property (GObject *object,
 		ivalue = MAX (1, ivalue);
 		if (calitem->min_cols != ivalue) {
 			calitem->min_cols = ivalue;
-			gnome_canvas_item_request_update (item);
+			foo_canvas_item_request_update (item);
 		}
 		return;
 	case PROP_MAXIMUM_ROWS:
 		ivalue = g_value_get_int (value);
 		if (calitem->max_rows != ivalue) {
 			calitem->max_rows = ivalue;
-			gnome_canvas_item_request_update (item);
+			foo_canvas_item_request_update (item);
 		}
 		return;
 	case PROP_MAXIMUM_COLUMNS:
 		ivalue = g_value_get_int (value);
 		if (calitem->max_cols != ivalue) {
 			calitem->max_cols = ivalue;
-			gnome_canvas_item_request_update (item);
+			foo_canvas_item_request_update (item);
 		}
 		return;
 	case PROP_WEEK_START_DAY:
 		ivalue = g_value_get_int (value);
 		if (calitem->week_start_day != ivalue) {
 			calitem->week_start_day = ivalue;
-			gnome_canvas_item_request_update (item);
+			foo_canvas_item_request_update (item);
 		}
 		return;
 	case PROP_SHOW_WEEK_NUMBERS:
 		bvalue = g_value_get_boolean (value);
 		if (calitem->show_week_numbers != bvalue) {
 			calitem->show_week_numbers = bvalue;
-			gnome_canvas_item_request_update (item);
+			foo_canvas_item_request_update (item);
 		}
 		return;
 	case PROP_MAXIMUM_DAYS_SELECTED:
@@ -834,12 +831,12 @@ e_calendar_item_set_property (GObject *object,
 }
 
 static void
-e_calendar_item_realize		(GnomeCanvasItem *item)
+e_calendar_item_realize		(FooCanvasItem *item)
 {
 	ECalendarItem *calitem;
 
-	if (GNOME_CANVAS_ITEM_CLASS (e_calendar_item_parent_class)->realize)
-		(* GNOME_CANVAS_ITEM_CLASS (e_calendar_item_parent_class)->realize) (item);
+	if (FOO_CANVAS_ITEM_CLASS (e_calendar_item_parent_class)->realize)
+		(* FOO_CANVAS_ITEM_CLASS (e_calendar_item_parent_class)->realize) (item);
 
 	calitem = E_CALENDAR_ITEM (item);
 
@@ -847,7 +844,7 @@ e_calendar_item_realize		(GnomeCanvasItem *item)
 }
 
 static void
-e_calendar_item_unrealize	(GnomeCanvasItem *item)
+e_calendar_item_unrealize	(FooCanvasItem *item)
 {
 	ECalendarItem *calitem;
 	GdkColormap *colormap;
@@ -858,30 +855,30 @@ e_calendar_item_unrealize	(GnomeCanvasItem *item)
 
 	gdk_colormap_free_colors (colormap, calitem->colors, E_CALENDAR_ITEM_COLOR_LAST);
 
-	if (GNOME_CANVAS_ITEM_CLASS (e_calendar_item_parent_class)->unrealize)
-		(* GNOME_CANVAS_ITEM_CLASS (e_calendar_item_parent_class)->unrealize) (item);
+	if (FOO_CANVAS_ITEM_CLASS (e_calendar_item_parent_class)->unrealize)
+		(* FOO_CANVAS_ITEM_CLASS (e_calendar_item_parent_class)->unrealize) (item);
 }
 
 static void
-e_calendar_item_unmap		(GnomeCanvasItem *item)
+e_calendar_item_unmap		(FooCanvasItem *item)
 {
 	ECalendarItem *calitem;
 
 	calitem = E_CALENDAR_ITEM (item);
 
 	if (calitem->selecting) {
-		gnome_canvas_item_ungrab (item, GDK_CURRENT_TIME);
+		foo_canvas_item_ungrab (item, GDK_CURRENT_TIME);
 		calitem->selecting = FALSE;
 	}
 
-	if (GNOME_CANVAS_ITEM_CLASS (e_calendar_item_parent_class)->unmap)
-		(* GNOME_CANVAS_ITEM_CLASS (e_calendar_item_parent_class)->unmap) (item);
+	if (FOO_CANVAS_ITEM_CLASS (e_calendar_item_parent_class)->unmap)
+		(* FOO_CANVAS_ITEM_CLASS (e_calendar_item_parent_class)->unmap) (item);
 }
 
 static void
-e_calendar_item_update		(GnomeCanvasItem *item,
-				 double		 *affine,
-				 ArtSVP		 *clip_path,
+e_calendar_item_update		(FooCanvasItem *item,
+				 double		 i2w_dx,
+				 double		 i2w_dy,
 				 gint		  flags)
 {
 	ECalendarItem *calitem;
@@ -892,8 +889,8 @@ e_calendar_item_update		(GnomeCanvasItem *item,
 	PangoContext *pango_context;
 	PangoFontMetrics *font_metrics;
 
-	if (GNOME_CANVAS_ITEM_CLASS (e_calendar_item_parent_class)->update)
-		(* GNOME_CANVAS_ITEM_CLASS (e_calendar_item_parent_class)->update) (item, affine, clip_path, flags);
+	if (FOO_CANVAS_ITEM_CLASS (e_calendar_item_parent_class)->update)
+		(* FOO_CANVAS_ITEM_CLASS (e_calendar_item_parent_class)->update) (item, i2w_dx, i2w_dy, flags);
 
 	calitem = E_CALENDAR_ITEM (item);
 	style = GTK_WIDGET (item->canvas)->style;
@@ -1002,7 +999,7 @@ e_calendar_item_update		(GnomeCanvasItem *item,
 	space = MAX (0, space);
 	calitem->x_offset = space / 2;
 
-	gnome_canvas_request_redraw (item->canvas, item->x1, item->y1,
+	foo_canvas_request_redraw (item->canvas, item->x1, item->y1,
 				     item->x2, item->y2);
 
 	pango_font_metrics_unref (font_metrics);
@@ -1012,28 +1009,32 @@ e_calendar_item_update		(GnomeCanvasItem *item,
  * DRAWING ROUTINES - functions to paint the canvas item.
  */
 static void
-e_calendar_item_draw		(GnomeCanvasItem *canvas_item,
+e_calendar_item_draw		(FooCanvasItem *canvas_item,
 				 GdkDrawable	 *drawable,
-				 gint		  x,
-				 gint		  y,
-				 gint		  width,
-				 gint		  height)
+				 GdkEventExpose  *expose)
 {
 	ECalendarItem *calitem;
 	GtkStyle *style;
 	GdkGC *base_gc, *bg_gc;
 	gint char_height, row, col, row_y, bar_height, col_x;
 	gint xthickness, ythickness;
+	gint x, y, width, height;
 	PangoFontDescription *font_desc;
 	PangoContext *pango_context;
 	PangoFontMetrics *font_metrics;
 	cairo_t *cr;
 	GdkColor base, bg;
 
+	x = expose->area.x;
+	y = expose->area.y;
+	width = expose->area.width;
+	height = expose->area.height;
+
 #if 0
 	g_print ("In e_calendar_item_draw %i,%i %ix%i\n",
 		 x, y, width, height);
 #endif
+
 	calitem = E_CALENDAR_ITEM (canvas_item);
 	style = GTK_WIDGET (canvas_item->canvas)->style;
 
@@ -1144,7 +1145,7 @@ e_calendar_item_draw_month	(ECalendarItem   *calitem,
 				 gint		  row,
 				 gint		  col)
 {
-	GnomeCanvasItem *item;
+	FooCanvasItem *item;
 	GtkWidget *widget;
 	GtkStyle *style;
 	PangoFontDescription *font_desc;
@@ -1168,7 +1169,7 @@ e_calendar_item_draw_month	(ECalendarItem   *calitem,
 	g_print ("In e_calendar_item_draw_month: %i,%i %ix%i row:%i col:%i\n",
 		 x, y, width, height, row, col);
 #endif
-	item = GNOME_CANVAS_ITEM (calitem);
+	item = FOO_CANVAS_ITEM (calitem);
 	widget = GTK_WIDGET (item->canvas);
 	style = widget->style;
 
@@ -1391,7 +1392,7 @@ e_calendar_item_draw_day_numbers (ECalendarItem	*calitem,
 				  gint		 cells_x,
 				  gint		 cells_y)
 {
-	GnomeCanvasItem *item;
+	FooCanvasItem *item;
 	GtkWidget *widget;
 	GtkStyle *style;
 	PangoFontDescription *font_desc, *wkfont_desc;
@@ -1415,7 +1416,7 @@ e_calendar_item_draw_day_numbers (ECalendarItem	*calitem,
 	PangoLayout *layout;
 	cairo_t *cr;
 
-	item = GNOME_CANVAS_ITEM (calitem);
+	item = FOO_CANVAS_ITEM (calitem);
 	widget = GTK_WIDGET (item->canvas);
 	style = widget->style;
 
@@ -1753,9 +1754,9 @@ e_calendar_item_get_week_number	(ECalendarItem *calitem,
    Since we are the only item we just return ourself and 0 for the distance.
    This is needed so that we get button/motion events. */
 static double
-e_calendar_item_point (GnomeCanvasItem *item, double x, double y,
+e_calendar_item_point (FooCanvasItem *item, double x, double y,
 			   gint cx, gint cy,
-			   GnomeCanvasItem **actual_item)
+			   FooCanvasItem **actual_item)
 {
 	*actual_item = item;
 	return 0.0;
@@ -1767,7 +1768,7 @@ e_calendar_item_stop_selecting (ECalendarItem *calitem, guint32 time)
 	if (!calitem->selecting)
 		return;
 
-	gnome_canvas_item_ungrab (GNOME_CANVAS_ITEM (calitem), time);
+	foo_canvas_item_ungrab (FOO_CANVAS_ITEM (calitem), time);
 
 	calitem->selecting = FALSE;
 
@@ -1788,7 +1789,7 @@ e_calendar_item_stop_selecting (ECalendarItem *calitem, guint32 time)
 	}
 
 	e_calendar_item_queue_signal_emission (calitem);
-	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (calitem));
+	foo_canvas_item_request_update (FOO_CANVAS_ITEM (calitem));
 }
 
 static void
@@ -1891,7 +1892,7 @@ e_calendar_item_key_press_event (ECalendarItem *calitem, GdkEvent *event)
 }
 
 static gint
-e_calendar_item_event (GnomeCanvasItem *item, GdkEvent *event)
+e_calendar_item_event (FooCanvasItem *item, GdkEvent *event)
 {
 	ECalendarItem *calitem;
 
@@ -1905,7 +1906,7 @@ e_calendar_item_event (GnomeCanvasItem *item, GdkEvent *event)
 	case GDK_MOTION_NOTIFY:
 		return e_calendar_item_motion (calitem, event);
 	case GDK_FOCUS_CHANGE:
-		gnome_canvas_item_request_update (item);
+		foo_canvas_item_request_update (item);
 	case GDK_KEY_PRESS:
 		return e_calendar_item_key_press_event (calitem, event);
 	default:
@@ -1916,7 +1917,7 @@ e_calendar_item_event (GnomeCanvasItem *item, GdkEvent *event)
 }
 
 static void
-e_calendar_item_bounds (GnomeCanvasItem *item, double *x1, double *y1,
+e_calendar_item_bounds (FooCanvasItem *item, double *x1, double *y1,
 			double *x2, double *y2)
 {
 	ECalendarItem *calitem;
@@ -1935,7 +1936,7 @@ e_calendar_item_bounds (GnomeCanvasItem *item, double *x1, double *y1,
 static void
 e_calendar_item_recalc_sizes		(ECalendarItem *calitem)
 {
-	GnomeCanvasItem *canvas_item;
+	FooCanvasItem *canvas_item;
 	GtkStyle *style;
 	gint day, max_day_width, digit, max_digit_width, max_week_number_digit_width;
 	gint char_height, width, min_cell_width, min_cell_height;
@@ -1944,7 +1945,7 @@ e_calendar_item_recalc_sizes		(ECalendarItem *calitem)
 	PangoFontMetrics *font_metrics;
 	PangoLayout *layout;
 
-	canvas_item = GNOME_CANVAS_ITEM (calitem);
+	canvas_item = FOO_CANVAS_ITEM (calitem);
 	style = GTK_WIDGET (canvas_item->canvas)->style;
 
 	if (!style)
@@ -2054,7 +2055,7 @@ e_calendar_item_get_day_style		(ECalendarItem	*calitem,
 	GtkWidget *widget;
 	GtkStyle *style;
 
-	widget = GTK_WIDGET (GNOME_CANVAS_ITEM (calitem)->canvas);
+	widget = GTK_WIDGET (FOO_CANVAS_ITEM (calitem)->canvas);
 	style = widget->style;
 
 	*bg_color = NULL;
@@ -2117,7 +2118,7 @@ e_calendar_item_button_press	(ECalendarItem	*calitem,
 	if (calitem->max_days_selected < 1)
 		return TRUE;
 
-	if (gnome_canvas_item_grab (GNOME_CANVAS_ITEM (calitem),
+	if (foo_canvas_item_grab (FOO_CANVAS_ITEM (calitem),
 				    GDK_POINTER_MOTION_MASK
 				    | GDK_BUTTON_RELEASE_MASK,
 				    NULL, event->button.time) != 0)
@@ -2158,7 +2159,7 @@ e_calendar_item_button_press	(ECalendarItem	*calitem,
 	if (round_down_start)
 		e_calendar_item_round_down_selection (calitem, &calitem->selection_start_month_offset, &calitem->selection_start_day);
 
-	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (calitem));
+	foo_canvas_item_request_update (FOO_CANVAS_ITEM (calitem));
 
 	return TRUE;
 }
@@ -2276,7 +2277,7 @@ e_calendar_item_motion		(ECalendarItem	*calitem,
 	calitem->selection_end_month_offset = end_month;
 	calitem->selection_end_day = end_day;
 
-	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (calitem));
+	foo_canvas_item_request_update (FOO_CANVAS_ITEM (calitem));
 
 	return TRUE;
 }
@@ -2374,7 +2375,7 @@ e_calendar_item_convert_position_to_day	(ECalendarItem	*calitem,
 					 gint		*day,
 					 gboolean	*entire_week)
 {
-	GnomeCanvasItem *item;
+	FooCanvasItem *item;
 	GtkWidget *widget;
 	GtkStyle *style;
 	gint xthickness, ythickness, char_height;
@@ -2385,7 +2386,7 @@ e_calendar_item_convert_position_to_day	(ECalendarItem	*calitem,
 	PangoContext *pango_context;
 	PangoFontMetrics *font_metrics;
 
-	item = GNOME_CANVAS_ITEM (calitem);
+	item = FOO_CANVAS_ITEM (calitem);
 	widget = GTK_WIDGET (item->canvas);
 	style = widget->style;
 
@@ -2671,7 +2672,7 @@ e_calendar_item_set_first_month(ECalendarItem	*calitem,
 	}
 
 	e_calendar_item_date_range_changed (calitem);
-	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (calitem));
+	foo_canvas_item_request_update (FOO_CANVAS_ITEM (calitem));
 }
 
 /* Get the maximum number of days selectable */
@@ -2687,7 +2688,7 @@ e_calendar_item_set_max_days_sel       (ECalendarItem	*calitem,
 					gint             days)
 {
 	calitem->max_days_selected = MAX (0, days);
-	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (calitem));
+	foo_canvas_item_request_update (FOO_CANVAS_ITEM (calitem));
 }
 
 /* Get the maximum number of days before whole weeks are selected */
@@ -2813,14 +2814,14 @@ e_calendar_item_get_date_range	(ECalendarItem	*calitem,
 void
 e_calendar_item_clear_marks	(ECalendarItem	*calitem)
 {
-	GnomeCanvasItem *item;
+	FooCanvasItem *item;
 
-	item = GNOME_CANVAS_ITEM (calitem);
+	item = FOO_CANVAS_ITEM (calitem);
 
 	g_free (calitem->styles);
 	calitem->styles = NULL;
 
-	gnome_canvas_request_redraw (item->canvas, item->x1, item->y1,
+	foo_canvas_request_redraw (item->canvas, item->x1, item->y1,
 				     item->x2, item->y2);
 }
 
@@ -2844,7 +2845,7 @@ e_calendar_item_mark_day	(ECalendarItem	*calitem,
 
 	calitem->styles[(month_offset + 1) * 32 + day] = (add_day_style ? calitem->styles[(month_offset + 1) * 32 + day] : 0) | day_style;
 
-	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (calitem));
+	foo_canvas_item_request_update (FOO_CANVAS_ITEM (calitem));
 }
 
 void
@@ -2908,7 +2909,7 @@ e_calendar_item_mark_days	(ECalendarItem	*calitem,
 		}
 	}
 
-	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (calitem));
+	foo_canvas_item_request_update (FOO_CANVAS_ITEM (calitem));
 }
 
 /* Rounds up the given day to the end of the week. */
@@ -3081,7 +3082,7 @@ e_calendar_item_set_selection_if_emission (ECalendarItem	*calitem,
 		calitem->selection_set = FALSE;
 		calitem->selection_changed = TRUE;
 		e_calendar_item_queue_signal_emission (calitem);
-		gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (calitem));
+		foo_canvas_item_request_update (FOO_CANVAS_ITEM (calitem));
 		return;
 	}
 
@@ -3137,7 +3138,7 @@ e_calendar_item_set_selection_if_emission (ECalendarItem	*calitem,
 	}
 
 	if (need_update)
-		gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (calitem));
+		foo_canvas_item_request_update (FOO_CANVAS_ITEM (calitem));
 }
 
 void
@@ -3157,7 +3158,7 @@ e_calendar_item_set_selection (ECalendarItem	*calitem,
 {
 	/* If the user is in the middle of a selection, we must abort it. */
 	if (calitem->selecting) {
-		gnome_canvas_item_ungrab (GNOME_CANVAS_ITEM (calitem),
+		foo_canvas_item_ungrab (FOO_CANVAS_ITEM (calitem),
 					  GDK_CURRENT_TIME);
 		calitem->selecting = FALSE;
 	}
diff --git a/widgets/misc/e-calendar-item.h b/widgets/misc/e-calendar-item.h
index 0ab34b3..7f0ef58 100644
--- a/widgets/misc/e-calendar-item.h
+++ b/widgets/misc/e-calendar-item.h
@@ -25,7 +25,7 @@
 #ifndef _E_CALENDAR_ITEM_H_
 #define _E_CALENDAR_ITEM_H_
 
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 
 G_BEGIN_DECLS
 
@@ -118,7 +118,7 @@ typedef struct tm (*ECalendarItemGetTimeCallback) (ECalendarItem *calitem,
 
 struct _ECalendarItem
 {
-	GnomeCanvasItem canvas_item;
+	FooCanvasItem canvas_item;
 
 	/* The year & month of the first calendar being displayed. */
 	gint year;
@@ -256,7 +256,7 @@ struct _ECalendarItem
 
 struct _ECalendarItemClass
 {
-	GnomeCanvasItemClass parent_class;
+	FooCanvasItemClass parent_class;
 
 	void (* date_range_changed)	(ECalendarItem *calitem);
 	void (* selection_changed)	(ECalendarItem *calitem);
diff --git a/widgets/misc/e-calendar.c b/widgets/misc/e-calendar.c
index fd17c67..439d902 100644
--- a/widgets/misc/e-calendar.c
+++ b/widgets/misc/e-calendar.c
@@ -25,7 +25,7 @@
  * ECalendar - displays a table of monthly calendars, allowing highlighting
  * and selection of one or more days. Like GtkCalendar with more features.
  * Most of the functionality is in the ECalendarItem canvas item, though
- * we also add GnomeCanvasWidget buttons to go to the previous/next month and
+ * we also add FooCanvasWidget buttons to go to the previous/next month and
  * to got to the current day.
  */
 
@@ -36,7 +36,7 @@
 #include "e-calendar.h"
 
 #include <gtk/gtk.h>
-#include <libgnomecanvas/gnome-canvas-widget.h>
+#include <libfoocanvas/foo-canvas-widget.h>
 #include <glib/gi18n.h>
 
 #define E_CALENDAR_SMALL_FONT_PTSIZE 6
@@ -122,7 +122,7 @@ e_calendar_class_init (ECalendarClass *class)
 static void
 e_calendar_init (ECalendar *cal)
 {
-	GnomeCanvasGroup *canvas_group;
+	FooCanvasGroup *canvas_group;
 	PangoFontDescription *small_font_desc;
 	GtkWidget *button, *pixmap;
 	AtkObject *a11y;
@@ -134,9 +134,9 @@ e_calendar_init (ECalendar *cal)
 	pango_font_description_set_size (small_font_desc,
 					 E_CALENDAR_SMALL_FONT_PTSIZE * PANGO_SCALE);
 
-	canvas_group = GNOME_CANVAS_GROUP (GNOME_CANVAS (cal)->root);
+	canvas_group = FOO_CANVAS_GROUP (FOO_CANVAS (cal)->root);
 
-	cal->calitem = E_CALENDAR_ITEM (gnome_canvas_item_new (canvas_group,
+	cal->calitem = E_CALENDAR_ITEM (foo_canvas_item_new (canvas_group,
 							       e_calendar_item_get_type (),
 							       "week_number_font_desc", small_font_desc,
 							       NULL));
@@ -161,8 +161,8 @@ e_calendar_init (ECalendar *cal)
 	gtk_widget_show (pixmap);
 	gtk_container_add (GTK_CONTAINER (button), pixmap);
 
-	cal->prev_item = gnome_canvas_item_new (canvas_group,
-						gnome_canvas_widget_get_type (),
+	cal->prev_item = foo_canvas_item_new (canvas_group,
+						foo_canvas_widget_get_type (),
 						"widget", button,
 						NULL);
 	a11y = gtk_widget_get_accessible (button);
@@ -185,8 +185,8 @@ e_calendar_init (ECalendar *cal)
 	gtk_widget_show (pixmap);
 	gtk_container_add (GTK_CONTAINER (button), pixmap);
 
-	cal->next_item = gnome_canvas_item_new (canvas_group,
-						gnome_canvas_widget_get_type (),
+	cal->next_item = foo_canvas_item_new (canvas_group,
+						foo_canvas_widget_get_type (),
 						"widget", button,
 						NULL);
 	a11y = gtk_widget_get_accessible (button);
@@ -315,16 +315,16 @@ e_calendar_size_allocate	(GtkWidget	*widget,
 						  pango_context_get_language (pango_context));
 
 	/* Set the scroll region to its allocated size, if changed. */
-	gnome_canvas_get_scroll_region (GNOME_CANVAS (cal),
+	foo_canvas_get_scroll_region (FOO_CANVAS (cal),
 					NULL, NULL, &old_x2, &old_y2);
 	new_x2 = widget->allocation.width - 1;
 	new_y2 = widget->allocation.height - 1;
 	if (old_x2 != new_x2 || old_y2 != new_y2)
-		gnome_canvas_set_scroll_region (GNOME_CANVAS (cal),
+		foo_canvas_set_scroll_region (FOO_CANVAS (cal),
 						0, 0, new_x2, new_y2);
 
 	/* Take off space for line & buttons if shown. */
-	gnome_canvas_item_set (GNOME_CANVAS_ITEM (cal->calitem),
+	foo_canvas_item_set (FOO_CANVAS_ITEM (cal->calitem),
 			       "x1", 0.0,
 			       "y1", 0.0,
 			       "x2", new_x2,
@@ -339,7 +339,7 @@ e_calendar_size_allocate	(GtkWidget	*widget,
 		+ E_CALENDAR_ITEM_YPAD_BELOW_MONTH_NAME
 		- E_CALENDAR_ARROW_BUTTON_Y_PAD * 2;
 
-	gnome_canvas_item_set (cal->prev_item,
+	foo_canvas_item_set (cal->prev_item,
 			       "x", (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
 			       ? new_x2 + 1 - xthickness * 2 - E_CALENDAR_ARROW_BUTTON_X_PAD
 				 - arrow_button_size
@@ -350,7 +350,7 @@ e_calendar_size_allocate	(GtkWidget	*widget,
 			       "height", arrow_button_size,
 			       NULL);
 
-	gnome_canvas_item_set (cal->next_item,
+	foo_canvas_item_set (cal->next_item,
 			       "x", (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
 			       ? xthickness * 2 + E_CALENDAR_ARROW_BUTTON_X_PAD
 			       : new_x2 + 1 - xthickness * 2 - E_CALENDAR_ARROW_BUTTON_X_PAD
@@ -374,7 +374,7 @@ e_calendar_set_minimum_size	(ECalendar	*cal,
 	cal->min_rows = rows;
 	cal->min_cols = cols;
 
-	gnome_canvas_item_set (GNOME_CANVAS_ITEM (cal->calitem),
+	foo_canvas_item_set (FOO_CANVAS_ITEM (cal->calitem),
 			       "minimum_rows", rows,
 			       "minimum_columns", cols,
 			       NULL);
@@ -392,7 +392,7 @@ e_calendar_set_maximum_size	(ECalendar	*cal,
 	cal->max_rows = rows;
 	cal->max_cols = cols;
 
-	gnome_canvas_item_set (GNOME_CANVAS_ITEM (cal->calitem),
+	foo_canvas_item_set (FOO_CANVAS_ITEM (cal->calitem),
 			       "maximum_rows", rows,
 			       "maximum_columns", cols,
 			       NULL);
@@ -543,8 +543,8 @@ e_calendar_button_has_focus (ECalendar	*cal)
 
 	g_return_val_if_fail (E_IS_CALENDAR (cal), FALSE);
 
-	prev_widget = GNOME_CANVAS_WIDGET(cal->prev_item)->widget;
-	next_widget = GNOME_CANVAS_WIDGET(cal->next_item)->widget;
+	prev_widget = FOO_CANVAS_WIDGET(cal->prev_item)->widget;
+	next_widget = FOO_CANVAS_WIDGET(cal->next_item)->widget;
 	ret_val = GTK_WIDGET_HAS_FOCUS (prev_widget) ||
 		GTK_WIDGET_HAS_FOCUS (next_widget);
 	return ret_val;
@@ -555,20 +555,20 @@ e_calendar_focus (GtkWidget *widget, GtkDirectionType direction)
 {
 #define E_CALENDAR_FOCUS_CHILDREN_NUM 3
 	ECalendar *cal;
-	GnomeCanvas *canvas;
-	GnomeCanvasItem *children[E_CALENDAR_FOCUS_CHILDREN_NUM];
+	FooCanvas *canvas;
+	FooCanvasItem *children[E_CALENDAR_FOCUS_CHILDREN_NUM];
 	gint focused_index = -1;
 	gint index;
 
 	g_return_val_if_fail (widget != NULL, FALSE);
 	g_return_val_if_fail (E_IS_CALENDAR (widget), FALSE);
 	cal = E_CALENDAR (widget);
-	canvas = GNOME_CANVAS (widget);
+	canvas = FOO_CANVAS (widget);
 
 	if (!GTK_WIDGET_CAN_FOCUS (widget))
 		return FALSE;
 
-	children[0] = GNOME_CANVAS_ITEM (cal->calitem);
+	children[0] = FOO_CANVAS_ITEM (cal->calitem);
 	children[1] = cal->prev_item;
 	children[2] = cal->next_item;
 
@@ -596,9 +596,9 @@ e_calendar_focus (GtkWidget *widget, GtkDirectionType direction)
 	    focused_index >= E_CALENDAR_FOCUS_CHILDREN_NUM)
 		/* move out of e-calendar */
 		return FALSE;
-	gnome_canvas_item_grab_focus (children[focused_index]);
-	if (GNOME_IS_CANVAS_WIDGET (children[focused_index])) {
-		widget = GNOME_CANVAS_WIDGET (children[focused_index])->widget;
+	foo_canvas_item_grab_focus (children[focused_index]);
+	if (FOO_IS_CANVAS_WIDGET (children[focused_index])) {
+		widget = FOO_CANVAS_WIDGET (children[focused_index])->widget;
 		gtk_widget_grab_focus (widget);
 	}
 	return TRUE;
@@ -611,8 +611,8 @@ e_calendar_set_focusable (ECalendar *cal, gboolean focusable)
 
 	g_return_if_fail (E_IS_CALENDAR (cal));
 
-	prev_widget = GNOME_CANVAS_WIDGET(cal->prev_item)->widget;
-	next_widget = GNOME_CANVAS_WIDGET(cal->next_item)->widget;
+	prev_widget = FOO_CANVAS_WIDGET(cal->prev_item)->widget;
+	next_widget = FOO_CANVAS_WIDGET(cal->next_item)->widget;
 
 	if (focusable) {
 		GTK_WIDGET_SET_FLAGS (cal, GTK_CAN_FOCUS);
diff --git a/widgets/misc/e-calendar.h b/widgets/misc/e-calendar.h
index d6b5020..7cbfb5b 100644
--- a/widgets/misc/e-calendar.h
+++ b/widgets/misc/e-calendar.h
@@ -33,7 +33,7 @@ G_BEGIN_DECLS
  * ECalendar - displays a table of monthly calendars, allowing highlighting
  * and selection of one or more days. Like GtkCalendar with more features.
  * Most of the functionality is in the ECalendarItem canvas item, though
- * we also add GnomeCanvasWidget buttons to go to the previous/next month and
+ * we also add FooCanvasWidget buttons to go to the previous/next month and
  * to got to the current day.
  */
 
@@ -65,8 +65,8 @@ struct _ECalendar
 
 	ECalendarItem *calitem;
 
-	GnomeCanvasItem *prev_item;
-	GnomeCanvasItem *next_item;
+	FooCanvasItem *prev_item;
+	FooCanvasItem *next_item;
 
 	gint min_rows;
 	gint min_cols;
diff --git a/widgets/misc/e-canvas-background.c b/widgets/misc/e-canvas-background.c
index 04c163e..e464bc7 100644
--- a/widgets/misc/e-canvas-background.c
+++ b/widgets/misc/e-canvas-background.c
@@ -36,12 +36,13 @@
 #include "misc/e-canvas.h"
 #include "misc/e-canvas-utils.h"
 #include "misc/e-hsv-utils.h"
+#include "libfoocanvas/libart-types.h"
 
 #include "e-canvas-background.h"
 
 /* workaround for avoiding API broken */
 #define ecb_get_type e_canvas_background_get_type
-G_DEFINE_TYPE (ECanvasBackground, ecb, GNOME_TYPE_CANVAS_ITEM)
+G_DEFINE_TYPE (ECanvasBackground, ecb, FOO_TYPE_CANVAS_ITEM)
 
 #define d(x)
 
@@ -80,15 +81,29 @@ enum {
 static void
 get_color(ECanvasBackground *ecb)
 {
-	GnomeCanvasItem *item = GNOME_CANVAS_ITEM (ecb);
-	ecb->priv->color.pixel = gnome_canvas_get_color_pixel (item->canvas,
-		GNOME_CANVAS_COLOR (ecb->priv->color.red >> 8,
+	FooCanvasItem *item = FOO_CANVAS_ITEM (ecb);
+	ecb->priv->color.pixel = foo_canvas_get_color_pixel (item->canvas,
+		FOO_CANVAS_COLOR (ecb->priv->color.red >> 8,
 				   ecb->priv->color.green>> 8,
 				   ecb->priv->color.blue>> 8));
 }
 
+/* Copied from libart_lgpl. */
+
 static void
-ecb_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y2)
+art_affine_point (ArtPoint *dst, ArtPoint *src,
+                  const double affine[6])
+{
+	double x, y;
+
+	x = src->x;
+	y = src->y;
+	dst->x = x * affine[0] + y * affine[2] + affine[4];
+	dst->y = x * affine[1] + y * affine[3] + affine[5];
+}
+
+static void
+ecb_bounds (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2)
 {
 	double   i2c [6];
 	ArtPoint c1, c2, i1, i2;
@@ -96,7 +111,7 @@ ecb_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y
 
 	/* Wrong BBox's are the source of redraw nightmares */
 
-	gnome_canvas_item_i2c_affine (GNOME_CANVAS_ITEM (ecb), i2c);
+	foo_canvas_item_i2c_affine (FOO_CANVAS_ITEM (ecb), i2c);
 
 	i1.x = ecb->priv->x1;
 	i1.y = ecb->priv->y1;
@@ -124,16 +139,16 @@ ecb_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y
 }
 
 /*
- * GnomeCanvasItem::update method
+ * FooCanvasItem::update method
  */
 static void
-ecb_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, gint flags)
+ecb_update (FooCanvasItem *item, double i2w_dx, double i2w_dy, gint flags)
 {
 	ArtPoint o1, o2;
 	ECanvasBackground *ecb = E_CANVAS_BACKGROUND (item);
 
-	if (GNOME_CANVAS_ITEM_CLASS (ecb_parent_class)->update)
-		GNOME_CANVAS_ITEM_CLASS (ecb_parent_class)->update (item, affine, clip_path, flags);
+	if (FOO_CANVAS_ITEM_CLASS (ecb_parent_class)->update)
+		FOO_CANVAS_ITEM_CLASS (ecb_parent_class)->update (item, i2w_dx, i2w_dy, flags);
 
 	o1.x = item->x1;
 	o1.y = item->y1;
@@ -145,12 +160,12 @@ ecb_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, gint flags
 	    item->y1 != o1.y ||
 	    item->x2 != o2.x ||
 	    item->y2 != o2.y) {
-		gnome_canvas_request_redraw (item->canvas, o1.x, o1.y, o2.x, o2.y);
+		foo_canvas_request_redraw (item->canvas, o1.x, o1.y, o2.x, o2.y);
 		ecb->priv->needs_redraw = 1;
 	}
 
 	if (ecb->priv->needs_redraw) {
-		gnome_canvas_request_redraw (item->canvas, item->x1, item->y1,
+		foo_canvas_request_redraw (item->canvas, item->x1, item->y1,
 					     item->x2, item->y2);
 		ecb->priv->needs_redraw = 0;
 	}
@@ -202,14 +217,14 @@ ecb_set_property (GObject *object,
 		  const GValue *value,
 		  GParamSpec *pspec)
 {
-	GnomeCanvasItem *item;
+	FooCanvasItem *item;
 	ECanvasBackground *ecb;
 
 	GdkColor color = { 0, 0, 0, 0, };
 	GdkColor *pcolor;
 	gboolean color_changed = FALSE;
 
-	item = GNOME_CANVAS_ITEM (object);
+	item = FOO_CANVAS_ITEM (object);
 	ecb = E_CANVAS_BACKGROUND (object);
 
 	switch (prop_id) {
@@ -266,16 +281,14 @@ ecb_set_property (GObject *object,
 	if (color_changed) {
 		ecb->priv->color = color;
 
-		if (GNOME_CANVAS_ITEM_REALIZED & GTK_OBJECT_FLAGS(item)) {
+		if (FOO_CANVAS_ITEM_REALIZED & GTK_OBJECT_FLAGS(item)) {
 			get_color (ecb);
-			if (!item->canvas->aa) {
-				gdk_gc_set_foreground (ecb->priv->gc, &ecb->priv->color);
-			}
+			gdk_gc_set_foreground (ecb->priv->gc, &ecb->priv->color);
 		}
 	}
 
 	ecb->priv->needs_redraw = 1;
-	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM(ecb));
+	foo_canvas_item_request_update (FOO_CANVAS_ITEM(ecb));
 }
 
 static void
@@ -334,48 +347,51 @@ ecb_init (ECanvasBackground *ecb)
 }
 
 static void
-ecb_realize (GnomeCanvasItem *item)
+ecb_realize (FooCanvasItem *item)
 {
 	ECanvasBackground *ecb = E_CANVAS_BACKGROUND (item);
 
-	if (GNOME_CANVAS_ITEM_CLASS (ecb_parent_class)->realize)
-                GNOME_CANVAS_ITEM_CLASS (ecb_parent_class)->realize (item);
+	if (FOO_CANVAS_ITEM_CLASS (ecb_parent_class)->realize)
+                FOO_CANVAS_ITEM_CLASS (ecb_parent_class)->realize (item);
 
 	ecb->priv->gc = gdk_gc_new (item->canvas->layout.bin_window);
 	get_color (ecb);
-	if (!item->canvas->aa)
-		gdk_gc_set_foreground (ecb->priv->gc, &ecb->priv->color);
+	gdk_gc_set_foreground (ecb->priv->gc, &ecb->priv->color);
 
 	set_stipple (ecb, NULL, FALSE);
 
 	ecb->priv->needs_redraw = 1;
-	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (ecb));
+	foo_canvas_item_request_update (FOO_CANVAS_ITEM (ecb));
 }
 
 static void
-ecb_unrealize (GnomeCanvasItem *item)
+ecb_unrealize (FooCanvasItem *item)
 {
 	ECanvasBackground *ecb = E_CANVAS_BACKGROUND (item);
 
 	g_object_unref (ecb->priv->gc);
 	ecb->priv->gc = NULL;
 
-	if (GNOME_CANVAS_ITEM_CLASS (ecb_parent_class)->unrealize)
-                GNOME_CANVAS_ITEM_CLASS (ecb_parent_class)->unrealize (item);
+	if (FOO_CANVAS_ITEM_CLASS (ecb_parent_class)->unrealize)
+                FOO_CANVAS_ITEM_CLASS (ecb_parent_class)->unrealize (item);
 }
 
 static void
-ecb_draw (GnomeCanvasItem *item, GdkDrawable *drawable, gint x, gint y, gint width, gint height)
+ecb_draw (FooCanvasItem *item, GdkDrawable *drawable, GdkEventExpose *expose)
 {
 	ECanvasBackground *ecb = E_CANVAS_BACKGROUND (item);
 	gint x1, x2, y1, y2;
+	gint width, height;
 	double i2c [6];
 	ArtPoint upper_left, lower_right, ecb_base_point;
 
+	width = expose->area.width;
+	height = expose->area.height;
+
 	/*
 	 * Find out our real position after grouping
 	 */
-	gnome_canvas_item_i2c_affine (item, i2c);
+	foo_canvas_item_i2c_affine (item, i2c);
 	ecb_base_point.x = ecb->priv->x1;
 	ecb_base_point.y = ecb->priv->y1;
 	art_affine_point (&upper_left, &ecb_base_point, i2c);
@@ -402,8 +418,8 @@ ecb_draw (GnomeCanvasItem *item, GdkDrawable *drawable, gint x, gint y, gint wid
 }
 
 static double
-ecb_point (GnomeCanvasItem *item, double x, double y, gint cx, gint cy,
-	   GnomeCanvasItem **actual_item)
+ecb_point (FooCanvasItem *item, double x, double y, gint cx, gint cy,
+	   FooCanvasItem **actual_item)
 {
 	ECanvasBackground *ecb = E_CANVAS_BACKGROUND (item);
 
@@ -423,18 +439,18 @@ ecb_point (GnomeCanvasItem *item, double x, double y, gint cx, gint cy,
 static void
 ecb_style_set (ECanvasBackground *ecb, GtkStyle *previous_style)
 {
-	GnomeCanvasItem *item = GNOME_CANVAS_ITEM (ecb);
+	FooCanvasItem *item = FOO_CANVAS_ITEM (ecb);
 
 	if (GTK_WIDGET_REALIZED (item->canvas)) {
 		gdk_gc_set_foreground (ecb->priv->gc, &GTK_WIDGET(item->canvas)->style->base[GTK_STATE_NORMAL]);
-		gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (ecb));
+		foo_canvas_item_request_update (FOO_CANVAS_ITEM (ecb));
 	}
 }
 
 static void
 ecb_class_init (ECanvasBackgroundClass *ecb_class)
 {
-	GnomeCanvasItemClass *item_class = GNOME_CANVAS_ITEM_CLASS (ecb_class);
+	FooCanvasItemClass *item_class = FOO_CANVAS_ITEM_CLASS (ecb_class);
 	GObjectClass *object_class = G_OBJECT_CLASS (ecb_class);
 
 	object_class->dispose       = ecb_dispose;
diff --git a/widgets/misc/e-canvas-background.h b/widgets/misc/e-canvas-background.h
index 7e3ac19..a8eb2c6 100644
--- a/widgets/misc/e-canvas-background.h
+++ b/widgets/misc/e-canvas-background.h
@@ -25,7 +25,7 @@
 #ifndef E_CANVAS_BACKGROUND_H
 #define E_CANVAS_BACKGROUND_H
 
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 
 G_BEGIN_DECLS
 
@@ -53,13 +53,13 @@ typedef struct _ECanvasBackgroundClass ECanvasBackgroundClass;
 typedef struct _ECanvasBackgroundPrivate ECanvasBackgroundPrivate;
 
 struct _ECanvasBackground {
-	GnomeCanvasItem item;
+	FooCanvasItem item;
 
 	ECanvasBackgroundPrivate *priv;
 };
 
 struct _ECanvasBackgroundClass {
-	GnomeCanvasItemClass parent_class;
+	FooCanvasItemClass parent_class;
 	void        (*style_set)        (ECanvasBackground *eti, GtkStyle *previous_style);
 };
 
diff --git a/widgets/misc/e-canvas-utils.c b/widgets/misc/e-canvas-utils.c
index e69bb9c..5d595f3 100644
--- a/widgets/misc/e-canvas-utils.c
+++ b/widgets/misc/e-canvas-utils.c
@@ -24,16 +24,17 @@
 #include "e-canvas-utils.h"
 
 void
-e_canvas_item_move_absolute (GnomeCanvasItem *item, double dx, double dy)
+e_canvas_item_move_absolute (FooCanvasItem *item, double dx, double dy)
 {
 	double translate[6];
 
 	g_return_if_fail (item != NULL);
-	g_return_if_fail (GNOME_IS_CANVAS_ITEM (item));
+	g_return_if_fail (FOO_IS_CANVAS_ITEM (item));
 
 	art_affine_translate (translate, dx, dy);
 
-	gnome_canvas_item_affine_absolute (item, translate);
+	/* FooCanvas does not provide this functionality. */
+	/*gnome_canvas_item_affine_absolute (item, translate);*/
 }
 
 static double
@@ -64,13 +65,13 @@ compute_offset(gint top, gint bottom, gint page_top, gint page_bottom)
 }
 
 static void
-e_canvas_show_area (GnomeCanvas *canvas, double x1, double y1, double x2, double y2)
+e_canvas_show_area (FooCanvas *canvas, double x1, double y1, double x2, double y2)
 {
 	GtkAdjustment *h, *v;
 	gint dx = 0, dy = 0;
 
 	g_return_if_fail (canvas != NULL);
-	g_return_if_fail (GNOME_IS_CANVAS (canvas));
+	g_return_if_fail (FOO_IS_CANVAS (canvas));
 
 	h = gtk_layout_get_hadjustment(GTK_LAYOUT(canvas));
 	dx = compute_offset(x1, x2, h->value, h->value + h->page_size);
@@ -84,25 +85,25 @@ e_canvas_show_area (GnomeCanvas *canvas, double x1, double y1, double x2, double
 }
 
 void
-e_canvas_item_show_area (GnomeCanvasItem *item, double x1, double y1, double x2, double y2)
+e_canvas_item_show_area (FooCanvasItem *item, double x1, double y1, double x2, double y2)
 {
 	g_return_if_fail (item != NULL);
-	g_return_if_fail (GNOME_IS_CANVAS_ITEM (item));
+	g_return_if_fail (FOO_IS_CANVAS_ITEM (item));
 
-	gnome_canvas_item_i2w(item, &x1, &y1);
-	gnome_canvas_item_i2w(item, &x2, &y2);
+	foo_canvas_item_i2w(item, &x1, &y1);
+	foo_canvas_item_i2w(item, &x2, &y2);
 
 	e_canvas_show_area(item->canvas, x1, y1, x2, y2);
 }
 
 static gboolean
-e_canvas_area_shown (GnomeCanvas *canvas, double x1, double y1, double x2, double y2)
+e_canvas_area_shown (FooCanvas *canvas, double x1, double y1, double x2, double y2)
 {
 	GtkAdjustment *h, *v;
 	gint dx = 0, dy = 0;
 
 	g_return_val_if_fail (canvas != NULL, FALSE);
-	g_return_val_if_fail (GNOME_IS_CANVAS (canvas), FALSE);
+	g_return_val_if_fail (FOO_IS_CANVAS (canvas), FALSE);
 
 	h = gtk_layout_get_hadjustment(GTK_LAYOUT(canvas));
 	dx = compute_offset(x1, x2, h->value, h->value + h->page_size);
@@ -117,13 +118,13 @@ e_canvas_area_shown (GnomeCanvas *canvas, double x1, double y1, double x2, doubl
 }
 
 gboolean
-e_canvas_item_area_shown (GnomeCanvasItem *item, double x1, double y1, double x2, double y2)
+e_canvas_item_area_shown (FooCanvasItem *item, double x1, double y1, double x2, double y2)
 {
 	g_return_val_if_fail (item != NULL, FALSE);
-	g_return_val_if_fail (GNOME_IS_CANVAS_ITEM (item), FALSE);
+	g_return_val_if_fail (FOO_IS_CANVAS_ITEM (item), FALSE);
 
-	gnome_canvas_item_i2w(item, &x1, &y1);
-	gnome_canvas_item_i2w(item, &x2, &y2);
+	foo_canvas_item_i2w(item, &x1, &y1);
+	foo_canvas_item_i2w(item, &x2, &y2);
 
 	return e_canvas_area_shown(item->canvas, x1, y1, x2, y2);
 }
@@ -133,7 +134,7 @@ typedef struct {
 	double y1;
 	double x2;
 	double y2;
-	GnomeCanvas *canvas;
+	FooCanvas *canvas;
 } DoubsAndCanvas;
 
 static gboolean
@@ -148,15 +149,15 @@ show_area_timeout (gpointer data)
 }
 
 void
-e_canvas_item_show_area_delayed (GnomeCanvasItem *item, double x1, double y1, double x2, double y2, gint delay)
+e_canvas_item_show_area_delayed (FooCanvasItem *item, double x1, double y1, double x2, double y2, gint delay)
 {
 	DoubsAndCanvas *dac;
 
 	g_return_if_fail (item != NULL);
-	g_return_if_fail (GNOME_IS_CANVAS_ITEM (item));
+	g_return_if_fail (FOO_IS_CANVAS_ITEM (item));
 
-	gnome_canvas_item_i2w(item, &x1, &y1);
-	gnome_canvas_item_i2w(item, &x2, &y2);
+	foo_canvas_item_i2w(item, &x1, &y1);
+	foo_canvas_item_i2w(item, &x2, &y2);
 
 	dac = g_new(DoubsAndCanvas, 1);
 	dac->x1 = x1;
diff --git a/widgets/misc/e-canvas-utils.h b/widgets/misc/e-canvas-utils.h
index cda34e9..abbcdad 100644
--- a/widgets/misc/e-canvas-utils.h
+++ b/widgets/misc/e-canvas-utils.h
@@ -23,19 +23,19 @@
 #ifndef __E_CANVAS_UTILS__
 #define __E_CANVAS_UTILS__
 
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 
 G_BEGIN_DECLS
 
-void      e_canvas_item_move_absolute      (GnomeCanvasItem *item,
+void      e_canvas_item_move_absolute      (FooCanvasItem *item,
 					    double           dx,
 					    double           dy);
-void      e_canvas_item_show_area          (GnomeCanvasItem *item,
+void      e_canvas_item_show_area          (FooCanvasItem *item,
 					    double           x1,
 					    double           y1,
 					    double           x2,
 					    double           y2);
-void      e_canvas_item_show_area_delayed  (GnomeCanvasItem *item,
+void      e_canvas_item_show_area_delayed  (FooCanvasItem *item,
 					    double           x1,
 					    double           y1,
 					    double           x2,
@@ -44,7 +44,7 @@ void      e_canvas_item_show_area_delayed  (GnomeCanvasItem *item,
 /* Returns TRUE if the area is already shown on the screen (including
    spacing.)  This is equivelent to returning FALSE iff show_area
    would do anything. */
-gboolean  e_canvas_item_area_shown         (GnomeCanvasItem *item,
+gboolean  e_canvas_item_area_shown         (FooCanvasItem *item,
 					    double           x1,
 					    double           y1,
 					    double           x2,
diff --git a/widgets/misc/e-canvas-vbox.c b/widgets/misc/e-canvas-vbox.c
index af159b2..d38a9bb 100644
--- a/widgets/misc/e-canvas-vbox.c
+++ b/widgets/misc/e-canvas-vbox.c
@@ -38,14 +38,14 @@ static void e_canvas_vbox_set_property (GObject *object, guint prop_id, const GV
 static void e_canvas_vbox_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
 static void e_canvas_vbox_dispose (GObject *object);
 
-static gint e_canvas_vbox_event   (GnomeCanvasItem *item, GdkEvent *event);
-static void e_canvas_vbox_realize (GnomeCanvasItem *item);
+static gint e_canvas_vbox_event   (FooCanvasItem *item, GdkEvent *event);
+static void e_canvas_vbox_realize (FooCanvasItem *item);
 
-static void e_canvas_vbox_reflow (GnomeCanvasItem *item, gint flags);
+static void e_canvas_vbox_reflow (FooCanvasItem *item, gint flags);
 
-static void e_canvas_vbox_real_add_item(ECanvasVbox *e_canvas_vbox, GnomeCanvasItem *item);
-static void e_canvas_vbox_real_add_item_start(ECanvasVbox *e_canvas_vbox, GnomeCanvasItem *item);
-static void e_canvas_vbox_resize_children (GnomeCanvasItem *item);
+static void e_canvas_vbox_real_add_item(ECanvasVbox *e_canvas_vbox, FooCanvasItem *item);
+static void e_canvas_vbox_real_add_item_start(ECanvasVbox *e_canvas_vbox, FooCanvasItem *item);
+static void e_canvas_vbox_resize_children (FooCanvasItem *item);
 
 /* The arguments we take */
 enum {
@@ -56,16 +56,16 @@ enum {
 	PROP_SPACING
 };
 
-G_DEFINE_TYPE (ECanvasVbox, e_canvas_vbox, GNOME_TYPE_CANVAS_GROUP)
+G_DEFINE_TYPE (ECanvasVbox, e_canvas_vbox, FOO_TYPE_CANVAS_GROUP)
 
 static void
 e_canvas_vbox_class_init (ECanvasVboxClass *klass)
 {
 	GObjectClass *object_class;
-	GnomeCanvasItemClass *item_class;
+	FooCanvasItemClass *item_class;
 
 	object_class = (GObjectClass*) klass;
-	item_class = (GnomeCanvasItemClass *) klass;
+	item_class = (FooCanvasItemClass *) klass;
 
 	klass->add_item       = e_canvas_vbox_real_add_item;
 	klass->add_item_start = e_canvas_vbox_real_add_item_start;
@@ -74,7 +74,7 @@ e_canvas_vbox_class_init (ECanvasVboxClass *klass)
 	object_class->get_property = e_canvas_vbox_get_property;
 	object_class->dispose      = e_canvas_vbox_dispose;
 
-	/* GnomeCanvasItem method overrides */
+	/* FooCanvasItem method overrides */
 	item_class->event       = e_canvas_vbox_event;
 	item_class->realize     = e_canvas_vbox_realize;
 
@@ -114,16 +114,16 @@ e_canvas_vbox_init (ECanvasVbox *vbox)
 	vbox->height = 10;
 	vbox->spacing = 0;
 
-	e_canvas_item_set_reflow_callback(GNOME_CANVAS_ITEM(vbox), e_canvas_vbox_reflow);
+	e_canvas_item_set_reflow_callback(FOO_CANVAS_ITEM(vbox), e_canvas_vbox_reflow);
 }
 
 static void
 e_canvas_vbox_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
 {
-	GnomeCanvasItem *item;
+	FooCanvasItem *item;
 	ECanvasVbox *e_canvas_vbox;
 
-	item = GNOME_CANVAS_ITEM (object);
+	item = FOO_CANVAS_ITEM (object);
 	e_canvas_vbox = E_CANVAS_VBOX (object);
 
 	switch (prop_id) {
@@ -171,11 +171,11 @@ static void
 disconnect_item_cb (gpointer data, gpointer user_data)
 {
 	ECanvasVbox *vbox;
-	GnomeCanvasItem *item;
+	FooCanvasItem *item;
 
 	vbox = E_CANVAS_VBOX (user_data);
 
-	item = GNOME_CANVAS_ITEM (data);
+	item = FOO_CANVAS_ITEM (data);
 	g_signal_handlers_disconnect_matched (item,
 					      G_SIGNAL_MATCH_DATA,
 					      0, 0, NULL, NULL,
@@ -197,7 +197,7 @@ e_canvas_vbox_dispose (GObject *object)
 }
 
 static gint
-e_canvas_vbox_event (GnomeCanvasItem *item, GdkEvent *event)
+e_canvas_vbox_event (FooCanvasItem *item, GdkEvent *event)
 {
 	gint return_val = TRUE;
 
@@ -226,18 +226,18 @@ e_canvas_vbox_event (GnomeCanvasItem *item, GdkEvent *event)
 		break;
 	}
 	if (!return_val) {
-		if (GNOME_CANVAS_ITEM_CLASS(e_canvas_vbox_parent_class)->event)
-			return GNOME_CANVAS_ITEM_CLASS (e_canvas_vbox_parent_class)->event (item, event);
+		if (FOO_CANVAS_ITEM_CLASS(e_canvas_vbox_parent_class)->event)
+			return FOO_CANVAS_ITEM_CLASS (e_canvas_vbox_parent_class)->event (item, event);
 	}
 	return return_val;
 
 }
 
 static void
-e_canvas_vbox_realize (GnomeCanvasItem *item)
+e_canvas_vbox_realize (FooCanvasItem *item)
 {
-	if (GNOME_CANVAS_ITEM_CLASS(e_canvas_vbox_parent_class)->realize)
-		(* GNOME_CANVAS_ITEM_CLASS(e_canvas_vbox_parent_class)->realize) (item);
+	if (FOO_CANVAS_ITEM_CLASS(e_canvas_vbox_parent_class)->realize)
+		(* FOO_CANVAS_ITEM_CLASS(e_canvas_vbox_parent_class)->realize) (item);
 
 	e_canvas_vbox_resize_children(item);
 	e_canvas_item_request_reflow(item);
@@ -251,13 +251,13 @@ e_canvas_vbox_remove_item (gpointer data, GObject *where_object_was)
 }
 
 static void
-e_canvas_vbox_real_add_item(ECanvasVbox *e_canvas_vbox, GnomeCanvasItem *item)
+e_canvas_vbox_real_add_item(ECanvasVbox *e_canvas_vbox, FooCanvasItem *item)
 {
 	e_canvas_vbox->items = g_list_append(e_canvas_vbox->items, item);
 	g_object_weak_ref (G_OBJECT (item),
 			   e_canvas_vbox_remove_item, e_canvas_vbox);
-	if ( GTK_OBJECT_FLAGS( e_canvas_vbox ) & GNOME_CANVAS_ITEM_REALIZED ) {
-		gnome_canvas_item_set(item,
+	if ( GTK_OBJECT_FLAGS( e_canvas_vbox ) & FOO_CANVAS_ITEM_REALIZED ) {
+		foo_canvas_item_set(item,
 				      "width", (double) e_canvas_vbox->minimum_width,
 				      NULL);
 		e_canvas_item_request_reflow(item);
@@ -265,13 +265,13 @@ e_canvas_vbox_real_add_item(ECanvasVbox *e_canvas_vbox, GnomeCanvasItem *item)
 }
 
 static void
-e_canvas_vbox_real_add_item_start(ECanvasVbox *e_canvas_vbox, GnomeCanvasItem *item)
+e_canvas_vbox_real_add_item_start(ECanvasVbox *e_canvas_vbox, FooCanvasItem *item)
 {
 	e_canvas_vbox->items = g_list_prepend(e_canvas_vbox->items, item);
 	g_object_weak_ref (G_OBJECT (item),
 			   e_canvas_vbox_remove_item, e_canvas_vbox);
-	if ( GTK_OBJECT_FLAGS( e_canvas_vbox ) & GNOME_CANVAS_ITEM_REALIZED ) {
-		gnome_canvas_item_set(item,
+	if ( GTK_OBJECT_FLAGS( e_canvas_vbox ) & FOO_CANVAS_ITEM_REALIZED ) {
+		foo_canvas_item_set(item,
 				      "width", (double) e_canvas_vbox->minimum_width,
 				      NULL);
 		e_canvas_item_request_reflow(item);
@@ -279,25 +279,25 @@ e_canvas_vbox_real_add_item_start(ECanvasVbox *e_canvas_vbox, GnomeCanvasItem *i
 }
 
 static void
-e_canvas_vbox_resize_children (GnomeCanvasItem *item)
+e_canvas_vbox_resize_children (FooCanvasItem *item)
 {
 	GList *list;
 	ECanvasVbox *e_canvas_vbox;
 
 	e_canvas_vbox = E_CANVAS_VBOX (item);
 	for ( list = e_canvas_vbox->items; list; list = list->next ) {
-		GnomeCanvasItem *child = GNOME_CANVAS_ITEM(list->data);
-		gnome_canvas_item_set(child,
+		FooCanvasItem *child = FOO_CANVAS_ITEM(list->data);
+		foo_canvas_item_set(child,
 				      "width", (double) e_canvas_vbox->minimum_width,
 				      NULL);
 	}
 }
 
 static void
-e_canvas_vbox_reflow( GnomeCanvasItem *item, gint flags )
+e_canvas_vbox_reflow( FooCanvasItem *item, gint flags )
 {
 	ECanvasVbox *e_canvas_vbox = E_CANVAS_VBOX(item);
-	if ( GTK_OBJECT_FLAGS( e_canvas_vbox ) & GNOME_CANVAS_ITEM_REALIZED ) {
+	if ( GTK_OBJECT_FLAGS( e_canvas_vbox ) & FOO_CANVAS_ITEM_REALIZED ) {
 
 		gdouble old_height;
 		gdouble running_height;
@@ -321,7 +321,7 @@ e_canvas_vbox_reflow( GnomeCanvasItem *item, gint flags )
 				      "height", &item_height,
 				      "width", &item_width,
 				      NULL);
-			e_canvas_item_move_absolute(GNOME_CANVAS_ITEM(list->data),
+			e_canvas_item_move_absolute(FOO_CANVAS_ITEM(list->data),
 						    (double) 0,
 						    (double) running_height);
 			running_height += item_height;
@@ -337,7 +337,7 @@ e_canvas_vbox_reflow( GnomeCanvasItem *item, gint flags )
 					      "width", &item_width,
 					      NULL);
 
-				e_canvas_item_move_absolute(GNOME_CANVAS_ITEM(list->data),
+				e_canvas_item_move_absolute(FOO_CANVAS_ITEM(list->data),
 							    (double) 0,
 							    (double) running_height);
 
@@ -356,14 +356,14 @@ e_canvas_vbox_reflow( GnomeCanvasItem *item, gint flags )
 }
 
 void
-e_canvas_vbox_add_item(ECanvasVbox *e_canvas_vbox, GnomeCanvasItem *item)
+e_canvas_vbox_add_item(ECanvasVbox *e_canvas_vbox, FooCanvasItem *item)
 {
 	if (E_CANVAS_VBOX_CLASS(GTK_OBJECT_GET_CLASS(e_canvas_vbox))->add_item)
 		(E_CANVAS_VBOX_CLASS(GTK_OBJECT_GET_CLASS(e_canvas_vbox))->add_item) (e_canvas_vbox, item);
 }
 
 void
-e_canvas_vbox_add_item_start(ECanvasVbox *e_canvas_vbox, GnomeCanvasItem *item)
+e_canvas_vbox_add_item_start(ECanvasVbox *e_canvas_vbox, FooCanvasItem *item)
 {
 	if (E_CANVAS_VBOX_CLASS(GTK_OBJECT_GET_CLASS(e_canvas_vbox))->add_item_start)
 		(E_CANVAS_VBOX_CLASS(GTK_OBJECT_GET_CLASS(e_canvas_vbox))->add_item_start) (e_canvas_vbox, item);
diff --git a/widgets/misc/e-canvas-vbox.h b/widgets/misc/e-canvas-vbox.h
index b41b8f8..9c271a9 100644
--- a/widgets/misc/e-canvas-vbox.h
+++ b/widgets/misc/e-canvas-vbox.h
@@ -24,7 +24,7 @@
 #define __E_CANVAS_VBOX_H__
 
 #include <gtk/gtk.h>
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 
 G_BEGIN_DECLS
 
@@ -50,10 +50,10 @@ typedef struct _ECanvasVboxClass  ECanvasVboxClass;
 
 struct _ECanvasVbox
 {
-	GnomeCanvasGroup parent;
+	FooCanvasGroup parent;
 
 	/* item specific fields */
-	GList *items; /* Of type GnomeCanvasItem */
+	GList *items; /* Of type FooCanvasItem */
 
 	double width;
 	double minimum_width;
@@ -63,11 +63,11 @@ struct _ECanvasVbox
 
 struct _ECanvasVboxClass
 {
-	GnomeCanvasGroupClass parent_class;
+	FooCanvasGroupClass parent_class;
 
 	/* Virtual methods. */
-	void (* add_item) (ECanvasVbox *CanvasVbox, GnomeCanvasItem *item);
-	void (* add_item_start) (ECanvasVbox *CanvasVbox, GnomeCanvasItem *item);
+	void (* add_item) (ECanvasVbox *CanvasVbox, FooCanvasItem *item);
+	void (* add_item_start) (ECanvasVbox *CanvasVbox, FooCanvasItem *item);
 };
 
 /*
@@ -76,8 +76,8 @@ struct _ECanvasVboxClass
  * should also do an ECanvas parent CanvasVbox request if its size
  * changes.
  */
-void       e_canvas_vbox_add_item(ECanvasVbox *e_canvas_vbox, GnomeCanvasItem *item);
-void       e_canvas_vbox_add_item_start(ECanvasVbox *e_canvas_vbox, GnomeCanvasItem *item);
+void       e_canvas_vbox_add_item(ECanvasVbox *e_canvas_vbox, FooCanvasItem *item);
+void       e_canvas_vbox_add_item_start(ECanvasVbox *e_canvas_vbox, FooCanvasItem *item);
 GType      e_canvas_vbox_get_type (void);
 
 G_END_DECLS
diff --git a/widgets/misc/e-canvas.c b/widgets/misc/e-canvas.c
index aeb2634..3aa1213 100644
--- a/widgets/misc/e-canvas.c
+++ b/widgets/misc/e-canvas.c
@@ -48,7 +48,7 @@ static gint e_canvas_focus_out      (GtkWidget        *widget,
 static void e_canvas_style_set      (GtkWidget        *widget,
 				     GtkStyle         *previous_style);
 
-static gint emit_event (GnomeCanvas *canvas, GdkEvent *event);
+static gint emit_event (FooCanvas *canvas, GdkEvent *event);
 
 #define d(x)
 
@@ -59,7 +59,7 @@ enum {
 
 static guint e_canvas_signals [LAST_SIGNAL] = { 0, };
 
-G_DEFINE_TYPE (ECanvas, e_canvas, GNOME_TYPE_CANVAS)
+G_DEFINE_TYPE (ECanvas, e_canvas, FOO_TYPE_CANVAS)
 
 static void
 e_canvas_class_init (ECanvasClass *klass)
@@ -147,12 +147,12 @@ e_canvas_new (void)
  * item, or focused item, as appropriate.
  */
 static gint
-emit_event (GnomeCanvas *canvas, GdkEvent *event)
+emit_event (FooCanvas *canvas, GdkEvent *event)
 {
 	GdkEvent *ev;
 	gint finished;
-	GnomeCanvasItem *item;
-	GnomeCanvasItem *parent;
+	FooCanvasItem *item;
+	FooCanvasItem *parent;
 	guint mask;
 
 	/* Choose where we send the event */
@@ -218,7 +218,7 @@ emit_event (GnomeCanvas *canvas, GdkEvent *event)
 	switch (ev->type) {
 	case GDK_ENTER_NOTIFY:
 	case GDK_LEAVE_NOTIFY:
-		gnome_canvas_window_to_world (canvas,
+		foo_canvas_window_to_world (canvas,
 					      ev->crossing.x, ev->crossing.y,
 					      &ev->crossing.x, &ev->crossing.y);
 		break;
@@ -228,7 +228,7 @@ emit_event (GnomeCanvas *canvas, GdkEvent *event)
 	case GDK_2BUTTON_PRESS:
 	case GDK_3BUTTON_PRESS:
 	case GDK_BUTTON_RELEASE:
-		gnome_canvas_window_to_world (canvas,
+		foo_canvas_window_to_world (canvas,
 					      ev->motion.x, ev->motion.y,
 					      &ev->motion.x, &ev->motion.y);
 		break;
@@ -264,14 +264,14 @@ emit_event (GnomeCanvas *canvas, GdkEvent *event)
 static gint
 e_canvas_key (GtkWidget *widget, GdkEventKey *event)
 {
-	GnomeCanvas *canvas;
+	FooCanvas *canvas;
 	GdkEvent full_event;
 
 	g_return_val_if_fail (widget != NULL, FALSE);
-	g_return_val_if_fail (GNOME_IS_CANVAS (widget), FALSE);
+	g_return_val_if_fail (FOO_IS_CANVAS (widget), FALSE);
 	g_return_val_if_fail (event != NULL, FALSE);
 
-	canvas = GNOME_CANVAS (widget);
+	canvas = FOO_CANVAS (widget);
 
 	full_event.key = *event;
 
@@ -282,11 +282,11 @@ e_canvas_key (GtkWidget *widget, GdkEventKey *event)
  * be in the parent's item-relative coordinate system.  This routine applies the
  * inverse of the item's transform, maintaining the affine invariant.
  */
-#define HACKISH_AFFINE
+/*#define HACKISH_AFFINE*/
 
 static double
-gnome_canvas_item_invoke_point (GnomeCanvasItem *item, double x, double y, gint cx, gint cy,
-				GnomeCanvasItem **actual_item)
+foo_canvas_item_invoke_point (FooCanvasItem *item, double x, double y, gint cx, gint cy,
+				FooCanvasItem **actual_item)
 {
 #ifdef HACKISH_AFFINE
 	double i2w[6], w2c[6], i2c[6], c2i[6];
@@ -294,8 +294,8 @@ gnome_canvas_item_invoke_point (GnomeCanvasItem *item, double x, double y, gint
 #endif
 
 #ifdef HACKISH_AFFINE
-	gnome_canvas_item_i2w_affine (item, i2w);
-	gnome_canvas_w2c_affine (item->canvas, w2c);
+	foo_canvas_item_i2w_affine (item, i2w);
+	foo_canvas_w2c_affine (item->canvas, w2c);
 	art_affine_multiply (i2c, i2w, w2c);
 	art_affine_invert (c2i, i2c);
 	c.x = cx;
@@ -305,17 +305,17 @@ gnome_canvas_item_invoke_point (GnomeCanvasItem *item, double x, double y, gint
 	y = i.y;
 #endif
 
-	return (* GNOME_CANVAS_ITEM_CLASS (GTK_OBJECT_GET_CLASS (item))->point) (
+	return (* FOO_CANVAS_ITEM_CLASS (GTK_OBJECT_GET_CLASS (item))->point) (
 		item, x, y, cx, cy, actual_item);
 }
 
 /* Re-picks the current item in the canvas, based on the event's coordinates.
  * Also emits enter/leave events for items as appropriate.
  */
-#define DISPLAY_X1(canvas) (GNOME_CANVAS (canvas)->layout.xoffset)
-#define DISPLAY_Y1(canvas) (GNOME_CANVAS (canvas)->layout.yoffset)
+#define DISPLAY_X1(canvas) (FOO_CANVAS (canvas)->layout.xoffset)
+#define DISPLAY_Y1(canvas) (FOO_CANVAS (canvas)->layout.yoffset)
 static gint
-pick_current_item (GnomeCanvas *canvas, GdkEvent *event)
+pick_current_item (FooCanvas *canvas, GdkEvent *event)
 {
 	gint button_down;
 	double x, y;
@@ -400,8 +400,8 @@ pick_current_item (GnomeCanvas *canvas, GdkEvent *event)
 
 		/* find the closest item */
 
-		if (canvas->root->object.flags & GNOME_CANVAS_ITEM_VISIBLE)
-			gnome_canvas_item_invoke_point (canvas->root, x, y, cx, cy,
+		if (canvas->root->object.flags & FOO_CANVAS_ITEM_VISIBLE)
+			foo_canvas_item_invoke_point (canvas->root, x, y, cx, cy,
 							&canvas->new_current_item);
 		else
 			canvas->new_current_item = NULL;
@@ -457,17 +457,17 @@ pick_current_item (GnomeCanvas *canvas, GdkEvent *event)
 static gint
 e_canvas_button (GtkWidget *widget, GdkEventButton *event)
 {
-	GnomeCanvas *canvas;
+	FooCanvas *canvas;
 	gint mask;
 	gint retval;
 
 	g_return_val_if_fail (widget != NULL, FALSE);
-	g_return_val_if_fail (GNOME_IS_CANVAS (widget), FALSE);
+	g_return_val_if_fail (FOO_IS_CANVAS (widget), FALSE);
 	g_return_val_if_fail (event != NULL, FALSE);
 
 	retval = FALSE;
 
-	canvas = GNOME_CANVAS (widget);
+	canvas = FOO_CANVAS (widget);
 
 	d(g_print ("button %d, event type %d, grabbed=%p, current=%p\n",
 		   event->button,
@@ -554,13 +554,13 @@ e_canvas_visibility (GtkWidget *widget, GdkEventVisibility *event, ECanvas *canv
  * the focus and @widget_too is %TRUE, it grabs that focus as well.
  **/
 void
-e_canvas_item_grab_focus (GnomeCanvasItem *item, gboolean widget_too)
+e_canvas_item_grab_focus (FooCanvasItem *item, gboolean widget_too)
 {
-	GnomeCanvasItem *focused_item;
+	FooCanvasItem *focused_item;
 	GdkEvent ev;
 
 	g_return_if_fail (item != NULL);
-	g_return_if_fail (GNOME_IS_CANVAS_ITEM (item));
+	g_return_if_fail (FOO_IS_CANVAS_ITEM (item));
 	g_return_if_fail (GTK_WIDGET_CAN_FOCUS (GTK_WIDGET (item->canvas)));
 
 	focused_item = item->canvas->focused_item;
@@ -594,11 +594,11 @@ e_canvas_item_grab_focus (GnomeCanvasItem *item, gboolean widget_too)
 static gint
 e_canvas_focus_in (GtkWidget *widget, GdkEventFocus *event)
 {
-	GnomeCanvas *canvas;
+	FooCanvas *canvas;
 	ECanvas *ecanvas;
 	GdkEvent full_event;
 
-	canvas = GNOME_CANVAS (widget);
+	canvas = FOO_CANVAS (widget);
 	ecanvas = E_CANVAS (widget);
 
 	GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
@@ -617,11 +617,11 @@ e_canvas_focus_in (GtkWidget *widget, GdkEventFocus *event)
 static gint
 e_canvas_focus_out (GtkWidget *widget, GdkEventFocus *event)
 {
-	GnomeCanvas *canvas;
+	FooCanvas *canvas;
 	ECanvas *ecanvas;
 	GdkEvent full_event;
 
-	canvas = GNOME_CANVAS (widget);
+	canvas = FOO_CANVAS (widget);
 	ecanvas = E_CANVAS (widget);
 
 	GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
@@ -637,7 +637,7 @@ e_canvas_focus_out (GtkWidget *widget, GdkEventFocus *event)
 }
 
 static void
-ec_style_set_recursive (GnomeCanvasItem *item, GtkStyle *previous_style)
+ec_style_set_recursive (FooCanvasItem *item, GtkStyle *previous_style)
 {
 	guint signal_id = g_signal_lookup ("style_set", G_OBJECT_TYPE (item));
 	if (signal_id >= 1) {
@@ -648,8 +648,8 @@ ec_style_set_recursive (GnomeCanvasItem *item, GtkStyle *previous_style)
 		}
 	}
 
-	if (GNOME_IS_CANVAS_GROUP (item) ) {
-		GList *items = GNOME_CANVAS_GROUP (item)->item_list;
+	if (FOO_IS_CANVAS_GROUP (item) ) {
+		GList *items = FOO_CANVAS_GROUP (item)->item_list;
 		for (; items; items = items->next)
 			ec_style_set_recursive (items->data, previous_style);
 	}
@@ -658,7 +658,7 @@ ec_style_set_recursive (GnomeCanvasItem *item, GtkStyle *previous_style)
 static void
 e_canvas_style_set (GtkWidget *widget, GtkStyle *previous_style)
 {
-	ec_style_set_recursive (GNOME_CANVAS_ITEM (gnome_canvas_root (GNOME_CANVAS (widget))), previous_style);
+	ec_style_set_recursive (FOO_CANVAS_ITEM (foo_canvas_root (FOO_CANVAS (widget))), previous_style);
 }
 
 static void
@@ -691,16 +691,16 @@ e_canvas_unrealize (GtkWidget *widget)
 }
 
 static void
-e_canvas_item_invoke_reflow (GnomeCanvasItem *item, gint flags)
+e_canvas_item_invoke_reflow (FooCanvasItem *item, gint flags)
 {
-	GnomeCanvasGroup *group;
+	FooCanvasGroup *group;
 	GList *list;
-	GnomeCanvasItem *child;
+	FooCanvasItem *child;
 
-	if (GNOME_IS_CANVAS_GROUP (item)) {
-		group = GNOME_CANVAS_GROUP (item);
+	if (FOO_IS_CANVAS_GROUP (item)) {
+		group = FOO_CANVAS_GROUP (item);
 		for (list = group->item_list; list; list = list->next) {
-			child = GNOME_CANVAS_ITEM (list->data);
+			child = FOO_CANVAS_ITEM (list->data);
 			if (child->object.flags & E_CANVAS_ITEM_DESCENDENT_NEEDS_REFLOW)
 				e_canvas_item_invoke_reflow (child, flags);
 		}
@@ -722,8 +722,8 @@ e_canvas_item_invoke_reflow (GnomeCanvasItem *item, gint flags)
 static void
 do_reflow (ECanvas *canvas)
 {
-	if (GNOME_CANVAS(canvas)->root->object.flags & E_CANVAS_ITEM_DESCENDENT_NEEDS_REFLOW)
-		e_canvas_item_invoke_reflow (GNOME_CANVAS(canvas)->root, 0);
+	if (FOO_CANVAS(canvas)->root->object.flags & E_CANVAS_ITEM_DESCENDENT_NEEDS_REFLOW)
+		e_canvas_item_invoke_reflow (FOO_CANVAS(canvas)->root, 0);
 }
 
 /* Idle handler for the e-canvas.  It deals with pending reflows. */
@@ -759,7 +759,7 @@ add_idle (ECanvas *canvas)
 }
 
 static void
-e_canvas_item_descendent_needs_reflow (GnomeCanvasItem *item)
+e_canvas_item_descendent_needs_reflow (FooCanvasItem *item)
 {
 	if (item->object.flags & E_CANVAS_ITEM_DESCENDENT_NEEDS_REFLOW)
 		return;
@@ -770,9 +770,9 @@ e_canvas_item_descendent_needs_reflow (GnomeCanvasItem *item)
 }
 
 void
-e_canvas_item_request_reflow (GnomeCanvasItem *item)
+e_canvas_item_request_reflow (FooCanvasItem *item)
 {
-	if (item->object.flags & GNOME_CANVAS_ITEM_REALIZED) {
+	if (item->object.flags & FOO_CANVAS_ITEM_REALIZED) {
 		item->object.flags |= E_CANVAS_ITEM_NEEDS_REFLOW;
 		e_canvas_item_descendent_needs_reflow(item);
 		add_idle(E_CANVAS(item->canvas));
@@ -780,33 +780,33 @@ e_canvas_item_request_reflow (GnomeCanvasItem *item)
 }
 
 void
-e_canvas_item_request_parent_reflow (GnomeCanvasItem *item)
+e_canvas_item_request_parent_reflow (FooCanvasItem *item)
 {
 	g_return_if_fail(item != NULL);
-	g_return_if_fail(GNOME_IS_CANVAS_ITEM(item));
+	g_return_if_fail(FOO_IS_CANVAS_ITEM(item));
 	e_canvas_item_request_reflow(item->parent);
 }
 
 void
-e_canvas_item_set_reflow_callback (GnomeCanvasItem *item, ECanvasItemReflowFunc func)
+e_canvas_item_set_reflow_callback (FooCanvasItem *item, ECanvasItemReflowFunc func)
 {
 	g_object_set_data(G_OBJECT(item), "ECanvasItem::reflow_callback", (gpointer) func);
 }
 
 void
-e_canvas_item_set_selection_callback (GnomeCanvasItem *item, ECanvasItemSelectionFunc func)
+e_canvas_item_set_selection_callback (FooCanvasItem *item, ECanvasItemSelectionFunc func)
 {
 	g_object_set_data(G_OBJECT(item), "ECanvasItem::selection_callback", (gpointer) func);
 }
 
 void
-e_canvas_item_set_selection_compare_callback (GnomeCanvasItem *item, ECanvasItemSelectionCompareFunc func)
+e_canvas_item_set_selection_compare_callback (FooCanvasItem *item, ECanvasItemSelectionCompareFunc func)
 {
 	g_object_set_data(G_OBJECT(item), "ECanvasItem::selection_compare_callback", (gpointer) func);
 }
 
 void
-e_canvas_item_set_cursor (GnomeCanvasItem *item, gpointer id)
+e_canvas_item_set_cursor (FooCanvasItem *item, gpointer id)
 {
 	GList *list;
 	gint flags;
@@ -815,7 +815,7 @@ e_canvas_item_set_cursor (GnomeCanvasItem *item, gpointer id)
 	ECanvasItemSelectionFunc func;
 
 	g_return_if_fail(item != NULL);
-	g_return_if_fail(GNOME_IS_CANVAS_ITEM(item));
+	g_return_if_fail(FOO_IS_CANVAS_ITEM(item));
 	g_return_if_fail(item->canvas != NULL);
 	g_return_if_fail(E_IS_CANVAS(item->canvas));
 
@@ -838,7 +838,7 @@ e_canvas_item_set_cursor (GnomeCanvasItem *item, gpointer id)
 
 	canvas->selection = NULL;
 
-	gnome_canvas_item_grab_focus(item);
+	foo_canvas_item_grab_focus(item);
 
 	info = g_new(ECanvasSelectionInfo, 1);
 	info->item = item;
@@ -857,12 +857,12 @@ e_canvas_item_set_cursor (GnomeCanvasItem *item, gpointer id)
 }
 
 void
-e_canvas_item_set_cursor_end (GnomeCanvasItem *item, gpointer id)
+e_canvas_item_set_cursor_end (FooCanvasItem *item, gpointer id)
 {
 }
 
 void
-e_canvas_item_add_selection (GnomeCanvasItem *item, gpointer id)
+e_canvas_item_add_selection (FooCanvasItem *item, gpointer id)
 {
 	gint flags;
 	ECanvas *canvas;
@@ -871,7 +871,7 @@ e_canvas_item_add_selection (GnomeCanvasItem *item, gpointer id)
 	GList *list;
 
 	g_return_if_fail(item != NULL);
-	g_return_if_fail(GNOME_IS_CANVAS_ITEM(item));
+	g_return_if_fail(FOO_IS_CANVAS_ITEM(item));
 	g_return_if_fail(item->canvas != NULL);
 	g_return_if_fail(E_IS_CANVAS(item->canvas));
 
@@ -885,7 +885,7 @@ e_canvas_item_add_selection (GnomeCanvasItem *item, gpointer id)
 			func(canvas->cursor->item, flags, canvas->cursor->id);
 	}
 
-	gnome_canvas_item_grab_focus(item);
+	foo_canvas_item_grab_focus(item);
 
 	flags = E_CANVAS_ITEM_SELECTION_SELECT | E_CANVAS_ITEM_SELECTION_CURSOR;
 
@@ -925,7 +925,7 @@ e_canvas_item_add_selection (GnomeCanvasItem *item, gpointer id)
 }
 
 void
-e_canvas_item_remove_selection (GnomeCanvasItem *item, gpointer id)
+e_canvas_item_remove_selection (FooCanvasItem *item, gpointer id)
 {
 	gint flags;
 	ECanvas *canvas;
@@ -933,7 +933,7 @@ e_canvas_item_remove_selection (GnomeCanvasItem *item, gpointer id)
 	GList *list;
 
 	g_return_if_fail(item != NULL);
-	g_return_if_fail(GNOME_IS_CANVAS_ITEM(item));
+	g_return_if_fail(FOO_IS_CANVAS_ITEM(item));
 	g_return_if_fail(item->canvas != NULL);
 	g_return_if_fail(E_IS_CANVAS(item->canvas));
 
@@ -1004,7 +1004,7 @@ grab_cancelled_check (gpointer data)
 {
 	ECanvas *canvas = data;
 
-	if (GNOME_CANVAS (canvas)->grabbed_item == NULL) {
+	if (FOO_CANVAS (canvas)->grabbed_item == NULL) {
 		canvas->grab_cancelled_cb = NULL;
 		canvas->grab_cancelled_check_id = 0;
 		canvas->grab_cancelled_time = 0;
@@ -1013,10 +1013,10 @@ grab_cancelled_check (gpointer data)
 	}
 
 	if (gtk_grab_get_current ()) {
-		gnome_canvas_item_ungrab(GNOME_CANVAS (canvas)->grabbed_item, canvas->grab_cancelled_time);
+		foo_canvas_item_ungrab(FOO_CANVAS (canvas)->grabbed_item, canvas->grab_cancelled_time);
 		if (canvas->grab_cancelled_cb) {
 			canvas->grab_cancelled_cb (canvas,
-						   GNOME_CANVAS (canvas)->grabbed_item,
+						   FOO_CANVAS (canvas)->grabbed_item,
 						   canvas->grab_cancelled_data);
 		}
 		canvas->grab_cancelled_cb = NULL;
@@ -1030,7 +1030,7 @@ grab_cancelled_check (gpointer data)
 
 gint
 e_canvas_item_grab (ECanvas *canvas,
-		    GnomeCanvasItem *item,
+		    FooCanvasItem *item,
 		    guint event_mask,
 		    GdkCursor *cursor,
 		    guint32 etime,
@@ -1040,7 +1040,7 @@ e_canvas_item_grab (ECanvas *canvas,
 	if (gtk_grab_get_current ()) {
 		return GDK_GRAB_ALREADY_GRABBED;
 	} else {
-		gint ret_val = gnome_canvas_item_grab (item, event_mask, cursor, etime);
+		gint ret_val = foo_canvas_item_grab (item, event_mask, cursor, etime);
 		if (ret_val == GDK_GRAB_SUCCESS) {
 			canvas->grab_cancelled_cb = cancelled_cb;
 			canvas->grab_cancelled_check_id =
@@ -1059,7 +1059,7 @@ e_canvas_item_grab (ECanvas *canvas,
 
 void
 e_canvas_item_ungrab (ECanvas *canvas,
-		      GnomeCanvasItem *item,
+		      FooCanvasItem *item,
 		      guint32 etime)
 {
 	if (canvas->grab_cancelled_check_id) {
@@ -1068,6 +1068,6 @@ e_canvas_item_ungrab (ECanvas *canvas,
 		canvas->grab_cancelled_check_id = 0;
 		canvas->grab_cancelled_time = 0;
 		canvas->grab_cancelled_data = NULL;
-		gnome_canvas_item_ungrab (item, etime);
+		foo_canvas_item_ungrab (item, etime);
 	}
 }
diff --git a/widgets/misc/e-canvas.h b/widgets/misc/e-canvas.h
index a78824e..ccc7ecc 100644
--- a/widgets/misc/e-canvas.h
+++ b/widgets/misc/e-canvas.h
@@ -24,7 +24,7 @@
 #define __E_CANVAS_H__
 
 #include <gtk/gtk.h>
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 
 G_BEGIN_DECLS
 
@@ -38,14 +38,14 @@ G_BEGIN_DECLS
 #define E_IS_CANVAS(obj)		(G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_CANVAS_TYPE))
 #define E_IS_CANVAS_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((obj), E_CANVAS_TYPE))
 
-typedef void		(*ECanvasItemReflowFunc)		(GnomeCanvasItem *item,
+typedef void		(*ECanvasItemReflowFunc)		(FooCanvasItem *item,
 								 gint	  flags);
 
-typedef void            (*ECanvasItemSelectionFunc)             (GnomeCanvasItem *item,
+typedef void            (*ECanvasItemSelectionFunc)             (FooCanvasItem *item,
 								 gint             flags,
 								 gpointer         user_data);
 /* Returns the same as strcmp does. */
-typedef gint            (*ECanvasItemSelectionCompareFunc)      (GnomeCanvasItem *item,
+typedef gint            (*ECanvasItemSelectionCompareFunc)      (FooCanvasItem *item,
 								 gpointer         data1,
 								 gpointer         data2,
 								 gint             flags);
@@ -66,15 +66,15 @@ enum {
 };
 
 typedef struct {
-	GnomeCanvasItem *item;
+	FooCanvasItem *item;
 	gpointer         id;
 } ECanvasSelectionInfo;
 
-typedef void (*ECanvasItemGrabCancelled) (ECanvas *canvas, GnomeCanvasItem *item, gpointer data);
+typedef void (*ECanvasItemGrabCancelled) (ECanvas *canvas, FooCanvasItem *item, gpointer data);
 
 struct _ECanvas
 {
-	GnomeCanvas parent;
+	FooCanvas parent;
 	gint                   idle_id;
 	GList                *selection;
 	ECanvasSelectionInfo *cursor;
@@ -96,7 +96,7 @@ struct _ECanvas
 
 struct _ECanvasClass
 {
-	GnomeCanvasClass parent_class;
+	FooCanvasClass parent_class;
 	void (* reflow) (ECanvas *canvas);
 };
 
@@ -106,36 +106,36 @@ GtkWidget *e_canvas_new                                  (void);
 /* Used to send all of the keystroke events to a specific item as well as
  * GDK_FOCUS_CHANGE events.
  */
-void       e_canvas_item_grab_focus                      (GnomeCanvasItem                 *item,
+void       e_canvas_item_grab_focus                      (FooCanvasItem                 *item,
 							  gboolean                         widget_too);
-void       e_canvas_item_request_reflow                  (GnomeCanvasItem                 *item);
-void       e_canvas_item_request_parent_reflow           (GnomeCanvasItem                 *item);
-void       e_canvas_item_set_reflow_callback             (GnomeCanvasItem                 *item,
+void       e_canvas_item_request_reflow                  (FooCanvasItem                 *item);
+void       e_canvas_item_request_parent_reflow           (FooCanvasItem                 *item);
+void       e_canvas_item_set_reflow_callback             (FooCanvasItem                 *item,
 							  ECanvasItemReflowFunc            func);
-void       e_canvas_item_set_selection_callback          (GnomeCanvasItem                 *item,
+void       e_canvas_item_set_selection_callback          (FooCanvasItem                 *item,
 							  ECanvasItemSelectionFunc         func);
-void       e_canvas_item_set_selection_compare_callback  (GnomeCanvasItem                 *item,
+void       e_canvas_item_set_selection_compare_callback  (FooCanvasItem                 *item,
 							  ECanvasItemSelectionCompareFunc  func);
-void       e_canvas_item_set_cursor                      (GnomeCanvasItem                 *item,
+void       e_canvas_item_set_cursor                      (FooCanvasItem                 *item,
 							  gpointer                         id);
-void       e_canvas_item_add_selection                   (GnomeCanvasItem                 *item,
+void       e_canvas_item_add_selection                   (FooCanvasItem                 *item,
 							  gpointer                         id);
-void       e_canvas_item_remove_selection                (GnomeCanvasItem                 *item,
+void       e_canvas_item_remove_selection                (FooCanvasItem                 *item,
 							  gpointer                         id);
 
 gint        e_canvas_item_grab                            (ECanvas                         *canvas,
-							  GnomeCanvasItem                 *item,
+							  FooCanvasItem                 *item,
 							  guint                            event_mask,
 							  GdkCursor                       *cursor,
 							  guint32                          etime,
 							  ECanvasItemGrabCancelled         cancelled,
 							  gpointer                         cancelled_data);
 void       e_canvas_item_ungrab                          (ECanvas                         *canvas,
-							  GnomeCanvasItem                 *item,
+							  FooCanvasItem                 *item,
 							  guint32                          etime);
 
 /* Not implemented yet. */
-void       e_canvas_item_set_cursor_end                  (GnomeCanvasItem                 *item,
+void       e_canvas_item_set_cursor_end                  (FooCanvasItem                 *item,
 							  gpointer                         id);
 void       e_canvas_popup_tooltip                        (ECanvas                         *canvas,
 							  GtkWidget                       *widget,
diff --git a/widgets/misc/e-dateedit.c b/widgets/misc/e-dateedit.c
index 07a9fc6..a6ce353 100644
--- a/widgets/misc/e-dateedit.c
+++ b/widgets/misc/e-dateedit.c
@@ -547,7 +547,7 @@ create_children			(EDateEdit	*dedit)
 
 	priv->calendar = e_calendar_new ();
 	calendar = E_CALENDAR (priv->calendar);
-	gnome_canvas_item_set (GNOME_CANVAS_ITEM (calendar->calitem),
+	foo_canvas_item_set (FOO_CANVAS_ITEM (calendar->calitem),
 			       "maximum_days_selected", 1,
 			       "move_selection_when_moving", FALSE,
 			       NULL);
@@ -1087,8 +1087,8 @@ e_date_edit_set_week_start_day (EDateEdit *dedit,
 {
 	g_return_if_fail (E_IS_DATE_EDIT (dedit));
 
-	gnome_canvas_item_set (
-		GNOME_CANVAS_ITEM (E_CALENDAR (dedit->priv->calendar)->calitem),
+	foo_canvas_item_set (
+		FOO_CANVAS_ITEM (E_CALENDAR (dedit->priv->calendar)->calitem),
 		"week_start_day", week_start_day, NULL);
 
 	g_object_notify (G_OBJECT (dedit), "week-start-day");
@@ -1115,8 +1115,8 @@ e_date_edit_set_show_week_numbers (EDateEdit *dedit,
 {
 	g_return_if_fail (E_IS_DATE_EDIT (dedit));
 
-	gnome_canvas_item_set (
-		GNOME_CANVAS_ITEM (E_CALENDAR (dedit->priv->calendar)->calitem),
+	foo_canvas_item_set (
+		FOO_CANVAS_ITEM (E_CALENDAR (dedit->priv->calendar)->calitem),
 		"show_week_numbers", show_week_numbers, NULL);
 
 	g_object_notify (G_OBJECT (dedit), "show-week-numbers");
diff --git a/widgets/misc/e-gui-utils.c b/widgets/misc/e-gui-utils.c
index 0974081..40619e1 100644
--- a/widgets/misc/e-gui-utils.c
+++ b/widgets/misc/e-gui-utils.c
@@ -24,7 +24,7 @@
 
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <gtk/gtk.h>
-#include <libgnomecanvas/gnome-canvas-pixbuf.h>
+#include <libfoocanvas/foo-canvas-pixbuf.h>
 
 #include "e-gui-utils.h"
 
diff --git a/widgets/misc/ea-calendar-cell.c b/widgets/misc/ea-calendar-cell.c
index 05d0dcc..052a538 100644
--- a/widgets/misc/ea-calendar-cell.c
+++ b/widgets/misc/ea-calendar-cell.c
@@ -376,8 +376,8 @@ component_interface_grab_focus (AtkComponent *component)
 	atk_selection_clear_selection (ATK_SELECTION (ea_calitem));
 	atk_selection_add_selection (ATK_SELECTION (ea_calitem), index);
 
-	gtk_widget_grab_focus (GTK_WIDGET (GNOME_CANVAS_ITEM (calitem)->canvas));
-	toplevel = gtk_widget_get_toplevel (GTK_WIDGET (GNOME_CANVAS_ITEM (calitem)->canvas));
+	gtk_widget_grab_focus (GTK_WIDGET (FOO_CANVAS_ITEM (calitem)->canvas));
+	toplevel = gtk_widget_get_toplevel (GTK_WIDGET (FOO_CANVAS_ITEM (calitem)->canvas));
 	if (toplevel && GTK_WIDGET_TOPLEVEL (toplevel))
 		gtk_window_present (GTK_WINDOW (toplevel));
 
diff --git a/widgets/misc/ea-calendar-item.c b/widgets/misc/ea-calendar-item.c
index 9dcb834..367c8b1 100644
--- a/widgets/misc/ea-calendar-item.c
+++ b/widgets/misc/ea-calendar-item.c
@@ -23,7 +23,7 @@
 #include <stdio.h>
 #include <time.h>
 #include <string.h>
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 #include <glib.h>
 #include <e-util/e-util.h>
 #include <glib/gi18n.h>
@@ -174,7 +174,7 @@ ea_calendar_item_get_type (void)
 		 */
 
 		factory = atk_registry_get_factory (atk_get_default_registry (),
-						    GNOME_TYPE_CANVAS_ITEM);
+						    FOO_TYPE_CANVAS_ITEM);
 		derived_atk_type = atk_object_factory_get_accessible_type (factory);
 		g_type_query (derived_atk_type, &query);
 
@@ -1140,7 +1140,7 @@ e_calendar_item_get_day_extents (ECalendarItem *calitem,
 				 gint *x, gint *y,
 				 gint *width, gint *height)
 {
-	GnomeCanvasItem *item;
+	FooCanvasItem *item;
 	GtkWidget *widget;
 	GtkStyle *style;
 	PangoFontDescription *font_desc;
@@ -1155,7 +1155,7 @@ e_calendar_item_get_day_extents (ECalendarItem *calitem,
 
 	g_return_val_if_fail (E_IS_CALENDAR_ITEM (calitem), FALSE);
 
-	item = GNOME_CANVAS_ITEM (calitem);
+	item = FOO_CANVAS_ITEM (calitem);
 	widget = GTK_WIDGET (item->canvas);
 	style = widget->style;
 
diff --git a/widgets/table/e-cell-checkbox.c b/widgets/table/e-cell-checkbox.c
index 583793e..8064afe 100644
--- a/widgets/table/e-cell-checkbox.c
+++ b/widgets/table/e-cell-checkbox.c
@@ -25,7 +25,7 @@
 
 #include <gdk/gdkkeysyms.h>
 #include <gtk/gtk.h>
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 
 #include "e-util/e-util.h"
 
diff --git a/widgets/table/e-cell-combo.c b/widgets/table/e-cell-combo.c
index af79261..f2f15e5 100644
--- a/widgets/table/e-cell-combo.c
+++ b/widgets/table/e-cell-combo.c
@@ -366,7 +366,7 @@ e_cell_combo_get_popup_pos		(ECellCombo	*ecc,
 {
 	ECellPopup *ecp = E_CELL_POPUP (ecc);
 	ETableItem *eti = E_TABLE_ITEM (ecp->popup_cell_view->cell_view.e_table_item_view);
-	GtkWidget *canvas = GTK_WIDGET (GNOME_CANVAS_ITEM (eti)->canvas);
+	GtkWidget *canvas = GTK_WIDGET (FOO_CANVAS_ITEM (eti)->canvas);
 	GtkBin *popwin;
 	GtkScrolledWindow *popup;
 	GtkRequisition list_requisition;
@@ -388,9 +388,9 @@ e_cell_combo_get_popup_pos		(ECellCombo	*ecc,
 						view_col + 1);
 	row_height = e_table_item_row_diff (eti, row,
 					    row + 1);
-	gnome_canvas_item_i2w (GNOME_CANVAS_ITEM (eti), &x1, &y1);
+	foo_canvas_item_i2w (FOO_CANVAS_ITEM (eti), &x1, &y1);
 
-	gnome_canvas_world_to_window (GNOME_CANVAS (canvas),
+	foo_canvas_world_to_window (FOO_CANVAS (canvas),
 				      x1,
 				      y1,
 				      &wx,
@@ -402,8 +402,8 @@ e_cell_combo_get_popup_pos		(ECellCombo	*ecc,
 	*x += x1;
 	/* The ETable positions don't include the grid lines, I think, so we add 1. */
 	*y += y1 + 1
-		- (gint)((GnomeCanvas *)canvas)->layout.vadjustment->value
-		+ ((GnomeCanvas *)canvas)->zoom_yofs;
+		- (gint)((FooCanvas *)canvas)->layout.vadjustment->value
+		+ ((FooCanvas *)canvas)->zoom_yofs;
 
 	scrollbar_width = popup->vscrollbar->requisition.width
 		+ GTK_SCROLLED_WINDOW_CLASS (GTK_OBJECT_GET_CLASS (popup))->scrollbar_spacing;
diff --git a/widgets/table/e-cell-date-edit.c b/widgets/table/e-cell-date-edit.c
index 1848b28..a6d992f 100644
--- a/widgets/table/e-cell-date-edit.c
+++ b/widgets/table/e-cell-date-edit.c
@@ -243,7 +243,7 @@ e_cell_date_edit_init (ECellDateEdit *ecde)
         gtk_widget_show (hbox);
 
 	ecde->calendar = e_calendar_new ();
-	gnome_canvas_item_set (GNOME_CANVAS_ITEM (E_CALENDAR (ecde->calendar)->calitem),
+	foo_canvas_item_set (FOO_CANVAS_ITEM (E_CALENDAR (ecde->calendar)->calitem),
 			       "move_selection_when_moving", FALSE,
 			       NULL);
 	gtk_box_pack_start (GTK_BOX (hbox), ecde->calendar, TRUE, TRUE, 0);
@@ -625,7 +625,7 @@ e_cell_date_edit_get_popup_pos		(ECellDateEdit	*ecde,
 {
 	ECellPopup *ecp = E_CELL_POPUP (ecde);
 	ETableItem *eti = E_TABLE_ITEM (ecp->popup_cell_view->cell_view.e_table_item_view);
-	GtkWidget *canvas = GTK_WIDGET (GNOME_CANVAS_ITEM (eti)->canvas);
+	GtkWidget *canvas = GTK_WIDGET (FOO_CANVAS_ITEM (eti)->canvas);
 	GtkRequisition popup_requisition;
 	gint avail_height, screen_width, column_width, row_height;
 	double x1, y1, wx, wy;
@@ -638,9 +638,9 @@ e_cell_date_edit_get_popup_pos		(ECellDateEdit	*ecde,
 						view_col + 1);
 	row_height = e_table_item_row_diff (eti, row,
 					    row + 1);
-	gnome_canvas_item_i2w (GNOME_CANVAS_ITEM (eti), &x1, &y1);
+	foo_canvas_item_i2w (FOO_CANVAS_ITEM (eti), &x1, &y1);
 
-	gnome_canvas_world_to_window (GNOME_CANVAS (canvas),
+	foo_canvas_world_to_window (FOO_CANVAS (canvas),
 				      x1,
 				      y1,
 				      &wx,
@@ -653,8 +653,8 @@ e_cell_date_edit_get_popup_pos		(ECellDateEdit	*ecde,
 	/* The ETable positions don't include the grid lines, I think, so we
 	   add 1. */
 	*y += y1 + 1
-		- (gint)((GnomeCanvas *)canvas)->layout.vadjustment->value
-		+ ((GnomeCanvas *)canvas)->zoom_yofs;
+		- (gint)((FooCanvas *)canvas)->layout.vadjustment->value
+		+ ((FooCanvas *)canvas)->zoom_yofs;
 
 	avail_height = gdk_screen_height () - *y;
 
diff --git a/widgets/table/e-cell-hbox.h b/widgets/table/e-cell-hbox.h
index fda96de..e920e15 100644
--- a/widgets/table/e-cell-hbox.h
+++ b/widgets/table/e-cell-hbox.h
@@ -24,7 +24,7 @@
 #ifndef _E_CELL_HBOX_H_
 #define _E_CELL_HBOX_H_
 
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 #include <table/e-cell.h>
 
 G_BEGIN_DECLS
diff --git a/widgets/table/e-cell-pixbuf.c b/widgets/table/e-cell-pixbuf.c
index cf90909..8b3cc83 100644
--- a/widgets/table/e-cell-pixbuf.c
+++ b/widgets/table/e-cell-pixbuf.c
@@ -25,7 +25,7 @@
 
 #include <stdio.h>
 
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
@@ -37,7 +37,7 @@ typedef struct _ECellPixbufView ECellPixbufView;
 
 struct _ECellPixbufView {
 	ECellView cell_view;
-	GnomeCanvas *canvas;
+	FooCanvas *canvas;
 };
 
 /* Object argument IDs */
@@ -80,7 +80,7 @@ pixbuf_new_view (ECell *ecell, ETableModel *table_model, gpointer e_table_item_v
 {
     ECellPixbufView *pixbuf_view = g_new0 (ECellPixbufView, 1);
     ETableItem *eti = E_TABLE_ITEM (e_table_item_view);
-    GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas;
+    FooCanvas *canvas = FOO_CANVAS_ITEM (eti)->canvas;
 
     pixbuf_view->cell_view.ecell = ecell;
     pixbuf_view->cell_view.e_table_model = table_model;
diff --git a/widgets/table/e-cell-popup.c b/widgets/table/e-cell-popup.c
index 45c6d07..f78dd14 100644
--- a/widgets/table/e-cell-popup.c
+++ b/widgets/table/e-cell-popup.c
@@ -261,7 +261,7 @@ ecp_draw (ECellView *ecv, GdkDrawable *drawable,
 {
 	ECellPopup *ecp = E_CELL_POPUP (ecv->ecell);
 	ECellPopupView *ecp_view = (ECellPopupView *) ecv;
-	GtkWidget *canvas = GTK_WIDGET (GNOME_CANVAS_ITEM (ecv->e_table_item_view)->canvas);
+	GtkWidget *canvas = GTK_WIDGET (FOO_CANVAS_ITEM (ecv->e_table_item_view)->canvas);
 	GtkShadowType shadow;
 	GdkRectangle rect;
 	gboolean show_popup_arrow;
diff --git a/widgets/table/e-cell-popup.h b/widgets/table/e-cell-popup.h
index 4ea1127..e36d231 100644
--- a/widgets/table/e-cell-popup.h
+++ b/widgets/table/e-cell-popup.h
@@ -32,7 +32,7 @@
 #ifndef _E_CELL_POPUP_H_
 #define _E_CELL_POPUP_H_
 
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 #include <table/e-cell.h>
 
 #define E_CELL_POPUP_TYPE        (e_cell_popup_get_type ())
diff --git a/widgets/table/e-cell-text.c b/widgets/table/e-cell-text.c
index 9f7d7f1..8263e40 100644
--- a/widgets/table/e-cell-text.c
+++ b/widgets/table/e-cell-text.c
@@ -19,9 +19,9 @@
  *
  * A lot of code taken from:
  *
- * Text item type for GnomeCanvas widget
+ * Text item type for FooCanvas widget
  *
- * GnomeCanvas is basically a port of the Tk toolkit's most excellent
+ * FooCanvas is basically a port of the Tk toolkit's most excellent
  * canvas widget.  Tk is copyrighted by the Regents of the University
  * of California, Sun Microsystems, and other parties.
  *
@@ -42,8 +42,8 @@
 
 #include <gdk/gdkkeysyms.h>
 #include <gtk/gtk.h>
-#include <libgnomecanvas/gnome-canvas.h>
-#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
+#include <libfoocanvas/foo-canvas.h>
+#include <libfoocanvas/foo-canvas-rect-ellipse.h>
 
 #include "gal-a11y-e-cell-registry.h"
 #include "gal-a11y-e-cell-text.h"
@@ -53,6 +53,7 @@
 #include "e-util/e-text-event-processor-emacs-like.h"
 #include "e-util/e-util.h"
 #include "misc/e-canvas.h"
+#include "libfoocanvas/libart-types.h"
 #include "e-util/e-unicode.h"
 
 #include "e-cell-text.h"
@@ -128,7 +129,7 @@ typedef struct {
 	GdkCursor *i_cursor;
 	GdkBitmap *stipple;		/* Stipple for text */
 
-	GnomeCanvas *canvas;
+	FooCanvas *canvas;
 
 	/*
 	 * During editing.
@@ -350,7 +351,7 @@ static ECellView *
 ect_new_view (ECell *ecell, ETableModel *table_model, gpointer e_table_item_view)
 {
 	ECellTextView *text_view = g_new0 (ECellTextView, 1);
-	GnomeCanvas *canvas = GNOME_CANVAS_ITEM (e_table_item_view)->canvas;
+	FooCanvas *canvas = FOO_CANVAS_ITEM (e_table_item_view)->canvas;
 
 	text_view->cell_view.ecell = ecell;
 	text_view->cell_view.e_table_model = table_model;
@@ -565,7 +566,7 @@ build_layout (ECellTextView *text_view, gint row, const gchar *text, gint width)
 	PangoContext *context;
 	cairo_font_options_t *font_options;
 
-	layout = gtk_widget_create_pango_layout (GTK_WIDGET (((GnomeCanvasItem *)ecell_view->e_table_item_view)->canvas), text);
+	layout = gtk_widget_create_pango_layout (GTK_WIDGET (((FooCanvasItem *)ecell_view->e_table_item_view)->canvas), text);
 
 	attrs = (PangoAttrList *) build_attr_list (text_view, row, text ? strlen (text) : 0);
 
@@ -596,7 +597,7 @@ build_layout (ECellTextView *text_view, gint row, const gchar *text, gint width)
 			fixed_points = !pango_font_description_get_size_is_absolute (fixed_desc);
 		}
 
-		desc = pango_font_description_copy (gtk_widget_get_style (GTK_WIDGET (((GnomeCanvasItem *)ecell_view->e_table_item_view)->canvas))->font_desc);
+		desc = pango_font_description_copy (gtk_widget_get_style (GTK_WIDGET (((FooCanvasItem *)ecell_view->e_table_item_view)->canvas))->font_desc);
 		pango_font_description_set_family (desc, fixed_family);
 		if (fixed_points)
 			pango_font_description_set_size (desc, fixed_size);
@@ -1476,12 +1477,12 @@ tooltip_event (GtkWidget *window,
 
 	switch (event->type) {
 	case GDK_LEAVE_NOTIFY:
-		e_canvas_hide_tooltip (E_CANVAS(GNOME_CANVAS_ITEM(tooltip->eti)->canvas));
+		e_canvas_hide_tooltip (E_CANVAS(FOO_CANVAS_ITEM(tooltip->eti)->canvas));
 		break;
 	case GDK_BUTTON_PRESS:
 	case GDK_BUTTON_RELEASE:
 		if (event->type == GDK_BUTTON_RELEASE) {
-			e_canvas_hide_tooltip (E_CANVAS(GNOME_CANVAS_ITEM(tooltip->eti)->canvas));
+			e_canvas_hide_tooltip (E_CANVAS(FOO_CANVAS_ITEM(tooltip->eti)->canvas));
 		}
 
 		event->button.x = tooltip->cx;
@@ -1489,15 +1490,15 @@ tooltip_event (GtkWidget *window,
 		g_signal_emit_by_name (tooltip->eti, "event",
 				       event, &ret_val);
 		if (!ret_val)
-			gtk_propagate_event (GTK_WIDGET(GNOME_CANVAS_ITEM(tooltip->eti)->canvas), event);
+			gtk_propagate_event (GTK_WIDGET(FOO_CANVAS_ITEM(tooltip->eti)->canvas), event);
 		ret_val = TRUE;
 		break;
 	case GDK_KEY_PRESS:
-		e_canvas_hide_tooltip (E_CANVAS(GNOME_CANVAS_ITEM(tooltip->eti)->canvas));
+		e_canvas_hide_tooltip (E_CANVAS(FOO_CANVAS_ITEM(tooltip->eti)->canvas));
 		g_signal_emit_by_name (tooltip->eti, "event",
 				       event, &ret_val);
 		if (!ret_val)
-			gtk_propagate_event (GTK_WIDGET(GNOME_CANVAS_ITEM(tooltip->eti)->canvas), event);
+			gtk_propagate_event (GTK_WIDGET(FOO_CANVAS_ITEM(tooltip->eti)->canvas), event);
 		ret_val = TRUE;
 		break;
 	default:
@@ -1521,12 +1522,12 @@ ect_show_tooltip (ECellView *ecell_view,
 	ArtPoint origin = {0, 0};
 	ArtPoint pixel_origin;
 	gint canvas_x, canvas_y;
-	GnomeCanvasItem *tooltip_text;
+	FooCanvasItem *tooltip_text;
 	double tooltip_width;
 	double tooltip_height;
 	double tooltip_x;
 	double tooltip_y;
-	GnomeCanvasItem *rect;
+	FooCanvasItem *rect;
 	ECellText *ect = E_CELL_TEXT(ecell_view->ecell);
 	GtkWidget *window;
 	PangoLayout *layout;
@@ -1541,7 +1542,7 @@ ect_show_tooltip (ECellView *ecell_view,
 		return;
 	}
 
-	gnome_canvas_item_i2c_affine (GNOME_CANVAS_ITEM (tooltip->eti), i2c);
+	foo_canvas_item_i2c_affine (FOO_CANVAS_ITEM (tooltip->eti), i2c);
 	art_affine_point (&pixel_origin, &origin, i2c);
 
 	gdk_window_get_origin (GTK_WIDGET (text_view->canvas)->window,
@@ -1560,8 +1561,8 @@ ect_show_tooltip (ECellView *ecell_view,
 	GTK_WIDGET_UNSET_FLAGS (canvas, GTK_CAN_FOCUS);
 	GTK_WIDGET_UNSET_FLAGS (window, GTK_CAN_FOCUS);
 
-	rect = gnome_canvas_item_new (gnome_canvas_root (GNOME_CANVAS (canvas)),
-				      gnome_canvas_rect_get_type (),
+	rect = foo_canvas_item_new (foo_canvas_root (FOO_CANVAS (canvas)),
+				      foo_canvas_rect_get_type (),
 				      "x1", (double) 0.0,
 				      "y1", (double) 0.0,
 				      "x2", (double) width + 4,
@@ -1569,7 +1570,7 @@ ect_show_tooltip (ECellView *ecell_view,
 				      "fill_color_gdk", tooltip->background,
 				      NULL);
 
-	tooltip_text = gnome_canvas_item_new (gnome_canvas_root (GNOME_CANVAS (canvas)),
+	tooltip_text = foo_canvas_item_new (foo_canvas_root (FOO_CANVAS (canvas)),
 					      e_text_get_type (),
 					      "anchor", GTK_ANCHOR_NW,
 					      "bold", (gboolean) ect->bold_column >= 0 && e_table_model_value_at(ecell_view->e_table_model, ect->bold_column, row),
@@ -1607,14 +1608,14 @@ ect_show_tooltip (ECellView *ecell_view,
 		break;
 	}
 
-	gnome_canvas_item_move (tooltip_text, 3.0, 1.0);
-	gnome_canvas_item_set (rect,
+	foo_canvas_item_move (tooltip_text, 3.0, 1.0);
+	foo_canvas_item_set (rect,
 			       "x2", (double) tooltip_width + 6,
 			       "y2", (double) tooltip->row_height + 1,
 			       NULL);
 	gtk_widget_set_size_request (window, tooltip_width + 6,
 				     tooltip->row_height + 1);
-	gnome_canvas_set_scroll_region (GNOME_CANVAS (canvas), 0.0, 0.0,
+	foo_canvas_set_scroll_region (FOO_CANVAS (canvas), 0.0, 0.0,
 					(double) tooltip_width + 6,
 					(double) tooltip_height);
 	gtk_widget_show (canvas);
@@ -1851,7 +1852,7 @@ e_cell_text_get_cursor_locations (ECellTextView *tv,
 	CellEdit *edit=tv->edit;
 	ECellView *cell_view = (ECellView *)tv;
 	ETableItem *item = E_TABLE_ITEM ((cell_view)->e_table_item_view);
-	GnomeCanvasItem *parent_item = GNOME_CANVAS_ITEM (item)->parent;
+	FooCanvasItem *parent_item = FOO_CANVAS_ITEM (item)->parent;
 	PangoRectangle pango_strong_pos;
 	PangoRectangle pango_weak_pos;
 	gint x, y, col, row;
@@ -1865,9 +1866,9 @@ e_cell_text_get_cursor_locations (ECellTextView *tv,
 	e_table_item_get_cell_geometry (item, &row, &col,
 					&x, &y, NULL, &area.height);
 
-	gnome_canvas_item_get_bounds (GNOME_CANVAS_ITEM (parent_item), &x1, &y1, NULL, NULL);
+	foo_canvas_item_get_bounds (FOO_CANVAS_ITEM (parent_item), &x1, &y1, NULL, NULL);
 
-	gnome_canvas_get_scroll_offsets (GNOME_CANVAS (GNOME_CANVAS_ITEM (parent_item)->canvas), &cx, &cy);
+	foo_canvas_get_scroll_offsets (FOO_CANVAS (FOO_CANVAS_ITEM (parent_item)->canvas), &cx, &cy);
 
 	index = edit->selection_end + edit->preedit_pos;
 
diff --git a/widgets/table/e-cell-text.h b/widgets/table/e-cell-text.h
index 740db82..79c4a6d 100644
--- a/widgets/table/e-cell-text.h
+++ b/widgets/table/e-cell-text.h
@@ -23,9 +23,9 @@
  *
  * A lot of code taken from:
  *
- * Text item type for GnomeCanvas widget
+ * Text item type for FooCanvas widget
  *
- * GnomeCanvas is basically a port of the Tk toolkit's most excellent
+ * FooCanvas is basically a port of the Tk toolkit's most excellent
  * canvas widget.  Tk is copyrighted by the Regents of the University
  * of California, Sun Microsystems, and other parties.
  *
@@ -39,7 +39,7 @@
 #define _E_CELL_TEXT_H_
 
 #include <gtk/gtk.h>
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 #include <table/e-cell.h>
 
 G_BEGIN_DECLS
diff --git a/widgets/table/e-cell-toggle.c b/widgets/table/e-cell-toggle.c
index db047f1..3f67b5d 100644
--- a/widgets/table/e-cell-toggle.c
+++ b/widgets/table/e-cell-toggle.c
@@ -26,7 +26,7 @@
 
 #include <gdk/gdkkeysyms.h>
 #include <gtk/gtk.h>
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 
 #include "gal-a11y-e-cell-toggle.h"
 #include "gal-a11y-e-cell-registry.h"
@@ -41,7 +41,7 @@ G_DEFINE_TYPE (ECellToggle, e_cell_toggle, E_CELL_TYPE)
 typedef struct {
 	ECellView     cell_view;
 	GdkGC        *gc;
-	GnomeCanvas  *canvas;
+	FooCanvas  *canvas;
 } ECellToggleView;
 
 #define CACHE_SEQ_COUNT 6
@@ -54,7 +54,7 @@ etog_new_view (ECell *ecell, ETableModel *table_model, gpointer e_table_item_vie
 {
 	ECellToggleView *toggle_view = g_new0 (ECellToggleView, 1);
 	ETableItem *eti = E_TABLE_ITEM (e_table_item_view);
-	GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas;
+	FooCanvas *canvas = FOO_CANVAS_ITEM (eti)->canvas;
 
 	toggle_view->cell_view.ecell = ecell;
 	toggle_view->cell_view.e_table_model = table_model;
diff --git a/widgets/table/e-cell-toggle.h b/widgets/table/e-cell-toggle.h
index 09b458f..111d322 100644
--- a/widgets/table/e-cell-toggle.h
+++ b/widgets/table/e-cell-toggle.h
@@ -26,7 +26,7 @@
 #ifndef _E_CELL_TOGGLE_H_
 #define _E_CELL_TOGGLE_H_
 
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <table/e-cell.h>
 
diff --git a/widgets/table/e-cell-tree.c b/widgets/table/e-cell-tree.c
index a22cf6d..ac9f967 100644
--- a/widgets/table/e-cell-tree.c
+++ b/widgets/table/e-cell-tree.c
@@ -36,7 +36,7 @@
 
 #include <gdk/gdkkeysyms.h>
 #include <gtk/gtk.h>
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 
 #include "gal-a11y-e-cell-registry.h"
 #include "gal-a11y-e-cell-tree.h"
@@ -58,7 +58,7 @@ typedef struct {
 	ECellView   *subcell_view;
 	GdkGC       *gc;
 
-	GnomeCanvas *canvas;
+	FooCanvas *canvas;
 	gboolean retro_look;
 	gboolean prelit;
 	gint animate_timeout;
@@ -126,7 +126,7 @@ ect_new_view (ECell *ecell, ETableModel *table_model, gpointer e_table_item_view
 {
 	ECellTree *ect = E_CELL_TREE (ecell);
 	ECellTreeView *tree_view = g_new0 (ECellTreeView, 1);
-	GnomeCanvas *canvas = GNOME_CANVAS_ITEM (e_table_item_view)->canvas;
+	FooCanvas *canvas = FOO_CANVAS_ITEM (e_table_item_view)->canvas;
 
 	tree_view->cell_view.ecell = ecell;
 	tree_view->cell_view.e_table_model = table_model;
diff --git a/widgets/table/e-cell-tree.h b/widgets/table/e-cell-tree.h
index 465af77..14a5ac0 100644
--- a/widgets/table/e-cell-tree.h
+++ b/widgets/table/e-cell-tree.h
@@ -31,7 +31,7 @@
 #ifndef _E_CELL_TREE_H_
 #define _E_CELL_TREE_H_
 
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 #include <table/e-cell.h>
 
 G_BEGIN_DECLS
diff --git a/widgets/table/e-cell-vbox.h b/widgets/table/e-cell-vbox.h
index 7762e62..1421e58 100644
--- a/widgets/table/e-cell-vbox.h
+++ b/widgets/table/e-cell-vbox.h
@@ -29,7 +29,7 @@
 #ifndef _E_CELL_VBOX_H_
 #define _E_CELL_VBOX_H_
 
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 #include <table/e-cell.h>
 
 G_BEGIN_DECLS
diff --git a/widgets/table/e-table-click-to-add.c b/widgets/table/e-table-click-to-add.c
index 57769d1..c9d8b62 100644
--- a/widgets/table/e-table-click-to-add.c
+++ b/widgets/table/e-table-click-to-add.c
@@ -24,9 +24,9 @@
 
 #include <gdk/gdkkeysyms.h>
 #include <gtk/gtk.h>
-#include <libgnomecanvas/gnome-canvas.h>
-#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
-#include <libgnomecanvas/gnome-canvas-util.h>
+#include <libfoocanvas/foo-canvas.h>
+#include <libfoocanvas/foo-canvas-rect-ellipse.h>
+#include <libfoocanvas/foo-canvas-util.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 
 #include "gal-a11y-e-table-click-to-add.h"
@@ -51,7 +51,7 @@ static guint etcta_signals [LAST_SIGNAL] = { 0 };
 
 /* workaround for avoiding APi breakage */
 #define etcta_get_type e_table_click_to_add_get_type
-G_DEFINE_TYPE (ETableClickToAdd, etcta, GNOME_TYPE_CANVAS_GROUP)
+G_DEFINE_TYPE (ETableClickToAdd, etcta, FOO_TYPE_CANVAS_GROUP)
 
 #define ELEMENTS(x) (sizeof (x) / sizeof (x[0]))
 
@@ -75,10 +75,10 @@ etcta_cursor_change (GtkObject *object, gint row, gint col, ETableClickToAdd *et
 static void
 etcta_style_set (ETableClickToAdd *etcta, GtkStyle *previous_style)
 {
-	GtkWidget *widget = GTK_WIDGET(GNOME_CANVAS_ITEM(etcta)->canvas);
+	GtkWidget *widget = GTK_WIDGET(FOO_CANVAS_ITEM(etcta)->canvas);
 
 	if (etcta->rect) {
-		gnome_canvas_item_set (etcta->rect,
+		foo_canvas_item_set (etcta->rect,
 					"outline_color_gdk", &widget->style->fg[GTK_STATE_NORMAL],
 					"fill_color_gdk", &widget->style->bg[GTK_STATE_NORMAL],
 					NULL );
@@ -86,7 +86,7 @@ etcta_style_set (ETableClickToAdd *etcta, GtkStyle *previous_style)
 	}
 
 	if (etcta->text)
-		gnome_canvas_item_set (etcta->text,
+		foo_canvas_item_set (etcta->text,
 					"fill_color_gdk", &widget->style->text[GTK_STATE_NORMAL],
 					NULL);
 
@@ -99,7 +99,7 @@ etcta_add_table_header (ETableClickToAdd *etcta, ETableHeader *header)
 	if (etcta->eth)
 		g_object_ref (etcta->eth);
 	if (etcta->row)
-		gnome_canvas_item_set(GNOME_CANVAS_ITEM(etcta->row),
+		foo_canvas_item_set(FOO_CANVAS_ITEM(etcta->row),
 				      "ETableHeader", header,
 				      NULL);
 }
@@ -121,7 +121,7 @@ etcta_add_one (ETableClickToAdd *etcta, ETableModel *one)
 	if (etcta->one)
 		g_object_ref (etcta->one);
 	if (etcta->row)
-		gnome_canvas_item_set(GNOME_CANVAS_ITEM(etcta->row),
+		foo_canvas_item_set(FOO_CANVAS_ITEM(etcta->row),
 				      "ETableModel", one,
 				      NULL);
 	g_object_set(etcta->selection,
@@ -191,10 +191,10 @@ etcta_dispose (GObject *object)
 static void
 etcta_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
 {
-	GnomeCanvasItem *item;
+	FooCanvasItem *item;
 	ETableClickToAdd *etcta;
 
-	item = GNOME_CANVAS_ITEM (object);
+	item = FOO_CANVAS_ITEM (object);
 	etcta = E_TABLE_CLICK_TO_ADD (object);
 
 	switch (prop_id) {
@@ -213,15 +213,15 @@ etcta_set_property (GObject *object, guint prop_id, const GValue *value, GParamS
 	case PROP_WIDTH:
 		etcta->width = g_value_get_double (value);
 		if (etcta->row)
-			gnome_canvas_item_set(etcta->row,
+			foo_canvas_item_set(etcta->row,
 					      "minimum_width", etcta->width,
 					      NULL);
 		if (etcta->text)
-			gnome_canvas_item_set(etcta->text,
+			foo_canvas_item_set(etcta->text,
 					      "width", etcta->width - 4,
 					      NULL);
 		if (etcta->rect)
-			gnome_canvas_item_set(etcta->rect,
+			foo_canvas_item_set(etcta->rect,
 					      "x2", etcta->width - 1,
 					      NULL);
 		break;
@@ -230,17 +230,17 @@ etcta_set_property (GObject *object, guint prop_id, const GValue *value, GParamS
 		return;
 
 	}
-	gnome_canvas_item_request_update(item);
+	foo_canvas_item_request_update(item);
 }
 
 static void
 create_rect_and_text (ETableClickToAdd *etcta)
 {
-	GtkWidget *widget = GTK_WIDGET (GNOME_CANVAS_ITEM(etcta)->canvas);
+	GtkWidget *widget = GTK_WIDGET (FOO_CANVAS_ITEM(etcta)->canvas);
 
 	if (!etcta->rect)
-		etcta->rect = gnome_canvas_item_new(GNOME_CANVAS_GROUP(etcta),
-					    gnome_canvas_rect_get_type(),
+		etcta->rect = foo_canvas_item_new(FOO_CANVAS_GROUP(etcta),
+					    foo_canvas_rect_get_type(),
 					    "x1", (double) 0,
 					    "y1", (double) 0,
 					    "x2", (double) etcta->width - 1,
@@ -250,7 +250,7 @@ create_rect_and_text (ETableClickToAdd *etcta)
 					    NULL);
 
 	if (!etcta->text)
-		etcta->text = gnome_canvas_item_new(GNOME_CANVAS_GROUP(etcta),
+		etcta->text = foo_canvas_item_new(FOO_CANVAS_GROUP(etcta),
 					    e_text_get_type(),
 					    "text", etcta->message ? etcta->message : "",
 					    "anchor", GTK_ANCHOR_NW,
@@ -290,24 +290,24 @@ etcta_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *p
 }
 
 static void
-etcta_realize (GnomeCanvasItem *item)
+etcta_realize (FooCanvasItem *item)
 {
 	ETableClickToAdd *etcta = E_TABLE_CLICK_TO_ADD (item);
 
 	create_rect_and_text (etcta);
 	e_canvas_item_move_absolute (etcta->text, 2, 2);
 
-	if (GNOME_CANVAS_ITEM_CLASS (etcta_parent_class)->realize)
-		(*GNOME_CANVAS_ITEM_CLASS (etcta_parent_class)->realize)(item);
+	if (FOO_CANVAS_ITEM_CLASS (etcta_parent_class)->realize)
+		(*FOO_CANVAS_ITEM_CLASS (etcta_parent_class)->realize)(item);
 
 	e_canvas_item_request_reflow (item);
 }
 
 static void
-etcta_unrealize (GnomeCanvasItem *item)
+etcta_unrealize (FooCanvasItem *item)
 {
-	if (GNOME_CANVAS_ITEM_CLASS (etcta_parent_class)->unrealize)
-		(*GNOME_CANVAS_ITEM_CLASS (etcta_parent_class)->unrealize)(item);
+	if (FOO_CANVAS_ITEM_CLASS (etcta_parent_class)->unrealize)
+		(*FOO_CANVAS_ITEM_CLASS (etcta_parent_class)->unrealize)(item);
 }
 
 static void finish_editing (ETableClickToAdd *etcta);
@@ -352,7 +352,7 @@ finish_editing (ETableClickToAdd *etcta)
 
 		e_selection_model_clear(E_SELECTION_MODEL(etcta->selection));
 
-		etcta->row = gnome_canvas_item_new(GNOME_CANVAS_GROUP(etcta),
+		etcta->row = foo_canvas_item_new(FOO_CANVAS_GROUP(etcta),
 						   e_table_item_get_type(),
 						   "ETableHeader", etcta->eth,
 						   "ETableModel", etcta->one,
@@ -374,7 +374,7 @@ finish_editing (ETableClickToAdd *etcta)
  * Handles the events on the ETableClickToAdd, particularly it creates the ETableItem and passes in some events.
  */
 static gint
-etcta_event (GnomeCanvasItem *item, GdkEvent *e)
+etcta_event (FooCanvasItem *item, GdkEvent *e)
 {
 	ETableClickToAdd *etcta = E_TABLE_CLICK_TO_ADD (item);
 
@@ -401,7 +401,7 @@ etcta_event (GnomeCanvasItem *item, GdkEvent *e)
 
 			e_selection_model_clear(E_SELECTION_MODEL(etcta->selection));
 
-			etcta->row = gnome_canvas_item_new(GNOME_CANVAS_GROUP(item),
+			etcta->row = foo_canvas_item_new(FOO_CANVAS_GROUP(item),
 							   e_table_item_get_type(),
 							   "ETableHeader", etcta->eth,
 							   "ETableModel", etcta->one,
@@ -415,7 +415,7 @@ etcta_event (GnomeCanvasItem *item, GdkEvent *e)
 			g_signal_connect(etcta->row, "key_press",
 					 G_CALLBACK (item_key_press), etcta);
 
-			e_canvas_item_grab_focus (GNOME_CANVAS_ITEM(etcta->row), TRUE);
+			e_canvas_item_grab_focus (FOO_CANVAS_ITEM(etcta->row), TRUE);
 
 			set_initial_selection (etcta);
 		}
@@ -450,7 +450,7 @@ etcta_event (GnomeCanvasItem *item, GdkEvent *e)
 }
 
 static void
-etcta_reflow (GnomeCanvasItem *item, gint flags)
+etcta_reflow (FooCanvasItem *item, gint flags)
 {
 	ETableClickToAdd *etcta = E_TABLE_CLICK_TO_ADD (item);
 
@@ -481,7 +481,7 @@ etcta_reflow (GnomeCanvasItem *item, gint flags)
 static void
 etcta_class_init (ETableClickToAddClass *klass)
 {
-	GnomeCanvasItemClass *item_class = GNOME_CANVAS_ITEM_CLASS(klass);
+	FooCanvasItemClass *item_class = FOO_CANVAS_ITEM_CLASS(klass);
 	GObjectClass *object_class = G_OBJECT_CLASS(klass);
 
 	klass->cursor_change = NULL;
@@ -570,7 +570,7 @@ etcta_init (ETableClickToAdd *etcta)
 	g_signal_connect(etcta->selection, "cursor_changed",
 			 G_CALLBACK (etcta_cursor_change), etcta);
 
-	e_canvas_item_set_reflow_callback (GNOME_CANVAS_ITEM (etcta), etcta_reflow);
+	e_canvas_item_set_reflow_callback (FOO_CANVAS_ITEM (etcta), etcta_reflow);
 
 	/* create its a11y object at this time if accessibility is enabled*/
 	if (atk_get_root () != NULL) {
diff --git a/widgets/table/e-table-click-to-add.h b/widgets/table/e-table-click-to-add.h
index 17ac7f7..581604f 100644
--- a/widgets/table/e-table-click-to-add.h
+++ b/widgets/table/e-table-click-to-add.h
@@ -24,7 +24,7 @@
 #define _E_TABLE_CLICK_TO_ADD_H_
 
 #include <libxml/tree.h>
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 #include <table/e-table-header.h>
 #include <table/e-table-sort-info.h>
 #include <table/e-table-item.h>
@@ -39,7 +39,7 @@ G_BEGIN_DECLS
 #define E_IS_TABLE_CLICK_TO_ADD_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TABLE_CLICK_TO_ADD_TYPE))
 
 typedef struct {
-	GnomeCanvasGroup  parent;
+	FooCanvasGroup  parent;
 
 	ETableModel      *one;    /* The ETableOne. */
 
@@ -48,9 +48,9 @@ typedef struct {
 
 	gchar             *message;
 
-	GnomeCanvasItem  *row;    /* If row is NULL, we're sitting with no data and a "Click here" message. */
-	GnomeCanvasItem  *text;   /* If text is NULL, row shouldn't be. */
-	GnomeCanvasItem  *rect;   /* What the heck.  Why not. */
+	FooCanvasItem  *row;    /* If row is NULL, we're sitting with no data and a "Click here" message. */
+	FooCanvasItem  *text;   /* If text is NULL, row shouldn't be. */
+	FooCanvasItem  *rect;   /* What the heck.  Why not. */
 
 	gdouble           width;
 	gdouble           height;
@@ -59,7 +59,7 @@ typedef struct {
 } ETableClickToAdd;
 
 typedef struct {
-	GnomeCanvasGroupClass parent_class;
+	FooCanvasGroupClass parent_class;
 
 	/*
 	 * signals
diff --git a/widgets/table/e-table-field-chooser-item.c b/widgets/table/e-table-field-chooser-item.c
index 7f0f39a..61a22ac 100644
--- a/widgets/table/e-table-field-chooser-item.c
+++ b/widgets/table/e-table-field-chooser-item.c
@@ -25,16 +25,17 @@
 #include <string.h>
 
 #include <gtk/gtk.h>
-#include <libgnomecanvas/gnome-canvas.h>
-#include <libgnomecanvas/gnome-canvas-util.h>
-#include <libgnomecanvas/gnome-canvas-polygon.h>
-#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
+#include <libfoocanvas/foo-canvas.h>
+#include <libfoocanvas/foo-canvas-util.h>
+#include <libfoocanvas/foo-canvas-polygon.h>
+#include <libfoocanvas/foo-canvas-rect-ellipse.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 
 #include <glib/gi18n.h>
 #include "e-util/e-util.h"
 #include "e-util/e-xml-utils.h"
 #include "misc/e-canvas.h"
+#include "libfoocanvas/libart-types.h"
 
 #include "e-table-col-dnd.h"
 #include "e-table-defines.h"
@@ -55,7 +56,7 @@ static guint etfci_signals [LAST_SIGNAL] = { 0, };
 
 /* workaround for avoiding API breakage */
 #define etfci_get_type e_table_field_chooser_item_get_type
-G_DEFINE_TYPE (ETableFieldChooserItem, etfci, GNOME_TYPE_CANVAS_ITEM)
+G_DEFINE_TYPE (ETableFieldChooserItem, etfci, FOO_TYPE_CANVAS_ITEM)
 
 #define ELEMENTS(x) (sizeof (x) / sizeof (x[0]))
 
@@ -105,7 +106,7 @@ etfci_find_button (ETableFieldChooserItem *etfci, double loc)
 		ecol = e_table_header_get_column (etfci->combined_header, i);
 		if (ecol->disabled)
 			continue;
-		height += e_table_header_compute_height (ecol, GTK_WIDGET (GNOME_CANVAS_ITEM (etfci)->canvas));
+		height += e_table_header_compute_height (ecol, GTK_WIDGET (FOO_CANVAS_ITEM (etfci)->canvas));
 		if (height > loc)
 			return i;
 	}
@@ -147,7 +148,7 @@ etfci_rebuild_combined (ETableFieldChooserItem *etfci)
 }
 
 static void
-etfci_reflow (GnomeCanvasItem *item, gint flags)
+etfci_reflow (FooCanvasItem *item, gint flags)
 {
 	ETableFieldChooserItem *etfci = E_TABLE_FIELD_CHOOSER_ITEM (item);
 	double old_height;
@@ -166,7 +167,7 @@ etfci_reflow (GnomeCanvasItem *item, gint flags)
 		ecol = e_table_header_get_column (etfci->combined_header, i);
 		if (ecol->disabled)
 			continue;
-		height += e_table_header_compute_height (ecol, GTK_WIDGET (GNOME_CANVAS_ITEM (etfci)->canvas));
+		height += e_table_header_compute_height (ecol, GTK_WIDGET (FOO_CANVAS_ITEM (etfci)->canvas));
 	}
 
 	etfci->height = height;
@@ -174,24 +175,24 @@ etfci_reflow (GnomeCanvasItem *item, gint flags)
 	if (old_height != etfci->height)
 		e_canvas_item_request_parent_reflow(item);
 
-	gnome_canvas_item_request_update(item);
+	foo_canvas_item_request_update(item);
 }
 
 static void
-etfci_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, gint flags)
+etfci_update (FooCanvasItem *item, double i2w_dx, double i2w_dy, gint flags)
 {
 	ETableFieldChooserItem *etfci = E_TABLE_FIELD_CHOOSER_ITEM (item);
 	double   i2c [6];
 	ArtPoint c1, c2, i1, i2;
 
-	if (GNOME_CANVAS_ITEM_CLASS (etfci_parent_class)->update)
-		(*GNOME_CANVAS_ITEM_CLASS (etfci_parent_class)->update)(item, affine, clip_path, flags);
+	if (FOO_CANVAS_ITEM_CLASS (etfci_parent_class)->update)
+		(*FOO_CANVAS_ITEM_CLASS (etfci_parent_class)->update)(item, i2w_dx, i2w_dy, flags);
 
 	i1.x = i1.y = 0;
 	i2.x = etfci->width;
 	i2.y = etfci->height;
 
-	gnome_canvas_item_i2c_affine (item, i2c);
+	foo_canvas_item_i2c_affine (item, i2c);
 	art_affine_point (&c1, &i1, i2c);
 	art_affine_point (&c2, &i2, i2c);
 
@@ -200,17 +201,17 @@ etfci_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, gint fla
 	     item->x2 != c2.x ||
 	     item->y2 != c2.y)
 		{
-			gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2);
+			foo_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2);
 			item->x1 = c1.x;
 			item->y1 = c1.y;
 			item->x2 = c2.x;
 			item->y2 = c2.y;
 /* FIXME: Group Child bounds !? */
 #if 0
-			gnome_canvas_group_child_bounds (GNOME_CANVAS_GROUP (item->parent), item);
+			foo_canvas_group_child_bounds (FOO_CANVAS_GROUP (item->parent), item);
 #endif
 		}
-	gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2);
+	foo_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2);
 }
 
 static void
@@ -221,7 +222,7 @@ etfci_font_load (ETableFieldChooserItem *etfci)
 	if (etfci->font_desc)
 		pango_font_description_free (etfci->font_desc);
 
-	style = GTK_WIDGET (GNOME_CANVAS_ITEM (etfci)->canvas)->style;
+	style = GTK_WIDGET (FOO_CANVAS_ITEM (etfci)->canvas)->style;
 	etfci->font_desc = pango_font_description_copy (style->font_desc);
 }
 
@@ -245,19 +246,19 @@ etfci_drop_full_header (ETableFieldChooserItem *etfci)
 		g_object_unref (header);
 	etfci->full_header = NULL;
 	etfci->height = 0;
-	e_canvas_item_request_reflow(GNOME_CANVAS_ITEM(etfci));
+	e_canvas_item_request_reflow(FOO_CANVAS_ITEM(etfci));
 }
 
 static void
 full_header_structure_changed (ETableHeader *header, ETableFieldChooserItem *etfci)
 {
-	e_canvas_item_request_reflow(GNOME_CANVAS_ITEM(etfci));
+	e_canvas_item_request_reflow(FOO_CANVAS_ITEM(etfci));
 }
 
 static void
 full_header_dimension_changed (ETableHeader *header, gint col, ETableFieldChooserItem *etfci)
 {
-	e_canvas_item_request_reflow(GNOME_CANVAS_ITEM(etfci));
+	e_canvas_item_request_reflow(FOO_CANVAS_ITEM(etfci));
 }
 
 static void
@@ -272,7 +273,7 @@ etfci_add_full_header (ETableFieldChooserItem *etfci, ETableHeader *header)
 	etfci->full_header_dimension_change_id = g_signal_connect (
 		header, "dimension_change",
 		G_CALLBACK(full_header_dimension_changed), etfci);
-	e_canvas_item_request_reflow(GNOME_CANVAS_ITEM(etfci));
+	e_canvas_item_request_reflow(FOO_CANVAS_ITEM(etfci));
 }
 
 static void
@@ -295,19 +296,19 @@ etfci_drop_table_header (ETableFieldChooserItem *etfci)
 		g_object_unref (header);
 	etfci->header = NULL;
 	etfci->height = 0;
-	e_canvas_item_request_reflow(GNOME_CANVAS_ITEM(etfci));
+	e_canvas_item_request_reflow(FOO_CANVAS_ITEM(etfci));
 }
 
 static void
 table_header_structure_changed (ETableHeader *header, ETableFieldChooserItem *etfci)
 {
-	e_canvas_item_request_reflow(GNOME_CANVAS_ITEM(etfci));
+	e_canvas_item_request_reflow(FOO_CANVAS_ITEM(etfci));
 }
 
 static void
 table_header_dimension_changed (ETableHeader *header, gint col, ETableFieldChooserItem *etfci)
 {
-	e_canvas_item_request_reflow(GNOME_CANVAS_ITEM(etfci));
+	e_canvas_item_request_reflow(FOO_CANVAS_ITEM(etfci));
 }
 
 static void
@@ -322,16 +323,16 @@ etfci_add_table_header (ETableFieldChooserItem *etfci, ETableHeader *header)
 	etfci->table_header_dimension_change_id = g_signal_connect (
 		header, "dimension_change",
 		G_CALLBACK(table_header_dimension_changed), etfci);
-	e_canvas_item_request_reflow(GNOME_CANVAS_ITEM(etfci));
+	e_canvas_item_request_reflow(FOO_CANVAS_ITEM(etfci));
 }
 
 static void
 etfci_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
 {
-	GnomeCanvasItem *item;
+	FooCanvasItem *item;
 	ETableFieldChooserItem *etfci;
 
-	item = GNOME_CANVAS_ITEM (object);
+	item = FOO_CANVAS_ITEM (object);
 	etfci = E_TABLE_FIELD_CHOOSER_ITEM (object);
 
 	switch (prop_id) {
@@ -354,7 +355,7 @@ etfci_set_property (GObject *object, guint prop_id, const GValue *value, GParamS
 
 	case PROP_WIDTH:
 		etfci->width = g_value_get_double (value);
-		gnome_canvas_item_request_update(item);
+		foo_canvas_item_request_update(item);
 		break;
 	}
 }
@@ -411,12 +412,12 @@ etfci_drag_end (GtkWidget      *canvas,
 }
 
 static void
-etfci_realize (GnomeCanvasItem *item)
+etfci_realize (FooCanvasItem *item)
 {
 	ETableFieldChooserItem *etfci = E_TABLE_FIELD_CHOOSER_ITEM (item);
 
-	if (GNOME_CANVAS_ITEM_CLASS (etfci_parent_class)-> realize)
-		(*GNOME_CANVAS_ITEM_CLASS (etfci_parent_class)->realize)(item);
+	if (FOO_CANVAS_ITEM_CLASS (etfci_parent_class)-> realize)
+		(*FOO_CANVAS_ITEM_CLASS (etfci_parent_class)->realize)(item);
 
 	if (!etfci->font_desc)
 		etfci_font_load (etfci);
@@ -427,11 +428,11 @@ etfci_realize (GnomeCanvasItem *item)
 	etfci->drag_data_get_id = g_signal_connect (
 		item->canvas, "drag_data_get",
 		G_CALLBACK (etfci_drag_data_get), etfci);
-	e_canvas_item_request_reflow(GNOME_CANVAS_ITEM(etfci));
+	e_canvas_item_request_reflow(FOO_CANVAS_ITEM(etfci));
 }
 
 static void
-etfci_unrealize (GnomeCanvasItem *item)
+etfci_unrealize (FooCanvasItem *item)
 {
 	ETableFieldChooserItem *etfci = E_TABLE_FIELD_CHOOSER_ITEM (item);
 
@@ -444,24 +445,30 @@ etfci_unrealize (GnomeCanvasItem *item)
 	g_signal_handler_disconnect (item->canvas, etfci->drag_data_get_id);
 	etfci->drag_data_get_id = 0;
 
-	if (GNOME_CANVAS_ITEM_CLASS (etfci_parent_class)->unrealize)
-		(*GNOME_CANVAS_ITEM_CLASS (etfci_parent_class)->unrealize)(item);
+	if (FOO_CANVAS_ITEM_CLASS (etfci_parent_class)->unrealize)
+		(*FOO_CANVAS_ITEM_CLASS (etfci_parent_class)->unrealize)(item);
 }
 
 static void
-etfci_draw (GnomeCanvasItem *item, GdkDrawable *drawable, gint x, gint y, gint width, gint height)
+etfci_draw (FooCanvasItem *item, GdkDrawable *drawable, GdkEventExpose *expose)
 {
 	ETableFieldChooserItem *etfci = E_TABLE_FIELD_CHOOSER_ITEM (item);
-	GnomeCanvas *canvas = item->canvas;
+	FooCanvas *canvas = item->canvas;
 	gint rows;
 	gint y1, y2;
 	gint row;
+	gint x, y, width, height;
 	GtkStyle *style;
 	GtkStateType state;
 
 	if (etfci->combined_header == NULL)
 		return;
 
+	x = expose->area.x;
+	y = expose->area.y;
+	width = expose->area.width;
+	height = expose->area.height;
+
 	rows = e_table_header_count (etfci->combined_header);
 
 	style = GTK_WIDGET (canvas)->style;
@@ -495,8 +502,8 @@ etfci_draw (GnomeCanvasItem *item, GdkDrawable *drawable, gint x, gint y, gint w
 }
 
 static double
-etfci_point (GnomeCanvasItem *item, double x, double y, gint cx, gint cy,
-	    GnomeCanvasItem **actual_item)
+etfci_point (FooCanvasItem *item, double x, double y, gint cx, gint cy,
+	    FooCanvasItem **actual_item)
 {
 	*actual_item = item;
 	return 0.0;
@@ -518,7 +525,7 @@ etfci_maybe_start_drag (ETableFieldChooserItem *etfci, gint x, gint y)
 static void
 etfci_start_drag (ETableFieldChooserItem *etfci, GdkEvent *event, double x, double y)
 {
-	GtkWidget *widget = GTK_WIDGET (GNOME_CANVAS_ITEM (etfci)->canvas);
+	GtkWidget *widget = GTK_WIDGET (FOO_CANVAS_ITEM (etfci)->canvas);
 	GtkTargetList *list;
 	GdkDragContext *context;
 	ETableCol *ecol;
@@ -576,22 +583,22 @@ etfci_start_drag (ETableFieldChooserItem *etfci, GdkEvent *event, double x, doub
  * Handles the events on the ETableFieldChooserItem
  */
 static gint
-etfci_event (GnomeCanvasItem *item, GdkEvent *e)
+etfci_event (FooCanvasItem *item, GdkEvent *e)
 {
 	ETableFieldChooserItem *etfci = E_TABLE_FIELD_CHOOSER_ITEM (item);
-	GnomeCanvas *canvas = item->canvas;
+	FooCanvas *canvas = item->canvas;
 	gint x, y;
 
 	switch (e->type) {
 	case GDK_MOTION_NOTIFY:
-		gnome_canvas_w2c (canvas, e->motion.x, e->motion.y, &x, &y);
+		foo_canvas_w2c (canvas, e->motion.x, e->motion.y, &x, &y);
 
 		if (etfci_maybe_start_drag (etfci, x, y))
 			etfci_start_drag (etfci, e, x, y);
 		break;
 
 	case GDK_BUTTON_PRESS:
-		gnome_canvas_w2c (canvas, e->button.x, e->button.y, &x, &y);
+		foo_canvas_w2c (canvas, e->button.x, e->button.y, &x, &y);
 
 		if (e->button.button == 1) {
 			etfci->click_x = x;
@@ -614,7 +621,7 @@ etfci_event (GnomeCanvasItem *item, GdkEvent *e)
 static void
 etfci_class_init (ETableFieldChooserItemClass *klass)
 {
-	GnomeCanvasItemClass *item_class = GNOME_CANVAS_ITEM_CLASS (klass);
+	FooCanvasItemClass *item_class = FOO_CANVAS_ITEM_CLASS (klass);
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
 	object_class->dispose = etfci_dispose;
@@ -685,6 +692,6 @@ etfci_init (ETableFieldChooserItem *etfci)
 	etfci->maybe_drag = 0;
 	etfci->drag_end_id = 0;
 
-	e_canvas_item_set_reflow_callback(GNOME_CANVAS_ITEM (etfci), etfci_reflow);
+	e_canvas_item_set_reflow_callback(FOO_CANVAS_ITEM (etfci), etfci_reflow);
 }
 
diff --git a/widgets/table/e-table-field-chooser-item.h b/widgets/table/e-table-field-chooser-item.h
index d0cbbd9..1bc435e 100644
--- a/widgets/table/e-table-field-chooser-item.h
+++ b/widgets/table/e-table-field-chooser-item.h
@@ -24,7 +24,7 @@
 #ifndef _E_TABLE_FIELD_CHOOSER_ITEM_H_
 #define _E_TABLE_FIELD_CHOOSER_ITEM_H_
 
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 #include <libxml/tree.h>
 #include <table/e-table-header.h>
 
@@ -37,7 +37,7 @@ G_BEGIN_DECLS
 #define E_IS_TABLE_FIELD_CHOOSER_ITEM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TABLE_FIELD_CHOOSER_ITEM_TYPE))
 
 typedef struct {
-	GnomeCanvasItem  parent;
+	FooCanvasItem  parent;
 	ETableHeader    *full_header;
 	ETableHeader    *header;
 	ETableHeader    *combined_header;
@@ -65,7 +65,7 @@ typedef struct {
 } ETableFieldChooserItem;
 
 typedef struct {
-	GnomeCanvasItemClass parent_class;
+	FooCanvasItemClass parent_class;
 } ETableFieldChooserItemClass;
 
 GType      e_table_field_chooser_item_get_type (void);
diff --git a/widgets/table/e-table-field-chooser.c b/widgets/table/e-table-field-chooser.c
index 231ad08..d45f845 100644
--- a/widgets/table/e-table-field-chooser.c
+++ b/widgets/table/e-table-field-chooser.c
@@ -23,7 +23,7 @@
 #include <config.h>
 
 #include <gtk/gtk.h>
-#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
+#include <libfoocanvas/foo-canvas-rect-ellipse.h>
 
 #include <glib/gi18n.h>
 #include "e-util/e-util.h"
@@ -103,22 +103,22 @@ static void allocate_callback(GtkWidget *canvas, GtkAllocation *allocation, ETab
 {
 	double height;
 	etfc->last_alloc = *allocation;
-	gnome_canvas_item_set( etfc->item,
+	foo_canvas_item_set( etfc->item,
 			       "width", (double) allocation->width,
 			       NULL );
 	g_object_get(etfc->item,
 		     "height", &height,
 		     NULL);
 	height = MAX(height, allocation->height);
-	gnome_canvas_set_scroll_region(GNOME_CANVAS( etfc->canvas ), 0, 0, allocation->width - 1, height - 1);
-	gnome_canvas_item_set( etfc->rect,
+	foo_canvas_set_scroll_region(FOO_CANVAS( etfc->canvas ), 0, 0, allocation->width - 1, height - 1);
+	foo_canvas_item_set( etfc->rect,
 			       "x2", (double) allocation->width,
 			       "y2", (double) height,
 			       NULL );
 	ensure_nonzero_step_increments (etfc);
 }
 
-static void resize(GnomeCanvas *canvas, ETableFieldChooser *etfc)
+static void resize(FooCanvas *canvas, ETableFieldChooser *etfc)
 {
 	double height;
 	g_object_get(etfc->item,
@@ -127,8 +127,8 @@ static void resize(GnomeCanvas *canvas, ETableFieldChooser *etfc)
 
 	height = MAX(height, etfc->last_alloc.height);
 
-	gnome_canvas_set_scroll_region (GNOME_CANVAS(etfc->canvas), 0, 0, etfc->last_alloc.width - 1, height - 1);
-	gnome_canvas_item_set( etfc->rect,
+	foo_canvas_set_scroll_region (FOO_CANVAS(etfc->canvas), 0, 0, etfc->last_alloc.width - 1, height - 1);
+	foo_canvas_item_set( etfc->rect,
 			       "x2", (double) etfc->last_alloc.width,
 			       "y2", (double) height,
 			       NULL );
@@ -156,10 +156,10 @@ e_table_field_chooser_init (ETableFieldChooser *etfc)
 
 	gtk_widget_push_colormap (gdk_rgb_get_colormap ());
 
-	etfc->canvas = GNOME_CANVAS(glade_xml_get_widget(gui, "canvas-buttons"));
+	etfc->canvas = FOO_CANVAS(glade_xml_get_widget(gui, "canvas-buttons"));
 
-	etfc->rect = gnome_canvas_item_new(gnome_canvas_root( GNOME_CANVAS( etfc->canvas ) ),
-					   gnome_canvas_rect_get_type(),
+	etfc->rect = foo_canvas_item_new(foo_canvas_root( FOO_CANVAS( etfc->canvas ) ),
+					   foo_canvas_rect_get_type(),
 					   "x1", (double) 0,
 					   "y1", (double) 0,
 					   "x2", (double) 100,
@@ -167,7 +167,7 @@ e_table_field_chooser_init (ETableFieldChooser *etfc)
 					   "fill_color", "white",
 					   NULL );
 
-	etfc->item = gnome_canvas_item_new(gnome_canvas_root(etfc->canvas),
+	etfc->item = foo_canvas_item_new(foo_canvas_root(etfc->canvas),
 					   e_table_field_chooser_item_get_type(),
 					   "width", (double) 100,
 					   "full_header", etfc->full_header,
@@ -179,7 +179,7 @@ e_table_field_chooser_init (ETableFieldChooser *etfc)
 			  G_CALLBACK ( resize ),
 			  etfc);
 
-	gnome_canvas_set_scroll_region ( GNOME_CANVAS( etfc->canvas ),
+	foo_canvas_set_scroll_region ( FOO_CANVAS( etfc->canvas ),
 					 0, 0,
 					 100, 100 );
 
diff --git a/widgets/table/e-table-field-chooser.h b/widgets/table/e-table-field-chooser.h
index 996ae9f..2d57b51 100644
--- a/widgets/table/e-table-field-chooser.h
+++ b/widgets/table/e-table-field-chooser.h
@@ -53,10 +53,10 @@ struct _ETableFieldChooser
 
 	/* item specific fields */
 	GladeXML *gui;
-	GnomeCanvas *canvas;
-	GnomeCanvasItem *item;
+	FooCanvas *canvas;
+	FooCanvasItem *item;
 
-	GnomeCanvasItem *rect;
+	FooCanvasItem *rect;
 	GtkAllocation last_alloc;
 
 	gchar *dnd_code;
diff --git a/widgets/table/e-table-group-container.c b/widgets/table/e-table-group-container.c
index 43513dd..6b5912a 100644
--- a/widgets/table/e-table-group-container.c
+++ b/widgets/table/e-table-group-container.c
@@ -24,7 +24,7 @@
 
 #include <gtk/gtk.h>
 #include <gdk/gdkkeysyms.h>
-#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
+#include <libfoocanvas/foo-canvas-rect-ellipse.h>
 
 #include "text/e-text.h"
 #include <glib/gi18n.h>
@@ -127,7 +127,7 @@ etgc_dispose (GObject *object)
 
 /**
  * e_table_group_container_construct
- * @parent: The %GnomeCanvasGroup to create a child of.
+ * @parent: The %FooCanvasGroup to create a child of.
  * @etgc: The %ETableGroupContainer.
  * @full_header: The full header of the %ETable.
  * @header: The current header of the %ETable.
@@ -138,7 +138,7 @@ etgc_dispose (GObject *object)
  * This routine constructs the new %ETableGroupContainer.
  */
 void
-e_table_group_container_construct (GnomeCanvasGroup *parent, ETableGroupContainer *etgc,
+e_table_group_container_construct (FooCanvasGroup *parent, ETableGroupContainer *etgc,
 				   ETableHeader *full_header,
 				   ETableHeader     *header,
 				   ETableModel *model, ETableSortInfo *sort_info, gint n)
@@ -159,7 +159,7 @@ e_table_group_container_construct (GnomeCanvasGroup *parent, ETableGroupContaine
 	etgc->n = n;
 	etgc->ascending = column.ascending;
 
-	style = GTK_WIDGET (GNOME_CANVAS_ITEM (etgc)->canvas)->style;
+	style = GTK_WIDGET (FOO_CANVAS_ITEM (etgc)->canvas)->style;
 	etgc->font_desc = pango_font_description_copy (style->font_desc);
 
 	etgc->open = TRUE;
@@ -167,7 +167,7 @@ e_table_group_container_construct (GnomeCanvasGroup *parent, ETableGroupContaine
 
 /**
  * e_table_group_container_new
- * @parent: The %GnomeCanvasGroup to create a child of.
+ * @parent: The %FooCanvasGroup to create a child of.
  * @full_header: The full header of the %ETable.
  * @header: The current header of the %ETable.
  * @model: The %ETableModel of the %ETable.
@@ -181,7 +181,7 @@ e_table_group_container_construct (GnomeCanvasGroup *parent, ETableGroupContaine
  * Returns: The new %ETableGroupContainer.
  */
 ETableGroup *
-e_table_group_container_new (GnomeCanvasGroup *parent, ETableHeader *full_header,
+e_table_group_container_new (FooCanvasGroup *parent, ETableHeader *full_header,
 			     ETableHeader     *header,
 			     ETableModel *model, ETableSortInfo *sort_info, gint n)
 {
@@ -197,7 +197,7 @@ e_table_group_container_new (GnomeCanvasGroup *parent, ETableHeader *full_header
 }
 
 static gint
-etgc_event (GnomeCanvasItem *item, GdkEvent *event)
+etgc_event (FooCanvasItem *item, GdkEvent *event)
 {
 	ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER(item);
 	gboolean return_val = TRUE;
@@ -303,8 +303,8 @@ etgc_event (GnomeCanvasItem *item, GdkEvent *event)
 		break;
 	}
 	if (return_val == FALSE) {
-		if (GNOME_CANVAS_ITEM_CLASS(etgc_parent_class)->event)
-			return GNOME_CANVAS_ITEM_CLASS (etgc_parent_class)->event (item, event);
+		if (FOO_CANVAS_ITEM_CLASS(etgc_parent_class)->event)
+			return FOO_CANVAS_ITEM_CLASS (etgc_parent_class)->event (item, event);
 	}
 	return return_val;
 
@@ -312,24 +312,24 @@ etgc_event (GnomeCanvasItem *item, GdkEvent *event)
 
 /* Realize handler for the text item */
 static void
-etgc_realize (GnomeCanvasItem *item)
+etgc_realize (FooCanvasItem *item)
 {
 	ETableGroupContainer *etgc;
 
-	if (GNOME_CANVAS_ITEM_CLASS (etgc_parent_class)->realize)
-		(* GNOME_CANVAS_ITEM_CLASS (etgc_parent_class)->realize) (item);
+	if (FOO_CANVAS_ITEM_CLASS (etgc_parent_class)->realize)
+		(* FOO_CANVAS_ITEM_CLASS (etgc_parent_class)->realize) (item);
 
 	etgc = E_TABLE_GROUP_CONTAINER (item);
 
-	e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (etgc));
+	e_canvas_item_request_reflow (FOO_CANVAS_ITEM (etgc));
 }
 
 /* Unrealize handler for the etgc item */
 static void
-etgc_unrealize (GnomeCanvasItem *item)
+etgc_unrealize (FooCanvasItem *item)
 {
-	if (GNOME_CANVAS_ITEM_CLASS (etgc_parent_class)->unrealize)
-		(* GNOME_CANVAS_ITEM_CLASS (etgc_parent_class)->unrealize) (item);
+	if (FOO_CANVAS_ITEM_CLASS (etgc_parent_class)->unrealize)
+		(* FOO_CANVAS_ITEM_CLASS (etgc_parent_class)->unrealize) (item);
 }
 
 static void
@@ -350,7 +350,7 @@ compute_text (ETableGroupContainer *etgc, ETableGroupContainerChildNode *child_n
 					child_node->string,
 					(gint) child_node->count);
 	}
-	gnome_canvas_item_set (child_node->text,
+	foo_canvas_item_set (child_node->text,
 			       "text", text,
 			       NULL);
 	g_free (text);
@@ -413,20 +413,20 @@ create_child_node (ETableGroupContainer *etgc, gpointer val)
 	ETableGroup *etg = E_TABLE_GROUP(etgc);
 
 	child_node = g_new (ETableGroupContainerChildNode, 1);
-	child_node->rect = gnome_canvas_item_new (GNOME_CANVAS_GROUP (etgc),
-						  gnome_canvas_rect_get_type (),
+	child_node->rect = foo_canvas_item_new (FOO_CANVAS_GROUP (etgc),
+						  foo_canvas_rect_get_type (),
 						  "fill_color", "grey70",
 						  "outline_color", "grey50",
 						  NULL);
-	child_node->text = gnome_canvas_item_new (GNOME_CANVAS_GROUP (etgc),
+	child_node->text = foo_canvas_item_new (FOO_CANVAS_GROUP (etgc),
 						  e_text_get_type (),
 						  "anchor", GTK_ANCHOR_SW,
 						  "fill_color", "black",
 						  "draw_background", FALSE,
 						  NULL);
-	child = e_table_group_new (GNOME_CANVAS_GROUP (etgc), etg->full_header,
+	child = e_table_group_new (FOO_CANVAS_GROUP (etgc), etg->full_header,
 				   etg->header, etg->model, etgc->sort_info, etgc->n + 1);
-	gnome_canvas_item_set(GNOME_CANVAS_ITEM(child),
+	foo_canvas_item_set(FOO_CANVAS_ITEM(child),
 			      "alternating_row_colors", etgc->alternating_row_colors,
 			      "horizontal_draw_grid", etgc->horizontal_draw_grid,
 			      "vertical_draw_grid", etgc->vertical_draw_grid,
@@ -498,7 +498,7 @@ etgc_add (ETableGroup *etg, gint row)
 		etgc->children = g_list_append (etgc->children, child_node);
 
 	compute_text (etgc, child_node);
-	e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (etgc));
+	e_canvas_item_request_reflow (FOO_CANVAS_ITEM (etgc));
 }
 
 static void
@@ -548,7 +548,7 @@ etgc_add_array (ETableGroup *etg, const gint *array, gint count)
 	etgc->children = g_list_append (etgc->children, child_node);
 	compute_text (etgc, child_node);
 
-	e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (etgc));
+	e_canvas_item_request_reflow (FOO_CANVAS_ITEM (etgc));
 }
 
 static void
@@ -583,7 +583,7 @@ etgc_remove (ETableGroup *etg, gint row)
 			} else
 				compute_text (etgc, child_node);
 
-			e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (etgc));
+			e_canvas_item_request_reflow (FOO_CANVAS_ITEM (etgc));
 
 			return TRUE;
 		}
@@ -745,7 +745,7 @@ etgc_get_cell_geometry (ETableGroup *etg, gint *row, gint *col, gint *x, gint *y
 
 static void etgc_thaw (ETableGroup *etg)
 {
-	e_canvas_item_request_reflow (GNOME_CANVAS_ITEM(etg));
+	e_canvas_item_request_reflow (FOO_CANVAS_ITEM(etg));
 }
 
 static void
@@ -893,7 +893,7 @@ etgc_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *ps
 static void
 etgc_class_init (ETableGroupContainerClass *klass)
 {
-	GnomeCanvasItemClass *item_class = GNOME_CANVAS_ITEM_CLASS (klass);
+	FooCanvasItemClass *item_class = FOO_CANVAS_ITEM_CLASS (klass);
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 	ETableGroupClass *e_group_class = E_TABLE_GROUP_CLASS (klass);
 
@@ -1005,7 +1005,7 @@ etgc_class_init (ETableGroupContainerClass *klass)
 }
 
 static void
-etgc_reflow (GnomeCanvasItem *item, gint flags)
+etgc_reflow (FooCanvasItem *item, gint flags)
 {
 	ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER(item);
 	gboolean frozen;
@@ -1017,7 +1017,7 @@ etgc_reflow (GnomeCanvasItem *item, gint flags)
 	if (frozen)
 		return;
 
-	if (GTK_OBJECT_FLAGS(etgc)& GNOME_CANVAS_ITEM_REALIZED) {
+	if (GTK_OBJECT_FLAGS(etgc)& FOO_CANVAS_ITEM_REALIZED) {
 		gdouble running_height = 0;
 		gdouble running_width = 0;
 		gdouble old_height;
@@ -1067,15 +1067,15 @@ etgc_reflow (GnomeCanvasItem *item, gint flags)
 					      "height", &item_height,
 					      NULL);
 
-				e_canvas_item_move_absolute (GNOME_CANVAS_ITEM(child_node->text),
+				e_canvas_item_move_absolute (FOO_CANVAS_ITEM(child_node->text),
 							    GROUP_INDENT,
 							    running_height - BUTTON_PADDING);
 
-				e_canvas_item_move_absolute (GNOME_CANVAS_ITEM(child),
+				e_canvas_item_move_absolute (FOO_CANVAS_ITEM(child),
 							    GROUP_INDENT,
 							    running_height);
 
-				gnome_canvas_item_set (GNOME_CANVAS_ITEM(child_node->rect),
+				foo_canvas_item_set (FOO_CANVAS_ITEM(child_node->rect),
 						      "x1", (double) 0,
 						      "x2", (double) running_width + GROUP_INDENT,
 						      "y1", (double) running_height - extra_height,
@@ -1099,7 +1099,7 @@ etgc_init (ETableGroupContainer *container)
 {
 	container->children = NULL;
 
-	e_canvas_item_set_reflow_callback (GNOME_CANVAS_ITEM(container), etgc_reflow);
+	e_canvas_item_set_reflow_callback (FOO_CANVAS_ITEM(container), etgc_reflow);
 
 	container->alternating_row_colors = 1;
 	container->horizontal_draw_grid = 1;
diff --git a/widgets/table/e-table-group-container.h b/widgets/table/e-table-group-container.h
index 911b7f3..4215dbb 100644
--- a/widgets/table/e-table-group-container.h
+++ b/widgets/table/e-table-group-container.h
@@ -24,7 +24,7 @@
 #ifndef _E_TABLE_GROUP_CONTAINER_H_
 #define _E_TABLE_GROUP_CONTAINER_H_
 
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 #include <table/e-table-model.h>
 #include <table/e-table-header.h>
 #include <table/e-table-group.h>
@@ -55,7 +55,7 @@ typedef struct {
 	/*
 	 * The canvas rectangle that contains the children
 	 */
-	GnomeCanvasItem *rect;
+	FooCanvasItem *rect;
 
 	PangoFontDescription *font_desc;
 
@@ -88,14 +88,14 @@ typedef struct {
         ETableGroup *child;
         gpointer key;
         gchar *string;
-        GnomeCanvasItem *text;
-        GnomeCanvasItem *rect;
+        FooCanvasItem *text;
+        FooCanvasItem *rect;
         gint count;
 } ETableGroupContainerChildNode;
 
-ETableGroup *e_table_group_container_new       (GnomeCanvasGroup *parent, ETableHeader *full_header, ETableHeader     *header,
+ETableGroup *e_table_group_container_new       (FooCanvasGroup *parent, ETableHeader *full_header, ETableHeader     *header,
 						ETableModel *model, ETableSortInfo *sort_info, gint n);
-void         e_table_group_container_construct (GnomeCanvasGroup *parent, ETableGroupContainer *etgc,
+void         e_table_group_container_construct (FooCanvasGroup *parent, ETableGroupContainer *etgc,
 						ETableHeader *full_header,
 						ETableHeader     *header,
 						ETableModel *model, ETableSortInfo *sort_info, gint n);
diff --git a/widgets/table/e-table-group-leaf.c b/widgets/table/e-table-group-leaf.c
index 61d357a..6b8a94a 100644
--- a/widgets/table/e-table-group-leaf.c
+++ b/widgets/table/e-table-group-leaf.c
@@ -24,7 +24,7 @@
 #include <config.h>
 
 #include <gtk/gtk.h>
-#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
+#include <libfoocanvas/foo-canvas-rect-ellipse.h>
 
 #include <glib/gi18n.h>
 #include "e-util/e-util.h"
@@ -111,7 +111,7 @@ etgl_dispose (GObject *object)
 }
 
 static void
-e_table_group_leaf_construct (GnomeCanvasGroup *parent,
+e_table_group_leaf_construct (FooCanvasGroup *parent,
 			      ETableGroupLeaf  *etgl,
 			      ETableHeader     *full_header,
 			      ETableHeader     *header,
@@ -134,7 +134,7 @@ e_table_group_leaf_construct (GnomeCanvasGroup *parent,
 
 /**
  * e_table_group_leaf_new
- * @parent: The %GnomeCanvasGroup to create a child of.
+ * @parent: The %FooCanvasGroup to create a child of.
  * @full_header: The full header of the %ETable.
  * @header: The current header of the %ETable.
  * @model: The %ETableModel of the %ETable.
@@ -146,7 +146,7 @@ e_table_group_leaf_construct (GnomeCanvasGroup *parent,
  * Returns: The new %ETableGroupLeaf.
  */
 ETableGroup *
-e_table_group_leaf_new       (GnomeCanvasGroup *parent,
+e_table_group_leaf_new       (FooCanvasGroup *parent,
 			      ETableHeader     *full_header,
 			      ETableHeader     *header,
 			      ETableModel      *model,
@@ -231,7 +231,7 @@ etgl_click (GtkObject *object, gint row, gint col, GdkEvent *event, ETableGroupL
 }
 
 static void
-etgl_reflow (GnomeCanvasItem *item, gint flags)
+etgl_reflow (FooCanvasItem *item, gint flags)
 {
 	ETableGroupLeaf *leaf = E_TABLE_GROUP_LEAF(item);
 
@@ -246,15 +246,15 @@ etgl_reflow (GnomeCanvasItem *item, gint flags)
 }
 
 static void
-etgl_realize (GnomeCanvasItem *item)
+etgl_realize (FooCanvasItem *item)
 {
 	ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF(item);
 
-	if (GNOME_CANVAS_ITEM_CLASS (etgl_parent_class)->realize)
-		GNOME_CANVAS_ITEM_CLASS (etgl_parent_class)->realize (item);
+	if (FOO_CANVAS_ITEM_CLASS (etgl_parent_class)->realize)
+		FOO_CANVAS_ITEM_CLASS (etgl_parent_class)->realize (item);
 
-	etgl->item = E_TABLE_ITEM(gnome_canvas_item_new (
-		GNOME_CANVAS_GROUP(etgl),
+	etgl->item = E_TABLE_ITEM(foo_canvas_item_new (
+		FOO_CANVAS_GROUP(etgl),
 		e_table_item_get_type (),
 		"ETableHeader", E_TABLE_GROUP(etgl)->header,
 		"ETableModel", etgl->ets,
@@ -442,7 +442,7 @@ etgl_set_property (GObject *object, guint prop_id, const GValue *value, GParamSp
 	case PROP_WIDTH:
 		etgl->minimum_width = g_value_get_double (value);
 		if (etgl->item) {
-			gnome_canvas_item_set (GNOME_CANVAS_ITEM(etgl->item),
+			foo_canvas_item_set (FOO_CANVAS_ITEM(etgl->item),
 					       "minimum_width", etgl->minimum_width,
 					       NULL);
 		}
@@ -450,7 +450,7 @@ etgl_set_property (GObject *object, guint prop_id, const GValue *value, GParamSp
 	case PROP_LENGTH_THRESHOLD:
 		etgl->length_threshold = g_value_get_int (value);
 		if (etgl->item) {
-			gnome_canvas_item_set (GNOME_CANVAS_ITEM(etgl->item),
+			foo_canvas_item_set (FOO_CANVAS_ITEM(etgl->item),
 					       "length_threshold", etgl->length_threshold,
 					       NULL);
 		}
@@ -463,7 +463,7 @@ etgl_set_property (GObject *object, guint prop_id, const GValue *value, GParamSp
 			g_object_ref(etgl->selection_model);
 		}
 		if (etgl->item) {
-			gnome_canvas_item_set (GNOME_CANVAS_ITEM(etgl->item),
+			foo_canvas_item_set (FOO_CANVAS_ITEM(etgl->item),
 					       "selection_model", etgl->selection_model,
 					       NULL);
 		}
@@ -472,7 +472,7 @@ etgl_set_property (GObject *object, guint prop_id, const GValue *value, GParamSp
 	case PROP_UNIFORM_ROW_HEIGHT:
 		etgl->uniform_row_height = g_value_get_boolean (value);
 		if (etgl->item) {
-			gnome_canvas_item_set (GNOME_CANVAS_ITEM(etgl->item),
+			foo_canvas_item_set (FOO_CANVAS_ITEM(etgl->item),
 					       "uniform_row_height", etgl->uniform_row_height,
 					       NULL);
 		}
@@ -481,7 +481,7 @@ etgl_set_property (GObject *object, guint prop_id, const GValue *value, GParamSp
 	case PROP_TABLE_ALTERNATING_ROW_COLORS:
 		etgl->alternating_row_colors = g_value_get_boolean (value);
 		if (etgl->item) {
-			gnome_canvas_item_set (GNOME_CANVAS_ITEM(etgl->item),
+			foo_canvas_item_set (FOO_CANVAS_ITEM(etgl->item),
 					       "alternating_row_colors", etgl->alternating_row_colors,
 					       NULL);
 		}
@@ -490,7 +490,7 @@ etgl_set_property (GObject *object, guint prop_id, const GValue *value, GParamSp
 	case PROP_TABLE_HORIZONTAL_DRAW_GRID:
 		etgl->horizontal_draw_grid = g_value_get_boolean (value);
 		if (etgl->item) {
-			gnome_canvas_item_set (GNOME_CANVAS_ITEM(etgl->item),
+			foo_canvas_item_set (FOO_CANVAS_ITEM(etgl->item),
 					       "horizontal_draw_grid", etgl->horizontal_draw_grid,
 					       NULL);
 		}
@@ -499,7 +499,7 @@ etgl_set_property (GObject *object, guint prop_id, const GValue *value, GParamSp
 	case PROP_TABLE_VERTICAL_DRAW_GRID:
 		etgl->vertical_draw_grid = g_value_get_boolean (value);
 		if (etgl->item) {
-			gnome_canvas_item_set (GNOME_CANVAS_ITEM(etgl->item),
+			foo_canvas_item_set (FOO_CANVAS_ITEM(etgl->item),
 					       "vertical_draw_grid", etgl->vertical_draw_grid,
 					       NULL);
 		}
@@ -508,7 +508,7 @@ etgl_set_property (GObject *object, guint prop_id, const GValue *value, GParamSp
 	case PROP_TABLE_DRAW_FOCUS:
 		etgl->draw_focus = g_value_get_boolean (value);
 		if (etgl->item) {
-			gnome_canvas_item_set (GNOME_CANVAS_ITEM(etgl->item),
+			foo_canvas_item_set (FOO_CANVAS_ITEM(etgl->item),
 					       "drawfocus", etgl->draw_focus,
 					       NULL);
 		}
@@ -517,7 +517,7 @@ etgl_set_property (GObject *object, guint prop_id, const GValue *value, GParamSp
 	case PROP_CURSOR_MODE:
 		etgl->cursor_mode = g_value_get_int (value);
 		if (etgl->item) {
-			gnome_canvas_item_set (GNOME_CANVAS_ITEM(etgl->item),
+			foo_canvas_item_set (FOO_CANVAS_ITEM(etgl->item),
 					       "cursor_mode", etgl->cursor_mode,
 					       NULL);
 		}
@@ -557,7 +557,7 @@ etgl_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *ps
 static void
 etgl_class_init (ETableGroupLeafClass *klass)
 {
-	GnomeCanvasItemClass *item_class = GNOME_CANVAS_ITEM_CLASS (klass);
+	FooCanvasItemClass *item_class = FOO_CANVAS_ITEM_CLASS (klass);
 	ETableGroupClass *e_group_class = E_TABLE_GROUP_CLASS (klass);
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
@@ -694,6 +694,6 @@ etgl_init (ETableGroupLeaf *etgl)
 	etgl->selection_model = NULL;
 	etgl->uniform_row_height = FALSE;
 
-	e_canvas_item_set_reflow_callback (GNOME_CANVAS_ITEM (etgl), etgl_reflow);
+	e_canvas_item_set_reflow_callback (FOO_CANVAS_ITEM (etgl), etgl_reflow);
 }
 
diff --git a/widgets/table/e-table-group-leaf.h b/widgets/table/e-table-group-leaf.h
index d34f034..744bb9d 100644
--- a/widgets/table/e-table-group-leaf.h
+++ b/widgets/table/e-table-group-leaf.h
@@ -24,7 +24,7 @@
 #ifndef _E_TABLE_GROUP_LEAF_H_
 #define _E_TABLE_GROUP_LEAF_H_
 
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 #include <table/e-table-group.h>
 #include <table/e-table-subset.h>
 #include <table/e-table-item.h>
@@ -76,7 +76,7 @@ typedef struct {
 	ETableGroupClass parent_class;
 } ETableGroupLeafClass;
 
-ETableGroup *e_table_group_leaf_new       (GnomeCanvasGroup *parent,
+ETableGroup *e_table_group_leaf_new       (FooCanvasGroup *parent,
 					   ETableHeader *full_header,
 					   ETableHeader     *header,
 					   ETableModel *model,
diff --git a/widgets/table/e-table-group.c b/widgets/table/e-table-group.c
index ebf8616..8754f18 100644
--- a/widgets/table/e-table-group.c
+++ b/widgets/table/e-table-group.c
@@ -23,7 +23,7 @@
 #include <config.h>
 
 #include <gtk/gtk.h>
-#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
+#include <libfoocanvas/foo-canvas-rect-ellipse.h>
 
 #include "e-util/e-util.h"
 
@@ -34,7 +34,7 @@
 
 /* workaround for avoiding API breakage*/
 #define etg_get_type e_table_group_get_type
-G_DEFINE_TYPE (ETableGroup, etg, GNOME_TYPE_CANVAS_GROUP)
+G_DEFINE_TYPE (ETableGroup, etg, FOO_TYPE_CANVAS_GROUP)
 
 #define ETG_CLASS(e) (E_TABLE_GROUP_CLASS(GTK_OBJECT_GET_CLASS(e)))
 
@@ -79,7 +79,7 @@ etg_dispose (GObject *object)
 
 /**
  * e_table_group_new
- * @parent: The %GnomeCanvasGroup to create a child of.
+ * @parent: The %FooCanvasGroup to create a child of.
  * @full_header: The full header of the %ETable.
  * @header: The current header of the %ETable.
  * @model: The %ETableModel of the %ETable.
@@ -87,7 +87,7 @@ etg_dispose (GObject *object)
  * @n: The grouping information object to group by.
  *
  * %ETableGroup is a collection of rows of an %ETable.  It's a
- * %GnomeCanvasItem.  There are two different forms.  If n < the
+ * %FooCanvasItem.  There are two different forms.  If n < the
  * number of groupings in the given %ETableSortInfo, then the
  * %ETableGroup will need to contain other %ETableGroups, thus it
  * creates an %ETableGroupContainer.  Otherwise, it will just contain
@@ -96,7 +96,7 @@ etg_dispose (GObject *object)
  * Returns: The new %ETableGroup.
  */
 ETableGroup *
-e_table_group_new (GnomeCanvasGroup *parent,
+e_table_group_new (FooCanvasGroup *parent,
 		   ETableHeader     *full_header,
 		   ETableHeader     *header,
 		   ETableModel      *model,
@@ -114,7 +114,7 @@ e_table_group_new (GnomeCanvasGroup *parent,
 
 /**
  * e_table_group_construct
- * @parent: The %GnomeCanvasGroup to create a child of.
+ * @parent: The %FooCanvasGroup to create a child of.
  * @etg: The %ETableGroup to construct.
  * @full_header: The full header of the %ETable.
  * @header: The current header of the %ETable.
@@ -123,7 +123,7 @@ e_table_group_new (GnomeCanvasGroup *parent,
  * This routine does the base construction of the %ETableGroup.
  */
 void
-e_table_group_construct (GnomeCanvasGroup *parent,
+e_table_group_construct (FooCanvasGroup *parent,
 			 ETableGroup      *etg,
 			 ETableHeader     *full_header,
 			 ETableHeader     *header,
@@ -591,7 +591,7 @@ e_table_group_get_header (ETableGroup *etg)
 }
 
 static gint
-etg_event (GnomeCanvasItem *item, GdkEvent *event)
+etg_event (FooCanvasItem *item, GdkEvent *event)
 {
 	ETableGroup *etg = E_TABLE_GROUP (item);
 	gboolean return_val = TRUE;
@@ -606,8 +606,8 @@ etg_event (GnomeCanvasItem *item, GdkEvent *event)
 		return_val = FALSE;
 	}
 	if (return_val == FALSE) {
-		if (GNOME_CANVAS_ITEM_CLASS(etg_parent_class)->event)
-			return GNOME_CANVAS_ITEM_CLASS(etg_parent_class)->event (item, event);
+		if (FOO_CANVAS_ITEM_CLASS(etg_parent_class)->event)
+			return FOO_CANVAS_ITEM_CLASS(etg_parent_class)->event (item, event);
 	}
 	return return_val;
 
@@ -622,7 +622,7 @@ etg_get_focus (ETableGroup      *etg)
 static void
 etg_class_init (ETableGroupClass *klass)
 {
-	GnomeCanvasItemClass *item_class = GNOME_CANVAS_ITEM_CLASS (klass);
+	FooCanvasItemClass *item_class = FOO_CANVAS_ITEM_CLASS (klass);
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
 	object_class->dispose = etg_dispose;
diff --git a/widgets/table/e-table-group.h b/widgets/table/e-table-group.h
index 7bf139e..36732d9 100644
--- a/widgets/table/e-table-group.h
+++ b/widgets/table/e-table-group.h
@@ -24,7 +24,7 @@
 #ifndef _E_TABLE_GROUP_H_
 #define _E_TABLE_GROUP_H_
 
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 #include <table/e-table-model.h>
 #include <table/e-table-header.h>
 #include <table/e-table-sort-info.h>
@@ -41,7 +41,7 @@ G_BEGIN_DECLS
 #define E_IS_TABLE_GROUP_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TABLE_GROUP_TYPE))
 
 typedef struct {
-	GnomeCanvasGroup group;
+	FooCanvasGroup group;
 
 	/*
 	 * The full header.
@@ -66,7 +66,7 @@ typedef struct {
 } ETableGroup;
 
 typedef struct {
-	GnomeCanvasGroupClass parent_class;
+	FooCanvasGroupClass parent_class;
 
 	/* Signals */
 	void        (*cursor_change)         (ETableGroup *etg, gint row);
@@ -133,13 +133,13 @@ void          e_table_group_get_cell_geometry (ETableGroup       *etg,
 					       gint               *y,
 					       gint               *width,
 					       gint               *height);
-ETableGroup  *e_table_group_new               (GnomeCanvasGroup  *parent,
+ETableGroup  *e_table_group_new               (FooCanvasGroup  *parent,
 					       ETableHeader      *full_header,
 					       ETableHeader      *header,
 					       ETableModel       *model,
 					       ETableSortInfo    *sort_info,
 					       gint                n);
-void          e_table_group_construct         (GnomeCanvasGroup  *parent,
+void          e_table_group_construct         (FooCanvasGroup  *parent,
 					       ETableGroup       *etg,
 					       ETableHeader      *full_header,
 					       ETableHeader      *header,
diff --git a/widgets/table/e-table-header-item.c b/widgets/table/e-table-header-item.c
index d5a02f4..b77990e 100644
--- a/widgets/table/e-table-header-item.c
+++ b/widgets/table/e-table-header-item.c
@@ -27,10 +27,10 @@
 #include <glib.h>
 
 #include <gtk/gtk.h>
-#include <libgnomecanvas/gnome-canvas.h>
-#include <libgnomecanvas/gnome-canvas-util.h>
-#include <libgnomecanvas/gnome-canvas-polygon.h>
-#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
+#include <libfoocanvas/foo-canvas.h>
+#include <libfoocanvas/foo-canvas-util.h>
+#include <libfoocanvas/foo-canvas-polygon.h>
+#include <libfoocanvas/foo-canvas-rect-ellipse.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <gdk/gdkkeysyms.h>
 
@@ -41,6 +41,7 @@
 #include "misc/e-cursors.h"
 #include "misc/e-gui-utils.h"
 #include "misc/e-popup-menu.h"
+#include "libfoocanvas/libart-types.h"
 
 #include "e-table.h"
 #include "e-table-col-dnd.h"
@@ -73,7 +74,7 @@ static guint ethi_signals [LAST_SIGNAL] = { 0, };
 #define ETHI_RESIZING(x) ((x)->resize_col != -1)
 
 #define ethi_get_type e_table_header_item_get_type
-G_DEFINE_TYPE (ETableHeaderItem, ethi, GNOME_TYPE_CANVAS_ITEM)
+G_DEFINE_TYPE (ETableHeaderItem, ethi, FOO_TYPE_CANVAS_ITEM)
 
 #define ELEMENTS(x) (sizeof (x) / sizeof (x[0]))
 #define d(x)
@@ -171,7 +172,7 @@ e_table_header_item_get_height (ETableHeaderItem *ethi)
 		gint height;
 
 		height = e_table_header_compute_height (ecol,
-							GTK_WIDGET (GNOME_CANVAS_ITEM (ethi)->canvas));
+							GTK_WIDGET (FOO_CANVAS_ITEM (ethi)->canvas));
 
 		if (height > maxheight)
 			maxheight = height;
@@ -181,15 +182,15 @@ e_table_header_item_get_height (ETableHeaderItem *ethi)
 }
 
 static void
-ethi_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, gint flags)
+ethi_update (FooCanvasItem *item, double i2w_dx, double i2w_dy, gint flags)
 {
 	ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item);
 
 	double   i2c [6];
 	ArtPoint c1, c2, i1, i2;
 
-	if (GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->update)
-		(*GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->update)(item, affine, clip_path, flags);
+	if (FOO_CANVAS_ITEM_CLASS (ethi_parent_class)->update)
+		(*FOO_CANVAS_ITEM_CLASS (ethi_parent_class)->update)(item, i2w_dx, i2w_dy, flags);
 
 	if (ethi->sort_info)
 		ethi->group_indent_width = e_table_sort_info_grouping_get_count(ethi->sort_info) * GROUP_INDENT;
@@ -202,7 +203,7 @@ ethi_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, gint flag
 	i2.x = ethi->width;
 	i2.y = ethi->height;
 
-	gnome_canvas_item_i2c_affine (item, i2c);
+	foo_canvas_item_i2c_affine (item, i2c);
 	art_affine_point (&c1, &i1, i2c);
 	art_affine_point (&c2, &i2, i2c);
 
@@ -211,17 +212,17 @@ ethi_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, gint flag
 	    item->x2 != c2.x ||
 	    item->y2 != c2.y)
 		{
-			gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2);
+			foo_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2);
 			item->x1 = c1.x;
 			item->y1 = c1.y;
 			item->x2 = c2.x;
 			item->y2 = c2.y;
 /* FIXME: Group Child bounds !? (FOO BAA) */
 #if 0
-			gnome_canvas_group_child_bounds (GNOME_CANVAS_GROUP (item->parent), item);
+			foo_canvas_group_child_bounds (FOO_CANVAS_GROUP (item->parent), item);
 #endif
 		}
-	gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2);
+	foo_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2);
 }
 
 static void
@@ -233,7 +234,7 @@ ethi_font_set (ETableHeaderItem *ethi, PangoFontDescription *font_desc)
 	ethi->font_desc = pango_font_description_copy (font_desc);
 
 	ethi->height = e_table_header_item_get_height (ethi);
-	e_canvas_item_request_reflow(GNOME_CANVAS_ITEM(ethi));
+	e_canvas_item_request_reflow(FOO_CANVAS_ITEM(ethi));
 }
 
 static void
@@ -256,13 +257,13 @@ ethi_drop_table_header (ETableHeaderItem *ethi)
 static void
 structure_changed (ETableHeader *header, ETableHeaderItem *ethi)
 {
-	gnome_canvas_item_request_update(GNOME_CANVAS_ITEM(ethi));
+	foo_canvas_item_request_update(FOO_CANVAS_ITEM(ethi));
 }
 
 static void
 dimension_changed (ETableHeader *header, gint col, ETableHeaderItem *ethi)
 {
-	gnome_canvas_item_request_update(GNOME_CANVAS_ITEM(ethi));
+	foo_canvas_item_request_update(FOO_CANVAS_ITEM(ethi));
 }
 
 static void
@@ -279,14 +280,14 @@ ethi_add_table_header (ETableHeaderItem *ethi, ETableHeader *header)
 	ethi->dimension_change_id = g_signal_connect (
 		header, "dimension_change",
 		G_CALLBACK (dimension_changed), ethi);
-	e_canvas_item_request_reflow(GNOME_CANVAS_ITEM(ethi));
-	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM(ethi));
+	e_canvas_item_request_reflow(FOO_CANVAS_ITEM(ethi));
+	foo_canvas_item_request_update (FOO_CANVAS_ITEM(ethi));
 }
 
 static void
 ethi_sort_info_changed (ETableSortInfo *sort_info, ETableHeaderItem *ethi)
 {
-	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM(ethi));
+	foo_canvas_item_request_update (FOO_CANVAS_ITEM(ethi));
 }
 
 static void
@@ -295,10 +296,10 @@ ethi_set_property (GObject *object,
 		   const GValue *value,
 		   GParamSpec *pspec)
 {
-	GnomeCanvasItem *item;
+	FooCanvasItem *item;
 	ETableHeaderItem *ethi;
 
-	item = GNOME_CANVAS_ITEM (object);
+	item = FOO_CANVAS_ITEM (object);
 	ethi = E_TABLE_HEADER_ITEM (object);
 
 	switch (prop_id) {
@@ -361,7 +362,7 @@ ethi_set_property (GObject *object,
 			ethi->tree = NULL;
 		break;
 	}
-	gnome_canvas_item_request_update(item);
+	foo_canvas_item_request_update(item);
 }
 
 static void
@@ -503,11 +504,11 @@ ethi_add_drop_marker (ETableHeaderItem *ethi, gint col, gboolean recreate)
 	}
 
 	gdk_window_get_origin (
-		GTK_WIDGET (GNOME_CANVAS_ITEM (ethi)->canvas)->window,
+		GTK_WIDGET (FOO_CANVAS_ITEM (ethi)->canvas)->window,
 		&rx, &ry);
 
-	rx -= gtk_layout_get_hadjustment (GTK_LAYOUT (GNOME_CANVAS_ITEM (ethi)->canvas))->value;
-	ry -= gtk_layout_get_vadjustment (GTK_LAYOUT (GNOME_CANVAS_ITEM (ethi)->canvas))->value;
+	rx -= gtk_layout_get_hadjustment (GTK_LAYOUT (FOO_CANVAS_ITEM (ethi)->canvas))->value;
+	ry -= gtk_layout_get_vadjustment (GTK_LAYOUT (FOO_CANVAS_ITEM (ethi)->canvas))->value;
 
 	gtk_window_move (GTK_WINDOW (arrow_down), rx + x - ARROW_PTR, ry - ARROW_DOWN_HEIGHT);
 	gtk_widget_show_all (arrow_down);
@@ -537,9 +538,9 @@ ethi_add_destroy_marker (ETableHeaderItem *ethi)
 	if (ethi->drag_col > 0)
 		x1 += ethi->group_indent_width;
 
-	ethi->remove_item = gnome_canvas_item_new (
-		GNOME_CANVAS_GROUP (GNOME_CANVAS_ITEM (ethi)->canvas->root),
-		gnome_canvas_rect_get_type (),
+	ethi->remove_item = foo_canvas_item_new (
+		FOO_CANVAS_GROUP (FOO_CANVAS_ITEM (ethi)->canvas->root),
+		foo_canvas_rect_get_type (),
 		"x1", x1 + 1,
 		"y1", (double) 1,
 		"x2", (double) x1 + e_table_header_col_diff (
@@ -635,8 +636,8 @@ scroll_timeout (gpointer data)
 	if (ethi->scroll_direction & ET_SCROLL_LEFT)
 		dx -= 20;
 
-	h = GTK_LAYOUT(GNOME_CANVAS_ITEM (ethi)->canvas)->hadjustment;
-	v = GTK_LAYOUT(GNOME_CANVAS_ITEM (ethi)->canvas)->vadjustment;
+	h = GTK_LAYOUT(FOO_CANVAS_ITEM (ethi)->canvas)->hadjustment;
+	v = GTK_LAYOUT(FOO_CANVAS_ITEM (ethi)->canvas)->vadjustment;
 
 	value = h->value;
 
@@ -750,7 +751,7 @@ ethi_drag_end (GtkWidget *canvas, GdkDragContext *context, ETableHeaderItem *eth
 {
 	if (context->action == 0) {
 		e_table_header_remove (ethi->eth, ethi->drag_col);
-		gnome_canvas_item_request_update(GNOME_CANVAS_ITEM(ethi));
+		foo_canvas_item_request_update(FOO_CANVAS_ITEM(ethi));
 	}
 	ethi_remove_drop_marker (ethi);
 	ethi_remove_destroy_marker (ethi);
@@ -802,7 +803,7 @@ ethi_drag_data_received (GtkWidget *canvas,
 		}
 	}
 	ethi_remove_drop_marker (ethi);
-	gnome_canvas_item_request_update(GNOME_CANVAS_ITEM(ethi));
+	foo_canvas_item_request_update(FOO_CANVAS_ITEM(ethi));
 }
 
 static void
@@ -867,15 +868,15 @@ ethi_drag_leave (GtkWidget *widget, GdkDragContext *context, guint time, ETableH
 }
 
 static void
-ethi_realize (GnomeCanvasItem *item)
+ethi_realize (FooCanvasItem *item)
 {
 	ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item);
 	GtkTargetEntry  ethi_drop_types [] = {
 		{ (gchar *) TARGET_ETABLE_COL_TYPE, 0, TARGET_ETABLE_COL_HEADER },
 	};
 
-	if (GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)-> realize)
-		(*GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->realize)(item);
+	if (FOO_CANVAS_ITEM_CLASS (ethi_parent_class)-> realize)
+		(*FOO_CANVAS_ITEM_CLASS (ethi_parent_class)->realize)(item);
 
 	if (!ethi->font_desc)
 		ethi_font_set (ethi, GTK_WIDGET (item->canvas)->style->font_desc);
@@ -908,7 +909,7 @@ ethi_realize (GnomeCanvasItem *item)
 }
 
 static void
-ethi_unrealize (GnomeCanvasItem *item)
+ethi_unrealize (FooCanvasItem *item)
 {
 	ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item);
 
@@ -932,20 +933,26 @@ ethi_unrealize (GnomeCanvasItem *item)
 		ethi->stipple = NULL;
 	}
 
-	if (GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->unrealize)
-		(*GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->unrealize)(item);
+	if (FOO_CANVAS_ITEM_CLASS (ethi_parent_class)->unrealize)
+		(*FOO_CANVAS_ITEM_CLASS (ethi_parent_class)->unrealize)(item);
 }
 
 static void
-ethi_draw (GnomeCanvasItem *item, GdkDrawable *drawable, gint x, gint y, gint width, gint height)
+ethi_draw (FooCanvasItem *item, GdkDrawable *drawable, GdkEventExpose *expose)
 {
 	ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item);
-	GnomeCanvas *canvas = item->canvas;
+	FooCanvas *canvas = item->canvas;
 	const gint cols = e_table_header_count (ethi->eth);
 	gint x1, x2;
 	gint col;
+	gint x, y, width, height;
 	GHashTable *arrows = g_hash_table_new (NULL, NULL);
 
+	x = expose->area.x;
+	y = expose->area.y;
+	width = expose->area.width;
+	height = expose->area.height;
+
 	if (ethi->sort_info) {
 		gint length = e_table_sort_info_grouping_get_count(ethi->sort_info);
 		gint i;
@@ -1003,8 +1010,8 @@ ethi_draw (GnomeCanvasItem *item, GdkDrawable *drawable, gint x, gint y, gint wi
 }
 
 static double
-ethi_point (GnomeCanvasItem *item, double x, double y, gint cx, gint cy,
-	    GnomeCanvasItem **actual_item)
+ethi_point (FooCanvasItem *item, double x, double y, gint cx, gint cy,
+	    FooCanvasItem **actual_item)
 {
 	*actual_item = item;
 	return 0.0;
@@ -1050,13 +1057,13 @@ is_pointer_on_division (ETableHeaderItem *ethi, gint pos, gint *the_total, gint
 	return FALSE;
 }
 
-#define convert(c,sx,sy,x,y) gnome_canvas_w2c (c,sx,sy,x,y)
+#define convert(c,sx,sy,x,y) foo_canvas_w2c (c,sx,sy,x,y)
 
 static void
 set_cursor (ETableHeaderItem *ethi, gint pos)
 {
 	gint col;
-	GtkWidget *canvas = GTK_WIDGET (GNOME_CANVAS_ITEM (ethi)->canvas);
+	GtkWidget *canvas = GTK_WIDGET (FOO_CANVAS_ITEM (ethi)->canvas);
 	gboolean resizable = FALSE;
 
 	/* We might be invoked before we are realized */
@@ -1098,7 +1105,7 @@ ethi_end_resize (ETableHeaderItem *ethi)
 	ethi->resize_col = -1;
 	ethi->resize_guide = GINT_TO_POINTER (0);
 
-	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM(ethi));
+	foo_canvas_item_request_update (FOO_CANVAS_ITEM(ethi));
 }
 
 static gboolean
@@ -1122,7 +1129,7 @@ ethi_maybe_start_drag (ETableHeaderItem *ethi, GdkEventMotion *event)
 static void
 ethi_start_drag (ETableHeaderItem *ethi, GdkEvent *event)
 {
-	GtkWidget *widget = GTK_WIDGET (GNOME_CANVAS_ITEM (ethi)->canvas);
+	GtkWidget *widget = GTK_WIDGET (FOO_CANVAS_ITEM (ethi)->canvas);
 	GtkTargetList *list;
 	GdkDragContext *context;
 	ETableCol *ecol;
@@ -1398,7 +1405,7 @@ ethi_popup_best_fit(GtkWidget *widget, EthiHeaderInfo *info)
 	/* Add 10 to stop it from "..."ing */
 	e_table_header_set_size (ethi->eth, info->col, width + 10);
 
-	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM(ethi));
+	foo_canvas_item_request_update (FOO_CANVAS_ITEM(ethi));
 
 }
 
@@ -1684,10 +1691,10 @@ ethi_change_sort_state (ETableHeaderItem *ethi, ETableCol *col)
  * Handles the events on the ETableHeaderItem, particularly it handles resizing
  */
 static gint
-ethi_event (GnomeCanvasItem *item, GdkEvent *e)
+ethi_event (FooCanvasItem *item, GdkEvent *e)
 {
 	ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item);
-	GnomeCanvas *canvas = item->canvas;
+	FooCanvas *canvas = item->canvas;
 	const gboolean resizing = ETHI_RESIZING (ethi);
 	gint x, y, start, col;
 	gint was_maybe_drag = 0;
@@ -1713,7 +1720,7 @@ ethi_event (GnomeCanvasItem *item, GdkEvent *e)
 				/* Quick hack until I actually bind the views */
 				ethi->resize_guide = GINT_TO_POINTER (1);
 
-				gnome_canvas_item_grab (item,
+				foo_canvas_item_grab (item,
 							GDK_POINTER_MOTION_MASK |
 							GDK_BUTTON_RELEASE_MASK,
 							e_cursor_get (E_CURSOR_SIZE_X),
@@ -1724,7 +1731,7 @@ ethi_event (GnomeCanvasItem *item, GdkEvent *e)
 
 			e_table_header_set_size (ethi->eth, ethi->resize_col, new_width);
 
-			gnome_canvas_item_request_update (GNOME_CANVAS_ITEM(ethi));
+			foo_canvas_item_request_update (FOO_CANVAS_ITEM(ethi));
 		} else if (ethi_maybe_start_drag (ethi, &e->motion)) {
 			ethi_start_drag (ethi, e);
 		} else
@@ -1784,7 +1791,7 @@ ethi_event (GnomeCanvasItem *item, GdkEvent *e)
 			/* Add 10 to stop it from "..."ing */
 			e_table_header_set_size (ethi->eth, ethi->resize_col, width + 10);
 
-			gnome_canvas_item_request_update (GNOME_CANVAS_ITEM(ethi));
+			foo_canvas_item_request_update (FOO_CANVAS_ITEM(ethi));
 			ethi->maybe_drag = FALSE;
 		}
 		break;
@@ -1807,7 +1814,7 @@ ethi_event (GnomeCanvasItem *item, GdkEvent *e)
 		}
 
 		if (needs_ungrab)
-			gnome_canvas_item_ungrab (item, e->button.time);
+			foo_canvas_item_ungrab (item, e->button.time);
 
 		break;
 	}
@@ -1867,7 +1874,7 @@ ethi_event (GnomeCanvasItem *item, GdkEvent *e)
 static void
 ethi_class_init (ETableHeaderItemClass *klass)
 {
-	GnomeCanvasItemClass *item_class = GNOME_CANVAS_ITEM_CLASS (klass);
+	FooCanvasItemClass *item_class = FOO_CANVAS_ITEM_CLASS (klass);
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
 	object_class->dispose = ethi_dispose;
@@ -1955,7 +1962,7 @@ ethi_class_init (ETableHeaderItemClass *klass)
 static void
 ethi_init (ETableHeaderItem *ethi)
 {
-	GnomeCanvasItem *item = GNOME_CANVAS_ITEM (ethi);
+	FooCanvasItem *item = FOO_CANVAS_ITEM (ethi);
 
 	ethi->resize_col = -1;
 
diff --git a/widgets/table/e-table-header-item.h b/widgets/table/e-table-header-item.h
index db2aeb3..ba773cb 100644
--- a/widgets/table/e-table-header-item.h
+++ b/widgets/table/e-table-header-item.h
@@ -26,7 +26,7 @@
 
 #include <table/e-table.h>
 #include <table/e-tree.h>
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 #include <libxml/tree.h>
 #include <table/e-table-header.h>
 #include <table/e-table-sort-info.h>
@@ -40,7 +40,7 @@ G_BEGIN_DECLS
 #define E_IS_TABLE_HEADER_ITEM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TABLE_HEADER_ITEM_TYPE))
 
 typedef struct {
-	GnomeCanvasItem  parent;
+	FooCanvasItem  parent;
 	ETableHeader    *eth;
 
 	GdkCursor       *change_cursor;
@@ -73,7 +73,7 @@ typedef struct {
 	gint              drag_col, drop_col, drag_mark;
         guint            drag_motion_id, drag_end_id, drag_leave_id, drag_drop_id, drag_data_received_id, drag_data_get_id;
 	guint            sort_info_changed_id, group_info_changed_id;
-	GnomeCanvasItem *remove_item;
+	FooCanvasItem *remove_item;
 	GdkBitmap       *stipple;
 
 	gchar           *dnd_code;
@@ -107,7 +107,7 @@ typedef struct {
 } ETableHeaderItem;
 
 typedef struct {
-	GnomeCanvasItemClass parent_class;
+	FooCanvasItemClass parent_class;
 
 	/*
 	 * signals
diff --git a/widgets/table/e-table-item.c b/widgets/table/e-table-item.c
index c8809b6..b20650d 100644
--- a/widgets/table/e-table-item.c
+++ b/widgets/table/e-table-item.c
@@ -43,6 +43,7 @@
 #include "misc/e-canvas.h"
 #include "misc/e-canvas-utils.h"
 #include "misc/e-hsv-utils.h"
+#include "libfoocanvas/libart-types.h"
 
 #include "e-cell.h"
 #include "e-table-item.h"
@@ -50,7 +51,7 @@
 
 /* workaround for avoiding API breakage */
 #define eti_get_type e_table_item_get_type
-G_DEFINE_TYPE (ETableItem, eti, GNOME_TYPE_CANVAS_ITEM)
+G_DEFINE_TYPE (ETableItem, eti, FOO_TYPE_CANVAS_ITEM)
 
 #define FOCUSED_BORDER 2
 
@@ -178,7 +179,7 @@ view_to_model_col(ETableItem *eti, gint col)
 }
 
 static void
-grab_cancelled (ECanvas *canvas, GnomeCanvasItem *item, gpointer data)
+grab_cancelled (ECanvas *canvas, FooCanvasItem *item, gpointer data)
 {
 	ETableItem *eti = data;
 
@@ -188,7 +189,7 @@ grab_cancelled (ECanvas *canvas, GnomeCanvasItem *item, gpointer data)
 inline static void
 eti_grab (ETableItem *eti, guint32 time)
 {
-	GnomeCanvasItem *item = GNOME_CANVAS_ITEM (eti);
+	FooCanvasItem *item = FOO_CANVAS_ITEM (eti);
 	d(g_print ("%s: time: %d\n", __FUNCTION__, time));
 	if (eti->grabbed_count == 0) {
 		eti->gtk_grabbed = FALSE;
@@ -211,7 +212,7 @@ eti_grab (ETableItem *eti, guint32 time)
 inline static void
 eti_ungrab (ETableItem *eti, guint32 time)
 {
-	GnomeCanvasItem *item = GNOME_CANVAS_ITEM (eti);
+	FooCanvasItem *item = FOO_CANVAS_ITEM (eti);
 	d(g_print ("%s: time: %d\n", __FUNCTION__, time));
 	eti->grabbed_count --;
 	if (eti->grabbed_count == 0) {
@@ -223,7 +224,7 @@ eti_ungrab (ETableItem *eti, guint32 time)
 				gtk_grab_remove (GTK_WIDGET (item->canvas));
 				eti->gtk_grabbed = FALSE;
 			}
-			gnome_canvas_item_ungrab(item, time);
+			foo_canvas_item_ungrab(item, time);
 			eti->grabbed_col = -1;
 			eti->grabbed_row = -1;
 		}
@@ -245,7 +246,7 @@ inline static GdkColor *
 eti_get_cell_background_color (ETableItem *eti, gint row, gint col, gboolean selected, gboolean *allocatedp)
 {
 	ECellView *ecell_view = eti->cell_views [col];
-	GtkWidget *canvas = GTK_WIDGET(GNOME_CANVAS_ITEM(eti)->canvas);
+	GtkWidget *canvas = GTK_WIDGET(FOO_CANVAS_ITEM(eti)->canvas);
 	GdkColor *background, bg;
 	gchar *color_spec = NULL;
 	gboolean allocated = FALSE;
@@ -292,7 +293,7 @@ eti_get_cell_background_color (ETableItem *eti, gint row, gint col, gboolean sel
 inline static GdkColor *
 eti_get_cell_foreground_color (ETableItem *eti, gint row, gint col, gboolean selected, gboolean *allocated)
 {
-	GtkWidget *canvas = GTK_WIDGET(GNOME_CANVAS_ITEM(eti)->canvas);
+	GtkWidget *canvas = GTK_WIDGET(FOO_CANVAS_ITEM(eti)->canvas);
 	GdkColor *foreground;
 
 	if (allocated)
@@ -340,7 +341,7 @@ eti_realize_cell_views ( ETableItem *eti)
 	if (eti->cell_views_realized)
 		return;
 
-	if (!(GTK_OBJECT_FLAGS(eti) & GNOME_CANVAS_ITEM_REALIZED))
+	if (!(GTK_OBJECT_FLAGS(eti) & FOO_CANVAS_ITEM_REALIZED))
 		return;
 
 	for (i = 0; i < eti->n_cells; i++)
@@ -377,9 +378,9 @@ eti_attach_cell_views (ETableItem *eti)
 	}
 
 	eti->needs_compute_height = 1;
-	e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (eti));
+	e_canvas_item_request_reflow (FOO_CANVAS_ITEM (eti));
 	eti->needs_redraw = 1;
-	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (eti));
+	foo_canvas_item_request_update (FOO_CANVAS_ITEM (eti));
 }
 
 /*
@@ -419,7 +420,7 @@ eti_detach_cell_views (ETableItem *eti)
 }
 
 static void
-eti_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y2)
+eti_bounds (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2)
 {
 	double   i2c [6];
 	ArtPoint c1, c2, i1, i2;
@@ -427,7 +428,7 @@ eti_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y
 
 	/* Wrong BBox's are the source of redraw nightmares */
 
-	gnome_canvas_item_i2c_affine (GNOME_CANVAS_ITEM (eti), i2c);
+	foo_canvas_item_i2c_affine (FOO_CANVAS_ITEM (eti), i2c);
 
 	i1.x = eti->x1;
 	i1.y = eti->y1;
@@ -443,7 +444,7 @@ eti_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y
 }
 
 static void
-eti_reflow (GnomeCanvasItem *item, gint flags)
+eti_reflow (FooCanvasItem *item, gint flags)
 {
 	ETableItem *eti = E_TABLE_ITEM (item);
 
@@ -452,9 +453,9 @@ eti_reflow (GnomeCanvasItem *item, gint flags)
 
 		if (new_height != eti->height) {
 			eti->height = new_height;
-			e_canvas_item_request_parent_reflow (GNOME_CANVAS_ITEM (eti));
+			e_canvas_item_request_parent_reflow (FOO_CANVAS_ITEM (eti));
 			eti->needs_redraw = 1;
-			gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (eti));
+			foo_canvas_item_request_update (FOO_CANVAS_ITEM (eti));
 		}
 		eti->needs_compute_height = 0;
 	}
@@ -462,25 +463,25 @@ eti_reflow (GnomeCanvasItem *item, gint flags)
 		gint new_width = e_table_header_total_width(eti->header);
 		if (new_width != eti->width) {
 			eti->width = new_width;
-			e_canvas_item_request_parent_reflow (GNOME_CANVAS_ITEM (eti));
+			e_canvas_item_request_parent_reflow (FOO_CANVAS_ITEM (eti));
 			eti->needs_redraw = 1;
-			gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (eti));
+			foo_canvas_item_request_update (FOO_CANVAS_ITEM (eti));
 		}
 		eti->needs_compute_width = 0;
 	}
 }
 
 /*
- * GnomeCanvasItem::update method
+ * FooCanvasItem::update method
  */
 static void
-eti_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, gint flags)
+eti_update (FooCanvasItem *item, double i2w_dx, double i2w_dy, gint flags)
 {
 	ArtPoint o1, o2;
 	ETableItem *eti = E_TABLE_ITEM (item);
 
-	if (GNOME_CANVAS_ITEM_CLASS (eti_parent_class)->update)
-		(*GNOME_CANVAS_ITEM_CLASS (eti_parent_class)->update)(item, affine, clip_path, flags);
+	if (FOO_CANVAS_ITEM_CLASS (eti_parent_class)->update)
+		(*FOO_CANVAS_ITEM_CLASS (eti_parent_class)->update)(item, i2w_dx, i2w_dy, flags);
 
 	o1.x = item->x1;
 	o1.y = item->y1;
@@ -492,12 +493,12 @@ eti_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, gint flags
 	    item->y1 != o1.y ||
 	    item->x2 != o2.x ||
 	    item->y2 != o2.y) {
-		gnome_canvas_request_redraw (item->canvas, o1.x, o1.y, o2.x, o2.y);
+		foo_canvas_request_redraw (item->canvas, o1.x, o1.y, o2.x, o2.y);
 		eti->needs_redraw = 1;
 	}
 
 	if (eti->needs_redraw) {
-		gnome_canvas_request_redraw (item->canvas, item->x1, item->y1,
+		foo_canvas_request_redraw (item->canvas, item->x1, item->y1,
 					     item->x2, item->y2);
 		eti->needs_redraw = 0;
 	}
@@ -665,7 +666,7 @@ height_cache_idle(ETableItem *eti)
 static void
 free_height_cache (ETableItem *eti)
 {
-	if (GNOME_CANVAS_ITEM_REALIZED & GTK_OBJECT_FLAGS (eti)) {
+	if (FOO_CANVAS_ITEM_REALIZED & GTK_OBJECT_FLAGS (eti)) {
 		if (eti->height_cache)
 			g_free (eti->height_cache);
 		eti->height_cache = NULL;
@@ -712,7 +713,7 @@ eti_row_height (ETableItem *eti, gint row)
 			    eti->rows > eti->length_threshold &&
 			    eti->height_cache[row] != eti_row_height(eti, 0)) {
 				eti->needs_compute_height = 1;
-				e_canvas_item_request_reflow(GNOME_CANVAS_ITEM(eti));
+				e_canvas_item_request_reflow(FOO_CANVAS_ITEM(eti));
 			}
 		}
 		return eti->height_cache[row];
@@ -780,7 +781,7 @@ eti_get_height (ETableItem *eti)
 static void
 eti_item_region_redraw (ETableItem *eti, gint x0, gint y0, gint x1, gint y1)
 {
-	GnomeCanvasItem *item = GNOME_CANVAS_ITEM (eti);
+	FooCanvasItem *item = FOO_CANVAS_ITEM (eti);
 	ArtDRect rect;
 	double i2c [6];
 
@@ -789,10 +790,10 @@ eti_item_region_redraw (ETableItem *eti, gint x0, gint y0, gint x1, gint y1)
 	rect.x1 = x1;
 	rect.y1 = y1;
 
-	gnome_canvas_item_i2c_affine (item, i2c);
+	foo_canvas_item_i2c_affine (item, i2c);
 	art_drect_affine_transform (&rect, &rect, i2c);
 
-	gnome_canvas_request_redraw (item->canvas, rect.x0, rect.y0, rect.x1, rect.y1);
+	foo_canvas_request_redraw (item->canvas, rect.x0, rect.y0, rect.x1, rect.y1);
 }
 
 /*
@@ -893,9 +894,9 @@ eti_request_region_show (ETableItem *eti,
 			&x1, &y1, &x2, &y2);
 
 	if (delay)
-		e_canvas_item_show_area_delayed(GNOME_CANVAS_ITEM(eti), x1, y1, x2, y2, delay);
+		e_canvas_item_show_area_delayed(FOO_CANVAS_ITEM(eti), x1, y1, x2, y2, delay);
 	else
-		e_canvas_item_show_area(GNOME_CANVAS_ITEM(eti), x1, y1, x2, y2);
+		e_canvas_item_show_area(FOO_CANVAS_ITEM(eti), x1, y1, x2, y2);
 }
 
 static void
@@ -903,7 +904,7 @@ eti_show_cursor (ETableItem *eti, gint delay)
 {
 	gint cursor_row;
 
-	if (!((GTK_OBJECT_FLAGS(eti) & GNOME_CANVAS_ITEM_REALIZED) && eti->cell_views_realized))
+	if (!((GTK_OBJECT_FLAGS(eti) & FOO_CANVAS_ITEM_REALIZED) && eti->cell_views_realized))
 		return;
 
 	if (eti->frozen_count > 0) {
@@ -938,7 +939,7 @@ eti_check_cursor_on_screen (ETableItem *eti)
 	    eti->cursor_y2 == -1)
 		return;
 
-	eti->cursor_on_screen = e_canvas_item_area_shown (GNOME_CANVAS_ITEM(eti),
+	eti->cursor_on_screen = e_canvas_item_area_shown (FOO_CANVAS_ITEM(eti),
 							  eti->cursor_x1,
 							  eti->cursor_y1,
 							  eti->cursor_x2,
@@ -953,14 +954,14 @@ eti_check_cursor_bounds (ETableItem *eti)
 	gint x1, y1, x2, y2;
 	gint cursor_row;
 
-	if (!((GTK_OBJECT_FLAGS(eti) & GNOME_CANVAS_ITEM_REALIZED) && eti->cell_views_realized))
+	if (!((GTK_OBJECT_FLAGS(eti) & FOO_CANVAS_ITEM_REALIZED) && eti->cell_views_realized))
 		return;
 
 	if (eti->frozen_count > 0) {
 		return;
 	}
 
-	if (!((GTK_OBJECT_FLAGS(eti) & GNOME_CANVAS_ITEM_REALIZED) && eti->cell_views_realized))
+	if (!((GTK_OBJECT_FLAGS(eti) & FOO_CANVAS_ITEM_REALIZED) && eti->cell_views_realized))
 		return;
 
 	if (eti->frozen_count > 0) {
@@ -993,7 +994,7 @@ eti_check_cursor_bounds (ETableItem *eti)
 	eti->cursor_y1 = y1;
 	eti->cursor_x2 = x2;
 	eti->cursor_y2 = y2;
-	eti->cursor_on_screen = e_canvas_item_area_shown (GNOME_CANVAS_ITEM(eti), x1, y1, x2, y2);
+	eti->cursor_on_screen = e_canvas_item_area_shown (FOO_CANVAS_ITEM(eti), x1, y1, x2, y2);
 
 	d(g_print ("%s: cursor on screen: %s\n", __FUNCTION__, eti->cursor_on_screen ? "TRUE" : "FALSE"));
 }
@@ -1099,7 +1100,7 @@ eti_table_model_no_change (ETableModel *table_model, ETableItem *eti)
 static void
 eti_table_model_changed (ETableModel *table_model, ETableItem *eti)
 {
-	if (!(GTK_OBJECT_FLAGS(eti) & GNOME_CANVAS_ITEM_REALIZED)) {
+	if (!(GTK_OBJECT_FLAGS(eti) & FOO_CANVAS_ITEM_REALIZED)) {
 		eti_unfreeze (eti);
 		return;
 	}
@@ -1111,9 +1112,9 @@ eti_table_model_changed (ETableModel *table_model, ETableItem *eti)
 	eti_unfreeze (eti);
 
 	eti->needs_compute_height = 1;
-	e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (eti));
+	e_canvas_item_request_reflow (FOO_CANVAS_ITEM (eti));
 	eti->needs_redraw = 1;
-	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (eti));
+	foo_canvas_item_request_update (FOO_CANVAS_ITEM (eti));
 
 	eti_idle_maybe_show_cursor(eti);
 }
@@ -1121,7 +1122,7 @@ eti_table_model_changed (ETableModel *table_model, ETableItem *eti)
 static void
 eti_table_model_row_changed (ETableModel *table_model, gint row, ETableItem *eti)
 {
-	if (!(GTK_OBJECT_FLAGS(eti) & GNOME_CANVAS_ITEM_REALIZED)) {
+	if (!(GTK_OBJECT_FLAGS(eti) & FOO_CANVAS_ITEM_REALIZED)) {
 		eti_unfreeze (eti);
 		return;
 	}
@@ -1139,7 +1140,7 @@ eti_table_model_row_changed (ETableModel *table_model, gint row, ETableItem *eti
 static void
 eti_table_model_cell_changed (ETableModel *table_model, gint col, gint row, ETableItem *eti)
 {
-	if (!(GTK_OBJECT_FLAGS(eti) & GNOME_CANVAS_ITEM_REALIZED)) {
+	if (!(GTK_OBJECT_FLAGS(eti) & FOO_CANVAS_ITEM_REALIZED)) {
 		eti_unfreeze (eti);
 		return;
 	}
@@ -1157,7 +1158,7 @@ eti_table_model_cell_changed (ETableModel *table_model, gint col, gint row, ETab
 static void
 eti_table_model_rows_inserted (ETableModel *table_model, gint row, gint count, ETableItem *eti)
 {
-	if (!(GTK_OBJECT_FLAGS(eti) & GNOME_CANVAS_ITEM_REALIZED)) {
+	if (!(GTK_OBJECT_FLAGS(eti) & FOO_CANVAS_ITEM_REALIZED)) {
 		eti_unfreeze (eti);
 		return;
 	}
@@ -1176,15 +1177,15 @@ eti_table_model_rows_inserted (ETableModel *table_model, gint row, gint count, E
 	eti_idle_maybe_show_cursor(eti);
 
 	eti->needs_compute_height = 1;
-	e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (eti));
+	e_canvas_item_request_reflow (FOO_CANVAS_ITEM (eti));
 	eti->needs_redraw = 1;
-	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (eti));
+	foo_canvas_item_request_update (FOO_CANVAS_ITEM (eti));
 }
 
 static void
 eti_table_model_rows_deleted (ETableModel *table_model, gint row, gint count, ETableItem *eti)
 {
-	if (!(GTK_OBJECT_FLAGS(eti) & GNOME_CANVAS_ITEM_REALIZED)) {
+	if (!(GTK_OBJECT_FLAGS(eti) & FOO_CANVAS_ITEM_REALIZED)) {
 		eti_unfreeze (eti);
 		return;
 	}
@@ -1200,9 +1201,9 @@ eti_table_model_rows_deleted (ETableModel *table_model, gint row, gint count, ET
 	eti_idle_maybe_show_cursor(eti);
 
 	eti->needs_compute_height = 1;
-	e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (eti));
+	e_canvas_item_request_reflow (FOO_CANVAS_ITEM (eti));
 	eti->needs_redraw = 1;
-	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (eti));
+	foo_canvas_item_request_update (FOO_CANVAS_ITEM (eti));
 }
 
 /**
@@ -1337,9 +1338,9 @@ static void
 eti_header_dim_changed (ETableHeader *eth, gint col, ETableItem *eti)
 {
 	eti->needs_compute_width = 1;
-	e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (eti));
+	e_canvas_item_request_reflow (FOO_CANVAS_ITEM (eti));
 	eti->needs_redraw = 1;
-	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (eti));
+	foo_canvas_item_request_update (FOO_CANVAS_ITEM (eti));
 }
 
 static void
@@ -1364,9 +1365,9 @@ eti_header_structure_changed (ETableHeader *eth, ETableItem *eti)
 		}
 	}
 	eti->needs_compute_width = 1;
-	e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (eti));
+	e_canvas_item_request_reflow (FOO_CANVAS_ITEM (eti));
 	eti->needs_redraw = 1;
-	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (eti));
+	foo_canvas_item_request_update (FOO_CANVAS_ITEM (eti));
 }
 
 static gint
@@ -1431,8 +1432,8 @@ eti_dispose (GObject *object)
 		g_free (eti->height_cache);
 	eti->height_cache = NULL;
 
-	if (E_CANVAS(GNOME_CANVAS_ITEM(eti)->canvas))
-		e_canvas_hide_tooltip (E_CANVAS(GNOME_CANVAS_ITEM(eti)->canvas));
+	if (E_CANVAS(FOO_CANVAS_ITEM(eti)->canvas))
+		e_canvas_hide_tooltip (E_CANVAS(FOO_CANVAS_ITEM(eti)->canvas));
 
 	if (eti->tooltip) {
 		if (eti->tooltip->background)
@@ -1511,7 +1512,7 @@ eti_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpe
 		if ((eti->minimum_width == eti->width && g_value_get_double(value) > eti->width) ||
 		    g_value_get_double(value) < eti->width) {
 			eti->needs_compute_width = 1;
-			e_canvas_item_request_reflow (GNOME_CANVAS_ITEM(eti));
+			e_canvas_item_request_reflow (FOO_CANVAS_ITEM(eti));
 		}
 		eti->minimum_width = g_value_get_double (value);
 		break;
@@ -1525,18 +1526,18 @@ eti_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpe
 	case PROP_UNIFORM_ROW_HEIGHT:
 		if (eti->uniform_row_height != g_value_get_boolean (value)) {
 			eti->uniform_row_height = g_value_get_boolean (value);
-			if (GTK_OBJECT_FLAGS(eti) & GNOME_CANVAS_ITEM_REALIZED) {
+			if (GTK_OBJECT_FLAGS(eti) & FOO_CANVAS_ITEM_REALIZED) {
 				free_height_cache(eti);
 				eti->needs_compute_height = 1;
-				e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (eti));
+				e_canvas_item_request_reflow (FOO_CANVAS_ITEM (eti));
 				eti->needs_redraw = 1;
-				gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (eti));
+				foo_canvas_item_request_update (FOO_CANVAS_ITEM (eti));
 			}
 		}
 		break;
 	}
 	eti->needs_redraw = 1;
-	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM(eti));
+	foo_canvas_item_request_update (FOO_CANVAS_ITEM(eti));
 }
 
 static void
@@ -1617,7 +1618,7 @@ eti_init (ETableItem *eti)
 
 	eti->tooltip                   = g_new0 (ETableTooltip, 1);
 	eti->tooltip->timer            = 0;
-	eti->tooltip->eti              = GNOME_CANVAS_ITEM (eti);
+	eti->tooltip->eti              = FOO_CANVAS_ITEM (eti);
 	eti->tooltip->background       = NULL;
 	eti->tooltip->foreground       = NULL;
 
@@ -1645,7 +1646,7 @@ eti_init (ETableItem *eti)
 	eti->frozen_count              = 0;
 	eti->queue_show_cursor         = FALSE;
 
-	e_canvas_item_set_reflow_callback (GNOME_CANVAS_ITEM (eti), eti_reflow);
+	e_canvas_item_set_reflow_callback (FOO_CANVAS_ITEM (eti), eti_reflow);
 }
 
 #define gray50_width 2
@@ -1657,7 +1658,7 @@ static void
 adjustment_changed (GtkAdjustment *adjustment, ETableItem *eti)
 {
 	/* FIXME: It is the ugliest of hack to set the focus to scroll. Fix this up when moving away from e-tree */
-	if (g_object_get_data ((GObject *) ((GnomeCanvasItem *) eti)->canvas, "freeze-cursor"))
+	if (g_object_get_data ((GObject *) ((FooCanvasItem *) eti)->canvas, "freeze-cursor"))
 		eti_maybe_show_cursor (eti, 0);
 
 	eti_check_cursor_on_screen (eti);
@@ -1674,14 +1675,14 @@ eti_tree_unfreeze (GtkWidget *widget,  GdkEvent *event, ETableItem *eti)
 }
 
 static void
-eti_realize (GnomeCanvasItem *item)
+eti_realize (FooCanvasItem *item)
 {
 	ETableItem *eti = E_TABLE_ITEM (item);
 	GtkWidget *canvas_widget = GTK_WIDGET (item->canvas);
 	GdkWindow *window;
 
-	if (GNOME_CANVAS_ITEM_CLASS (eti_parent_class)->realize)
-                (*GNOME_CANVAS_ITEM_CLASS (eti_parent_class)->realize)(item);
+	if (FOO_CANVAS_ITEM_CLASS (eti_parent_class)->realize)
+                (*FOO_CANVAS_ITEM_CLASS (eti_parent_class)->realize)(item);
 
 	eti->rows = e_table_model_row_count (eti->table_model);
 
@@ -1738,13 +1739,13 @@ eti_realize (GnomeCanvasItem *item)
 
 	eti->needs_compute_height = 1;
 	eti->needs_compute_width = 1;
-	e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (eti));
+	e_canvas_item_request_reflow (FOO_CANVAS_ITEM (eti));
 	eti->needs_redraw = 1;
-	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (eti));
+	foo_canvas_item_request_update (FOO_CANVAS_ITEM (eti));
 }
 
 static void
-eti_unrealize (GnomeCanvasItem *item)
+eti_unrealize (FooCanvasItem *item)
 {
 	ETableItem *eti = E_TABLE_ITEM (item);
 
@@ -1766,7 +1767,7 @@ eti_unrealize (GnomeCanvasItem *item)
 	eti->height_cache = NULL;
 	eti->height_cache_idle_count = 0;
 
-	e_canvas_hide_tooltip (E_CANVAS(GNOME_CANVAS_ITEM(eti)->canvas));
+	e_canvas_hide_tooltip (E_CANVAS(FOO_CANVAS_ITEM(eti)->canvas));
 	if (eti->tooltip) {
 		if (eti->tooltip->background) {
 			gdk_color_free (eti->tooltip->background);
@@ -1804,12 +1805,12 @@ eti_unrealize (GnomeCanvasItem *item)
 	g_signal_handler_disconnect(gtk_layout_get_vadjustment(GTK_LAYOUT(item->canvas)),
 				    eti->vadjustment_value_change_id);
 
-	if (GNOME_CANVAS_ITEM_CLASS (eti_parent_class)->unrealize)
-                (*GNOME_CANVAS_ITEM_CLASS (eti_parent_class)->unrealize)(item);
+	if (FOO_CANVAS_ITEM_CLASS (eti_parent_class)->unrealize)
+                (*FOO_CANVAS_ITEM_CLASS (eti_parent_class)->unrealize)(item);
 }
 
 static void
-eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, gint x, gint y, gint width, gint height)
+eti_draw (FooCanvasItem *item, GdkDrawable *drawable, GdkEventExpose *expose)
 {
 	ETableItem *eti = E_TABLE_ITEM (item);
 	const gint rows = eti->rows;
@@ -1819,6 +1820,7 @@ eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, gint x, gint y, gint wid
 	gint first_row, last_row, y_offset, yd;
 	gint x1, x2;
 	gint f_x1, f_x2, f_y1, f_y2;
+	gint x, y, width, height;
 	gboolean f_found;
 	double i2c [6];
 	ArtPoint eti_base, eti_base_item, lower_right;
@@ -1826,12 +1828,17 @@ eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, gint x, gint y, gint wid
 	gint height_extra = eti->horizontal_draw_grid ? 1 : 0;
 	cairo_t *cr;
 
+	x = expose->area.x;
+	y = expose->area.y;
+	width = expose->area.width;
+	height = expose->area.height;
+
 	cr = gdk_cairo_create (drawable);
 
 	/*
 	 * Find out our real position after grouping
 	 */
-	gnome_canvas_item_i2c_affine (item, i2c);
+	foo_canvas_item_i2c_affine (item, i2c);
 	eti_base_item.x = eti->x1;
 	eti_base_item.y = eti->y1;
 	art_affine_point (&eti_base, &eti_base_item, i2c);
@@ -2107,8 +2114,8 @@ exit:
 }
 
 static double
-eti_point (GnomeCanvasItem *item, double x, double y, gint cx, gint cy,
-	   GnomeCanvasItem **actual_item)
+eti_point (FooCanvasItem *item, double x, double y, gint cx, gint cy,
+	   FooCanvasItem **actual_item)
 {
 	*actual_item = item;
 
@@ -2225,7 +2232,7 @@ _do_tooltip (ETableItem *eti)
 	gboolean selected;
 	gint cursor_row, cursor_col;
 
-	e_canvas_hide_tooltip (E_CANVAS(GNOME_CANVAS_ITEM(eti)->canvas));
+	e_canvas_hide_tooltip (E_CANVAS(FOO_CANVAS_ITEM(eti)->canvas));
 
 	if (eti_editing (eti))
 		return FALSE;
@@ -2307,7 +2314,7 @@ eti_e_cell_event     (ETableItem *item, ECellView *ecell_view, GdkEvent *event,
 
 /* FIXME: cursor */
 static gint
-eti_event (GnomeCanvasItem *item, GdkEvent *e)
+eti_event (FooCanvasItem *item, GdkEvent *e)
 {
 	ETableItem *eti = E_TABLE_ITEM (item);
 	ECellView *ecell_view;
@@ -2339,8 +2346,8 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
 		switch (e->button.button) {
 		case 1: /* Fall through. */
 		case 2:
-			e_canvas_item_grab_focus(GNOME_CANVAS_ITEM(eti), TRUE);
-			gnome_canvas_item_w2i (item, &e->button.x, &e->button.y);
+			e_canvas_item_grab_focus(FOO_CANVAS_ITEM(eti), TRUE);
+			foo_canvas_item_w2i (item, &e->button.x, &e->button.y);
 
 			realx = e->button.x;
 			realy = e->button.y;
@@ -2429,8 +2436,8 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
 
 			break;
 		case 3:
-			e_canvas_item_grab_focus(GNOME_CANVAS_ITEM(eti), TRUE);
-			gnome_canvas_item_w2i (item, &e->button.x, &e->button.y);
+			e_canvas_item_grab_focus(FOO_CANVAS_ITEM(eti), TRUE);
+			foo_canvas_item_w2i (item, &e->button.x, &e->button.y);
 			if (!find_cell (eti, e->button.x, e->button.y, &col, &row, &x1, &y1))
 				return TRUE;
 
@@ -2476,12 +2483,12 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
 			g_source_remove (eti->tooltip->timer);
 			eti->tooltip->timer = 0;
 		}
-		e_canvas_hide_tooltip (E_CANVAS(GNOME_CANVAS_ITEM(eti)->canvas));
+		e_canvas_hide_tooltip (E_CANVAS(FOO_CANVAS_ITEM(eti)->canvas));
 		switch (e->button.button) {
 		case 1: /* Fall through. */
 		case 2:
 
-			gnome_canvas_item_w2i (item, &e->button.x, &e->button.y);
+			foo_canvas_item_w2i (item, &e->button.x, &e->button.y);
 #if d(!)0
 			{
 				gboolean cell_found = find_cell (eti, e->button.x, e->button.y, &col, &row, &x1, &y1);
@@ -2546,7 +2553,7 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
 
 		if (eti->click_count >= 2) {
 
-			gnome_canvas_item_w2i (item, &e->button.x, &e->button.y);
+			foo_canvas_item_w2i (item, &e->button.x, &e->button.y);
 
 #if 0
 			if (!find_cell (eti, e->button.x, e->button.y, &current_col, &current_row, &x1, &y1))
@@ -2592,7 +2599,7 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
 		double x1, y1;
 		gint cursor_col, cursor_row;
 
-		gnome_canvas_item_w2i (item, &e->motion.x, &e->motion.y);
+		foo_canvas_item_w2i (item, &e->motion.x, &e->motion.y);
 
 		if (eti->maybe_in_drag) {
 			if (abs (e->motion.x - eti->drag_x) >= 3 ||
@@ -2630,7 +2637,7 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
 			     "cursor_col", &cursor_col,
 			     NULL);
 
-		e_canvas_hide_tooltip (E_CANVAS(GNOME_CANVAS_ITEM(eti)->canvas));
+		e_canvas_hide_tooltip (E_CANVAS(FOO_CANVAS_ITEM(eti)->canvas));
 
 #ifdef DO_TOOLTIPS
 		if (!g_getenv ("GAL_DONT_DO_TOOLTIPS")) {
@@ -2677,7 +2684,7 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
 			g_source_remove (eti->tooltip->timer);
 			eti->tooltip->timer = 0;
 		}
-		e_canvas_hide_tooltip (E_CANVAS(GNOME_CANVAS_ITEM(eti)->canvas));
+		e_canvas_hide_tooltip (E_CANVAS(FOO_CANVAS_ITEM(eti)->canvas));
 
 		if (cursor_row == -1 && cursor_col == -1)
 			return FALSE;
@@ -2944,7 +2951,7 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
 static void
 eti_style_set (ETableItem *eti, GtkStyle *previous_style)
 {
-	if (!(GTK_OBJECT_FLAGS(eti) & GNOME_CANVAS_ITEM_REALIZED))
+	if (!(GTK_OBJECT_FLAGS(eti) & FOO_CANVAS_ITEM_REALIZED))
 		return;
 
 	if (eti->cell_views_realized) {
@@ -2957,9 +2964,9 @@ eti_style_set (ETableItem *eti, GtkStyle *previous_style)
 	}
 
 	eti->needs_compute_height = 1;
-	e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (eti));
+	e_canvas_item_request_reflow (FOO_CANVAS_ITEM (eti));
 	eti->needs_redraw = 1;
-	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (eti));
+	foo_canvas_item_request_update (FOO_CANVAS_ITEM (eti));
 
 	free_height_cache (eti);
 
@@ -2969,7 +2976,7 @@ eti_style_set (ETableItem *eti, GtkStyle *previous_style)
 static void
 eti_class_init (ETableItemClass *klass)
 {
-	GnomeCanvasItemClass *item_class = GNOME_CANVAS_ITEM_CLASS (klass);
+	FooCanvasItemClass *item_class = FOO_CANVAS_ITEM_CLASS (klass);
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
 	object_class->dispose       = eti_dispose;
@@ -3255,7 +3262,7 @@ eti_cursor_change (ESelectionModel *selection, gint row, gint col, ETableItem *e
 {
 	gint view_row;
 
-	if (!(GTK_OBJECT_FLAGS(eti) & GNOME_CANVAS_ITEM_REALIZED))
+	if (!(GTK_OBJECT_FLAGS(eti) & FOO_CANVAS_ITEM_REALIZED))
 		return;
 
 	view_row = model_to_view_row(eti, row);
@@ -3277,7 +3284,7 @@ eti_cursor_change (ESelectionModel *selection, gint row, gint col, ETableItem *e
 		}
 	}
 
-	e_canvas_item_grab_focus(GNOME_CANVAS_ITEM(eti), FALSE);
+	e_canvas_item_grab_focus(FOO_CANVAS_ITEM(eti), FALSE);
 	if (eti_editing(eti))
 		e_table_item_leave_edit_(eti);
 	g_signal_emit (eti, eti_signals [CURSOR_CHANGE], 0,
@@ -3294,7 +3301,7 @@ eti_cursor_activated (ESelectionModel *selection, gint row, gint col, ETableItem
 	gint view_row;
 	gint view_col;
 
-	if (!(GTK_OBJECT_FLAGS(eti) & GNOME_CANVAS_ITEM_REALIZED))
+	if (!(GTK_OBJECT_FLAGS(eti) & FOO_CANVAS_ITEM_REALIZED))
 		return;
 
 	view_row = model_to_view_row(eti, row);
@@ -3322,17 +3329,17 @@ eti_cursor_activated (ESelectionModel *selection, gint row, gint col, ETableItem
 static void
 eti_selection_change (ESelectionModel *selection, ETableItem *eti)
 {
-	if (!(GTK_OBJECT_FLAGS(eti) & GNOME_CANVAS_ITEM_REALIZED))
+	if (!(GTK_OBJECT_FLAGS(eti) & FOO_CANVAS_ITEM_REALIZED))
 		return;
 
 	eti->needs_redraw = TRUE;
-	gnome_canvas_item_request_update(GNOME_CANVAS_ITEM(eti));
+	foo_canvas_item_request_update(FOO_CANVAS_ITEM(eti));
 }
 
 static void
 eti_selection_row_change (ESelectionModel *selection, gint row, ETableItem *eti)
 {
-	if (!(GTK_OBJECT_FLAGS(eti) & GNOME_CANVAS_ITEM_REALIZED))
+	if (!(GTK_OBJECT_FLAGS(eti) & FOO_CANVAS_ITEM_REALIZED))
 		return;
 
 	if (!eti->needs_redraw) {
@@ -3453,7 +3460,7 @@ e_table_item_compute_mouse_over (ETableItem        *eti,
 	realx = x;
 	realy = y;
 
-	gnome_canvas_item_w2i (GNOME_CANVAS_ITEM (eti), &realx, &realy);
+	foo_canvas_item_w2i (FOO_CANVAS_ITEM (eti), &realx, &realy);
 
 	if (!find_cell (eti, (gint)realx, (gint)realy, col, row, NULL, NULL)) {
 		*row = -1;
diff --git a/widgets/table/e-table-item.h b/widgets/table/e-table-item.h
index cd3bf1d..e00007f 100644
--- a/widgets/table/e-table-item.h
+++ b/widgets/table/e-table-item.h
@@ -25,7 +25,7 @@
 #ifndef _E_TABLE_ITEM_H_
 #define _E_TABLE_ITEM_H_
 
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 #include <table/e-table-model.h>
 #include <table/e-table-header.h>
 #include <table/e-table-defines.h>
@@ -42,7 +42,7 @@ G_BEGIN_DECLS
 #define E_IS_TABLE_ITEM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TABLE_ITEM_TYPE))
 
 typedef struct {
-	GnomeCanvasItem  parent;
+	FooCanvasItem  parent;
 	ETableModel     *table_model;
 	ETableHeader    *header;
 
@@ -172,7 +172,7 @@ typedef struct {
 } ETableItem;
 
 typedef struct {
-	GnomeCanvasItemClass parent_class;
+	FooCanvasItemClass parent_class;
 
 	void        (*cursor_change)    (ETableItem *eti, gint row);
 	void        (*cursor_activated) (ETableItem *eti, gint row);
diff --git a/widgets/table/e-table-scrolled.c b/widgets/table/e-table-scrolled.c
index 3d937dd..6960d3a 100644
--- a/widgets/table/e-table-scrolled.c
+++ b/widgets/table/e-table-scrolled.c
@@ -26,7 +26,7 @@
 #include <stdio.h>
 #include <string.h>
 
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 #include <gtk/gtk.h>
 #include <libxml/parser.h>
 #include <libxml/xmlmemory.h>
diff --git a/widgets/table/e-table-tooltip.h b/widgets/table/e-table-tooltip.h
index 27dcf26..ec397f9 100644
--- a/widgets/table/e-table-tooltip.h
+++ b/widgets/table/e-table-tooltip.h
@@ -23,7 +23,7 @@
 #ifndef _E_TABLE_TOOLTIP_H_
 #define _E_TABLE_TOOLTIP_H_
 
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 
 G_BEGIN_DECLS
 
@@ -35,7 +35,7 @@ typedef struct {
 	gint cx, cy;
 	GdkColor *foreground;
 	GdkColor *background;
-	GnomeCanvasItem *eti;
+	FooCanvasItem *eti;
 } ETableTooltip;
 
 G_END_DECLS
diff --git a/widgets/table/e-table.c b/widgets/table/e-table.c
index 96e5e57..a21e7cf 100644
--- a/widgets/table/e-table.c
+++ b/widgets/table/e-table.c
@@ -33,8 +33,8 @@
 #include <glib/gstdio.h>
 #include <gdk/gdkkeysyms.h>
 #include <gtk/gtk.h>
-#include <libgnomecanvas/gnome-canvas.h>
-#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
+#include <libfoocanvas/foo-canvas.h>
+#include <libfoocanvas/foo-canvas-rect-ellipse.h>
 
 #include "gal-a11y-e-table.h"
 #include <glib/gi18n.h>
@@ -593,15 +593,15 @@ set_header_canvas_width (ETable *e_table)
 	if (!(e_table->header_item && e_table->header_canvas && e_table->table_canvas))
 		return;
 
-	gnome_canvas_get_scroll_region (GNOME_CANVAS (e_table->table_canvas),
+	foo_canvas_get_scroll_region (FOO_CANVAS (e_table->table_canvas),
 					NULL, NULL, &width, NULL);
-	gnome_canvas_get_scroll_region (GNOME_CANVAS (e_table->header_canvas),
+	foo_canvas_get_scroll_region (FOO_CANVAS (e_table->header_canvas),
 					NULL, NULL, &oldwidth, &oldheight);
 
 	if (oldwidth != width ||
 	    oldheight != E_TABLE_HEADER_ITEM (e_table->header_item)->height - 1)
-		gnome_canvas_set_scroll_region (
-						GNOME_CANVAS (e_table->header_canvas),
+		foo_canvas_set_scroll_region (
+						FOO_CANVAS (e_table->header_canvas),
 						0, 0, width, /*  COLUMN_HEADER_HEIGHT - 1 */
 						E_TABLE_HEADER_ITEM (e_table->header_item)->height - 1);
 
@@ -651,14 +651,14 @@ static void
 e_table_setup_header (ETable *e_table)
 {
 	gchar *pointer;
-	e_table->header_canvas = GNOME_CANVAS (e_canvas_new ());
+	e_table->header_canvas = FOO_CANVAS (e_canvas_new ());
 
 	gtk_widget_show (GTK_WIDGET (e_table->header_canvas));
 
 	pointer = g_strdup_printf("%p", (gpointer) e_table);
 
-	e_table->header_item = gnome_canvas_item_new (
-		gnome_canvas_root (e_table->header_canvas),
+	e_table->header_item = foo_canvas_item_new (
+		foo_canvas_root (e_table->header_canvas),
 		e_table_header_item_get_type (),
 		"ETableHeader", e_table->header,
 		"full_header", e_table->full_header,
@@ -692,12 +692,12 @@ table_canvas_reflow_idle (ETable *e_table)
 	height = MAX ((gint)height, alloc->height);
 	width = MAX((gint)width, alloc->width);
 	/* I have no idea why this needs to be -1, but it works. */
-	gnome_canvas_get_scroll_region (GNOME_CANVAS (e_table->table_canvas),
+	foo_canvas_get_scroll_region (FOO_CANVAS (e_table->table_canvas),
 					NULL, NULL, &oldwidth, &oldheight);
 
 	if (oldwidth != width - 1 ||
 	    oldheight != height - 1) {
-		gnome_canvas_set_scroll_region (GNOME_CANVAS (e_table->table_canvas),
+		foo_canvas_set_scroll_region (FOO_CANVAS (e_table->table_canvas),
 						0, 0, width - 1, height - 1);
 		set_header_canvas_width (e_table);
 	}
@@ -732,7 +732,7 @@ table_canvas_size_allocate (GtkWidget *widget, GtkAllocation *alloc,
 }
 
 static void
-table_canvas_reflow (GnomeCanvas *canvas, ETable *e_table)
+table_canvas_reflow (FooCanvas *canvas, ETable *e_table)
 {
 	if (!e_table->reflow_idle_id)
 		e_table->reflow_idle_id = g_idle_add_full (400, (GSourceFunc) table_canvas_reflow_idle, e_table, NULL);
@@ -919,7 +919,7 @@ et_build_groups (ETable *et)
 
 	et->is_grouped = e_table_sort_info_grouping_get_count(et->sort_info) > 0;
 
-	et->group = e_table_group_new (GNOME_CANVAS_GROUP (et->canvas_vbox),
+	et->group = e_table_group_new (FOO_CANVAS_GROUP (et->canvas_vbox),
 				       et->full_header,
 				       et->header,
 				       et->model,
@@ -927,11 +927,11 @@ et_build_groups (ETable *et)
 				       0);
 
 	if (et->use_click_to_add_end)
-		e_canvas_vbox_add_item_start(E_CANVAS_VBOX(et->canvas_vbox), GNOME_CANVAS_ITEM(et->group));
+		e_canvas_vbox_add_item_start(E_CANVAS_VBOX(et->canvas_vbox), FOO_CANVAS_ITEM(et->group));
 	else
-		e_canvas_vbox_add_item(E_CANVAS_VBOX(et->canvas_vbox), GNOME_CANVAS_ITEM(et->group));
+		e_canvas_vbox_add_item(E_CANVAS_VBOX(et->canvas_vbox), FOO_CANVAS_ITEM(et->group));
 
-	gnome_canvas_item_set(GNOME_CANVAS_ITEM(et->group),
+	foo_canvas_item_set(FOO_CANVAS_ITEM(et->group),
 			      "alternating_row_colors", et->alternating_row_colors,
 			      "horizontal_draw_grid", et->horizontal_draw_grid,
 			      "vertical_draw_grid", et->vertical_draw_grid,
@@ -1010,7 +1010,7 @@ changed_idle (gpointer data)
 static void
 et_canvas_realize (GtkWidget *canvas, ETable *e_table)
 {
-	gnome_canvas_item_set(
+	foo_canvas_item_set(
 		e_table->white_item,
 		"fill_color_gdk", &GTK_WIDGET(e_table->table_canvas)->style->base[GTK_STATE_NORMAL],
 		NULL);
@@ -1020,7 +1020,7 @@ et_canvas_realize (GtkWidget *canvas, ETable *e_table)
 }
 
 static gint
-white_item_event (GnomeCanvasItem *white_item, GdkEvent *event, ETable *e_table)
+white_item_event (FooCanvasItem *white_item, GdkEvent *event, ETable *e_table)
 {
 	gint return_val = 0;
 	g_signal_emit (GTK_OBJECT (e_table), et_signals [WHITE_SPACE_EVENT], 0,
@@ -1031,10 +1031,10 @@ white_item_event (GnomeCanvasItem *white_item, GdkEvent *event, ETable *e_table)
 static void
 et_eti_leave_edit (ETable *et)
 {
-	GnomeCanvas *canvas = et->table_canvas;
+	FooCanvas *canvas = et->table_canvas;
 
 	if (GTK_WIDGET_HAS_FOCUS(canvas)) {
-		GnomeCanvasItem *item = GNOME_CANVAS(canvas)->focused_item;
+		FooCanvasItem *item = FOO_CANVAS(canvas)->focused_item;
 
 		if (E_IS_TABLE_ITEM(item)) {
 			e_table_item_leave_edit_(E_TABLE_ITEM(item));
@@ -1043,7 +1043,7 @@ et_eti_leave_edit (ETable *et)
 }
 
 static gint
-et_canvas_root_event (GnomeCanvasItem *root, GdkEvent *event, ETable *e_table)
+et_canvas_root_event (FooCanvasItem *root, GdkEvent *event, ETable *e_table)
 {
 	switch (event->type) {
 	case GDK_BUTTON_PRESS:
@@ -1065,21 +1065,21 @@ et_canvas_root_event (GnomeCanvasItem *root, GdkEvent *event, ETable *e_table)
 static void
 focus_first_etable_item (ETableGroup *group)
 {
-	GnomeCanvasGroup *cgroup;
+	FooCanvasGroup *cgroup;
 	GList *l;
 
-	cgroup = GNOME_CANVAS_GROUP (group);
+	cgroup = FOO_CANVAS_GROUP (group);
 
 	for (l = cgroup->item_list; l; l = l->next) {
-		GnomeCanvasItem *i;
+		FooCanvasItem *i;
 
-		i = GNOME_CANVAS_ITEM (l->data);
+		i = FOO_CANVAS_ITEM (l->data);
 
 		if (E_IS_TABLE_GROUP (i))
 			focus_first_etable_item (E_TABLE_GROUP (i));
 		else if (E_IS_TABLE_ITEM (i)) {
 			e_table_item_set_cursor (E_TABLE_ITEM (i), 0, 0);
-			gnome_canvas_item_grab_focus (i);
+			foo_canvas_item_grab_focus (i);
 		}
 	}
 }
@@ -1090,12 +1090,12 @@ focus_first_etable_item (ETableGroup *group)
 static gint
 table_canvas_focus_event_cb (GtkWidget *widget, GdkEventFocus *event, gpointer data)
 {
-	GnomeCanvas *canvas;
+	FooCanvas *canvas;
 	ECanvas *ecanvas;
 	ETable *etable;
 
 	gtk_widget_queue_draw (widget);
-	canvas = GNOME_CANVAS (widget);
+	canvas = FOO_CANVAS (widget);
 	ecanvas = E_CANVAS (widget);
 
 	if (!event->in) {
@@ -1110,8 +1110,8 @@ table_canvas_focus_event_cb (GtkWidget *widget, GdkEventFocus *event, gpointer d
 	if (e_table_model_row_count(etable->model) < 1
 	    && (etable->click_to_add)
 	    && !(E_TABLE_CLICK_TO_ADD(etable->click_to_add)->row)) {
-		gnome_canvas_item_grab_focus (etable->canvas_vbox);
-		gnome_canvas_item_grab_focus (etable->click_to_add);
+		foo_canvas_item_grab_focus (etable->canvas_vbox);
+		foo_canvas_item_grab_focus (etable->click_to_add);
 	} else if (!canvas->focused_item && etable->group) {
 		focus_first_etable_item (etable->group);
 	} else if (canvas->focused_item) {
@@ -1119,7 +1119,7 @@ table_canvas_focus_event_cb (GtkWidget *widget, GdkEventFocus *event, gpointer d
 
 		/* check whether click_to_add already got the focus */
 		if (etable->click_to_add) {
-			GnomeCanvasItem *row = E_TABLE_CLICK_TO_ADD(etable->click_to_add)->row;
+			FooCanvasItem *row = E_TABLE_CLICK_TO_ADD(etable->click_to_add)->row;
 			if (canvas->focused_item == row)
 				return TRUE;
 		}
@@ -1143,7 +1143,7 @@ canvas_vbox_event (ECanvasVbox *vbox, GdkEventKey *key, ETable *etable)
 		case GDK_KP_Tab:
 		case GDK_ISO_Left_Tab:
 			if ((key->state & GDK_CONTROL_MASK) && etable->click_to_add) {
-				gnome_canvas_item_grab_focus (etable->click_to_add);
+				foo_canvas_item_grab_focus (etable->click_to_add);
 				break;
 			}
 		default:
@@ -1185,7 +1185,7 @@ static void
 e_table_setup_table (ETable *e_table, ETableHeader *full_header, ETableHeader *header,
 		     ETableModel *model)
 {
-	e_table->table_canvas = GNOME_CANVAS (e_canvas_new ());
+	e_table->table_canvas = FOO_CANVAS (e_canvas_new ());
 	g_signal_connect (
 		G_OBJECT (e_table->table_canvas), "size_allocate",
 		G_CALLBACK (table_canvas_size_allocate), e_table);
@@ -1226,8 +1226,8 @@ e_table_setup_table (ETable *e_table, ETableHeader *full_header, ETableHeader *h
 
 	gtk_widget_show (GTK_WIDGET (e_table->table_canvas));
 
-	e_table->white_item = gnome_canvas_item_new(
-		gnome_canvas_root(e_table->table_canvas),
+	e_table->white_item = foo_canvas_item_new(
+		foo_canvas_root(e_table->table_canvas),
 		e_canvas_background_get_type(),
 		"fill_color_gdk", &GTK_WIDGET(e_table->table_canvas)->style->base[GTK_STATE_NORMAL],
 		NULL);
@@ -1238,11 +1238,11 @@ e_table_setup_table (ETable *e_table, ETableHeader *full_header, ETableHeader *h
 	g_signal_connect (G_OBJECT(e_table->table_canvas), "realize",
 			  G_CALLBACK(et_canvas_realize), e_table);
 
-	g_signal_connect (G_OBJECT(gnome_canvas_root (e_table->table_canvas)), "event",
+	g_signal_connect (G_OBJECT(foo_canvas_root (e_table->table_canvas)), "event",
 			  G_CALLBACK(et_canvas_root_event), e_table);
 
-	e_table->canvas_vbox = gnome_canvas_item_new(
-		gnome_canvas_root(e_table->table_canvas),
+	e_table->canvas_vbox = foo_canvas_item_new(
+		foo_canvas_root(e_table->table_canvas),
 		e_canvas_vbox_get_type(),
 		"spacing", 10.0,
 		NULL);
@@ -1254,8 +1254,8 @@ e_table_setup_table (ETable *e_table, ETableHeader *full_header, ETableHeader *h
 	et_build_groups(e_table);
 
 	if (e_table->use_click_to_add) {
-		e_table->click_to_add = gnome_canvas_item_new (
-			GNOME_CANVAS_GROUP(e_table->canvas_vbox),
+		e_table->click_to_add = foo_canvas_item_new (
+			FOO_CANVAS_GROUP(e_table->canvas_vbox),
 			e_table_click_to_add_get_type (),
 			"header", e_table->header,
 			"model", e_table->model,
@@ -2156,7 +2156,7 @@ et_set_property (GObject *object,
 	case PROP_LENGTH_THRESHOLD:
 		etable->length_threshold = g_value_get_int (value);
 		if (etable->group) {
-			gnome_canvas_item_set (GNOME_CANVAS_ITEM(etable->group),
+			foo_canvas_item_set (FOO_CANVAS_ITEM(etable->group),
 					       "length_threshold", etable->length_threshold,
 					       NULL);
 		}
@@ -2164,7 +2164,7 @@ et_set_property (GObject *object,
 	case PROP_UNIFORM_ROW_HEIGHT:
 		etable->uniform_row_height = g_value_get_boolean (value);
 		if (etable->group) {
-			gnome_canvas_item_set (GNOME_CANVAS_ITEM(etable->group),
+			foo_canvas_item_set (FOO_CANVAS_ITEM(etable->group),
 					       "uniform_row_height", etable->uniform_row_height,
 					       NULL);
 		}
@@ -2184,8 +2184,8 @@ et_set_property (GObject *object,
 		clear_current_search_col (etable);
 
 		if (etable->use_click_to_add) {
-			etable->click_to_add = gnome_canvas_item_new
-				(GNOME_CANVAS_GROUP(etable->canvas_vbox),
+			etable->click_to_add = foo_canvas_item_new
+				(FOO_CANVAS_GROUP(etable->canvas_vbox),
 				 e_table_click_to_add_get_type (),
 				 "header", etable->header,
 				 "model", etable->model,
@@ -2572,15 +2572,15 @@ e_table_drag_highlight (ETable *table,
 
 		if (table->drop_highlight == NULL) {
 			table->drop_highlight =
-				gnome_canvas_item_new (gnome_canvas_root (table->table_canvas),
-						       gnome_canvas_rect_get_type (),
+				foo_canvas_item_new (foo_canvas_root (table->table_canvas),
+						       foo_canvas_rect_get_type (),
 						       "fill_color", NULL,
 						       /*						       "outline_color", "black",
 						       "width_pixels", 1,*/
 						       "outline_color_gdk", &(GTK_WIDGET (table)->style->fg[GTK_STATE_NORMAL]),
 						       NULL);
 		}
-		gnome_canvas_item_set (table->drop_highlight,
+		foo_canvas_item_set (table->drop_highlight,
 				       "x1", (double) x,
 				       "x2", (double) x + width - 1,
 				       "y1", (double) y,
diff --git a/widgets/table/e-table.h b/widgets/table/e-table.h
index bb82ef1..2282caa 100644
--- a/widgets/table/e-table.h
+++ b/widgets/table/e-table.h
@@ -24,7 +24,7 @@
 #ifndef _E_TABLE_H_
 #define _E_TABLE_H_
 
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 #include <gtk/gtk.h>
 #include <libxml/tree.h>
 #include <table/e-table-model.h>
@@ -63,7 +63,7 @@ typedef struct {
 
 	ETableHeader *full_header, *header;
 
-	GnomeCanvasItem *canvas_vbox;
+	FooCanvasItem *canvas_vbox;
 	ETableGroup  *group;
 
 	ETableSortInfo *sort_info;
@@ -96,11 +96,11 @@ typedef struct {
 	gint reflow_idle_id;
 	gint scroll_idle_id;
 
-	GnomeCanvas *header_canvas, *table_canvas;
+	FooCanvas *header_canvas, *table_canvas;
 
-	GnomeCanvasItem *header_item, *root;
+	FooCanvasItem *header_item, *root;
 
-	GnomeCanvasItem *white_item;
+	FooCanvasItem *white_item;
 
 	gint length_threshold;
 
@@ -132,7 +132,7 @@ typedef struct {
 	guint search_col_set : 1;
 
 	gchar *click_to_add_message;
-	GnomeCanvasItem *click_to_add;
+	FooCanvasItem *click_to_add;
 	gboolean use_click_to_add;
 	gboolean use_click_to_add_end;
 
@@ -140,7 +140,7 @@ typedef struct {
 
 	gint drop_row;
 	gint drop_col;
-	GnomeCanvasItem *drop_highlight;
+	FooCanvasItem *drop_highlight;
 	gint last_drop_x;
 	gint last_drop_y;
 	gint last_drop_time;
diff --git a/widgets/table/e-tree-scrolled.c b/widgets/table/e-tree-scrolled.c
index eac8044..334bc48 100644
--- a/widgets/table/e-tree-scrolled.c
+++ b/widgets/table/e-tree-scrolled.c
@@ -27,7 +27,7 @@
 #include <stdio.h>
 #include <string.h>
 
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 #include <gtk/gtk.h>
 #include <libxml/parser.h>
 #include <libxml/xmlmemory.h>
diff --git a/widgets/table/e-tree.c b/widgets/table/e-tree.c
index 38c7a51..c467261 100644
--- a/widgets/table/e-tree.c
+++ b/widgets/table/e-tree.c
@@ -28,7 +28,7 @@
 
 #include <gdk/gdkkeysyms.h>
 #include <gtk/gtk.h>
-#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
+#include <libfoocanvas/foo-canvas-rect-ellipse.h>
 
 #include "gal-a11y-e-tree.h"
 #include <glib/gi18n.h>
@@ -36,6 +36,7 @@
 #include "misc/e-canvas.h"
 #include "misc/e-canvas-utils.h"
 #include "misc/e-canvas-background.h"
+#include "libfoocanvas/foo-canvas.h"
 #include "text/e-text.h"
 
 #include "e-table-column-specification.h"
@@ -139,15 +140,15 @@ struct ETreePriv {
 	gint table_cell_change_id;
 	gint table_rows_delete_id;
 
-	GnomeCanvasItem *info_text;
+	FooCanvasItem *info_text;
 	guint info_text_resize_id;
 
-	GnomeCanvas *header_canvas, *table_canvas;
+	FooCanvas *header_canvas, *table_canvas;
 
-	GnomeCanvasItem *header_item, *root;
+	FooCanvasItem *header_item, *root;
 
-	GnomeCanvasItem *white_item;
-	GnomeCanvasItem *item;
+	FooCanvasItem *white_item;
+	FooCanvasItem *item;
 
 	gint length_threshold;
 
@@ -177,7 +178,7 @@ struct ETreePriv {
 	ETreePath drop_path;
 	gint drop_col;
 
-	GnomeCanvasItem *drop_highlight;
+	FooCanvasItem *drop_highlight;
 	gint last_drop_x;
 	gint last_drop_y;
 	gint last_drop_time;
@@ -665,15 +666,15 @@ set_header_canvas_width (ETree *e_tree)
 	if (!(e_tree->priv->header_item && e_tree->priv->header_canvas && e_tree->priv->table_canvas))
 		return;
 
-	gnome_canvas_get_scroll_region (GNOME_CANVAS (e_tree->priv->table_canvas),
+	foo_canvas_get_scroll_region (FOO_CANVAS (e_tree->priv->table_canvas),
 					NULL, NULL, &width, NULL);
-	gnome_canvas_get_scroll_region (GNOME_CANVAS (e_tree->priv->header_canvas),
+	foo_canvas_get_scroll_region (FOO_CANVAS (e_tree->priv->header_canvas),
 					NULL, NULL, &oldwidth, &oldheight);
 
 	if (oldwidth != width ||
 	    oldheight != E_TABLE_HEADER_ITEM (e_tree->priv->header_item)->height - 1)
-		gnome_canvas_set_scroll_region (
-						GNOME_CANVAS (e_tree->priv->header_canvas),
+		foo_canvas_set_scroll_region (
+						FOO_CANVAS (e_tree->priv->header_canvas),
 						0, 0, width, /*  COLUMN_HEADER_HEIGHT - 1 */
 						E_TABLE_HEADER_ITEM (e_tree->priv->header_item)->height - 1);
 
@@ -698,15 +699,15 @@ static void
 e_tree_setup_header (ETree *e_tree)
 {
 	gchar *pointer;
-	e_tree->priv->header_canvas = GNOME_CANVAS (e_canvas_new ());
+	e_tree->priv->header_canvas = FOO_CANVAS (e_canvas_new ());
 	GTK_WIDGET_UNSET_FLAGS (e_tree->priv->header_canvas, GTK_CAN_FOCUS);
 
 	gtk_widget_show (GTK_WIDGET (e_tree->priv->header_canvas));
 
 	pointer = g_strdup_printf("%p", (gpointer) e_tree);
 
-	e_tree->priv->header_item = gnome_canvas_item_new (
-		gnome_canvas_root (e_tree->priv->header_canvas),
+	e_tree->priv->header_item = foo_canvas_item_new (
+		foo_canvas_root (e_tree->priv->header_canvas),
 		e_table_header_item_get_type (),
 		"ETableHeader", e_tree->priv->header,
 		"full_header", e_tree->priv->full_header,
@@ -740,12 +741,12 @@ tree_canvas_reflow_idle (ETree *e_tree)
 	height = MAX ((gint)height, alloc->height);
 	width = MAX((gint)width, alloc->width);
 	/* I have no idea why this needs to be -1, but it works. */
-	gnome_canvas_get_scroll_region (GNOME_CANVAS (e_tree->priv->table_canvas),
+	foo_canvas_get_scroll_region (FOO_CANVAS (e_tree->priv->table_canvas),
 					NULL, NULL, &oldwidth, &oldheight);
 
 	if (oldwidth != width - 1 ||
 	    oldheight != height - 1) {
-		gnome_canvas_set_scroll_region (GNOME_CANVAS (e_tree->priv->table_canvas),
+		foo_canvas_set_scroll_region (FOO_CANVAS (e_tree->priv->table_canvas),
 						0, 0, width - 1, height - 1);
 		set_header_canvas_width (e_tree);
 	}
@@ -797,7 +798,7 @@ tree_canvas_size_allocate (GtkWidget *widget, GtkAllocation *alloc,
 }
 
 static void
-tree_canvas_reflow (GnomeCanvas *canvas, ETree *e_tree)
+tree_canvas_reflow (FooCanvas *canvas, ETree *e_tree)
 {
 	if (!e_tree->priv->reflow_idle_id)
 		e_tree->priv->reflow_idle_id = g_idle_add_full (400, (GSourceFunc) tree_canvas_reflow_idle, e_tree, NULL);
@@ -975,7 +976,7 @@ et_selection_model_selection_row_changed (ETableSelectionModel *etsm, gint row,
 static void
 et_build_item (ETree *et)
 {
-	et->priv->item = gnome_canvas_item_new(GNOME_CANVAS_GROUP (gnome_canvas_root(et->priv->table_canvas)),
+	et->priv->item = foo_canvas_item_new(FOO_CANVAS_GROUP (foo_canvas_root(et->priv->table_canvas)),
 					 e_table_item_get_type(),
 					 "ETableHeader", et->priv->header,
 					 "ETableModel", et->priv->etta,
@@ -1008,14 +1009,14 @@ et_build_item (ETree *et)
 static void
 et_canvas_style_set (GtkWidget *widget, GtkStyle *prev_style)
 {
-	gnome_canvas_item_set(
+	foo_canvas_item_set(
 		E_TREE(widget)->priv->white_item,
 		"fill_color_gdk", &widget->style->base[GTK_STATE_NORMAL],
 		NULL);
 }
 
 static gint
-white_item_event (GnomeCanvasItem *white_item, GdkEvent *event, ETree *e_tree)
+white_item_event (FooCanvasItem *white_item, GdkEvent *event, ETree *e_tree)
 {
 	gint return_val = 0;
 	g_signal_emit (e_tree,
@@ -1025,7 +1026,7 @@ white_item_event (GnomeCanvasItem *white_item, GdkEvent *event, ETree *e_tree)
 }
 
 static gint
-et_canvas_root_event (GnomeCanvasItem *root, GdkEvent *event, ETree *e_tree)
+et_canvas_root_event (FooCanvasItem *root, GdkEvent *event, ETree *e_tree)
 {
 	switch (event->type) {
 	case GDK_BUTTON_PRESS:
@@ -1033,7 +1034,7 @@ et_canvas_root_event (GnomeCanvasItem *root, GdkEvent *event, ETree *e_tree)
 	case GDK_BUTTON_RELEASE:
 		if (event->button.button != 4 && event->button.button != 5) {
 			if (GTK_WIDGET_HAS_FOCUS(root->canvas)) {
-				GnomeCanvasItem *item = GNOME_CANVAS(root->canvas)->focused_item;
+				FooCanvasItem *item = FOO_CANVAS(root->canvas)->focused_item;
 
 				if (E_IS_TABLE_ITEM(item)) {
 					e_table_item_leave_edit_(E_TABLE_ITEM(item));
@@ -1055,7 +1056,7 @@ et_canvas_root_event (GnomeCanvasItem *root, GdkEvent *event, ETree *e_tree)
 static gint
 table_canvas_focus_event_cb (GtkWidget *widget, GdkEventFocus *event, gpointer data)
 {
-	GnomeCanvas *canvas;
+	FooCanvas *canvas;
 	ETree *tree;
 
 	gtk_widget_queue_draw (widget);
@@ -1063,12 +1064,12 @@ table_canvas_focus_event_cb (GtkWidget *widget, GdkEventFocus *event, gpointer d
 	if (!event->in)
 		return TRUE;
 
-	canvas = GNOME_CANVAS (widget);
+	canvas = FOO_CANVAS (widget);
 	tree = E_TREE (data);
 
 	if (!canvas->focused_item || (e_selection_model_cursor_row (tree->priv->selection) == -1)) {
 		e_table_item_set_cursor (E_TABLE_ITEM (tree->priv->item), 0, 0);
-		gnome_canvas_item_grab_focus (tree->priv->item);
+		foo_canvas_item_grab_focus (tree->priv->item);
 	}
 
 	return TRUE;
@@ -1077,7 +1078,7 @@ table_canvas_focus_event_cb (GtkWidget *widget, GdkEventFocus *event, gpointer d
 static void
 e_tree_setup_table (ETree *e_tree)
 {
-	e_tree->priv->table_canvas = GNOME_CANVAS (e_canvas_new ());
+	e_tree->priv->table_canvas = FOO_CANVAS (e_canvas_new ());
 	g_signal_connect (
 		e_tree->priv->table_canvas, "size_allocate",
 		G_CALLBACK (tree_canvas_size_allocate), e_tree);
@@ -1118,8 +1119,8 @@ e_tree_setup_table (ETree *e_tree)
 
 	gtk_widget_show (GTK_WIDGET (e_tree->priv->table_canvas));
 
-	e_tree->priv->white_item = gnome_canvas_item_new(
-		gnome_canvas_root(e_tree->priv->table_canvas),
+	e_tree->priv->white_item = foo_canvas_item_new(
+		foo_canvas_root(e_tree->priv->table_canvas),
 		e_canvas_background_get_type(),
 		"fill_color_gdk", &GTK_WIDGET(e_tree->priv->table_canvas)->style->base[GTK_STATE_NORMAL],
 		NULL);
@@ -1127,7 +1128,7 @@ e_tree_setup_table (ETree *e_tree)
 	g_signal_connect (e_tree->priv->white_item, "event",
 			  G_CALLBACK (white_item_event), e_tree);
 	g_signal_connect (
-		gnome_canvas_root (e_tree->priv->table_canvas), "event",
+		foo_canvas_root (e_tree->priv->table_canvas), "event",
 		G_CALLBACK(et_canvas_root_event), e_tree);
 
 	et_build_item(e_tree);
@@ -1840,7 +1841,7 @@ et_set_property (GObject *object,
 	case PROP_LENGTH_THRESHOLD:
 		etree->priv->length_threshold = g_value_get_int (value);
 		if (etree->priv->item) {
-			gnome_canvas_item_set (GNOME_CANVAS_ITEM(etree->priv->item),
+			foo_canvas_item_set (FOO_CANVAS_ITEM(etree->priv->item),
 					       "length_threshold", etree->priv->length_threshold,
 					       NULL);
 		}
@@ -1849,7 +1850,7 @@ et_set_property (GObject *object,
 	case PROP_HORIZONTAL_DRAW_GRID:
 		etree->priv->horizontal_draw_grid = g_value_get_boolean (value);
 		if (etree->priv->item) {
-			gnome_canvas_item_set (GNOME_CANVAS_ITEM(etree->priv->item),
+			foo_canvas_item_set (FOO_CANVAS_ITEM(etree->priv->item),
 					       "horizontal_draw_grid", etree->priv->horizontal_draw_grid,
 					       NULL);
 		}
@@ -1858,7 +1859,7 @@ et_set_property (GObject *object,
 	case PROP_VERTICAL_DRAW_GRID:
 		etree->priv->vertical_draw_grid = g_value_get_boolean (value);
 		if (etree->priv->item) {
-			gnome_canvas_item_set (GNOME_CANVAS_ITEM(etree->priv->item),
+			foo_canvas_item_set (FOO_CANVAS_ITEM(etree->priv->item),
 					       "vertical_draw_grid", etree->priv->vertical_draw_grid,
 					       NULL);
 		}
@@ -1867,7 +1868,7 @@ et_set_property (GObject *object,
 	case PROP_DRAW_FOCUS:
 		etree->priv->draw_focus = g_value_get_boolean (value);
 		if (etree->priv->item) {
-			gnome_canvas_item_set (GNOME_CANVAS_ITEM(etree->priv->item),
+			foo_canvas_item_set (FOO_CANVAS_ITEM(etree->priv->item),
 					       "drawfocus", etree->priv->draw_focus,
 					       NULL);
 		}
@@ -1876,7 +1877,7 @@ et_set_property (GObject *object,
 	case PROP_UNIFORM_ROW_HEIGHT:
 		etree->priv->uniform_row_height = g_value_get_boolean (value);
 		if (etree->priv->item) {
-			gnome_canvas_item_set (GNOME_CANVAS_ITEM(etree->priv->item),
+			foo_canvas_item_set (FOO_CANVAS_ITEM(etree->priv->item),
 					       "uniform_row_height", etree->priv->uniform_row_height,
 					       NULL);
 		}
@@ -2238,7 +2239,7 @@ e_tree_get_item(ETree * et)
 	return E_TABLE_ITEM (et->priv->item);
 }
 
-GnomeCanvasItem *
+FooCanvasItem *
 e_tree_get_header_item(ETree * et)
 {
 	g_return_val_if_fail (et != NULL, NULL);
@@ -2366,15 +2367,15 @@ e_tree_drag_highlight (ETree *tree,
 
 		if (tree->priv->drop_highlight == NULL) {
 			tree->priv->drop_highlight =
-				gnome_canvas_item_new (gnome_canvas_root (tree->priv->table_canvas),
-						       gnome_canvas_rect_get_type (),
+				foo_canvas_item_new (foo_canvas_root (tree->priv->table_canvas),
+						       foo_canvas_rect_get_type (),
 						       "fill_color", NULL,
 						       /*						       "outline_color", "black",
 						       "width_pixels", 1,*/
 						       "outline_color_gdk", &(GTK_WIDGET (tree)->style->fg[GTK_STATE_NORMAL]),
 						       NULL);
 		}
-		gnome_canvas_item_set (tree->priv->drop_highlight,
+		foo_canvas_item_set (tree->priv->drop_highlight,
 				       "x1", (double) x,
 				       "x2", (double) x + width - 1,
 				       "y1", (double) y,
@@ -3402,7 +3403,7 @@ tree_size_allocate (GtkWidget *widget, GtkAllocation *alloc, ETree *tree)
 	g_return_if_fail (tree->priv != NULL);
 	g_return_if_fail (tree->priv->info_text != NULL);
 
-	gnome_canvas_get_scroll_region (GNOME_CANVAS (tree->priv->table_canvas), NULL, NULL, &width, NULL);
+	foo_canvas_get_scroll_region (FOO_CANVAS (tree->priv->table_canvas), NULL, NULL, &width, NULL);
 
 	width -= 60.0;
 
@@ -3433,7 +3434,7 @@ e_tree_set_info_message (ETree *tree, const gchar *info_message)
 	}
 
 	if (!tree->priv->info_text) {
-		tree->priv->info_text = gnome_canvas_item_new (GNOME_CANVAS_GROUP (gnome_canvas_root (tree->priv->table_canvas)),
+		tree->priv->info_text = foo_canvas_item_new (FOO_CANVAS_GROUP (foo_canvas_root (tree->priv->table_canvas)),
 						e_text_get_type (),
 						"anchor", GTK_ANCHOR_NW,
 						"line_wrap", TRUE,
@@ -3449,5 +3450,5 @@ e_tree_set_info_message (ETree *tree, const gchar *info_message)
 
 		tree->priv->info_text_resize_id = g_signal_connect (tree, "size_allocate", G_CALLBACK (tree_size_allocate), tree);
 	} else
-		gnome_canvas_item_set (tree->priv->info_text, "text", info_message, NULL);
+		foo_canvas_item_set (tree->priv->info_text, "text", info_message, NULL);
 }
diff --git a/widgets/table/e-tree.h b/widgets/table/e-tree.h
index b746156..d5c0a78 100644
--- a/widgets/table/e-tree.h
+++ b/widgets/table/e-tree.h
@@ -25,7 +25,6 @@
 
 #include <gtk/gtk.h>
 #include <libxml/tree.h>
-#include <libgnomecanvas/gnome-canvas.h>
 #include <misc/e-printable.h>
 
 #include <table/e-table-extras.h>
@@ -309,7 +308,7 @@ void            e_tree_right_click_up             (ETree                *et);
 
 ETableItem *	e_tree_get_item(ETree * et);
 
-GnomeCanvasItem * e_tree_get_header_item(ETree * et);
+FooCanvasItem * e_tree_get_header_item(ETree * et);
 
 void e_tree_set_info_message (ETree *tree, const gchar *info_message);
 
diff --git a/widgets/table/gal-a11y-e-cell-popup.c b/widgets/table/gal-a11y-e-cell-popup.c
index 141ce17..2341cbd 100644
--- a/widgets/table/gal-a11y-e-cell-popup.c
+++ b/widgets/table/gal-a11y-e-cell-popup.c
@@ -134,7 +134,7 @@ popup_cell_action (GalA11yECell *cell)
 	GdkEvent event;
 
 	event.key.type = GDK_KEY_PRESS;
-	event.key.window = GTK_LAYOUT(GNOME_CANVAS_ITEM(cell->item)->canvas)->bin_window;;
+	event.key.window = GTK_LAYOUT(FOO_CANVAS_ITEM(cell->item)->canvas)->bin_window;;
 	event.key.send_event = TRUE;
 	event.key.time = GDK_CURRENT_TIME;
 	event.key.state = GDK_MOD1_MASK;
diff --git a/widgets/table/gal-a11y-e-cell-toggle.c b/widgets/table/gal-a11y-e-cell-toggle.c
index fa23f6c..d0d5e95 100644
--- a/widgets/table/gal-a11y-e-cell-toggle.c
+++ b/widgets/table/gal-a11y-e-cell-toggle.c
@@ -100,11 +100,11 @@ toggle_cell_action (GalA11yECell *cell)
 	e_table_item_get_cell_geometry (cell->item, &row, &col,
 					&x, &y, &width, &height);
 
-	event.x = x + width / 2 + (gint)(GNOME_CANVAS_ITEM (cell->item)->x1);
-	event.y = y + height / 2 + (gint)(GNOME_CANVAS_ITEM (cell->item)->y1);
+	event.x = x + width / 2 + (gint)(FOO_CANVAS_ITEM (cell->item)->x1);
+	event.y = y + height / 2 + (gint)(FOO_CANVAS_ITEM (cell->item)->y1);
 
 	event.type = GDK_BUTTON_PRESS;
-	event.window = GTK_LAYOUT(GNOME_CANVAS_ITEM(cell->item)->canvas)->bin_window;
+	event.window = GTK_LAYOUT(FOO_CANVAS_ITEM(cell->item)->canvas)->bin_window;
         event.button = 1;
         event.send_event = TRUE;
         event.time = GDK_CURRENT_TIME;
diff --git a/widgets/table/gal-a11y-e-cell.c b/widgets/table/gal-a11y-e-cell.c
index 211afa4..a032762 100644
--- a/widgets/table/gal-a11y-e-cell.c
+++ b/widgets/table/gal-a11y-e-cell.c
@@ -209,8 +209,8 @@ gal_a11y_e_cell_grab_focus (AtkComponent *component)
 	atk_selection_clear_selection (ATK_SELECTION (a11yTableItem));
 	atk_selection_add_selection (ATK_SELECTION (a11yTableItem), index);
 
-	gtk_widget_grab_focus (GTK_WIDGET (GNOME_CANVAS_ITEM (a11y->item)->canvas));
-	toplevel = gtk_widget_get_toplevel (GTK_WIDGET (GNOME_CANVAS_ITEM (a11y->item)->canvas));
+	gtk_widget_grab_focus (GTK_WIDGET (FOO_CANVAS_ITEM (a11y->item)->canvas));
+	toplevel = gtk_widget_get_toplevel (GTK_WIDGET (FOO_CANVAS_ITEM (a11y->item)->canvas));
 	if (toplevel && GTK_WIDGET_TOPLEVEL (toplevel))
 		gtk_window_present (GTK_WINDOW (toplevel));
 
diff --git a/widgets/table/gal-a11y-e-table-click-to-add.c b/widgets/table/gal-a11y-e-table-click-to-add.c
index 225f24c..ddc6595 100644
--- a/widgets/table/gal-a11y-e-table-click-to-add.c
+++ b/widgets/table/gal-a11y-e-table-click-to-add.c
@@ -85,7 +85,7 @@ idle_do_action (gpointer data)
 	event.y = 0;
 
         event.type = GDK_BUTTON_PRESS;
-        event.window = GTK_LAYOUT(GNOME_CANVAS_ITEM(etcta)->canvas)->bin_window;
+        event.window = GTK_LAYOUT(FOO_CANVAS_ITEM(etcta)->canvas)->bin_window;
         event.button = 1;
         event.send_event = TRUE;
         event.time = GDK_CURRENT_TIME;
@@ -230,7 +230,7 @@ gal_a11y_e_table_click_to_add_get_type (void)
 			NULL
 		};
 
-                factory = atk_registry_get_factory (atk_get_default_registry (), GNOME_TYPE_CANVAS_ITEM);
+                factory = atk_registry_get_factory (atk_get_default_registry (), FOO_TYPE_CANVAS_ITEM);
 
 		parent_type = atk_object_factory_get_accessible_type (factory);
                 type = gal_a11y_type_register_static_with_private (PARENT_TYPE,
@@ -245,7 +245,7 @@ gal_a11y_e_table_click_to_add_get_type (void)
 }
 
 static gboolean
-etcta_event (GnomeCanvasItem *item, GdkEvent *e, gpointer data)
+etcta_event (FooCanvasItem *item, GdkEvent *e, gpointer data)
 {
         ETableClickToAdd *etcta = E_TABLE_CLICK_TO_ADD (item);
 	GalA11yETableClickToAdd *a11y;
diff --git a/widgets/table/gal-a11y-e-table-item.c b/widgets/table/gal-a11y-e-table-item.c
index 37f55f6..1e7aecd 100644
--- a/widgets/table/gal-a11y-e-table-item.c
+++ b/widgets/table/gal-a11y-e-table-item.c
@@ -995,7 +995,7 @@ gal_a11y_e_table_item_get_type (void)
 			NULL
 		};
 
-		factory = atk_registry_get_factory (atk_get_default_registry (), GNOME_TYPE_CANVAS_ITEM);
+		factory = atk_registry_get_factory (atk_get_default_registry (), FOO_TYPE_CANVAS_ITEM);
 		parent_type = atk_object_factory_get_accessible_type (factory);
 
 		type = gal_a11y_type_register_static_with_private (PARENT_TYPE, "GalA11yETableItem", &info, 0,
@@ -1240,7 +1240,7 @@ selection_add_selection (AtkSelection *selection, gint index)
 
 	if (model_row != cursor_row) {
 		/* we need to make the item get focus */
-		e_canvas_item_grab_focus (GNOME_CANVAS_ITEM (item), TRUE);
+		e_canvas_item_grab_focus (FOO_CANVAS_ITEM (item), TRUE);
 
 		/* FIXME, currently we only support single row selection */
 		atk_selection_clear_selection (selection);
diff --git a/widgets/table/gal-a11y-e-table.c b/widgets/table/gal-a11y-e-table.c
index bf75227..df1fc8d 100644
--- a/widgets/table/gal-a11y-e-table.c
+++ b/widgets/table/gal-a11y-e-table.c
@@ -48,15 +48,15 @@ struct _GalA11yETablePrivate {
 static ETableItem *
 find_first_table_item (ETableGroup *group)
 {
-	GnomeCanvasGroup *cgroup;
+	FooCanvasGroup *cgroup;
 	GList *l;
 
-	cgroup = GNOME_CANVAS_GROUP (group);
+	cgroup = FOO_CANVAS_GROUP (group);
 
 	for (l = cgroup->item_list; l; l = l->next) {
-		GnomeCanvasItem *i;
+		FooCanvasItem *i;
 
-		i = GNOME_CANVAS_ITEM (l->data);
+		i = FOO_CANVAS_ITEM (l->data);
 
 		if (E_IS_TABLE_GROUP (i))
 			return find_first_table_item (E_TABLE_GROUP (i));
diff --git a/widgets/text/e-reflow-model.c b/widgets/text/e-reflow-model.c
index 1eaccda..13d5f15 100644
--- a/widgets/text/e-reflow-model.c
+++ b/widgets/text/e-reflow-model.c
@@ -76,12 +76,12 @@ e_reflow_model_count (EReflowModel *e_reflow_model)
  * e_reflow_model_height:
  * @e_reflow_model: The e-reflow-model to operate on
  * @n: The item number to get the height of.
- * @parent: The parent GnomeCanvasItem.
+ * @parent: The parent FooCanvasItem.
  *
  * Returns: the height of the nth item.
  */
 gint
-e_reflow_model_height (EReflowModel *e_reflow_model, gint n, GnomeCanvasGroup *parent)
+e_reflow_model_height (EReflowModel *e_reflow_model, gint n, FooCanvasGroup *parent)
 {
 	g_return_val_if_fail (e_reflow_model != NULL, 0);
 	g_return_val_if_fail (E_IS_REFLOW_MODEL (e_reflow_model), 0);
@@ -93,14 +93,14 @@ e_reflow_model_height (EReflowModel *e_reflow_model, gint n, GnomeCanvasGroup *p
  * e_reflow_model_incarnate:
  * @e_reflow_model: The e-reflow-model to operate on
  * @n: The item to create.
- * @parent: The parent GnomeCanvasItem to create a child of.
+ * @parent: The parent FooCanvasItem to create a child of.
  *
- * Create a GnomeCanvasItem to represent the nth piece of data.
+ * Create a FooCanvasItem to represent the nth piece of data.
  *
- * Returns: the new GnomeCanvasItem.
+ * Returns: the new FooCanvasItem.
  */
-GnomeCanvasItem *
-e_reflow_model_incarnate (EReflowModel *e_reflow_model, gint n, GnomeCanvasGroup *parent)
+FooCanvasItem *
+e_reflow_model_incarnate (EReflowModel *e_reflow_model, gint n, FooCanvasGroup *parent)
 {
 	g_return_val_if_fail (e_reflow_model != NULL, NULL);
 	g_return_val_if_fail (E_IS_REFLOW_MODEL (e_reflow_model), NULL);
@@ -138,7 +138,7 @@ e_reflow_model_compare (EReflowModel *e_reflow_model, gint n1, gint n2)
  * Update item to represent the nth piece of data.
  */
 void
-e_reflow_model_reincarnate (EReflowModel *e_reflow_model, gint n, GnomeCanvasItem *item)
+e_reflow_model_reincarnate (EReflowModel *e_reflow_model, gint n, FooCanvasItem *item)
 {
 	g_return_if_fail (e_reflow_model != NULL);
 	g_return_if_fail (E_IS_REFLOW_MODEL (e_reflow_model));
diff --git a/widgets/text/e-reflow-model.h b/widgets/text/e-reflow-model.h
index ebbf3c1..214dcb7 100644
--- a/widgets/text/e-reflow-model.h
+++ b/widgets/text/e-reflow-model.h
@@ -25,7 +25,7 @@
 #define _E_REFLOW_MODEL_H_
 
 #include <glib-object.h>
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 
 G_BEGIN_DECLS
 
@@ -49,10 +49,10 @@ typedef struct {
 	void             (*set_width)      (EReflowModel *etm, gint width);
 
 	gint              (*count)          (EReflowModel *etm);
-	gint              (*height)         (EReflowModel *etm, gint n, GnomeCanvasGroup *parent);
-	GnomeCanvasItem *(*incarnate)      (EReflowModel *etm, gint n, GnomeCanvasGroup *parent);
+	gint              (*height)         (EReflowModel *etm, gint n, FooCanvasGroup *parent);
+	FooCanvasItem *(*incarnate)      (EReflowModel *etm, gint n, FooCanvasGroup *parent);
 	gint              (*compare)        (EReflowModel *etm, gint n1, gint n2);
-	void             (*reincarnate)    (EReflowModel *etm, gint n, GnomeCanvasItem *item);
+	void             (*reincarnate)    (EReflowModel *etm, gint n, FooCanvasItem *item);
 
 	/*
 	 * Signals
@@ -79,16 +79,16 @@ void             e_reflow_model_set_width       (EReflowModel     *e_reflow_mode
 gint              e_reflow_model_count           (EReflowModel     *e_reflow_model);
 gint              e_reflow_model_height          (EReflowModel     *e_reflow_model,
 						 gint               n,
-						 GnomeCanvasGroup *parent);
-GnomeCanvasItem *e_reflow_model_incarnate       (EReflowModel     *e_reflow_model,
+						 FooCanvasGroup *parent);
+FooCanvasItem *e_reflow_model_incarnate       (EReflowModel     *e_reflow_model,
 						 gint               n,
-						 GnomeCanvasGroup *parent);
+						 FooCanvasGroup *parent);
 gint              e_reflow_model_compare         (EReflowModel     *e_reflow_model,
 						 gint               n1,
 						 gint               n2);
 void             e_reflow_model_reincarnate     (EReflowModel     *e_reflow_model,
 						 gint               n,
-						 GnomeCanvasItem  *item);
+						 FooCanvasItem  *item);
 
 /*
  * Routines for emitting signals on the e_reflow
diff --git a/widgets/text/e-reflow.c b/widgets/text/e-reflow.c
index 705678b..381efea 100644
--- a/widgets/text/e-reflow.c
+++ b/widgets/text/e-reflow.c
@@ -37,23 +37,23 @@
 #include "e-reflow.h"
 #include "misc/e-selection-model-simple.h"
 
-static gboolean e_reflow_event (GnomeCanvasItem *item, GdkEvent *event);
-static void e_reflow_realize (GnomeCanvasItem *item);
-static void e_reflow_unrealize (GnomeCanvasItem *item);
-static void e_reflow_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
-				    gint x, gint y, gint width, gint height);
-static void e_reflow_update (GnomeCanvasItem *item, double affine[6], ArtSVP *clip_path, gint flags);
-static double e_reflow_point (GnomeCanvasItem *item, double x, double y, gint cx, gint cy, GnomeCanvasItem **actual_item);
-static void e_reflow_reflow (GnomeCanvasItem *item, gint flags);
+static gboolean e_reflow_event (FooCanvasItem *item, GdkEvent *event);
+static void e_reflow_realize (FooCanvasItem *item);
+static void e_reflow_unrealize (FooCanvasItem *item);
+static void e_reflow_draw (FooCanvasItem *item, GdkDrawable *drawable,
+				    GdkEventExpose *expose);
+static void e_reflow_update (FooCanvasItem *item, double i2w_dx, double i2w_dy, gint flags);
+static double e_reflow_point (FooCanvasItem *item, double x, double y, gint cx, gint cy, FooCanvasItem **actual_item);
+static void e_reflow_reflow (FooCanvasItem *item, gint flags);
 static void set_empty(EReflow *reflow);
 
-static void e_reflow_resize_children (GnomeCanvasItem *item);
+static void e_reflow_resize_children (FooCanvasItem *item);
 
 #define E_REFLOW_DIVIDER_WIDTH 2
 #define E_REFLOW_BORDER_WIDTH 7
 #define E_REFLOW_FULL_GUTTER (E_REFLOW_DIVIDER_WIDTH + E_REFLOW_BORDER_WIDTH * 2)
 
-G_DEFINE_TYPE (EReflow, e_reflow, GNOME_TYPE_CANVAS_GROUP)
+G_DEFINE_TYPE (EReflow, e_reflow, FOO_TYPE_CANVAS_GROUP)
 
 /* The arguments we take */
 enum {
@@ -90,7 +90,7 @@ e_reflow_pick_line (EReflow *reflow, double x)
 }
 
 static gint
-er_find_item (EReflow *reflow, GnomeCanvasItem *item)
+er_find_item (EReflow *reflow, FooCanvasItem *item)
 {
 	gint i;
 	for (i = 0; i < reflow->count; i++) {
@@ -101,7 +101,7 @@ er_find_item (EReflow *reflow, GnomeCanvasItem *item)
 }
 
 static void
-e_reflow_resize_children (GnomeCanvasItem *item)
+e_reflow_resize_children (FooCanvasItem *item)
 {
 	EReflow *reflow;
 	gint i;
@@ -112,7 +112,7 @@ e_reflow_resize_children (GnomeCanvasItem *item)
 	count = reflow->count;
 	for (i = 0; i < count; i++) {
 		if (reflow->items[i])
-			gnome_canvas_item_set(reflow->items[i],
+			foo_canvas_item_set(reflow->items[i],
 					      "width", (double) reflow->column_width,
 					      NULL);
 	}
@@ -126,7 +126,7 @@ e_reflow_update_selection_row (EReflow *reflow, gint row)
 			     "selected", e_selection_model_is_row_selected(E_SELECTION_MODEL(reflow->selection), row),
 			     NULL);
 	} else if (e_selection_model_is_row_selected (E_SELECTION_MODEL (reflow->selection), row)) {
-		reflow->items[row] = e_reflow_model_incarnate (reflow->model, row, GNOME_CANVAS_GROUP (reflow));
+		reflow->items[row] = e_reflow_model_incarnate (reflow->model, row, FOO_CANVAS_GROUP (reflow));
 		g_object_set (reflow->items[row],
 			      "selected", e_selection_model_is_row_selected(E_SELECTION_MODEL(reflow->selection), row),
 			      "width", (double) reflow->column_width,
@@ -170,7 +170,7 @@ do_adjustment (gpointer user_data)
 	if (row == -1)
 		return FALSE;
 
-	adj = gtk_layout_get_hadjustment (GTK_LAYOUT (GNOME_CANVAS_ITEM (reflow)->canvas));
+	adj = gtk_layout_get_hadjustment (GTK_LAYOUT (FOO_CANVAS_ITEM (reflow)->canvas));
 	value = adj->value;
 
 	if ((!reflow->items) || (!reflow->items[row]))
@@ -216,7 +216,7 @@ cursor_changed (ESelectionModel *selection, gint row, gint col, EReflow *reflow)
 				      "has_cursor", TRUE,
 				      NULL);
 		} else {
-			reflow->items[row] = e_reflow_model_incarnate (reflow->model, row, GNOME_CANVAS_GROUP (reflow));
+			reflow->items[row] = e_reflow_model_incarnate (reflow->model, row, FOO_CANVAS_GROUP (reflow));
 			g_object_set (reflow->items[row],
 				      "has_cursor", TRUE,
 				      "width", (double) reflow->column_width,
@@ -238,7 +238,7 @@ incarnate (EReflow *reflow)
 	gint first_cell;
 	gint last_cell;
 	gint i;
-	GtkAdjustment *adjustment = gtk_layout_get_hadjustment (GTK_LAYOUT (GNOME_CANVAS_ITEM (reflow)->canvas));
+	GtkAdjustment *adjustment = gtk_layout_get_hadjustment (GTK_LAYOUT (FOO_CANVAS_ITEM (reflow)->canvas));
 
 	column_width = reflow->column_width;
 
@@ -263,7 +263,7 @@ incarnate (EReflow *reflow)
 		gint unsorted = e_sorter_sorted_to_model (E_SORTER (reflow->sorter), i);
 		if (reflow->items[unsorted] == NULL) {
 			if (reflow->model) {
-				reflow->items[unsorted] = e_reflow_model_incarnate (reflow->model, unsorted, GNOME_CANVAS_GROUP (reflow));
+				reflow->items[unsorted] = e_reflow_model_incarnate (reflow->model, unsorted, FOO_CANVAS_GROUP (reflow));
 				g_object_set (reflow->items[unsorted],
 					      "selected", e_selection_model_is_row_selected(E_SELECTION_MODEL(reflow->selection), unsorted),
 					      "width", (double) reflow->column_width,
@@ -354,13 +354,13 @@ item_changed (EReflowModel *model, gint i, EReflow *reflow)
 	if (i < 0 || i >= reflow->count)
 		return;
 
-	reflow->heights[i] = e_reflow_model_height (reflow->model, i, GNOME_CANVAS_GROUP (reflow));
+	reflow->heights[i] = e_reflow_model_height (reflow->model, i, FOO_CANVAS_GROUP (reflow));
 	if (reflow->items[i] != NULL)
 		e_reflow_model_reincarnate (model, i, reflow->items[i]);
 	e_sorter_array_clean (reflow->sorter);
 	reflow->reflow_from_column = -1;
 	reflow->need_reflow_columns = TRUE;
-	e_canvas_item_request_reflow(GNOME_CANVAS_ITEM (reflow));
+	e_canvas_item_request_reflow(FOO_CANVAS_ITEM (reflow));
 }
 
 static void
@@ -389,7 +389,7 @@ item_removed (EReflowModel *model, gint i, EReflow *reflow)
 		gtk_object_destroy (GTK_OBJECT (reflow->items[i]));
 
 	memmove (reflow->heights + i, reflow->heights + i + 1, (reflow->count - i - 1) * sizeof (gint));
-	memmove (reflow->items + i, reflow->items + i + 1, (reflow->count - i - 1) * sizeof (GnomeCanvasItem *));
+	memmove (reflow->items + i, reflow->items + i + 1, (reflow->count - i - 1) * sizeof (FooCanvasItem *));
 
 	reflow->count --;
 
@@ -398,7 +398,7 @@ item_removed (EReflowModel *model, gint i, EReflow *reflow)
 
 	reflow->need_reflow_columns = TRUE;
 	set_empty (reflow);
-	e_canvas_item_request_reflow(GNOME_CANVAS_ITEM (reflow));
+	e_canvas_item_request_reflow(FOO_CANVAS_ITEM (reflow));
 
 	e_sorter_array_set_count (reflow->sorter, reflow->count);
 
@@ -421,13 +421,13 @@ items_inserted (EReflowModel *model, gint position, gint count, EReflow *reflow)
 		while (reflow->count > reflow->allocated_count)
 			reflow->allocated_count += 256;
 		reflow->heights = g_renew (int, reflow->heights, reflow->allocated_count);
-		reflow->items = g_renew (GnomeCanvasItem *, reflow->items, reflow->allocated_count);
+		reflow->items = g_renew (FooCanvasItem *, reflow->items, reflow->allocated_count);
 	}
 	memmove (reflow->heights + position + count, reflow->heights + position, (reflow->count - position - count) * sizeof (gint));
-	memmove (reflow->items + position + count, reflow->items + position, (reflow->count - position - count) * sizeof (GnomeCanvasItem *));
+	memmove (reflow->items + position + count, reflow->items + position, (reflow->count - position - count) * sizeof (FooCanvasItem *));
 	for (i = position; i < position + count; i++) {
 		reflow->items[i] = NULL;
-		reflow->heights[i] = e_reflow_model_height (reflow->model, i, GNOME_CANVAS_GROUP (reflow));
+		reflow->heights[i] = e_reflow_model_height (reflow->model, i, FOO_CANVAS_GROUP (reflow));
 	}
 
 	e_selection_model_simple_set_row_count (E_SELECTION_MODEL_SIMPLE (reflow->selection), reflow->count);
@@ -455,7 +455,7 @@ items_inserted (EReflowModel *model, gint position, gint count, EReflow *reflow)
 
 	reflow->need_reflow_columns = TRUE;
 	set_empty (reflow);
-	e_canvas_item_request_reflow(GNOME_CANVAS_ITEM (reflow));
+	e_canvas_item_request_reflow(FOO_CANVAS_ITEM (reflow));
 }
 
 static void
@@ -476,13 +476,13 @@ model_changed (EReflowModel *model, EReflow *reflow)
 	g_free (reflow->heights);
 	reflow->count = e_reflow_model_count (model);
 	reflow->allocated_count = reflow->count;
-	reflow->items = g_new (GnomeCanvasItem *, reflow->count);
+	reflow->items = g_new (FooCanvasItem *, reflow->count);
 	reflow->heights = g_new (int, reflow->count);
 
 	count = reflow->count;
 	for (i = 0; i < count; i++) {
 		reflow->items[i] = NULL;
-		reflow->heights[i] = e_reflow_model_height (reflow->model, i, GNOME_CANVAS_GROUP (reflow));
+		reflow->heights[i] = e_reflow_model_height (reflow->model, i, FOO_CANVAS_GROUP (reflow));
 	}
 
 	e_selection_model_simple_set_row_count (E_SELECTION_MODEL_SIMPLE (reflow->selection), count);
@@ -492,7 +492,7 @@ model_changed (EReflowModel *model, EReflow *reflow)
 	if (oldcount > reflow->count)
 		reflow_columns (reflow);
 	set_empty (reflow);
-	e_canvas_item_request_reflow(GNOME_CANVAS_ITEM (reflow));
+	e_canvas_item_request_reflow(FOO_CANVAS_ITEM (reflow));
 }
 
 static void
@@ -501,7 +501,7 @@ comparison_changed (EReflowModel *model, EReflow *reflow)
 	e_sorter_array_clean (reflow->sorter);
 	reflow->reflow_from_column = -1;
 	reflow->need_reflow_columns = TRUE;
-	e_canvas_item_request_reflow(GNOME_CANVAS_ITEM (reflow));
+	e_canvas_item_request_reflow(FOO_CANVAS_ITEM (reflow));
 }
 
 static void
@@ -510,7 +510,7 @@ set_empty(EReflow *reflow)
 	if (reflow->count == 0) {
 		if (reflow->empty_text) {
 			if (reflow->empty_message) {
-				gnome_canvas_item_set(reflow->empty_text,
+				foo_canvas_item_set(reflow->empty_text,
 						      "width", reflow->minimum_width,
 						      "text", reflow->empty_message,
 						      NULL);
@@ -524,7 +524,7 @@ set_empty(EReflow *reflow)
 		} else {
 			if (reflow->empty_message) {
 				reflow->empty_text =
-					gnome_canvas_item_new(GNOME_CANVAS_GROUP(reflow),
+					foo_canvas_item_new(FOO_CANVAS_GROUP(reflow),
 							      e_text_get_type(),
 							      "anchor", GTK_ANCHOR_N,
 							      "width", reflow->minimum_width,
@@ -676,7 +676,7 @@ static void
 connect_set_adjustment (EReflow *reflow)
 {
 	reflow->set_scroll_adjustments_id =
-		g_signal_connect (GNOME_CANVAS_ITEM (reflow)->canvas,
+		g_signal_connect (FOO_CANVAS_ITEM (reflow)->canvas,
 				  "set_scroll_adjustments",
 				  G_CALLBACK (set_scroll_adjustments), reflow);
 }
@@ -686,7 +686,7 @@ static void
 disconnect_set_adjustment (EReflow *reflow)
 {
 	if (reflow->set_scroll_adjustments_id != 0) {
-		g_signal_handler_disconnect (GNOME_CANVAS_ITEM (reflow)->canvas,
+		g_signal_handler_disconnect (FOO_CANVAS_ITEM (reflow)->canvas,
 					     reflow->set_scroll_adjustments_id);
 		reflow->set_scroll_adjustments_id = 0;
 	}
@@ -704,10 +704,10 @@ column_width_changed (EReflow *reflow)
 static void
 e_reflow_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
 {
-	GnomeCanvasItem *item;
+	FooCanvasItem *item;
 	EReflow *reflow;
 
-	item = GNOME_CANVAS_ITEM (object);
+	item = FOO_CANVAS_ITEM (object);
 	reflow = E_REFLOW (object);
 
 	switch (prop_id) {
@@ -718,14 +718,14 @@ e_reflow_set_property (GObject *object, guint prop_id, const GValue *value, GPar
 		break;
 	case PROP_MINIMUM_WIDTH:
 		reflow->minimum_width = g_value_get_double (value);
-		if (GNOME_CANVAS_ITEM_REALIZED & GTK_OBJECT_FLAGS(object))
+		if (FOO_CANVAS_ITEM_REALIZED & GTK_OBJECT_FLAGS(object))
 			set_empty(reflow);
 		e_canvas_item_request_reflow(item);
 		break;
 	case PROP_EMPTY_MESSAGE:
 		g_free(reflow->empty_message);
 		reflow->empty_message = g_strdup(g_value_get_string (value));
-		if (GNOME_CANVAS_ITEM_REALIZED & GTK_OBJECT_FLAGS(object))
+		if (FOO_CANVAS_ITEM_REALIZED & GTK_OBJECT_FLAGS(object))
 			set_empty(reflow);
 		break;
 	case PROP_MODEL:
@@ -744,7 +744,7 @@ e_reflow_set_property (GObject *object, guint prop_id, const GValue *value, GPar
 			e_canvas_item_request_reflow(item);
 
 			reflow->need_column_resize = TRUE;
-			gnome_canvas_item_request_update(item);
+			foo_canvas_item_request_update(item);
 
 			if (old_width != reflow->column_width)
 				column_width_changed (reflow);
@@ -823,7 +823,7 @@ e_reflow_dispose (GObject *object)
 }
 
 static void
-e_reflow_realize (GnomeCanvasItem *item)
+e_reflow_realize (FooCanvasItem *item)
 {
 	EReflow *reflow;
 	GtkAdjustment *adjustment;
@@ -832,8 +832,8 @@ e_reflow_realize (GnomeCanvasItem *item)
 
 	reflow = E_REFLOW (item);
 
-	if (GNOME_CANVAS_ITEM_CLASS(e_reflow_parent_class)->realize)
-		(* GNOME_CANVAS_ITEM_CLASS(e_reflow_parent_class)->realize) (item);
+	if (FOO_CANVAS_ITEM_CLASS(e_reflow_parent_class)->realize)
+		(* FOO_CANVAS_ITEM_CLASS(e_reflow_parent_class)->realize) (item);
 
 	reflow->arrow_cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW);
 	reflow->default_cursor = gdk_cursor_new (GDK_LEFT_PTR);
@@ -841,7 +841,7 @@ e_reflow_realize (GnomeCanvasItem *item)
 	count = reflow->count;
 	for (i = 0; i < count; i++) {
 		if (reflow->items[i])
-			gnome_canvas_item_set(reflow->items[i],
+			foo_canvas_item_set(reflow->items[i],
 					      "width", reflow->column_width,
 					      NULL);
 	}
@@ -861,21 +861,15 @@ e_reflow_realize (GnomeCanvasItem *item)
 	adjustment->step_increment = (reflow->column_width + E_REFLOW_FULL_GUTTER) / 2;
 	adjustment->page_increment = adjustment->page_size - adjustment->step_increment;
 	gtk_adjustment_changed(adjustment);
-
-	if (!item->canvas->aa) {
-	}
 }
 
 static void
-e_reflow_unrealize (GnomeCanvasItem *item)
+e_reflow_unrealize (FooCanvasItem *item)
 {
 	EReflow *reflow;
 
 	reflow = E_REFLOW (item);
 
-	if (!item->canvas->aa) {
-	}
-
 	gdk_cursor_unref (reflow->arrow_cursor);
 	gdk_cursor_unref (reflow->default_cursor);
 	reflow->arrow_cursor = NULL;
@@ -887,12 +881,12 @@ e_reflow_unrealize (GnomeCanvasItem *item)
 	disconnect_set_adjustment (reflow);
 	disconnect_adjustment (reflow);
 
-	if (GNOME_CANVAS_ITEM_CLASS(e_reflow_parent_class)->unrealize)
-		(* GNOME_CANVAS_ITEM_CLASS(e_reflow_parent_class)->unrealize) (item);
+	if (FOO_CANVAS_ITEM_CLASS(e_reflow_parent_class)->unrealize)
+		(* FOO_CANVAS_ITEM_CLASS(e_reflow_parent_class)->unrealize) (item);
 }
 
 static gboolean
-e_reflow_event (GnomeCanvasItem *item, GdkEvent *event)
+e_reflow_event (FooCanvasItem *item, GdkEvent *event)
 {
 	EReflow *reflow;
 	gint return_val = FALSE;
@@ -913,7 +907,7 @@ e_reflow_event (GnomeCanvasItem *item, GdkEvent *event)
 				count = reflow->count;
 				for (i = 0; i < count; i++) {
 					gint unsorted = e_sorter_sorted_to_model (E_SORTER (reflow->sorter), i);
-					GnomeCanvasItem *item = reflow->items[unsorted];
+					FooCanvasItem *item = reflow->items[unsorted];
 					EFocus has_focus;
 					if (item) {
 						g_object_get(item,
@@ -932,11 +926,11 @@ e_reflow_event (GnomeCanvasItem *item, GdkEvent *event)
 
 							unsorted = e_sorter_sorted_to_model (E_SORTER (reflow->sorter), i);
 							if (reflow->items[unsorted] == NULL) {
-								reflow->items[unsorted] = e_reflow_model_incarnate (reflow->model, unsorted, GNOME_CANVAS_GROUP (reflow));
+								reflow->items[unsorted] = e_reflow_model_incarnate (reflow->model, unsorted, FOO_CANVAS_GROUP (reflow));
 							}
 
 							item = reflow->items[unsorted];
-							gnome_canvas_item_set(item,
+							foo_canvas_item_set(item,
 									      "has_focus", (event->key.state & GDK_SHIFT_MASK) ? E_FOCUS_END : E_FOCUS_START,
 									      NULL);
 							return TRUE;
@@ -965,14 +959,14 @@ e_reflow_event (GnomeCanvasItem *item, GdkEvent *event)
 							reflow->temp_column_width = reflow->column_width;
 							reflow->column_drag = TRUE;
 
-							gnome_canvas_item_grab (item,
+							foo_canvas_item_grab (item,
 										GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK,
 										reflow->arrow_cursor,
 										button->time);
 
 							reflow->previous_temp_column_width = -1;
 							reflow->need_column_resize = TRUE;
-							gnome_canvas_item_request_update(item);
+							foo_canvas_item_request_update(item);
 							return TRUE;
 						}
 					}
@@ -1015,12 +1009,12 @@ e_reflow_event (GnomeCanvasItem *item, GdkEvent *event)
 					gtk_adjustment_changed(adjustment);
 					e_reflow_resize_children(item);
 					e_canvas_item_request_reflow(item);
-					gnome_canvas_request_redraw(item->canvas, 0, 0, reflow->width, reflow->height);
+					foo_canvas_request_redraw(item->canvas, 0, 0, reflow->width, reflow->height);
 					column_width_changed (reflow);
 				}
 				reflow->need_column_resize = TRUE;
-				gnome_canvas_item_request_update(item);
-				gnome_canvas_item_ungrab (item, button->time);
+				foo_canvas_item_request_update(item);
+				foo_canvas_item_ungrab (item, button->time);
 				return TRUE;
 			}
 			break;
@@ -1035,7 +1029,7 @@ e_reflow_event (GnomeCanvasItem *item, GdkEvent *event)
 					reflow->temp_column_width = 50;
 				if (old_width != reflow->temp_column_width) {
 					reflow->need_column_resize = TRUE;
-					gnome_canvas_item_request_update(item);
+					foo_canvas_item_request_update(item);
 				}
 				return TRUE;
 			} else {
@@ -1095,23 +1089,29 @@ e_reflow_event (GnomeCanvasItem *item, GdkEvent *event)
 		}
 	if (return_val)
 		return return_val;
-	else if (GNOME_CANVAS_ITEM_CLASS( e_reflow_parent_class )->event)
-		return (* GNOME_CANVAS_ITEM_CLASS( e_reflow_parent_class )->event) (item, event);
+	else if (FOO_CANVAS_ITEM_CLASS( e_reflow_parent_class )->event)
+		return (* FOO_CANVAS_ITEM_CLASS( e_reflow_parent_class )->event) (item, event);
 	else
 		return FALSE;
 }
 
-static void e_reflow_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
-				    gint x, gint y, gint width, gint height)
+static void e_reflow_draw (FooCanvasItem *item, GdkDrawable *drawable,
+				    GdkEventExpose *expose)
 {
 	gint x_rect, y_rect, width_rect, height_rect;
+	gint x, y, width, height;
 	gdouble running_width;
 	EReflow *reflow = E_REFLOW(item);
 	gint i;
 	double column_width;
 
-	if (GNOME_CANVAS_ITEM_CLASS(e_reflow_parent_class)->draw)
-		GNOME_CANVAS_ITEM_CLASS(e_reflow_parent_class)->draw (item, drawable, x, y, width, height);
+	x = expose->area.x;
+	y = expose->area.y;
+	width = expose->area.width;
+	height = expose->area.height;
+
+	if (FOO_CANVAS_ITEM_CLASS(e_reflow_parent_class)->draw)
+		FOO_CANVAS_ITEM_CLASS(e_reflow_parent_class)->draw (item, drawable, expose);
 	column_width = reflow->column_width;
 	running_width = E_REFLOW_BORDER_WIDTH + column_width + E_REFLOW_BORDER_WIDTH;
 	x_rect = running_width;
@@ -1176,15 +1176,15 @@ static void e_reflow_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
 }
 
 static void
-e_reflow_update (GnomeCanvasItem *item, double affine[6], ArtSVP *clip_path, gint flags)
+e_reflow_update (FooCanvasItem *item, double i2w_dx, double i2w_dy, gint flags)
 {
 	EReflow *reflow;
 	double x0, x1, y0, y1;
 
 	reflow = E_REFLOW (item);
 
-	if (GNOME_CANVAS_ITEM_CLASS(e_reflow_parent_class)->update)
-		GNOME_CANVAS_ITEM_CLASS(e_reflow_parent_class)->update (item, affine, clip_path, flags);
+	if (FOO_CANVAS_ITEM_CLASS(e_reflow_parent_class)->update)
+		FOO_CANVAS_ITEM_CLASS(e_reflow_parent_class)->update (item, i2w_dx, i2w_dy, flags);
 
 	x0 = item->x1;
 	y0 = item->y1;
@@ -1211,7 +1211,7 @@ e_reflow_update (GnomeCanvasItem *item, double affine[6], ArtSVP *clip_path, gin
 		if ( x1 < E_REFLOW(item)->height )
 			x1 = E_REFLOW(item)->height;
 
-		gnome_canvas_request_redraw(item->canvas, x0, y0, x1, y1);
+		foo_canvas_request_redraw(item->canvas, x0, y0, x1, y1);
 		reflow->need_height_update = FALSE;
 	} else if (reflow->need_column_resize) {
 		gint x_rect, y_rect, width_rect, height_rect;
@@ -1232,7 +1232,7 @@ e_reflow_update (GnomeCanvasItem *item, double affine[6], ArtSVP *clip_path, gin
 
 			for ( i = 0; i < reflow->column_count; i++) {
 				x_rect = running_width;
-				gnome_canvas_request_redraw(item->canvas, x_rect, y_rect, x_rect + width_rect, y_rect + height_rect);
+				foo_canvas_request_redraw(item->canvas, x_rect, y_rect, x_rect + width_rect, y_rect + height_rect);
 				running_width += E_REFLOW_DIVIDER_WIDTH + E_REFLOW_BORDER_WIDTH + column_width + E_REFLOW_BORDER_WIDTH;
 			}
 		}
@@ -1248,7 +1248,7 @@ e_reflow_update (GnomeCanvasItem *item, double affine[6], ArtSVP *clip_path, gin
 
 			for ( i = 0; i < reflow->column_count; i++) {
 				x_rect = running_width;
-				gnome_canvas_request_redraw(item->canvas, x_rect, y_rect, x_rect + width_rect, y_rect + height_rect);
+				foo_canvas_request_redraw(item->canvas, x_rect, y_rect, x_rect + width_rect, y_rect + height_rect);
 				running_width += E_REFLOW_DIVIDER_WIDTH + E_REFLOW_BORDER_WIDTH + column_width + E_REFLOW_BORDER_WIDTH;
 			}
 		}
@@ -1259,16 +1259,16 @@ e_reflow_update (GnomeCanvasItem *item, double affine[6], ArtSVP *clip_path, gin
 }
 
 static double
-e_reflow_point (GnomeCanvasItem *item,
+e_reflow_point (FooCanvasItem *item,
 		double x, double y, gint cx, gint cy,
-		GnomeCanvasItem **actual_item)
+		FooCanvasItem **actual_item)
 {
 	double distance = 1;
 
 	*actual_item = NULL;
 
-	if (GNOME_CANVAS_ITEM_CLASS(e_reflow_parent_class)->point)
-		distance = GNOME_CANVAS_ITEM_CLASS(e_reflow_parent_class)->point (item, x, y, cx, cy, actual_item);
+	if (FOO_CANVAS_ITEM_CLASS(e_reflow_parent_class)->point)
+		distance = FOO_CANVAS_ITEM_CLASS(e_reflow_parent_class)->point (item, x, y, cx, cy, actual_item);
 	if ((gint) (distance * item->canvas->pixels_per_unit + 0.5) <= item->canvas->close_enough && *actual_item)
 		return distance;
 
@@ -1290,7 +1290,7 @@ e_reflow_point (GnomeCanvasItem *item,
 }
 
 static void
-e_reflow_reflow( GnomeCanvasItem *item, gint flags )
+e_reflow_reflow( FooCanvasItem *item, gint flags )
 {
 	EReflow *reflow = E_REFLOW(item);
 	gdouble old_width;
@@ -1299,7 +1299,7 @@ e_reflow_reflow( GnomeCanvasItem *item, gint flags )
 	gint next_column;
 	gint i;
 
-	if (! (GTK_OBJECT_FLAGS (reflow) & GNOME_CANVAS_ITEM_REALIZED))
+	if (! (GTK_OBJECT_FLAGS (reflow) & FOO_CANVAS_ITEM_REALIZED))
 		return;
 
 	if (reflow->need_reflow_columns) {
@@ -1322,7 +1322,7 @@ e_reflow_reflow( GnomeCanvasItem *item, gint flags )
 		}
 
 		if (unsorted >= 0 && reflow->items[unsorted]) {
-			e_canvas_item_move_absolute(GNOME_CANVAS_ITEM(reflow->items[unsorted]),
+			e_canvas_item_move_absolute(FOO_CANVAS_ITEM(reflow->items[unsorted]),
 						    (double) running_width,
 						    (double) running_height);
 			running_height += reflow->heights[unsorted] + E_REFLOW_BORDER_WIDTH;
@@ -1336,7 +1336,7 @@ e_reflow_reflow( GnomeCanvasItem *item, gint flags )
 }
 
 static gint
-e_reflow_selection_event_real (EReflow *reflow, GnomeCanvasItem *item, GdkEvent *event)
+e_reflow_selection_event_real (EReflow *reflow, FooCanvasItem *item, GdkEvent *event)
 {
 	gint row;
 	gint return_val = TRUE;
@@ -1389,16 +1389,16 @@ static void
 e_reflow_class_init (EReflowClass *klass)
 {
 	GObjectClass *object_class;
-	GnomeCanvasItemClass *item_class;
+	FooCanvasItemClass *item_class;
 
 	object_class = (GObjectClass*) klass;
-	item_class = (GnomeCanvasItemClass *) klass;
+	item_class = (FooCanvasItemClass *) klass;
 
 	object_class->set_property  = e_reflow_set_property;
 	object_class->get_property  = e_reflow_get_property;
 	object_class->dispose  = e_reflow_dispose;
 
-	/* GnomeCanvasItem method overrides */
+	/* FooCanvasItem method overrides */
 	item_class->event      = e_reflow_event;
 	item_class->realize    = e_reflow_realize;
 	item_class->unrealize  = e_reflow_unrealize;
@@ -1527,5 +1527,5 @@ e_reflow_init (EReflow *reflow)
 		g_signal_connect(reflow->selection, "cursor_changed",
 				 G_CALLBACK (cursor_changed), reflow);
 
-	e_canvas_item_set_reflow_callback(GNOME_CANVAS_ITEM(reflow), e_reflow_reflow);
+	e_canvas_item_set_reflow_callback(FOO_CANVAS_ITEM(reflow), e_reflow_reflow);
 }
diff --git a/widgets/text/e-reflow.h b/widgets/text/e-reflow.h
index 1559ad6..c20f5ee 100644
--- a/widgets/text/e-reflow.h
+++ b/widgets/text/e-reflow.h
@@ -23,7 +23,7 @@
 #ifndef __E_REFLOW_H__
 #define __E_REFLOW_H__
 
-#include <libgnomecanvas/gnome-canvas.h>
+#include <libfoocanvas/foo-canvas.h>
 #include <text/e-reflow-model.h>
 #include <misc/e-selection-model.h>
 #include <e-util/e-sorter-array.h>
@@ -54,7 +54,7 @@ typedef struct _EReflowClass  EReflowClass;
 
 struct _EReflow
 {
-	GnomeCanvasGroup parent;
+	FooCanvasGroup parent;
 
 	/* item specific fields */
 	EReflowModel *model;
@@ -76,14 +76,14 @@ struct _EReflow
 	guint set_scroll_adjustments_id;
 
 	gint *heights;
-	GnomeCanvasItem **items;
+	FooCanvasItem **items;
 	gint count;
 	gint allocated_count;
 
 	gint *columns;
 	gint column_count; /* Number of columnns */
 
-	GnomeCanvasItem *empty_text;
+	FooCanvasItem *empty_text;
 	gchar *empty_message;
 
 	double minimum_width;
@@ -121,9 +121,9 @@ struct _EReflow
 
 struct _EReflowClass
 {
-	GnomeCanvasGroupClass parent_class;
+	FooCanvasGroupClass parent_class;
 
-	gint (*selection_event) (EReflow *reflow, GnomeCanvasItem *item, GdkEvent *event);
+	gint (*selection_event) (EReflow *reflow, FooCanvasItem *item, GdkEvent *event);
 	void (*column_width_changed) (EReflow *reflow, double width);
 };
 
diff --git a/widgets/text/e-text.c b/widgets/text/e-text.c
index b9c5e0c..b9eb4b7 100644
--- a/widgets/text/e-text.c
+++ b/widgets/text/e-text.c
@@ -9,9 +9,9 @@
  *
  * A majority of code taken from:
  *
- * Text item type for GnomeCanvas widget
+ * Text item type for FooCanvas widget
  *
- * GnomeCanvas is basically a port of the Tk toolkit's most excellent
+ * FooCanvas is basically a port of the Tk toolkit's most excellent
  * canvas widget.  Tk is copyrighted by the Regents of the University
  * of California, Sun Microsystems, and other parties.
  *
@@ -44,7 +44,7 @@
 #include <glib-object.h>
 #include <gdk/gdkkeysyms.h>
 #include <gtk/gtk.h>
-#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
+#include <libfoocanvas/foo-canvas-rect-ellipse.h>
 
 #include "gal-a11y-e-text.h"
 #include "misc/e-canvas.h"
@@ -53,10 +53,11 @@
 #include <glib/gi18n.h>
 #include "e-util/e-text-event-processor-emacs-like.h"
 #include "e-util/e-util.h"
+#include "libfoocanvas/libart-types.h"
 
 #include "e-text.h"
 
-G_DEFINE_TYPE (EText, e_text, GNOME_TYPE_CANVAS_ITEM)
+G_DEFINE_TYPE (EText, e_text, FOO_TYPE_CANVAS_ITEM)
 
 #define BORDER_INDENT 3
 #define d(x)
@@ -181,7 +182,7 @@ e_text_style_set (EText *text, GtkStyle *previous_style)
 	} else {
 		text->needs_calc_height = 1;
 	}
-	e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (text));
+	e_canvas_item_request_reflow (FOO_CANVAS_ITEM (text));
 }
 #endif
 
@@ -196,7 +197,7 @@ e_text_dispose (GObject *object)
 	text = E_TEXT (object);
 
 	if (text->tooltip_owner)
-		e_canvas_hide_tooltip (E_CANVAS(GNOME_CANVAS_ITEM(text)->canvas));
+		e_canvas_hide_tooltip (E_CANVAS(FOO_CANVAS_ITEM(text)->canvas));
 	text->tooltip_owner = 0;
 
 	if (text->model_changed_signal_id)
@@ -396,7 +397,7 @@ reset_layout_attrs (EText *text)
 static void
 create_layout (EText *text)
 {
-	GnomeCanvasItem *item = GNOME_CANVAS_ITEM (text);
+	FooCanvasItem *item = FOO_CANVAS_ITEM (text);
 
 	if (text->layout)
 		return;
@@ -410,7 +411,7 @@ create_layout (EText *text)
 static void
 reset_layout (EText *text)
 {
-	GnomeCanvasItem *item = GNOME_CANVAS_ITEM (text);
+	FooCanvasItem *item = FOO_CANVAS_ITEM (text);
 	cairo_font_options_t *font_options;
 	PangoContext *context;
 
@@ -469,8 +470,8 @@ e_text_text_model_changed (ETextModel *model, EText *text)
 	text->needs_reset_layout = 1;
 	text->needs_split_into_lines = 1;
 	text->needs_redraw = 1;
-	e_canvas_item_request_reflow (GNOME_CANVAS_ITEM(text));
-	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (text));
+	e_canvas_item_request_reflow (FOO_CANVAS_ITEM(text));
+	foo_canvas_item_request_update (FOO_CANVAS_ITEM (text));
 
 	g_signal_emit (text, e_text_signals[E_TEXT_CHANGED], 0);
 }
@@ -499,18 +500,18 @@ e_text_text_model_reposition (ETextModel *model, ETextModelReposFn fn, gpointer
 static void
 get_bounds (EText *text, double *px1, double *py1, double *px2, double *py2)
 {
-	GnomeCanvasItem *item;
+	FooCanvasItem *item;
 	double wx, wy, clip_width, clip_height;
 
-	item = GNOME_CANVAS_ITEM (text);
+	item = FOO_CANVAS_ITEM (text);
 
 	/* Get canvas pixel coordinates for text position */
 
 	wx = 0;
 	wy = 0;
-	gnome_canvas_item_i2w (item, &wx, &wy);
-	gnome_canvas_w2c (item->canvas, wx, wy, &text->cx, &text->cy);
-	gnome_canvas_w2c (item->canvas, wx, wy, &text->clip_cx, &text->clip_cy);
+	foo_canvas_item_i2w (item, &wx, &wy);
+	foo_canvas_w2c (item->canvas, wx, wy, &text->cx, &text->cy);
+	foo_canvas_w2c (item->canvas, wx, wy, &text->clip_cx, &text->clip_cy);
 
 	if (text->clip_width < 0)
 		clip_width = text->width;
@@ -596,13 +597,13 @@ get_bounds (EText *text, double *px1, double *py1, double *px2, double *py2)
 static void
 calc_height (EText *text)
 {
-	GnomeCanvasItem *item;
+	FooCanvasItem *item;
 	gint old_height;
 	gint old_width;
 	gint width = 0;
 	gint height = 0;
 
-	item = GNOME_CANVAS_ITEM (text);
+	item = FOO_CANVAS_ITEM (text);
 
 	/* Calculate text dimensions */
 
@@ -624,7 +625,7 @@ calc_ellipsis (EText *text)
 {
 /* FIXME: a pango layout per calc_ellipsis sucks */
 	gint width;
-	PangoLayout *layout = gtk_widget_create_pango_layout (GTK_WIDGET (GNOME_CANVAS_ITEM (text)->canvas),
+	PangoLayout *layout = gtk_widget_create_pango_layout (GTK_WIDGET (FOO_CANVAS_ITEM (text)->canvas),
 							      text->ellipsis ? text->ellipsis : "...");
 	pango_layout_get_size (layout, &width, NULL);
 
@@ -676,7 +677,7 @@ e_text_set_property (GObject *object,
                     const GValue *value,
                     GParamSpec *pspec)
 {
-	GnomeCanvasItem *item;
+	FooCanvasItem *item;
 	EText *text;
 	GdkColor color = { 0, 0, 0, 0, };
 	GdkColor *pcolor;
@@ -685,7 +686,7 @@ e_text_set_property (GObject *object,
 	gboolean needs_update = 0;
 	gboolean needs_reflow = 0;
 
-	item = GNOME_CANVAS_ITEM (object);
+	item = FOO_CANVAS_ITEM (object);
 	text = E_TEXT (object);
 
 	color_changed = FALSE;
@@ -1001,8 +1002,7 @@ e_text_set_property (GObject *object,
 	       text->color = color;
                gdk_rgb_find_color (colormap, &text->color);
 
-	       if (!item->canvas->aa)
-		       set_text_gc_foreground (text);
+	       set_text_gc_foreground (text);
 
 	       text->needs_redraw = 1;
 	       needs_update = 1;
@@ -1011,7 +1011,7 @@ e_text_set_property (GObject *object,
 	if ( needs_reflow )
 		e_canvas_item_request_reflow (item);
 	if ( needs_update )
-		gnome_canvas_item_request_update (item);
+		foo_canvas_item_request_update (item);
 }
 
 /* Get_arg handler for the text item */
@@ -1167,7 +1167,7 @@ e_text_get_property (GObject *object,
 
 /* Update handler for the text item */
 static void
-e_text_reflow (GnomeCanvasItem *item, gint flags)
+e_text_reflow (FooCanvasItem *item, gint flags)
 {
 	EText *text;
 
@@ -1188,7 +1188,7 @@ e_text_reflow (GnomeCanvasItem *item, gint flags)
 
 	if ( text->needs_calc_height ) {
 		calc_height (text);
-		gnome_canvas_item_request_update(item);
+		foo_canvas_item_request_update(item);
 		text->needs_calc_height = 0;
 		text->needs_recalc_bounds = 1;
 	}
@@ -1196,55 +1196,52 @@ e_text_reflow (GnomeCanvasItem *item, gint flags)
 
 /* Update handler for the text item */
 static void
-e_text_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, gint flags)
+e_text_update (FooCanvasItem *item, double i2w_dx, double i2w_dy, gint flags)
 {
 	EText *text;
 	double x1, y1, x2, y2;
 
 	text = E_TEXT (item);
 
-	if (GNOME_CANVAS_ITEM_CLASS (e_text_parent_class)->update)
-		(* GNOME_CANVAS_ITEM_CLASS (e_text_parent_class)->update) (item, affine, clip_path, flags);
-
-	if ( text->needs_recalc_bounds
-	     || (flags & GNOME_CANVAS_UPDATE_AFFINE)) {
-		if (!item->canvas->aa) {
-			set_text_gc_foreground (text);
-			set_stipple (text, text->stipple, TRUE);
-			get_bounds (text, &x1, &y1, &x2, &y2);
-			if ( item->x1 != x1 ||
-			     item->x2 != x2 ||
-			     item->y1 != y1 ||
-			     item->y2 != y2 ) {
-				gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2);
-				item->x1 = x1;
-				item->y1 = y1;
-				item->x2 = x2;
-				item->y2 = y2;
-				text->needs_redraw = 1;
-				item->canvas->need_repick = TRUE;
-			}
-			if (!text->fill_clip_rectangle)
-				item->canvas->need_repick = TRUE;
+	if (FOO_CANVAS_ITEM_CLASS (e_text_parent_class)->update)
+		(* FOO_CANVAS_ITEM_CLASS (e_text_parent_class)->update) (item, i2w_dx, i2w_dy, flags);
+
+	if ( text->needs_recalc_bounds) {
+		set_text_gc_foreground (text);
+		set_stipple (text, text->stipple, TRUE);
+		get_bounds (text, &x1, &y1, &x2, &y2);
+		if ( item->x1 != x1 ||
+		     item->x2 != x2 ||
+		     item->y1 != y1 ||
+		     item->y2 != y2 ) {
+			foo_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2);
+			item->x1 = x1;
+			item->y1 = y1;
+			item->x2 = x2;
+			item->y2 = y2;
+			text->needs_redraw = 1;
+			item->canvas->need_repick = TRUE;
 		}
+		if (!text->fill_clip_rectangle)
+			item->canvas->need_repick = TRUE;
 		text->needs_recalc_bounds = 0;
 	}
 	if ( text->needs_redraw ) {
-		gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2);
+		foo_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2);
 		text->needs_redraw = 0;
 	}
 }
 
 /* Realize handler for the text item */
 static void
-e_text_realize (GnomeCanvasItem *item)
+e_text_realize (FooCanvasItem *item)
 {
 	EText *text;
 
 	text = E_TEXT (item);
 
-	if (GNOME_CANVAS_ITEM_CLASS (e_text_parent_class)->realize)
-		(* GNOME_CANVAS_ITEM_CLASS (e_text_parent_class)->realize) (item);
+	if (FOO_CANVAS_ITEM_CLASS (e_text_parent_class)->realize)
+		(* FOO_CANVAS_ITEM_CLASS (e_text_parent_class)->realize) (item);
 
 	create_layout (text);
 
@@ -1261,7 +1258,7 @@ e_text_realize (GnomeCanvasItem *item)
 
 /* Unrealize handler for the text item */
 static void
-e_text_unrealize (GnomeCanvasItem *item)
+e_text_unrealize (FooCanvasItem *item)
 {
 	EText *text;
 
@@ -1275,8 +1272,8 @@ e_text_unrealize (GnomeCanvasItem *item)
 	gdk_cursor_unref (text->default_cursor);
 	text->default_cursor = NULL;
 
-	if (GNOME_CANVAS_ITEM_CLASS (e_text_parent_class)->unrealize)
-		(* GNOME_CANVAS_ITEM_CLASS (e_text_parent_class)->unrealize) (item);
+	if (FOO_CANVAS_ITEM_CLASS (e_text_parent_class)->unrealize)
+		(* FOO_CANVAS_ITEM_CLASS (e_text_parent_class)->unrealize) (item);
 }
 
 static void
@@ -1371,18 +1368,24 @@ show_pango_rectangle (EText *text, PangoRectangle rect)
 
 /* Draw handler for the text item */
 static void
-e_text_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
-	     gint x, gint y, gint width, gint height)
+e_text_draw (FooCanvasItem *item, GdkDrawable *drawable,
+	     GdkEventExpose *expose)
 {
 	EText *text;
 	GdkRectangle rect, *clip_rect;
 	gint xpos, ypos;
+	gint x, y, width, height;
 	GdkGC *main_gc;
-	GnomeCanvas *canvas;
+	FooCanvas *canvas;
 	GtkWidget *widget;
 
+	x = expose->area.x;
+	y = expose->area.y;
+	width = expose->area.width;
+	height = expose->area.height;
+
 	text = E_TEXT (item);
-	canvas = GNOME_CANVAS_ITEM(text)->canvas;
+	canvas = FOO_CANVAS_ITEM(text)->canvas;
 	widget = GTK_WIDGET(canvas);
 
 	if (text->draw_background || text->draw_button) {
@@ -1528,7 +1531,7 @@ e_text_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
 		return;
 
 	if (text->stipple)
-		gnome_canvas_set_stipple_origin (item->canvas, main_gc);
+		foo_canvas_set_stipple_origin (item->canvas, main_gc);
 
 	xpos = text->text_cx;
 	ypos = text->text_cy;
@@ -1664,8 +1667,8 @@ e_text_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
 
 /* Point handler for the text item */
 static double
-e_text_point (GnomeCanvasItem *item, double x, double y,
-	      gint cx, gint cy, GnomeCanvasItem **actual_item)
+e_text_point (FooCanvasItem *item, double x, double y,
+	      gint cx, gint cy, FooCanvasItem **actual_item)
 {
 	EText *text;
 	double clip_width;
@@ -1714,7 +1717,7 @@ e_text_point (GnomeCanvasItem *item, double x, double y,
 
 /* Bounds handler for the text item */
 static void
-e_text_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y2)
+e_text_bounds (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2)
 {
 	EText *text;
 	double width, height;
@@ -1885,7 +1888,7 @@ _blink_scroll_timeout (gpointer data)
 	}
 	if (redraw) {
 		text->needs_redraw = 1;
-		gnome_canvas_item_request_update (GNOME_CANVAS_ITEM(text));
+		foo_canvas_item_request_update (FOO_CANVAS_ITEM(text));
 	}
 	return TRUE;
 }
@@ -1900,18 +1903,18 @@ tooltip_event(GtkWidget *tooltip, GdkEvent *event, EText *text)
 
 	switch (event->type) {
 	case GDK_LEAVE_NOTIFY:
-		e_canvas_hide_tooltip (E_CANVAS(GNOME_CANVAS_ITEM(text)->canvas));
+		e_canvas_hide_tooltip (E_CANVAS(FOO_CANVAS_ITEM(text)->canvas));
 		break;
 	case GDK_BUTTON_PRESS:
 	case GDK_BUTTON_RELEASE:
 		if (event->type == GDK_BUTTON_RELEASE) {
-			e_canvas_hide_tooltip (E_CANVAS(GNOME_CANVAS_ITEM(text)->canvas));
+			e_canvas_hide_tooltip (E_CANVAS(FOO_CANVAS_ITEM(text)->canvas));
 		}
 		/* Forward events to the text item */
 		g_signal_emit_by_name (text, "event", event,
 				       &ret_val);
 		if (!ret_val)
-			gtk_propagate_event (GTK_WIDGET(GNOME_CANVAS_ITEM(text)->canvas), event);
+			gtk_propagate_event (GTK_WIDGET(FOO_CANVAS_ITEM(text)->canvas), event);
 		ret_val = TRUE;
 	default:
 		break;
@@ -1924,9 +1927,9 @@ tooltip_ungrab (GtkWidget *tooltip, GdkEvent *event, EText *text)
 {
 	gdk_keyboard_ungrab(GDK_CURRENT_TIME);
 
-	e_canvas_hide_tooltip (E_CANVAS(GNOME_CANVAS_ITEM(text)->canvas));
+	e_canvas_hide_tooltip (E_CANVAS(FOO_CANVAS_ITEM(text)->canvas));
 
-	gtk_propagate_event (GTK_WIDGET(GNOME_CANVAS_ITEM(text)->canvas), event);
+	gtk_propagate_event (GTK_WIDGET(FOO_CANVAS_ITEM(text)->canvas), event);
 
 	return TRUE;
 }
@@ -1952,7 +1955,7 @@ _do_tooltip (gpointer data)
 	ArtPoint origin = {0, 0};
 	ArtPoint pixel_origin;
 	gint canvas_x, canvas_y;
-	GnomeCanvasItem *tooltip_text;
+	FooCanvasItem *tooltip_text;
 	double tooltip_width;
 	double tooltip_height;
 	double tooltip_x;
@@ -1960,12 +1963,12 @@ _do_tooltip (gpointer data)
 #if 0
 	double x1, x2, y1, y2;
 #endif
-	GnomeCanvasItem *rect;
+	FooCanvasItem *rect;
 	GtkWidget *tooltip_window;      /* GtkWindow for displaying the tooltip */
 
 	text->tooltip_count = 0;
 
-	if (E_CANVAS(GNOME_CANVAS_ITEM(text)->canvas)->tooltip_window || text->editing || !text->num_lines) {
+	if (E_CANVAS(FOO_CANVAS_ITEM(text)->canvas)->tooltip_window || text->editing || !text->num_lines) {
 		text->tooltip_timeout = 0;
 		return FALSE;
 	}
@@ -1987,14 +1990,14 @@ _do_tooltip (gpointer data)
 		return FALSE;
 	}
 
-	gnome_canvas_item_i2c_affine(GNOME_CANVAS_ITEM(text), i2c);
+	foo_canvas_item_i2c_affine(FOO_CANVAS_ITEM(text), i2c);
 	art_affine_point (&pixel_origin, &origin, i2c);
 
-	gdk_window_get_origin (GTK_WIDGET(GNOME_CANVAS_ITEM(text)->canvas)->window, &canvas_x, &canvas_y);
+	gdk_window_get_origin (GTK_WIDGET(FOO_CANVAS_ITEM(text)->canvas)->window, &canvas_x, &canvas_y);
 	pixel_origin.x += canvas_x;
 	pixel_origin.y += canvas_y;
-	pixel_origin.x -= (gint) gtk_layout_get_hadjustment(GTK_LAYOUT(GNOME_CANVAS_ITEM(text)->canvas))->value;
-	pixel_origin.y -= (gint) gtk_layout_get_vadjustment(GTK_LAYOUT(GNOME_CANVAS_ITEM(text)->canvas))->value;
+	pixel_origin.x -= (gint) gtk_layout_get_hadjustment(GTK_LAYOUT(FOO_CANVAS_ITEM(text)->canvas))->value;
+	pixel_origin.y -= (gint) gtk_layout_get_vadjustment(GTK_LAYOUT(FOO_CANVAS_ITEM(text)->canvas))->value;
 
 	tooltip_window = gtk_window_new (GTK_WINDOW_POPUP);
 	gtk_container_set_border_width (GTK_CONTAINER (tooltip_window), 1);
@@ -2007,15 +2010,15 @@ _do_tooltip (gpointer data)
 	/* Get the longest line length */
 	pango_layout_get_size (text->layout, &max_width, NULL);
 
-	rect = gnome_canvas_item_new (gnome_canvas_root (GNOME_CANVAS (canvas)),
-				      gnome_canvas_rect_get_type (),
+	rect = foo_canvas_item_new (foo_canvas_root (FOO_CANVAS (canvas)),
+				      foo_canvas_rect_get_type (),
 				      "x1", (double) 0,
 				      "y1", (double) 0,
 				      "x2", (double) max_width + 4,
 				      "y2", (double) text->height + 4,
 				      NULL);
 
-	tooltip_text = gnome_canvas_item_new (gnome_canvas_root (GNOME_CANVAS (canvas)),
+	tooltip_text = foo_canvas_item_new (foo_canvas_root (FOO_CANVAS (canvas)),
 					      e_text_get_type (),
 					      "anchor", GTK_ANCHOR_NW,
 					      "bold", text->bold,
@@ -2039,7 +2042,7 @@ _do_tooltip (gpointer data)
 	split_into_lines (E_TEXT(tooltip_text));
 	calc_height (E_TEXT(tooltip_text));
 
-	gnome_canvas_item_set (tooltip_text,
+	foo_canvas_item_set (tooltip_text,
 			       "clip_height", (double) E_TEXT(tooltip_text)->height,
 			       "clip_width", (double) E_TEXT(tooltip_text)->width,
 			       NULL);
@@ -2097,7 +2100,7 @@ _do_tooltip (gpointer data)
 		break;
 	}
 
-	gnome_canvas_item_set(rect,
+	foo_canvas_item_set(rect,
 			      "x2", (double) tooltip_width + 4 + (text->draw_borders ? BORDER_INDENT * 2 : 0),
 			      "y2", (double) tooltip_height + 4 + (text->draw_borders ? BORDER_INDENT * 2 : 0),
 			      NULL);
@@ -2108,7 +2111,7 @@ _do_tooltip (gpointer data)
 	gtk_widget_set_size_request (tooltip_window,
 				     tooltip_width + 4 + (text->draw_borders ? BORDER_INDENT * 2 : 0),
 				     tooltip_height + 4 + (text->draw_borders ? BORDER_INDENT * 2 : 0));
-	gnome_canvas_set_scroll_region (GNOME_CANVAS(canvas), 0.0, 0.0,
+	foo_canvas_set_scroll_region (FOO_CANVAS(canvas), 0.0, 0.0,
 					tooltip_width + (text->draw_borders ? BORDER_INDENT * 2 : 0),
 					(double)tooltip_height + (text->draw_borders ? BORDER_INDENT * 2 : 0));
 	g_signal_connect (tooltip_window, "event",
@@ -2118,7 +2121,7 @@ _do_tooltip (gpointer data)
 			   tooltip_destroy, text);
 	g_object_ref (text);
 
-	e_canvas_popup_tooltip (E_CANVAS(GNOME_CANVAS_ITEM(text)->canvas),
+	e_canvas_popup_tooltip (E_CANVAS(FOO_CANVAS_ITEM(text)->canvas),
 				tooltip_window,
 				pixel_origin.x - 2 + tooltip_x,
 				pixel_origin.y - 2 + tooltip_y);
@@ -2145,7 +2148,7 @@ start_editing (EText *text)
 	text->editing = TRUE;
 	if (text->pointer_in) {
 		if (text->default_cursor_shown && (!text->draw_borders)) {
-			gdk_window_set_cursor (GTK_WIDGET (GNOME_CANVAS_ITEM (text)->canvas)->window, text->i_cursor);
+			gdk_window_set_cursor (GTK_WIDGET (FOO_CANVAS_ITEM (text)->canvas)->window, text->i_cursor);
 			text->default_cursor_shown = FALSE;
 		}
 	}
@@ -2170,7 +2173,7 @@ e_text_stop_editing (EText *text)
 
 	text->editing = FALSE;
 	if ( (!text->default_cursor_shown) && (!text->draw_borders) ) {
-		gdk_window_set_cursor (GTK_WIDGET (GNOME_CANVAS_ITEM (text)->canvas)->window, text->default_cursor);
+		gdk_window_set_cursor (GTK_WIDGET (FOO_CANVAS_ITEM (text)->canvas)->window, text->default_cursor);
 		text->default_cursor_shown = TRUE;
 	}
 	if (text->timer) {
@@ -2196,7 +2199,7 @@ _click (gpointer data)
 }
 
 static gint
-e_text_event (GnomeCanvasItem *item, GdkEvent *event)
+e_text_event (FooCanvasItem *item, GdkEvent *event)
 {
 	EText *text = E_TEXT(item);
 	ETextEventProcessorEvent e_tep_event;
@@ -2273,12 +2276,12 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event)
 				if (text->show_cursor || text->draw_borders) {
 					text->show_cursor = FALSE;
 					text->needs_redraw = 1;
-					gnome_canvas_item_request_update (GNOME_CANVAS_ITEM(text));
+					foo_canvas_item_request_update (FOO_CANVAS_ITEM(text));
 				}
 			}
 			if ( text->line_wrap )
 				text->needs_split_into_lines = 1;
-			e_canvas_item_request_reflow (GNOME_CANVAS_ITEM(text));
+			e_canvas_item_request_reflow (FOO_CANVAS_ITEM(text));
 		}
 		return_val = 0;
 		break;
@@ -2357,7 +2360,7 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event)
 			g_source_remove (text->tooltip_timeout);
 			text->tooltip_timeout = 0;
 		}
-		e_canvas_hide_tooltip (E_CANVAS(GNOME_CANVAS_ITEM(text)->canvas));
+		e_canvas_hide_tooltip (E_CANVAS(FOO_CANVAS_ITEM(text)->canvas));
 #if 0
 		if ((!text->editing)
 		    && text->editable
@@ -2400,7 +2403,7 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event)
 		}
 
 		/* Create our own double and triple click events,
-		   as gnome-canvas doesn't forward them to us */
+		   as foo-canvas doesn't forward them to us */
 		if (event->type == GDK_BUTTON_PRESS) {
 			if (text->dbl_timeout == 0 &&
 			    text->tpl_timeout == 0) {
@@ -2491,8 +2494,8 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event)
 	}
 	if (return_val)
 		return return_val;
-	if (GNOME_CANVAS_ITEM_CLASS(e_text_parent_class)->event)
-		return GNOME_CANVAS_ITEM_CLASS(e_text_parent_class)->event(item, event);
+	if (FOO_CANVAS_ITEM_CLASS(e_text_parent_class)->event)
+		return FOO_CANVAS_ITEM_CLASS(e_text_parent_class)->event(item, event);
 	else
 		return 0;
 }
@@ -2511,7 +2514,7 @@ e_text_copy_clipboard (EText *text)
 	selection_end_pos = g_utf8_offset_to_pointer (text->text, selection_end_pos) - text->text;
 
 	gtk_clipboard_set_text (
-				gtk_widget_get_clipboard (GTK_WIDGET (GNOME_CANVAS_ITEM (text)->canvas),
+				gtk_widget_get_clipboard (GTK_WIDGET (FOO_CANVAS_ITEM (text)->canvas),
 							  GDK_SELECTION_CLIPBOARD),
 				text->text + selection_start_pos,
 				selection_end_pos - selection_start_pos);
@@ -2605,7 +2608,7 @@ e_text_update_primary_selection (EText *text)
 	};
 	GtkClipboard *clipboard;
 
-	clipboard = gtk_widget_get_clipboard (GTK_WIDGET (GNOME_CANVAS_ITEM (text)->canvas), GDK_SELECTION_PRIMARY);
+	clipboard = gtk_widget_get_clipboard (GTK_WIDGET (FOO_CANVAS_ITEM (text)->canvas), GDK_SELECTION_PRIMARY);
 
 	if (text->selection_start != text->selection_end) {
 		if (!gtk_clipboard_set_with_owner (clipboard, targets, G_N_ELEMENTS (targets),
@@ -2641,7 +2644,7 @@ e_text_paste (EText *text, GdkAtom selection)
 	g_object_ref (text);
 	gtk_clipboard_request_text (
 
-				    gtk_widget_get_clipboard (GTK_WIDGET (GNOME_CANVAS_ITEM (text)->canvas),
+				    gtk_widget_get_clipboard (GTK_WIDGET (FOO_CANVAS_ITEM (text)->canvas),
 							      selection),
 				    paste_received, text);
 }
@@ -2662,8 +2665,8 @@ static void
 popup_menu_placement_cb (GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer user_data)
 {
 	EText *text = E_TEXT(user_data);
-	GnomeCanvasItem *item = &text->item;
-	GnomeCanvas *parent = item->canvas;
+	FooCanvasItem *item = &text->item;
+	FooCanvas *parent = item->canvas;
 
 	if (parent) {
 		gdk_window_get_origin (((GtkWidget*) parent)->window, x, y);
@@ -2689,7 +2692,7 @@ popup_targets_received (GtkClipboard     *clipboard,
 	g_free (closure);
 
 	gtk_menu_attach_to_widget (GTK_MENU (popup_menu),
-				   GTK_WIDGET(GNOME_CANVAS_ITEM (text)->canvas),
+				   GTK_WIDGET(FOO_CANVAS_ITEM (text)->canvas),
 				   popup_menu_detach);
 
 	/* cut menu item */
@@ -2772,7 +2775,7 @@ e_text_do_popup (EText *text, GdkEventButton *button, gint position)
 
 	gtk_clipboard_request_contents (
 
-					gtk_widget_get_clipboard (GTK_WIDGET (GNOME_CANVAS_ITEM (text)->canvas),
+					gtk_widget_get_clipboard (GTK_WIDGET (FOO_CANVAS_ITEM (text)->canvas),
 								  GDK_SELECTION_CLIPBOARD),
 					gdk_atom_intern ("TARGETS", FALSE),
 					popup_targets_received,
@@ -3344,8 +3347,8 @@ e_text_command(ETextEventProcessor *tep, ETextEventProcessorCommand *command, gp
 		text->select_by_word = command->value;
 		break;
 	case E_TEP_GRAB:
-		e_canvas_item_grab (E_CANVAS (GNOME_CANVAS_ITEM(text)->canvas),
-				    GNOME_CANVAS_ITEM(text),
+		e_canvas_item_grab (E_CANVAS (FOO_CANVAS_ITEM(text)->canvas),
+				    FOO_CANVAS_ITEM(text),
 				    GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK,
 				    text->i_cursor,
 				    command->time,
@@ -3354,8 +3357,8 @@ e_text_command(ETextEventProcessor *tep, ETextEventProcessorCommand *command, gp
 		scroll = FALSE;
 		break;
 	case E_TEP_UNGRAB:
-		e_canvas_item_ungrab (E_CANVAS (GNOME_CANVAS_ITEM(text)->canvas),
-				      GNOME_CANVAS_ITEM(text),
+		e_canvas_item_ungrab (E_CANVAS (FOO_CANVAS_ITEM(text)->canvas),
+				      FOO_CANVAS_ITEM(text),
 				      command->time);
 		scroll = FALSE;
 		break;
@@ -3472,7 +3475,7 @@ e_text_command(ETextEventProcessor *tep, ETextEventProcessorCommand *command, gp
 	}
 
 	text->needs_redraw = 1;
-	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM(text));
+	foo_canvas_item_request_update (FOO_CANVAS_ITEM(text));
 }
 
 /* Class initialization function for the text item */
@@ -3480,10 +3483,10 @@ static void
 e_text_class_init (ETextClass *klass)
 {
 	GObjectClass *gobject_class;
-	GnomeCanvasItemClass *item_class;
+	FooCanvasItemClass *item_class;
 
 	gobject_class = (GObjectClass *) klass;
-	item_class = (GnomeCanvasItemClass *) klass;
+	item_class = (FooCanvasItemClass *) klass;
 
 	gobject_class->dispose = e_text_dispose;
 	gobject_class->set_property = e_text_set_property;
@@ -3871,7 +3874,7 @@ e_text_init (EText *text)
 
 	text->handle_popup            = FALSE;
 
-	e_canvas_item_set_reflow_callback(GNOME_CANVAS_ITEM(text), e_text_reflow);
+	e_canvas_item_set_reflow_callback(FOO_CANVAS_ITEM(text), e_text_reflow);
 }
 
 /* IM Context Callbacks */
diff --git a/widgets/text/e-text.h b/widgets/text/e-text.h
index 057ff50..3780d00 100644
--- a/widgets/text/e-text.h
+++ b/widgets/text/e-text.h
@@ -21,9 +21,9 @@
  *
  * A majority of code taken from:
  *
- * Text item type for GnomeCanvas widget
+ * Text item type for FooCanvas widget
  *
- * GnomeCanvas is basically a port of the Tk toolkit's most excellent
+ * FooCanvas is basically a port of the Tk toolkit's most excellent
  * canvas widget.  Tk is copyrighted by the Regents of the University
  * of California, Sun Microsystems, and other parties.
  *
@@ -100,7 +100,7 @@ typedef struct _EText EText;
 typedef struct _ETextClass ETextClass;
 
 struct _EText {
-	GnomeCanvasItem item;
+	FooCanvasItem item;
 
 	ETextModel *model;
 	gint model_changed_signal_id;
@@ -220,7 +220,7 @@ struct _EText {
 };
 
 struct _ETextClass {
-	GnomeCanvasItemClass parent_class;
+	FooCanvasItemClass parent_class;
 
 	void (* changed)         (EText *text);
 	void (* activate)        (EText *text);
diff --git a/widgets/text/gal-a11y-e-text.c b/widgets/text/gal-a11y-e-text.c
index 113c503..cb6eaf5 100644
--- a/widgets/text/gal-a11y-e-text.c
+++ b/widgets/text/gal-a11y-e-text.c
@@ -519,7 +519,7 @@ et_get_character_extents (AtkText *text,
 {
         GObject *obj;
         EText *etext;
-        GnomeCanvas *canvas;
+        FooCanvas *canvas;
         gint x_widget, y_widget, x_window, y_window;
         GdkWindow *window;
         GtkWidget *widget;
@@ -531,7 +531,7 @@ et_get_character_extents (AtkText *text,
             return;
         g_return_if_fail (E_IS_TEXT (obj));
         etext = E_TEXT(obj);
-        canvas = GNOME_CANVAS_ITEM(etext)->canvas;
+        canvas = FOO_CANVAS_ITEM(etext)->canvas;
         widget = GTK_WIDGET(canvas);
         window = widget->window;
         gdk_window_get_origin (window, &x_widget, &y_widget);
@@ -596,7 +596,7 @@ et_get_offset_at_point (AtkText *text,
 {
         GObject *obj;
         EText *etext;
-        GnomeCanvas *canvas;
+        FooCanvas *canvas;
 	gint x_widget, y_widget, x_window, y_window;
 	GdkWindow *window;
         GtkWidget *widget;
@@ -609,7 +609,7 @@ et_get_offset_at_point (AtkText *text,
             return -1;
         g_return_val_if_fail (E_IS_TEXT (obj), -1);
         etext = E_TEXT(obj);
-        canvas = GNOME_CANVAS_ITEM(etext)->canvas;
+        canvas = FOO_CANVAS_ITEM(etext)->canvas;
         widget = GTK_WIDGET(canvas);
 	window = widget->window;
 	gdk_window_get_origin (window, &x_widget, &y_widget);
@@ -721,8 +721,8 @@ et_add_selection (AtkText *text,
 		etext->selection_start = real_start;
 		etext->selection_end = real_end;
 
-		gnome_canvas_item_grab_focus (GNOME_CANVAS_ITEM (etext));
-		gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (etext));
+		foo_canvas_item_grab_focus (FOO_CANVAS_ITEM (etext));
+		foo_canvas_item_request_update (FOO_CANVAS_ITEM (etext));
 
 		g_signal_emit_by_name (ATK_OBJECT (text), "text_selection_changed");
 
@@ -1096,7 +1096,7 @@ gal_a11y_e_text_get_type (void)
 			NULL
 		};
 
-		factory = atk_registry_get_factory (atk_get_default_registry (), GNOME_TYPE_CANVAS_ITEM);
+		factory = atk_registry_get_factory (atk_get_default_registry (), FOO_TYPE_CANVAS_ITEM);
 		parent_type = atk_object_factory_get_accessible_type (factory);
 
 		type = gal_a11y_type_register_static_with_private (PARENT_TYPE, "GalA11yEText", &info, 0,



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