Code

Split SPCanvasItem and SPCanvasGroup to individual .h files. Removed forward header.
[inkscape.git] / src / display / canvas-arena.cpp
index 84ed621dbebe904b54a8b7d60a62faee29df16a4..fb7ca9d78d482a070dfaa2995907afd8ff2fdf49 100644 (file)
@@ -1,5 +1,3 @@
-#define __SP_CANVAS_ARENA_C__
-
 /*
  * RGBA display list system for inkscape
  *
 #include <libnr/nr-blit.h>
 #include <gtk/gtksignal.h>
 
-#include <display/display-forward.h>
 #include <display/sp-canvas-util.h>
-#include <helper/sp-marshal.h>
+#include "helper/sp-marshal.h"
 #include <display/nr-arena.h>
 #include <display/nr-arena-group.h>
 #include <display/canvas-arena.h>
+#include <display/inkscape-cairo.h>
 
 enum {
-       ARENA_EVENT,
-       LAST_SIGNAL
+    ARENA_EVENT,
+    LAST_SIGNAL
 };
 
 static void sp_canvas_arena_class_init(SPCanvasArenaClass *klass);
 static void sp_canvas_arena_init(SPCanvasArena *group);
 static void sp_canvas_arena_destroy(GtkObject *object);
 
-static void sp_canvas_arena_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags);
+static void sp_canvas_arena_update (SPCanvasItem *item, Geom::Matrix const &affine, unsigned int flags);
 static void sp_canvas_arena_render (SPCanvasItem *item, SPCanvasBuf *buf);
-static double sp_canvas_arena_point (SPCanvasItem *item, NR::Point p, SPCanvasItem **actual_item);
+static double sp_canvas_arena_point (SPCanvasItem *item, Geom::Point p, SPCanvasItem **actual_item);
 static gint sp_canvas_arena_event (SPCanvasItem *item, GdkEvent *event);
 
 static gint sp_canvas_arena_send_event (SPCanvasArena *arena, GdkEvent *event);
@@ -42,9 +40,9 @@ static void sp_canvas_arena_request_update (NRArena *arena, NRArenaItem *item, v
 static void sp_canvas_arena_request_render (NRArena *arena, NRRectL *area, void *data);
 
 NRArenaEventVector carenaev = {
-       {NULL},
-       sp_canvas_arena_request_update,
-       sp_canvas_arena_request_render
+    {NULL},
+    sp_canvas_arena_request_update,
+    sp_canvas_arena_request_render
 };
 
 static SPCanvasItemClass *parent_class;
@@ -53,403 +51,348 @@ static guint signals[LAST_SIGNAL] = {0};
 GtkType
 sp_canvas_arena_get_type (void)
 {
-       static GtkType type = 0;
-       if (!type) {
-               GtkTypeInfo info = {
-                       "SPCanvasArena",
-                       sizeof (SPCanvasArena),
-                       sizeof (SPCanvasArenaClass),
-                       (GtkClassInitFunc) sp_canvas_arena_class_init,
-                       (GtkObjectInitFunc) sp_canvas_arena_init,
-                       NULL, NULL, NULL
-               };
-               type = gtk_type_unique (SP_TYPE_CANVAS_ITEM, &info);
-       }
-       return type;
+    static GtkType type = 0;
+    if (!type) {
+        GtkTypeInfo info = {
+            (gchar *)"SPCanvasArena",
+            sizeof (SPCanvasArena),
+            sizeof (SPCanvasArenaClass),
+            (GtkClassInitFunc) sp_canvas_arena_class_init,
+            (GtkObjectInitFunc) sp_canvas_arena_init,
+            NULL, NULL, NULL
+        };
+        type = gtk_type_unique (SP_TYPE_CANVAS_ITEM, &info);
+    }
+    return type;
 }
 
 static void
 sp_canvas_arena_class_init (SPCanvasArenaClass *klass)
 {
-       GtkObjectClass *object_class;
-       SPCanvasItemClass *item_class;
+    GtkObjectClass *object_class;
+    SPCanvasItemClass *item_class;
 
-       object_class = (GtkObjectClass *) klass;
-       item_class = (SPCanvasItemClass *) klass;
+    object_class = (GtkObjectClass *) klass;
+    item_class = (SPCanvasItemClass *) klass;
 
-       parent_class = (SPCanvasItemClass*)gtk_type_class (SP_TYPE_CANVAS_ITEM);
+    parent_class = (SPCanvasItemClass*)gtk_type_class (SP_TYPE_CANVAS_ITEM);
 
-       signals[ARENA_EVENT] = gtk_signal_new ("arena_event",
-                                              GTK_RUN_LAST,
-                                              GTK_CLASS_TYPE(object_class),
-                                              GTK_SIGNAL_OFFSET (SPCanvasArenaClass, arena_event),
-                                              sp_marshal_INT__POINTER_POINTER,
-                                              GTK_TYPE_INT, 2, GTK_TYPE_POINTER, GTK_TYPE_POINTER);
+    signals[ARENA_EVENT] = gtk_signal_new ("arena_event",
+                                           GTK_RUN_LAST,
+                                           GTK_CLASS_TYPE(object_class),
+                                           ((glong)((guint8*)&(klass->arena_event) - (guint8*)klass)),
+                                           sp_marshal_INT__POINTER_POINTER,
+                                           GTK_TYPE_INT, 2, GTK_TYPE_POINTER, GTK_TYPE_POINTER);
 
-       object_class->destroy = sp_canvas_arena_destroy;
+    object_class->destroy = sp_canvas_arena_destroy;
 
-       item_class->update = sp_canvas_arena_update;
-       item_class->render = sp_canvas_arena_render;
-       item_class->point = sp_canvas_arena_point;
-       item_class->event = sp_canvas_arena_event;
+    item_class->update = sp_canvas_arena_update;
+    item_class->render = sp_canvas_arena_render;
+    item_class->point = sp_canvas_arena_point;
+    item_class->event = sp_canvas_arena_event;
 }
 
 static void
 sp_canvas_arena_init (SPCanvasArena *arena)
 {
-       arena->sticky = FALSE;
+    arena->sticky = FALSE;
 
-       arena->arena = NRArena::create();
-       arena->root = NRArenaGroup::create(arena->arena);
-       nr_arena_group_set_transparent (NR_ARENA_GROUP (arena->root), TRUE);
+    arena->arena = NRArena::create();
+    arena->arena->canvasarena = arena;
+    arena->root = NRArenaGroup::create(arena->arena);
+    nr_arena_group_set_transparent (NR_ARENA_GROUP (arena->root), TRUE);
 
-#ifdef arena_item_tile_cache
-  arena->root->skipCaching=true;
-#endif
-  
-       arena->active = NULL;
+    arena->active = NULL;
 
-       nr_active_object_add_listener ((NRActiveObject *) arena->arena, (NRObjectEventVector *) &carenaev, sizeof (carenaev), arena);
+    nr_active_object_add_listener ((NRActiveObject *) arena->arena, (NRObjectEventVector *) &carenaev, sizeof (carenaev), arena);
 }
 
 static void
 sp_canvas_arena_destroy (GtkObject *object)
 {
-       SPCanvasArena *arena = SP_CANVAS_ARENA (object);
+    SPCanvasArena *arena = SP_CANVAS_ARENA (object);
 
-       if (arena->active) {
-               nr_object_unref ((NRObject *) arena->active);
-               arena->active = NULL;
-       }
+    if (arena->active) {
+        nr_object_unref ((NRObject *) arena->active);
+        arena->active = NULL;
+    }
 
-       if (arena->root) {
-               nr_arena_item_unref (arena->root);
-               arena->root = NULL;
-       }
+    if (arena->root) {
+        nr_arena_item_unref (arena->root);
+        arena->root = NULL;
+    }
 
-       if (arena->arena) {
-               nr_active_object_remove_listener_by_data ((NRActiveObject *) arena->arena, arena);
+    if (arena->arena) {
+        nr_active_object_remove_listener_by_data ((NRActiveObject *) arena->arena, arena);
 
-               nr_object_unref ((NRObject *) arena->arena);
-               arena->arena = NULL;
-       }
+        nr_object_unref ((NRObject *) arena->arena);
+        arena->arena = NULL;
+    }
 
-       if (GTK_OBJECT_CLASS (parent_class)->destroy)
-               (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+    if (GTK_OBJECT_CLASS (parent_class)->destroy)
+        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
 }
 
 static void
-sp_canvas_arena_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags)
+sp_canvas_arena_update (SPCanvasItem *item, Geom::Matrix const &affine, unsigned int flags)
 {
-       SPCanvasArena *arena = SP_CANVAS_ARENA (item);
-
-       if (((SPCanvasItemClass *) parent_class)->update)
-               (* ((SPCanvasItemClass *) parent_class)->update) (item, affine, flags);
-
-       arena->gc.transform = affine;
-
-       guint reset;
-       reset = (flags & SP_CANVAS_UPDATE_AFFINE)? NR_ARENA_ITEM_STATE_ALL : NR_ARENA_ITEM_STATE_NONE;
-
-       nr_arena_item_invoke_update (arena->root, NULL, &arena->gc, NR_ARENA_ITEM_STATE_ALL, reset);
-
-       item->x1 = arena->root->bbox.x0 - 1;
-       item->y1 = arena->root->bbox.y0 - 1;
-       item->x2 = arena->root->bbox.x1 + 1;
-       item->y2 = arena->root->bbox.y1 + 1;
-
-       if (arena->cursor) {
-               /* Mess with enter/leave notifiers */
-               NRArenaItem *new_arena = nr_arena_item_invoke_pick (arena->root, arena->c, arena->arena->delta, arena->sticky);
-               if (new_arena != arena->active) {
-                       GdkEventCrossing ec;
-                       ec.window = GTK_WIDGET (item->canvas)->window;
-                       ec.send_event = TRUE;
-                       ec.subwindow = ec.window;
-                       ec.time = GDK_CURRENT_TIME;
-                       ec.x = arena->c[NR::X];
-                       ec.y = arena->c[NR::Y];
-                       /* fixme: */
-                       if (arena->active) {
-                               ec.type = GDK_LEAVE_NOTIFY;
-                               sp_canvas_arena_send_event (arena, (GdkEvent *) &ec);
-                       }
-                       /* fixme: This is not optimal - better track ::destroy (Lauris) */
-                       if (arena->active) nr_object_unref ((NRObject *) arena->active);
-                       arena->active = new_arena;
-                       if (arena->active) nr_object_ref ((NRObject *) arena->active);
-                       if (arena->active) {
-                               ec.type = GDK_ENTER_NOTIFY;
-                               sp_canvas_arena_send_event (arena, (GdkEvent *) &ec);
-                       }
-               }
-       }
+    SPCanvasArena *arena = SP_CANVAS_ARENA (item);
+
+    if (((SPCanvasItemClass *) parent_class)->update)
+        (* ((SPCanvasItemClass *) parent_class)->update) (item, affine, flags);
+
+    arena->gc.transform = affine;
+
+    guint reset;
+    reset = (flags & SP_CANVAS_UPDATE_AFFINE)? NR_ARENA_ITEM_STATE_ALL : NR_ARENA_ITEM_STATE_NONE;
+
+    nr_arena_item_invoke_update (arena->root, NULL, &arena->gc, NR_ARENA_ITEM_STATE_ALL, reset);
+
+    item->x1 = arena->root->bbox.x0 - 1;
+    item->y1 = arena->root->bbox.y0 - 1;
+    item->x2 = arena->root->bbox.x1 + 1;
+    item->y2 = arena->root->bbox.y1 + 1;
+
+    if (arena->cursor) {
+        /* Mess with enter/leave notifiers */
+        NRArenaItem *new_arena = nr_arena_item_invoke_pick (arena->root, arena->c, arena->arena->delta, arena->sticky);
+        if (new_arena != arena->active) {
+            GdkEventCrossing ec;
+            ec.window = GTK_WIDGET (item->canvas)->window;
+            ec.send_event = TRUE;
+            ec.subwindow = ec.window;
+            ec.time = GDK_CURRENT_TIME;
+            ec.x = arena->c[Geom::X];
+            ec.y = arena->c[Geom::Y];
+            /* fixme: */
+            if (arena->active) {
+                ec.type = GDK_LEAVE_NOTIFY;
+                sp_canvas_arena_send_event (arena, (GdkEvent *) &ec);
+            }
+            /* fixme: This is not optimal - better track ::destroy (Lauris) */
+            if (arena->active) nr_object_unref ((NRObject *) arena->active);
+            arena->active = new_arena;
+            if (arena->active) nr_object_ref ((NRObject *) arena->active);
+            if (arena->active) {
+                ec.type = GDK_ENTER_NOTIFY;
+                sp_canvas_arena_send_event (arena, (GdkEvent *) &ec);
+            }
+        }
+    }
 }
 
