diff --git a/pd/nw/pdgui.js b/pd/nw/pdgui.js
index fa87ae8281c5ca3ed8cf4d04640d55e07c75d183..4ce6b2e5aa03ec19ca13df7a4ff421223bc2aa58 100644
--- a/pd/nw/pdgui.js
+++ b/pd/nw/pdgui.js
@@ -2159,6 +2159,20 @@ function gui_draw_coords(cid, tag, shape, points) {
     }
 }
 
+function gui_draw_event(cid, tag, scalar_sym, draw_sym, event_name, state) {
+    var item = get_item(cid, tag),
+        event_type = "on" + event_name; 
+    if (state === 1) {
+        item[event_type] = function(e) {
+//            gui_post("Entered! Tag is " + tag);
+            pdsend(cid, "scalar_event", scalar_sym, draw_sym, event_name,
+                e.pageX, e.pageY);
+        };
+    } else {
+        item[event_type] = null;
+    }
+}
+
 // Configure one attr/val pair at a time, received from Pd
 function gui_draw_configure(cid, tag, attr, val) {
     var item = get_item(cid, tag);
diff --git a/pd/src/g_canvas.c b/pd/src/g_canvas.c
index a7a3e6409ecac5987b8f2238758bb90f2afe26c4..7bea503e1c0c3e045ad6a1f2c69583d3cfc1800d 100644
--- a/pd/src/g_canvas.c
+++ b/pd/src/g_canvas.c
@@ -729,14 +729,12 @@ void canvas_dirty(t_canvas *x, t_floatarg n)
     }
 }
 
-extern t_canvas *sc_mouseover_canvas;
-void canvas_scalar_mouseover(t_canvas *x, t_symbol *sendsym, t_floatarg state)
+extern t_canvas *sc_mouseover_canvas; /* not needed */
+
+void draw_notify(t_canvas *x, t_symbol *s, int argc, t_atom *argv);
+void canvas_scalar_event(t_canvas *x, t_symbol *s, int argc, t_atom *argv)
 {
-    t_atom at[1];
-    SETFLOAT(&at[0], state);
-    sc_mouseover_canvas = x;
-    if (sendsym->s_thing) typedmess(sendsym->s_thing, gensym("mouseover"),
-        1, at);
+    draw_notify(x, s, argc, argv);
 }
 
 extern void canvas_check_nlet_highlights(t_canvas *x);
@@ -2327,8 +2325,8 @@ void g_canvas_setup(void)
         gensym("dirty"), A_FLOAT, A_NULL);
     class_setpropertiesfn(canvas_class, (t_propertiesfn)canvas_properties);
 
-    class_addmethod(canvas_class, (t_method)canvas_scalar_mouseover,
-        gensym("scalar_mouseover"), A_SYMBOL, A_FLOAT, 0);
+    class_addmethod(canvas_class, (t_method)canvas_scalar_event,
+        gensym("scalar_event"), A_GIMME, 0);
 
 /* ---------------------- list handling ------------------------ */
     class_addmethod(canvas_class, (t_method)glist_clear, gensym("clear"),
diff --git a/pd/src/g_scalar.c b/pd/src/g_scalar.c
index e1c29df761e9252c8df64dfb447c45e5037a3a90..6088658df843abce4797b9382fd39cb051bc5e64 100644
--- a/pd/src/g_scalar.c
+++ b/pd/src/g_scalar.c
@@ -316,7 +316,7 @@ t_scalar *scalar_new(t_glist *owner, t_symbol *templatesym)
     gpointer_setglist(&gp, owner, &x->sc_gobj);
     word_init(x->sc_vec, template, &gp);
     char buf[50];
-    sprintf(buf, ".x%lx", (long unsigned int)x);
+    sprintf(buf, "x%lx", (long unsigned int)x);
     pd_bind(&x->sc_gobj.g_pd, gensym(buf));
     return (x);
 }
@@ -1298,7 +1298,7 @@ static void scalar_free(t_scalar *x)
     }
     word_free(x->sc_vec, template);
     char buf[50];
-    sprintf(buf, ".x%lx", (long unsigned int)x);
+    sprintf(buf, "x%lx", (long unsigned int)x);
     pd_unbind(&x->sc_gobj.g_pd, gensym(buf));
     gfxstub_deleteforkey(x);
         /* the "size" field in the class is zero, so Pd doesn't try to free
diff --git a/pd/src/g_template.c b/pd/src/g_template.c
index db981642245e448d3d4286bf07d6cabdd52c6368..7713a00a85123aabe51e8f10b2f71e123c6ee17b 100644
--- a/pd/src/g_template.c
+++ b/pd/src/g_template.c
@@ -1178,12 +1178,18 @@ void draw_notifyforscalar(t_draw *x, t_glist *owner,
     t_scalar *sc, t_symbol *s, int argc, t_atom *argv)
 {
     t_gpointer gp;
+    t_binbuf *b = binbuf_new();
+    t_atom at[1];
     gpointer_init(&gp);
     gpointer_setglist(&gp, owner, &sc->sc_gobj);
-    SETPOINTER(argv, &gp);
+    SETPOINTER(at, &gp);
+    binbuf_add(b, 1, at);
+    binbuf_add(b, argc, argv);
     if (x)
-        outlet_anything(x->x_obj.ob_outlet, s, argc, argv);
+        outlet_anything(x->x_obj.ob_outlet, s, binbuf_getnatom(b),
+            binbuf_getvec(b));
     gpointer_unset(&gp);
+    binbuf_free(b);
 }
 
 static int is_svgpath_cmd(t_symbol *s)
@@ -1412,6 +1418,11 @@ static void *draw_new(t_symbol *classsym, t_int argc, t_atom *argv)
     inlet_new(&x->x_obj, &sa->x_pd, 0, 0);
     /* x_canvas can stay here */
     x->x_canvas = canvas_getcurrent();