-#ifdef arena_item_tile_cache
-extern void age_cache(void);
-#endif
-
 static void
 sp_canvas_arena_render (SPCanvasItem *item, SPCanvasBuf *buf)
 {
-       gint bw, bh, sw, sh;
-       gint x, y;
-
-       SPCanvasArena *arena = SP_CANVAS_ARENA (item);
-
-       nr_arena_item_invoke_update (arena->root, NULL, &arena->gc,
-                                    NR_ARENA_ITEM_STATE_BBOX | NR_ARENA_ITEM_STATE_RENDER,
-                                    NR_ARENA_ITEM_STATE_NONE);
-
-       sp_canvas_prepare_buffer(buf);
-  
-#ifdef arena_item_tile_cache
-  age_cache();
-#endif
-       bw = buf->rect.x1 - buf->rect.x0;
-       bh = buf->rect.y1 - buf->rect.y0;
-       if ((bw < 1) || (bh < 1)) return;
-
-       if (arena->arena->rendermode != RENDERMODE_OUTLINE) { // use 256K as a compromise to not slow down gradients
-               /* 256K is the cached buffer and we need 4 channels */
-               if (bw * bh < 65536) { // 256K/4
-                       /* We can go with single buffer */
-                       sw = bw;
-                       sh = bh;
-               } else if (bw <= 4096) {
-                       /* Go with row buffer */
-                       sw = bw;
-                       sh = 65536 / bw;
-               } else if (bh <= 4096) {
-                       /* Go with column buffer */
-                       sw = 65536 / bh;
-                       sh = bh;
-               } else {
-                       sw = 256;
-                       sh = 256;
-               }
-       } else { // paths only, so 1M works faster
-               /* 1M is the cached buffer and we need 4 channels */
-               if (bw * bh < 262144) { // 1M/4
-                       /* We can go with single buffer */
-                       sw = bw;
-                       sh = bh;
-               } else if (bw <= 8192) {
-                       /* Go with row buffer */
-                       sw = bw;
-                       sh = 262144 / bw;
-               } else if (bh <= 8192) {
-                       /* Go with column buffer */
-                       sw = 262144 / bh;
-                       sh = bh;
-               } else {
-                       sw = 512;
-                       sh = 512;
-               }
-       }
-
-/* fixme: RGB transformed bitmap blit is not implemented (Lauris) */
-/* And even if it would be, unless it uses MMX there is little reason to go RGB */
-#define STRICT_RGBA
-
-       for (y = buf->rect.y0; y < buf->rect.y1; y += sh) {
-               for (x = buf->rect.x0; x < buf->rect.x1; x += sw) {
-                       NRRectL area;
-#ifdef STRICT_RGBA
-                       NRPixBlock pb;
-#endif
-                       NRPixBlock cb;
-
-                       area.x0 = x;
-                       area.y0 = y;
-                       area.x1 = MIN (x + sw, buf->rect.x1);
-                       area.y1 = MIN (y + sh, buf->rect.y1);
-
-#ifdef STRICT_RGBA
-                       nr_pixblock_setup_fast (&pb, NR_PIXBLOCK_MODE_R8G8B8A8P, area.x0, area.y0, area.x1, area.y1, TRUE);
-                       /* fixme: */
-                       pb.empty = FALSE;
-#endif
-
-                       nr_pixblock_setup_extern (&cb, NR_PIXBLOCK_MODE_R8G8B8, area.x0, area.y0, area.x1, area.y1,
-                                                 buf->buf + (y - buf->rect.y0) * buf->buf_rowstride + 3 * (x - buf->rect.x0),
-                                                 buf->buf_rowstride,
-                                                 FALSE, FALSE);
-
-#ifdef STRICT_RGBA
-            pb.visible_area = buf->visible_rect; 
-                       if (pb.data.px != NULL) {
-                           nr_arena_item_invoke_render (arena->root, &area, &pb, 0);
-                           nr_blit_pixblock_pixblock (&cb, &pb);
-                       }
-                       nr_pixblock_release (&pb);
-#else
-            cb.visible_area = buf->visible_rect; 
-                       nr_arena_item_invoke_render (arena->root, &area, &cb, 0);
-#endif
-
-                       nr_pixblock_release (&cb);
-               }
-       }
+    gint bw, bh;
+    SPCanvasArena *arena = SP_CANVAS_ARENA (item);
+
+    nr_arena_item_invoke_update (arena->root, NULL, &arena->gc,
+                                 NR_ARENA_ITEM_STATE_BBOX | NR_ARENA_ITEM_STATE_RENDER,
+                                 NR_ARENA_ITEM_STATE_NONE);
+
+    sp_canvas_prepare_buffer(buf);
+
+    bw = buf->rect.x1 - buf->rect.x0;
+    bh = buf->rect.y1 - buf->rect.y0;
+    if ((bw < 1) || (bh < 1)) return;
+
+    NRRectL area;
+    NRPixBlock cb;
+
+    area.x0 = buf->rect.x0;
+    area.y0 = buf->rect.y0;
+    area.x1 = buf->rect.x1;
+    area.y1 = buf->rect.y1;
+
+    nr_pixblock_setup_extern (&cb, NR_PIXBLOCK_MODE_R8G8B8A8P, area.x0, area.y0, area.x1, area.y1,
+                              buf->buf,
+                              buf->buf_rowstride,
+                              FALSE, FALSE);
+
+    cb.visible_area = buf->visible_rect;
+    cairo_t *ct = nr_create_cairo_context (&area, &cb);
+    nr_arena_item_invoke_render (ct, arena->root, &area, &cb, 0);
+
+    cairo_surface_t *cst = cairo_get_target(ct);
+    cairo_destroy (ct);
+    cairo_surface_finish (cst);
+    cairo_surface_destroy (cst);
+
+    nr_pixblock_release (&cb);
 }
 
 static double