+
+    char buf[50];
+    sprintf(buf, "x%lx", (long unsigned int)x);
+    pd_bind(&x->x_obj.te_pd, gensym(buf));
+
     return (x);
 }
 
@@ -1638,6 +1649,41 @@ void svg_sendupdate(t_svg *x, t_canvas *c, t_symbol *s,
             mbuf);
         *predraw_bbox = 1;
     }
+    else if (s == gensym("mouseover"))
+    {
+        gui_vmess("gui_draw_event", "xsxxsi",
+            glist_getcanvas(c), tag, sc, x->x_parent, "mouseover",
+            (int)fielddesc_getcoord(
+                &x->x_events.e_mouseover, template, data, 1));
+    }
+    else if (s == gensym("mouseout"))
+    {
+        gui_vmess("gui_draw_event", "xsxxsi",
+            glist_getcanvas(c), tag, sc, x->x_parent, "mouseout",
+            (int)fielddesc_getcoord(
+                &x->x_events.e_mouseout, template, data, 1));
+    }
+    else if (s == gensym("mousemove"))
+    {
+        gui_vmess("gui_draw_event", "xsxxsi",
+            glist_getcanvas(c), tag, sc, x->x_parent, "mousemove",
+            (int)fielddesc_getcoord(
+                &x->x_events.e_mousemove, template, data, 1));
+    }
+    else if (s == gensym("mouseup"))
+    {
+        gui_vmess("gui_draw_event", "xsxxsi",
+            glist_getcanvas(c), tag, sc, x->x_parent, "mouseup",
+            (int)fielddesc_getcoord(
+                &x->x_events.e_mouseup, template, data, 1));
+    }
+    else if (s == gensym("mousedown"))
+    {
+        gui_vmess("gui_draw_event", "xsxxsi",
+            glist_getcanvas(c), tag, sc, x->x_parent, "mousedown",
+            (int)fielddesc_getcoord(
+                &x->x_events.e_mousedown, template, data, 1));
+    }
     else if (s == gensym("vis"))
     {
         gui_vmess("gui_draw_configure", "xsss",
@@ -2101,7 +2147,7 @@ void svg_event(t_svg *x, t_symbol *s, int argc, t_atom *argv)
             fielddesc_setfloatarg(&x->x_events.e_mousemove, argc, argv);
         else if (s == gensym("mouseout"))
             fielddesc_setfloatarg(&x->x_events.e_mouseout, argc, argv);
-//        svg_update(x, s);
+        svg_update(x, s);
     }
 }
 
@@ -3993,13 +4039,37 @@ static int draw_click(t_gobj *z, t_glist *glist,
                 glist_grab(glist, z, draw_motion, 0, xpix, ypix);
         //        outlet_anything(x->x_obj.ob_outlet, gensym("click"), 0, 0);
             }
-            draw_notifyforscalar(x, glist, sc, gensym("mousedown"), 5, at);
+//            draw_notifyforscalar(x, glist, sc, gensym("mousedown"), 5, at);
         }
         return (1);
     }
     return (0);
 }
 
+void draw_notify(t_canvas *x, t_symbol *s, int argc, t_atom *argv)
+{
+    t_symbol *scalarsym = atom_getsymbolarg(0, argc--, argv++);
+    t_symbol *drawsym = atom_getsymbolarg(0, argc--, argv++);
+    t_symbol *event_name = atom_getsymbolarg(0, argc--, argv++);
+    t_scalar *sc;
+    t_draw *d;
+    if (scalarsym->s_thing)
+        sc = (t_scalar *)scalarsym->s_thing;
+    else
+    {
+        error("draw_notify: can't get scalar from symbol");
+        return;
+    }
+    if (drawsym->s_thing)
+        d = (t_draw *)drawsym->s_thing;
+    else
+    {
+        error("draw_notify: can't get draw object from symbol");
+        return;
+    }
+    draw_notifyforscalar(d, x, sc, event_name, argc, argv);
+}
+
 /*
 static int draw_click(t_gobj *z, t_glist *glist, 
     t_word *data, t_template *template, t_scalar *sc, t_array *ap,
@@ -4119,6 +4189,9 @@ void canvas_group_free(t_pd *x)
 
 static void draw_free(t_draw *x)
 {
+    char buf[50];
+    sprintf(buf, "x%lx", (long unsigned int)x);
+    pd_unbind(&x->x_obj.te_pd, gensym(buf));
     t_svg *sa = (t_svg *)x->x_attr;
     svg_free(sa);
 }
@@ -4160,6 +4233,14 @@ static void draw_setup(void)
         gensym("height"), A_GIMME, 0);
     class_addmethod(svg_class, (t_method)svg_event,
         gensym("mousedown"), A_GIMME, 0);
+    class_addmethod(svg_class, (t_method)svg_event,
+        gensym("mousemove"), A_GIMME, 0);
+    class_addmethod(svg_class, (t_method)svg_event,
+        gensym("mouseover"), A_GIMME, 0);
+    class_addmethod(svg_class, (t_method)svg_event,
+        gensym("mouseout"), A_GIMME, 0);
+    class_addmethod(svg_class, (t_method)svg_event,
+        gensym("mouseup"), A_GIMME, 0);
     class_addmethod(svg_class, (t_method)svg_setattr,
         gensym("opacity"), A_GIMME, 0);
     class_addmethod(svg_class, (t_method)svg_setattr,