-sp_canvas_arena_point (SPCanvasItem *item, NR::Point p, SPCanvasItem **actual_item)
+sp_canvas_arena_point (SPCanvasItem *item, Geom::Point p, SPCanvasItem **actual_item)
 {
-       SPCanvasArena *arena = SP_CANVAS_ARENA (item);
+    SPCanvasArena *arena = SP_CANVAS_ARENA (item);
 
-       nr_arena_item_invoke_update (arena->root, NULL, &arena->gc,
-                                    NR_ARENA_ITEM_STATE_BBOX | NR_ARENA_ITEM_STATE_PICK,
-                                    NR_ARENA_ITEM_STATE_NONE);
+    nr_arena_item_invoke_update (arena->root, NULL, &arena->gc,
+                                 NR_ARENA_ITEM_STATE_BBOX | NR_ARENA_ITEM_STATE_PICK,
+                                 NR_ARENA_ITEM_STATE_NONE);
 
-       NRArenaItem *picked = nr_arena_item_invoke_pick (arena->root, p, arena->arena->delta, arena->sticky);
+    NRArenaItem *picked = nr_arena_item_invoke_pick (arena->root, p, arena->arena->delta, arena->sticky);
 
-       arena->picked = picked;
+    arena->picked = picked;
 
-       if (picked) {
-               *actual_item = item;
-               return 0.0;
-       }
+    if (picked) {
+        *actual_item = item;
+        return 0.0;
+    }
 
-       return 1e18;
+    return 1e18;
 }
 
 static gint
 sp_canvas_arena_event (SPCanvasItem *item, GdkEvent *event)
 {
-       NRArenaItem *new_arena;
-       /* fixme: This sucks, we have to handle enter/leave notifiers */
-
-       SPCanvasArena *arena = SP_CANVAS_ARENA (item);
-
-       gint ret = FALSE;
-
-       switch (event->type) {
-       case GDK_ENTER_NOTIFY:
-               if (!arena->cursor) {
-                       if (arena->active) {
-                               //g_warning ("Cursor entered to arena with already active item");
-                               nr_object_unref ((NRObject *) arena->active);
-                       }
-                       arena->cursor = TRUE;
-
-                       /* TODO ... event -> arena transform? */
-                       arena->c = NR::Point(event->crossing.x, event->crossing.y);
-
-                       /* fixme: Not sure abut this, but seems the right thing (Lauris) */
-                       nr_arena_item_invoke_update (arena->root, NULL, &arena->gc, NR_ARENA_ITEM_STATE_PICK, NR_ARENA_ITEM_STATE_NONE);
-                       arena->active = nr_arena_item_invoke_pick (arena->root, arena->c, arena->arena->delta, arena->sticky);
-                       if (arena->active) nr_object_ref ((NRObject *) arena->active);
-                       ret = sp_canvas_arena_send_event (arena, event);
-               }
-               break;
-       case GDK_LEAVE_NOTIFY:
-               if (arena->cursor) {
-                       ret = sp_canvas_arena_send_event (arena, event);
-                       if (arena->active) nr_object_unref ((NRObject *) arena->active);
-                       arena->active = NULL;
-                       arena->cursor = FALSE;
-               }
-               break;
-       case GDK_MOTION_NOTIFY:
-               /* TODO ... event -> arena transform? */
-               arena->c = NR::Point(event->motion.x, event->motion.y);
-
-               /* fixme: Not sure abut this, but seems the right thing (Lauris) */
-               nr_arena_item_invoke_update (arena->root, NULL, &arena->gc, NR_ARENA_ITEM_STATE_PICK, NR_ARENA_ITEM_STATE_NONE);
-               new_arena = nr_arena_item_invoke_pick (arena->root, arena->c, arena->arena->delta, arena->sticky);
-               if (new_arena != arena->active) {
-                       GdkEventCrossing ec;
-                       ec.window = event->motion.window;
-                       ec.send_event = event->motion.send_event;
-                       ec.subwindow = event->motion.window;
-                       ec.time = event->motion.time;
-                       ec.x = event->motion.x;
-                       ec.y = event->motion.y;
-                       /* fixme: */
-                       if (arena->active) {
-                               ec.type = GDK_LEAVE_NOTIFY;
-                               ret = sp_canvas_arena_send_event (arena, (GdkEvent *) &ec);
-                       }
-                       if (arena->active) nr_object_unref ((NRObject *) arena->active);
-                       arena->active = new_arena;
-                       if (arena->active) nr_object_ref ((NRObject *) arena->active);
-                       if (arena->active) {
-                               ec.type = GDK_ENTER_NOTIFY;
-                               ret = sp_canvas_arena_send_event (arena, (GdkEvent *) &ec);
-                       }
-               }
-               ret = sp_canvas_arena_send_event (arena, event);
-               break;
-       default:
-               /* Just send event */
-               ret = sp_canvas_arena_send_event (arena, event);
-               break;
-       }
-
-       return ret;
+    NRArenaItem *new_arena;
+    /* fixme: This sucks, we have to handle enter/leave notifiers */
+
+    SPCanvasArena *arena = SP_CANVAS_ARENA (item);
+
+    gint ret = FALSE;
+
+    switch (event->type) {
+        case GDK_ENTER_NOTIFY:
+            if (!arena->cursor) {
+                if (arena->active) {
+                    //g_warning ("Cursor entered to arena with already active item");
+                    nr_object_unref ((NRObject *) arena->active);
+                }
+                arena->cursor = TRUE;
+
+                /* TODO ... event -> arena transform? */
+                arena->c = Geom::Point(event->crossing.x, event->crossing.y);
+
+                /* fixme: Not sure abut this, but seems the right thing (Lauris) */
+                nr_arena_item_invoke_update (arena->root, NULL, &arena->gc, NR_ARENA_ITEM_STATE_PICK, NR_ARENA_ITEM_STATE_NONE);
+                arena->active = nr_arena_item_invoke_pick (arena->root, arena->c, arena->arena->delta, arena->sticky);
+                if (arena->active) nr_object_ref ((NRObject *) arena->active);
+                ret = sp_canvas_arena_send_event (arena, event);
+            }
+            break;
+
+        case GDK_LEAVE_NOTIFY:
+            if (arena->cursor) {
+                ret = sp_canvas_arena_send_event (arena, event);
+                if (arena->active) nr_object_unref ((NRObject *) arena->active);
+                arena->active = NULL;
+                arena->cursor = FALSE;
+            }
+            break;
+
+        case GDK_MOTION_NOTIFY:
+            /* TODO ... event -> arena transform? */
+            arena->c = Geom::Point(event->motion.x, event->motion.y);
+
+            /* fixme: Not sure abut this, but seems the right thing (Lauris) */
+            nr_arena_item_invoke_update (arena->root, NULL, &arena->gc, NR_ARENA_ITEM_STATE_PICK, NR_ARENA_ITEM_STATE_NONE);
+            new_arena = nr_arena_item_invoke_pick (arena->root, arena->c, arena->arena->delta, arena->sticky);
+            if (new_arena != arena->active) {
+                GdkEventCrossing ec;
+                ec.window = event->motion.window;
+                ec.send_event = event->motion.send_event;
+                ec.subwindow = event->motion.window;
+                ec.time = event->motion.time;
+                ec.x = event->motion.x;
+                ec.y = event->motion.y;
+                /* fixme: */
+                if (arena->active) {
+                    ec.type = GDK_LEAVE_NOTIFY;
+                    ret = sp_canvas_arena_send_event (arena, (GdkEvent *) &ec);
+                }
+                if (arena->active) nr_object_unref ((NRObject *) arena->active);
+                arena->active = new_arena;
+                if (arena->active) nr_object_ref ((NRObject *) arena->active);
+                if (arena->active) {
+                    ec.type = GDK_ENTER_NOTIFY;
+                    ret = sp_canvas_arena_send_event (arena, (GdkEvent *) &ec);
+                }
+            }
+            ret = sp_canvas_arena_send_event (arena, event);
+            break;
+
+        default:
+            /* Just send event */
+            ret = sp_canvas_arena_send_event (arena, event);
+            break;
+    }
+
+    return ret;
 }
 
 static gint
 sp_canvas_arena_send_event (SPCanvasArena *arena, GdkEvent *event)
 {
-       gint ret = FALSE;
+    gint ret = FALSE;
 
-       /* Send event to arena */
-       gtk_signal_emit (GTK_OBJECT (arena), signals[ARENA_EVENT], arena->active, event, &ret);
+    /* Send event to arena */
+    gtk_signal_emit (GTK_OBJECT (arena), signals[ARENA_EVENT], arena->active, event, &ret);
 
-       return ret;
+    return ret;
 }
 
 static void
-sp_canvas_arena_request_update (NRArena *arena, NRArenaItem *item, void *data)
+sp_canvas_arena_request_update (NRArena */*arena*/, NRArenaItem */*item*/, void *data)
 {
-       sp_canvas_item_request_update (SP_CANVAS_ITEM (data));
+    sp_canvas_item_request_update (SP_CANVAS_ITEM (data));
 }
 
 static void
-sp_canvas_arena_request_render (NRArena *arena, NRRectL *area, void *data)
+sp_canvas_arena_request_render (NRArena */*arena*/, NRRectL *area, void *data)
 {
-       sp_canvas_request_redraw (SP_CANVAS_ITEM (data)->canvas, area->x0, area->y0, area->x1, area->y1);
+    sp_canvas_request_redraw (SP_CANVAS_ITEM (data)->canvas, area->x0, area->y0, area->x1, area->y1);
 }
 
 void
 sp_canvas_arena_set_pick_delta (SPCanvasArena *ca, gdouble delta)
 {
-       g_return_if_fail (ca != NULL);
-       g_return_if_fail (SP_IS_CANVAS_ARENA (ca));
+    g_return_if_fail (ca != NULL);
+    g_return_if_fail (SP_IS_CANVAS_ARENA (ca));
 
-       /* fixme: repick? */
-       ca->delta = delta;
+    /* fixme: repick? */
+    ca->delta = delta;
 }
 
 void
 sp_canvas_arena_set_sticky (SPCanvasArena *ca, gboolean sticky)
 {
-       g_return_if_fail (ca != NULL);
-       g_return_if_fail (SP_IS_CANVAS_ARENA (ca));
+    g_return_if_fail (ca != NULL);
+    g_return_if_fail (SP_IS_CANVAS_ARENA (ca));
 
-       /* fixme: repick? */
-       ca->sticky = sticky;
+    /* fixme: repick? */
+    ca->sticky = sticky;
 }
 
 void
 sp_canvas_arena_render_pixblock (SPCanvasArena *ca, NRPixBlock *pb)
 {
-       NRRectL area;
+    NRRectL area;
 
-       g_return_if_fail (ca != NULL);
-       g_return_if_fail (SP_IS_CANVAS_ARENA (ca));
+    g_return_if_fail (ca != NULL);
+    g_return_if_fail (SP_IS_CANVAS_ARENA (ca));
 
-       /* fixme: */
-       pb->empty = FALSE;
+    /* fixme: */
+    pb->empty = FALSE;
 
-       area.x0 = pb->area.x0;
-       area.y0 = pb->area.y0;
-       area.x1 = pb->area.x1;
-       area.y1 = pb->area.y1;
+    area.x0 = pb->area.x0;
+    area.y0 = pb->area.y0;
+    area.x1 = pb->area.x1;
+    area.y1 = pb->area.y1;
 
-       nr_arena_item_invoke_render (ca->root, &area, pb, 0);
+    nr_arena_item_invoke_render (NULL, ca->root, &area, pb, 0);
 }
 
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :