From 43a2cb9dce539515828d5b7bb36d34508528b754 Mon Sep 17 00:00:00 2001
From: Ivica Ico Bukvic <ico@vt.edu>
Date: Tue, 4 Mar 2014 22:34:15 -0500
Subject: [PATCH] *updated expr to the latest version (still exhibits a crasher
 bug due to buggy free function). *updated latest additions by Jonathan--still
 need following fixes: 1) enter-leave demos don't work at all (any demo
 involving enter-leave) 2) crasher in easing is still valid 3) spin-spin-spin
 crashes pd-l2ork when trying to close the patch while the image is spinning
 and being animated 4) curve-bbox is still having accuracy issues (tkpath
 issue) 5) polar clock still exhibits issues of warping curve (tkpath issue)
 6) On the 15.events.pd change call is never issued--is this another
 side-effect of me not applying everything? 7) Is there a 14. patch for
 ds-tutorials? I didn't find one. 8) in ds-tutorials is gmon.out necessary or
 is this a stale file?

---
 pd/extra/expr~/vexp.c     |  34 ++---
 pd/extra/expr~/vexp_fun.c | 256 +++++++++++++++++++-------------------
 pd/extra/expr~/vexp_if.c  |  18 +--
 pd/src/g_canvas.c         |  13 ++
 pd/src/g_scalar.c         | 102 ++++++++-------
 pd/src/g_template.c       |  90 +++++++++++---
 pd/src/pd.tk              |  26 ++++
 7 files changed, 321 insertions(+), 218 deletions(-)

diff --git a/pd/extra/expr~/vexp.c b/pd/extra/expr~/vexp.c
index 732944deb..f1cd483aa 100644
--- a/pd/extra/expr~/vexp.c
+++ b/pd/extra/expr~/vexp.c
@@ -3,7 +3,7 @@
  * Copyright (C) 1994, 1995, 1998, 1999 by IRCAM-Centre Georges Pompidou, Paris, France.
  * 
  * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
+ * modify it under the terms of the GNU Lesser General Public License
  * as published by the Free Software Foundation; either version 2
  * of the License, or (at your option) any later version.
  * 
@@ -12,9 +12,9 @@
  * This program 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
  * 
- * You should have received a copy of the GNU General Public License
+ * You should have received a copy of the GNU Lesser General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  * 
@@ -97,10 +97,10 @@ struct ex_ex *eval_store(struct expr *expr, struct ex_ex *eptr,
 struct ex_ex *eval_sigidx(struct expr *expr, struct ex_ex *eptr,
                                                 struct ex_ex *optr, int i);
 static int cal_sigidx(struct ex_ex *optr,       /* The output value */
-           int i, float rem_i,      /* integer and fractinal part of index */
+           int i, t_float rem_i,      /* integer and fractinal part of index */
            int idx,                  /* index of current fexpr~ processing */
            int vsize,                                       /* vector size */
-           float *curvec, float *prevec);   /* current and previous table */
+           t_float *curvec, t_float *prevec);   /* current and previous table */
 t_ex_func *find_func(char *s);
 void ex_dzdetect(struct expr *expr);
 
@@ -691,7 +691,7 @@ case ET_INT:                                                            \
         case ET_INT:                                                    \
                 if (optr->ex_type == ET_VEC) {                          \
                         op = optr->ex_vec;                              \
-                        scalar = (float)DZC(left.ex_int, OPR, right.ex_int); \
+                        scalar = (t_float)DZC(left.ex_int, OPR, right.ex_int); \
                         for (j = 0; j < expr->exp_vsize; j++)           \
                                 *op++ = scalar;                         \
                 } else {                                                \
@@ -702,12 +702,12 @@ case ET_INT:                                                            \
         case ET_FLT:                                                    \
                 if (optr->ex_type == ET_VEC) {                          \
                         op = optr->ex_vec;                              \
-                        scalar = DZC(((float)left.ex_int), OPR, right.ex_flt);\
+                        scalar = DZC(((t_float)left.ex_int), OPR, right.ex_flt);\
                         for (j = 0; j < expr->exp_vsize; j++)           \
                                 *op++ = scalar;                         \
                 } else {                                                \
                         optr->ex_type = ET_FLT;                         \
-                        optr->ex_flt = DZC(((float)left.ex_int), OPR,   \
+                        optr->ex_flt = DZC(((t_float)left.ex_int), OPR,   \
                                                         right.ex_flt);  \
                 }                                                       \
                 break;                                                  \
@@ -743,7 +743,7 @@ case ET_FLT:                                                            \
         case ET_INT:                                                    \
                 if (optr->ex_type == ET_VEC) {                          \
                         op = optr->ex_vec;                              \
-                        scalar = DZC((float) left.ex_flt, OPR, right.ex_int); \
+                        scalar = DZC((t_float) left.ex_flt, OPR, right.ex_int); \
                         for (j = 0; j < expr->exp_vsize; j++)           \
                                 *op++ = scalar;                         \
                 } else {                                                \
@@ -854,7 +854,7 @@ break;
         switch(left.ex_type) {                                          \
         case ET_INT:                                                    \
                 if (optr->ex_type == ET_VEC) {                          \
-                        ex_mkvector(optr->ex_vec,(float)(OPR left.ex_int),\
+                        ex_mkvector(optr->ex_vec,(t_float)(OPR left.ex_int),\
                                                         expr->exp_vsize);\
                         break;                                          \
                 }                                                       \
@@ -960,7 +960,7 @@ ex_eval(struct expr *expr, struct ex_ex *eptr, struct ex_ex *optr, int idx)
         switch (eptr->ex_type) {
         case ET_INT:
                 if (optr->ex_type == ET_VEC)
-                        ex_mkvector(optr->ex_vec, (float) eptr->ex_int,
+                        ex_mkvector(optr->ex_vec, (t_float) eptr->ex_int,
                                                                 expr->exp_vsize);
                 else
                         *optr = *eptr;
@@ -1407,7 +1407,7 @@ eval_sigidx(struct expr *expr, struct ex_ex *eptr, struct ex_ex *optr, int idx)
         struct ex_ex arg;
         struct ex_ex *reteptr;
         int i = 0, j = 0;
-        float fi = 0,           /* index in float */
+        t_float fi = 0,         /* index in float */
               rem_i = 0;        /* remains of the float */
         char *tbl;
 
@@ -1504,10 +1504,10 @@ eval_sigidx(struct expr *expr, struct ex_ex *eptr, struct ex_ex *optr, int idx)
  */
 static int
 cal_sigidx(struct ex_ex *optr,  /* The output value */
-           int i, float rem_i,  /* integer and fractinal part of index */
+           int i, t_float rem_i,/* integer and fractinal part of index */
            int idx,             /* index of current fexpr~ processing */
            int vsize,           /* vector size */
-           float *curvec, float *prevec)        /* current and previous table */
+           t_float *curvec, t_float *prevec)        /* current and previous table */
 {
         int n;
 
@@ -1873,8 +1873,8 @@ atoif(char *s, long int *value, long int *type)
         char *p;
         long int_val = 0;
         int flt = 0;
-        float pos = 0;
-        float flt_val = 0;
+        t_float pos = 0;
+        t_float flt_val = 0;
         int base = 10;
 
         p = s;
@@ -1940,7 +1940,7 @@ atoif(char *s, long int *value, long int *type)
                 default:
                         if (flt) {
                                 *type = ET_FLT;
-                                *((float *) value) = flt_val;
+                                *((t_float *) value) = flt_val;
                         } else {
                                 *type = ET_INT;
                                 *value = int_val;
diff --git a/pd/extra/expr~/vexp_fun.c b/pd/extra/expr~/vexp_fun.c
index 41fca48ef..47d95e1d9 100644
--- a/pd/extra/expr~/vexp_fun.c
+++ b/pd/extra/expr~/vexp_fun.c
@@ -3,7 +3,7 @@
  * Copyright (C) 1994, 1995, 1998, 1999 by IRCAM-Centre Georges Pompidou, Paris, France.
  * 
  * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
+ * modify it under the terms of the GNU Lesser General Public License
  * as published by the Free Software Foundation; either version 2
  * of the License, or (at your option) any later version.
  * 
@@ -12,9 +12,9 @@
  * This program 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
  * 
- * You should have received a copy of the GNU General Public License
+ * You should have received a copy of the GNU Lesser General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  * 
@@ -68,7 +68,7 @@
  *                the last argument is a pointer to a struct ex_ex for
  *                the result.  Up do this point, the content of the
  *                struct ex_ex that these functions receive are either
- *                ET_INT (long), ET_FLT (float), or ET_SYM (char **, it is
+ *                ET_INT (long), ET_FLT (t_float), or ET_SYM (char **, it is
  *                char ** and not char * since NewHandle of Mac returns
  *                a char ** for relocatability.)  The common practice in
  *                these functions is that they figure out the type of their
@@ -151,8 +151,8 @@ t_ex_func ex_funcs[] = {
         {"rint",        ex_rint,        1},
         {"float",       ex_tofloat,     1},
         {"fmod",        ex_fmod,        2},
-        {"floor",       ex_floor,       1},
-        {"ceil",        ex_ceil,        1},
+        {"floor",       ex_floor,       2},
+        {"ceil",        ex_ceil,        2},
         {"pow",         ex_pow,         2},
         {"sqrt",        ex_sqrt,        1},
         {"exp",         ex_exp,         1},
@@ -221,7 +221,7 @@ case ET_INT:                                                            \
         case ET_INT:                                                    \
                 if (optr->ex_type == ET_VEC) {                          \
                         op = optr->ex_vec;                              \
-                        scalar = (float)func(leftfuncast left->ex_int,  \
+                        scalar = (t_float)func(leftfuncast left->ex_int,  \
                                         rightfuncast right->ex_int);    \
                         j = e->exp_vsize;                               \
                         while (j--)                                     \
@@ -229,7 +229,7 @@ case ET_INT:                                                            \
                 } else {                                                \
                         if (fltret) {                                   \
                                 optr->ex_type = ET_FLT;                 \
-                                optr->ex_flt = (float)func(leftfuncast  \
+                                optr->ex_flt = (t_float)func(leftfuncast  \
                                 left->ex_int, rightfuncast right->ex_int); \
                         } else {                                        \
                                 optr->ex_type = ET_INT;                 \
@@ -241,14 +241,14 @@ case ET_INT:                                                            \
         case ET_FLT:                                                    \
                 if (optr->ex_type == ET_VEC) {                          \
                         op = optr->ex_vec;                              \
-                        scalar = (float)func(leftfuncast left->ex_int,  \
+                        scalar = (t_float)func(leftfuncast left->ex_int,  \
                                         rightfuncast right->ex_flt);    \
                         j = e->exp_vsize;                               \
                         while (j--)                                     \
                                 *op++ = scalar;                         \
                 } else {                                                \
                         optr->ex_type = ET_FLT;                         \
-                        optr->ex_flt = (float)func(leftfuncast left->ex_int,  \
+                        optr->ex_flt = (t_float)func(leftfuncast left->ex_int,  \
                                         rightfuncast right->ex_flt);    \
                 }                                                       \
                 break;                                                  \
@@ -268,7 +268,7 @@ case ET_INT:                                                            \
                 op = optr->ex_vec;                                      \
                 j = e->exp_vsize;                                       \
                 while (j--) {                                           \
-                        *op++ = (float)func(leftfuncast scalar,         \
+                        *op++ = (t_float)func(leftfuncast scalar,         \
                                                 rightfuncast *rp);      \
                         rp++;                                           \
                 }                                                       \
@@ -285,28 +285,28 @@ case ET_FLT:                                                            \
         case ET_INT:                                                    \
                 if (optr->ex_type == ET_VEC) {                          \
                         op = optr->ex_vec;                              \
-                        scalar = (float)func(leftfuncast left->ex_flt,  \
+                        scalar = (t_float)func(leftfuncast left->ex_flt,  \
                                         rightfuncast right->ex_int);    \
                         j = e->exp_vsize;                               \
                         while (j--)                                     \
                                 *op++ = scalar;                         \
                 } else {                                                \
                         optr->ex_type = ET_FLT;                         \
-                        optr->ex_flt = (float)func(leftfuncast left->ex_flt,  \
+                        optr->ex_flt = (t_float)func(leftfuncast left->ex_flt,  \
                                         rightfuncast right->ex_int);    \
                 }                                                       \
                 break;                                                  \
         case ET_FLT:                                                    \
                 if (optr->ex_type == ET_VEC) {                          \
                         op = optr->ex_vec;                              \
-                        scalar = (float)func(leftfuncast left->ex_flt,  \
+                        scalar = (t_float)func(leftfuncast left->ex_flt,  \
                                         rightfuncast right->ex_flt);    \
                         j = e->exp_vsize;                               \
                         while (j--)                                     \
                                 *op++ = scalar;                         \
                 } else {                                                \
                         optr->ex_type = ET_FLT;                         \
-                        optr->ex_flt = (float)func(leftfuncast left->ex_flt,  \
+                        optr->ex_flt = (t_float)func(leftfuncast left->ex_flt,  \
                                         rightfuncast right->ex_flt);    \
                 }                                                       \
                 break;                                                  \
@@ -326,7 +326,7 @@ case ET_FLT:                                                            \
                 op = optr->ex_vec;                                      \
                 j = e->exp_vsize;                                       \
                 while (j--) {                                           \
-                        *op++ = (float)func(leftfuncast scalar,         \
+                        *op++ = (t_float)func(leftfuncast scalar,         \
                                                 rightfuncast *rp);      \
                         rp++;                                           \
                 }                                                       \
@@ -356,7 +356,7 @@ case ET_VI:                                                             \
                 scalar = right->ex_int;                                 \
                 j = e->exp_vsize;                                       \
                 while (j--) {                                           \
-                        *op++ = (float)func(leftfuncast *lp,            \
+                        *op++ = (t_float)func(leftfuncast *lp,            \
                                                 rightfuncast scalar);   \
                         lp++;                                           \
                 }                                                       \
@@ -365,7 +365,7 @@ case ET_VI:                                                             \
                 scalar = right->ex_flt;                                 \
                 j = e->exp_vsize;                                       \
                 while (j--) {                                           \
-                        *op++ = (float)func(leftfuncast *lp,            \
+                        *op++ = (t_float)func(leftfuncast *lp,            \
                                                 rightfuncast scalar);   \
                         lp++;                                           \
                 }                                                       \
@@ -380,7 +380,7 @@ case ET_VI:                                                             \
                          * 8 times in each round to get a considerable  \
                          * improvement                                  \
                          */                                             \
-                        *op++ = (float)func(leftfuncast *lp,            \
+                        *op++ = (t_float)func(leftfuncast *lp,            \
                                                 rightfuncast *rp);      \
                         rp++; lp++;                                     \
                 }                                                       \
@@ -401,7 +401,7 @@ default:                                                                \
 
 /*
  * FUNC_EVAL_UNARY - evaluate a unary function,
- *              if fltret is set return float
+ *              if fltret is set return t_float
  *              otherwise return value based on regular typechecking,
  */
 #define FUNC_EVAL_UNARY(left, func, leftcast, optr, fltret)             \
@@ -409,12 +409,12 @@ switch(left->ex_type) {                                         \
 case ET_INT:                                                    \
         if (optr->ex_type == ET_VEC) {                          \
                 ex_mkvector(optr->ex_vec,                       \
-                (float)(func (leftcast left->ex_int)), e->exp_vsize);\
+                (t_float)(func (leftcast left->ex_int)), e->exp_vsize);\
                 break;                                          \
         }                                                       \
         if (fltret) {                                           \
                 optr->ex_type = ET_FLT;                         \
-                optr->ex_flt = (float) func(leftcast left->ex_int); \
+                optr->ex_flt = (t_float) func(leftcast left->ex_int); \
                 break;                                          \
         }                                                       \
         optr->ex_type = ET_INT;                                 \
@@ -423,11 +423,11 @@ case ET_INT:                                                    \
 case ET_FLT:                                                    \
         if (optr->ex_type == ET_VEC) {                          \
                 ex_mkvector(optr->ex_vec,                       \
-                (float)(func (leftcast left->ex_flt)), e->exp_vsize);\
+                (t_float)(func (leftcast left->ex_flt)), e->exp_vsize);\
                 break;                                          \
         }                                                       \
         optr->ex_type = ET_FLT;                                 \
-        optr->ex_flt = (float) func(leftcast left->ex_flt);     \
+        optr->ex_flt = (t_float) func(leftcast left->ex_flt);     \
         break;                                                  \
 case ET_VI:                                                     \
 case ET_VEC:                                                    \
@@ -440,7 +440,7 @@ case ET_VEC:                                                    \
         lp = left->ex_vec;                                      \
         j = e->exp_vsize;                                       \
         while (j--)                                             \
-                *op++ = (float)(func (leftcast *lp++));         \
+                *op++ = (t_float)(func (leftcast *lp++));         \
         break;                                                  \
 default:                                                        \
         post_error((fts_object_t *) e,                          \
@@ -458,9 +458,9 @@ static void                                                             \
 ex_func(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)\
 {                                                                       \
         struct ex_ex *left, *right;                                     \
-        float *op; /* output pointer */                                 \
-        float *lp, *rp;         /* left and right vector pointers */    \
-        float scalar;                                                   \
+        t_float *op; /* output pointer */                                 \
+        t_float *lp, *rp;         /* left and right vector pointers */    \
+        t_float scalar;                                                   \
         int j;                                                          \
                                                                         \
         left = argv++;                                                  \
@@ -474,9 +474,9 @@ static void                                                             \
 ex_func(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)\
 {                                                                       \
         struct ex_ex *left;                                             \
-        float *op; /* output pointer */                                 \
-        float *lp, *rp;         /* left and right vector pointers */    \
-        float scalar;                                                   \
+        t_float *op; /* output pointer */                                 \
+        t_float *lp, *rp;         /* left and right vector pointers */    \
+        t_float scalar;                                                   \
         int j;                                                          \
                                                                         \
         left = argv++;                                                  \
@@ -493,9 +493,9 @@ static void
 ex_min(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
 {
         struct ex_ex *left, *right;
-        float *op; /* output pointer */
-        float *lp, *rp;         /* left and right vector pointers */
-        float scalar;
+        t_float *op; /* output pointer */
+        t_float *lp, *rp;         /* left and right vector pointers */
+        t_float scalar;
         int j;
 
         left = argv++;
@@ -513,9 +513,9 @@ static void
 ex_max(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
 {
         struct ex_ex *left, *right;
-        float *op; /* output pointer */
-        float *lp, *rp;         /* left and right vector pointers */
-        float scalar;
+        t_float *op; /* output pointer */
+        t_float *lp, *rp;         /* left and right vector pointers */
+        t_float scalar;
         int j;
 
         left = argv++;
@@ -531,9 +531,9 @@ static void
 ex_toint(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
 {
         struct ex_ex *left;
-        float *op; /* output pointer */
-        float *lp, *rp;         /* left and right vector pointers */
-        float scalar;
+        t_float *op; /* output pointer */
+        t_float *lp, *rp;         /* left and right vector pointers */
+        t_float scalar;
         int j;
 
         left = argv++;
@@ -561,9 +561,9 @@ static void
 ex_rint(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
 {
         struct ex_ex *left;
-        float *op; /* output pointer */
-        float *lp, *rp;         /* left and right vector pointers */
-        float scalar;
+        t_float *op; /* output pointer */
+        t_float *lp, *rp;         /* left and right vector pointers */
+        t_float scalar;
         int j;
 
         left = argv++;
@@ -573,20 +573,20 @@ ex_rint(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
 }
 
 /*
- * ex_tofloat -- convert to float
+ * ex_tofloat -- convert to t_float
  */
 static void
 ex_tofloat(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
 {
         struct ex_ex *left;
-        float *op; /* output pointer */
-        float *lp, *rp;         /* left and right vector pointers */
-        float scalar;
+        t_float *op; /* output pointer */
+        t_float *lp, *rp;         /* left and right vector pointers */
+        t_float scalar;
         int j;
 
         left = argv++;
 
-#define tofloat(x)      ((float)(x))
+#define tofloat(x)      ((t_float)(x))
         FUNC_EVAL_UNARY(left, tofloat, (int), optr, 1);
 }
 
@@ -598,9 +598,9 @@ static void
 ex_pow(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
 {
         struct ex_ex *left, *right;
-        float *op; /* output pointer */
-        float *lp, *rp;         /* left and right vector pointers */
-        float scalar;
+        t_float *op; /* output pointer */
+        t_float *lp, *rp;         /* left and right vector pointers */
+        t_float scalar;
         int j;
 
         left = argv++;
@@ -615,9 +615,9 @@ static void
 ex_sqrt(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
 {
         struct ex_ex *left;
-        float *op; /* output pointer */
-        float *lp, *rp;         /* left and right vector pointers */
-        float scalar;
+        t_float *op; /* output pointer */
+        t_float *lp, *rp;         /* left and right vector pointers */
+        t_float scalar;
         int j;
 
         left = argv++;
@@ -632,9 +632,9 @@ static void
 ex_exp(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
 {
         struct ex_ex *left;
-        float *op; /* output pointer */
-        float *lp, *rp;         /* left and right vector pointers */
-        float scalar;
+        t_float *op; /* output pointer */
+        t_float *lp, *rp;         /* left and right vector pointers */
+        t_float scalar;
         int j;
 
         left = argv++;
@@ -649,9 +649,9 @@ static void
 ex_log(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
 {
         struct ex_ex *left;
-        float *op; /* output pointer */
-        float *lp, *rp;         /* left and right vector pointers */
-        float scalar;
+        t_float *op; /* output pointer */
+        t_float *lp, *rp;         /* left and right vector pointers */
+        t_float scalar;
         int j;
 
         left = argv++;
@@ -666,9 +666,9 @@ static void
 ex_ln(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
 {
         struct ex_ex *left;
-        float *op; /* output pointer */
-        float *lp, *rp;         /* left and right vector pointers */
-        float scalar;
+        t_float *op; /* output pointer */
+        t_float *lp, *rp;         /* left and right vector pointers */
+        t_float scalar;
         int j;
 
         left = argv++;
@@ -680,9 +680,9 @@ static void
 ex_sin(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
 {
         struct ex_ex *left;
-        float *op; /* output pointer */
-        float *lp, *rp;         /* left and right vector pointers */
-        float scalar;
+        t_float *op; /* output pointer */
+        t_float *lp, *rp;         /* left and right vector pointers */
+        t_float scalar;
         int j;
 
         left = argv++;
@@ -694,9 +694,9 @@ static void
 ex_cos(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
 {
         struct ex_ex *left;
-        float *op; /* output pointer */
-        float *lp, *rp;         /* left and right vector pointers */
-        float scalar;
+        t_float *op; /* output pointer */
+        t_float *lp, *rp;         /* left and right vector pointers */
+        t_float scalar;
         int j;
 
         left = argv++;
@@ -709,9 +709,9 @@ static void
 ex_tan(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
 {
         struct ex_ex *left;
-        float *op; /* output pointer */
-        float *lp, *rp;         /* left and right vector pointers */
-        float scalar;
+        t_float *op; /* output pointer */
+        t_float *lp, *rp;         /* left and right vector pointers */
+        t_float scalar;
         int j;
 
         left = argv++;
@@ -723,9 +723,9 @@ static void
 ex_asin(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
 {
         struct ex_ex *left;
-        float *op; /* output pointer */
-        float *lp, *rp;         /* left and right vector pointers */
-        float scalar;
+        t_float *op; /* output pointer */
+        t_float *lp, *rp;         /* left and right vector pointers */
+        t_float scalar;
         int j;
 
         left = argv++;
@@ -737,9 +737,9 @@ static void
 ex_acos(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
 {
         struct ex_ex *left;
-        float *op; /* output pointer */
-        float *lp, *rp;         /* left and right vector pointers */
-        float scalar;
+        t_float *op; /* output pointer */
+        t_float *lp, *rp;         /* left and right vector pointers */
+        t_float scalar;
         int j;
 
         left = argv++;
@@ -752,9 +752,9 @@ static void
 ex_atan(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
 {
         struct ex_ex *left;
-        float *op; /* output pointer */
-        float *lp, *rp;         /* left and right vector pointers */
-        float scalar;
+        t_float *op; /* output pointer */
+        t_float *lp, *rp;         /* left and right vector pointers */
+        t_float scalar;
         int j;
 
         left = argv++;
@@ -769,9 +769,9 @@ static void
 ex_atan2(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
 {
         struct ex_ex *left, *right;
-        float *op; /* output pointer */
-        float *lp, *rp;         /* left and right vector pointers */
-        float scalar;
+        t_float *op; /* output pointer */
+        t_float *lp, *rp;         /* left and right vector pointers */
+        t_float scalar;
         int j;
 
         left = argv++;
@@ -786,9 +786,9 @@ static void
 ex_fmod(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
 {
         struct ex_ex *left, *right;
-        float *op; /* output pointer */
-        float *lp, *rp;         /* left and right vector pointers */
-        float scalar;
+        t_float *op; /* output pointer */
+        t_float *lp, *rp;         /* left and right vector pointers */
+        t_float scalar;
         int j;
 
         left = argv++;
@@ -804,9 +804,9 @@ static void
 ex_floor(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
 {
         struct ex_ex *left;
-        float *op; /* output pointer */
-        float *lp, *rp;         /* left and right vector pointers */
-        float scalar;
+        t_float *op; /* output pointer */
+        t_float *lp, *rp;         /* left and right vector pointers */
+        t_float scalar;
         int j;
 
         left = argv++;
@@ -821,9 +821,9 @@ static void
 ex_ceil(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
 {
         struct ex_ex *left;
-        float *op; /* output pointer */
-        float *lp, *rp;         /* left and right vector pointers */
-        float scalar;
+        t_float *op; /* output pointer */
+        t_float *lp, *rp;         /* left and right vector pointers */
+        t_float scalar;
         int j;
 
         left = argv++;
@@ -834,9 +834,9 @@ static void
 ex_sinh(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
 {
         struct ex_ex *left;
-        float *op; /* output pointer */
-        float *lp, *rp;         /* left and right vector pointers */
-        float scalar;
+        t_float *op; /* output pointer */
+        t_float *lp, *rp;         /* left and right vector pointers */
+        t_float scalar;
         int j;
 
         left = argv++;
@@ -848,9 +848,9 @@ static void
 ex_cosh(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
 {
         struct ex_ex *left;
-        float *op; /* output pointer */
-        float *lp, *rp;         /* left and right vector pointers */
-        float scalar;
+        t_float *op; /* output pointer */
+        t_float *lp, *rp;         /* left and right vector pointers */
+        t_float scalar;
         int j;
 
         left = argv++;
@@ -863,9 +863,9 @@ static void
 ex_tanh(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
 {
         struct ex_ex *left;
-        float *op; /* output pointer */
-        float *lp, *rp;         /* left and right vector pointers */
-        float scalar;
+        t_float *op; /* output pointer */
+        t_float *lp, *rp;         /* left and right vector pointers */
+        t_float scalar;
         int j;
 
         left = argv++;
@@ -879,9 +879,9 @@ static void
 ex_asinh(t_expr *e, long argc, struct ex_ex *argv, struct ex_ex *optr)
 {
         struct ex_ex *left;
-        float *op; /* output pointer */
-        float *lp, *rp;         /* left and right vector pointers */
-        float scalar;
+        t_float *op; /* output pointer */
+        t_float *lp, *rp;         /* left and right vector pointers */
+        t_float scalar;
         int j;
 
         left = argv++;
@@ -893,9 +893,9 @@ static void
 ex_acosh(t_expr *e, long argc, struct ex_ex *argv, struct ex_ex *optr)
 {
         struct ex_ex *left;
-        float *op; /* output pointer */
-        float *lp, *rp;         /* left and right vector pointers */
-        float scalar;
+        t_float *op; /* output pointer */
+        t_float *lp, *rp;         /* left and right vector pointers */
+        t_float scalar;
         int j;
 
         left = argv++;
@@ -907,9 +907,9 @@ static void
 ex_atanh(t_expr *e, long argc, struct ex_ex *argv, struct ex_ex *optr)
 {
         struct ex_ex *left;
-        float *op; /* output pointer */
-        float *lp, *rp;         /* left and right vector pointers */
-        float scalar;
+        t_float *op; /* output pointer */
+        t_float *lp, *rp;         /* left and right vector pointers */
+        t_float scalar;
         int j;
 
         left = argv++;
@@ -939,9 +939,9 @@ static void
 ex_fact(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
 {
         struct ex_ex *left;
-        float *op; /* output pointer */
-        float *lp, *rp;         /* left and right vector pointers */
-        float scalar;
+        t_float *op; /* output pointer */
+        t_float *lp, *rp;         /* left and right vector pointers */
+        t_float scalar;
         int j;
 
         left = argv++;
@@ -961,9 +961,9 @@ static void
 ex_random(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
 {
         struct ex_ex *left, *right;
-        float *op; /* output pointer */
-        float *lp, *rp;         /* left and right vector pointers */
-        float scalar;
+        t_float *op; /* output pointer */
+        t_float *lp, *rp;         /* left and right vector pointers */
+        t_float scalar;
         int j;
 
         left = argv++;
@@ -976,9 +976,9 @@ static void
 ex_abs(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
 {
         struct ex_ex *left;
-        float *op; /* output pointer */
-        float *lp, *rp;         /* left and right vector pointers */
-        float scalar;
+        t_float *op; /* output pointer */
+        t_float *lp, *rp;         /* left and right vector pointers */
+        t_float scalar;
         int j;
 
         left = argv++;
@@ -993,10 +993,10 @@ static void
 ex_if(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
 {
         struct ex_ex *left, *right, *cond, *res;
-        float *op; /* output pointer */
-        float *lp, *rp;         /* left and right vector pointers */
-        float *cp;              /* condition pointer */
-        float leftvalue, rightvalue;
+        t_float *op; /* output pointer */
+        t_float *lp, *rp;         /* left and right vector pointers */
+        t_float *cp;              /* condition pointer */
+        t_float leftvalue, rightvalue;
         int j;
 
         cond = argv++;
@@ -1169,7 +1169,7 @@ ex_if(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
         switch(res->ex_type) {
         case ET_INT:
                 if (optr->ex_type == ET_VEC) {
-                        ex_mkvector(optr->ex_vec, (float)res->ex_int,
+                        ex_mkvector(optr->ex_vec, (t_float)res->ex_int,
                                                                 e->exp_vsize);
                         return;
                 }
@@ -1177,7 +1177,7 @@ ex_if(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
                 return;
         case ET_FLT:
                 if (optr->ex_type == ET_VEC) {
-                        ex_mkvector(optr->ex_vec, (float)res->ex_flt,
+                        ex_mkvector(optr->ex_vec, (t_float)res->ex_flt,
                                                                 e->exp_vsize);
                         return;
                 }
@@ -1273,7 +1273,7 @@ FUNC_DEF_UNARY(ex_isinf, isinf, (double), 0);
 /*
  * ex_finite - is the value finite
  */
-FUNC_DEF_UNARY(ex_finite, finite, (double), 0);
+FUNC_DEF_UNARY(ex_finite, isfinite, (double), 0);
 
 /*
  * ex_isnan -- is the resut a nan (Not a number)
@@ -1288,7 +1288,7 @@ FUNC_DEF(ex_copysign, copysign, (double), (double), 1);
 /*
  * ex_drem - floating-point remainder function
  */
-FUNC_DEF(ex_drem, drem, (double), (double), 1);
+FUNC_DEF(ex_drem, remainder, (double), (double), 1);
 #endif
 
 #ifdef notdef
diff --git a/pd/extra/expr~/vexp_if.c b/pd/extra/expr~/vexp_if.c
index aaaf4ef3c..91f47ba22 100644
--- a/pd/extra/expr~/vexp_if.c
+++ b/pd/extra/expr~/vexp_if.c
@@ -3,7 +3,7 @@
  * Copyright (C) 1994, 1995, 1998, 1999 by IRCAM-Centre Georges Pompidou, Paris, France.
  * 
  * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
+ * modify it under the terms of the GNU Lesser General Public License
  * as published by the Free Software Foundation; either version 2
  * of the License, or (at your option) any later version.
  * 
@@ -12,9 +12,9 @@
  * This program 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
  * 
- * You should have received a copy of the GNU General Public License
+ * You should have received a copy of the GNU Lesser General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  * 
@@ -426,7 +426,7 @@ expr_perform(t_int *w)
         if (x->exp_flags & EF_STOP) {
                 for (i = 0; i < x->exp_nexpr; i++)
                         memset(x->exp_res[i].ex_vec, 0,
-                                        x->exp_vsize * sizeof (float));
+                                        x->exp_vsize * sizeof (t_float));
                 return (w + 2);
         }
 
@@ -726,11 +726,11 @@ fexpr_tilde_clear(t_expr *x, t_symbol *s, int argc, t_atom *argv)
          */
         if (!argc) {
                 for (i = 0; i < x->exp_nexpr; i++)
-                        memset(x->exp_p_res[i], 0, x->exp_vsize*sizeof(float));
+                        memset(x->exp_p_res[i], 0, x->exp_vsize*sizeof(t_float));
                 for (i = 0; i < MAX_VARS; i++)
                         if (x->exp_var[i].ex_type == ET_XI)
                                 memset(x->exp_p_var[i], 0,
-                                                x->exp_vsize*sizeof(float));
+                                                x->exp_vsize*sizeof(t_float));
                 return;
         }
         if (argc > 1) {
@@ -760,7 +760,7 @@ fexpr_tilde_clear(t_expr *x, t_symbol *s, int argc, t_atom *argv)
                         post("fexpr~-clear: no signal at inlet %d", vecno + 1);
                         return;
                 }
-                memset(x->exp_p_var[vecno], 0, x->exp_vsize*sizeof(float));
+                memset(x->exp_p_var[vecno], 0, x->exp_vsize*sizeof(t_float));
                 return;
         case 'y':
                 if (!sx->s_name[1])
@@ -777,7 +777,7 @@ fexpr_tilde_clear(t_expr *x, t_symbol *s, int argc, t_atom *argv)
                         post("fexpr~.clear: only %d outlets", x->exp_nexpr);
                         return;
                 }
-                memset(x->exp_p_res[vecno], 0, x->exp_vsize*sizeof(float));
+                memset(x->exp_p_res[vecno], 0, x->exp_vsize*sizeof(t_float));
                 return;
                 return;
         default:
@@ -997,7 +997,7 @@ ex_sum(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
         t_garray *garray;
         int size;
         t_word *wvec;
-        float sum;
+        t_float sum;
         int indx;
 
         if (argv->ex_type != ET_SYM)
diff --git a/pd/src/g_canvas.c b/pd/src/g_canvas.c
index 72ef3f14f..971985ee5 100644
--- a/pd/src/g_canvas.c
+++ b/pd/src/g_canvas.c
@@ -707,6 +707,16 @@ 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)
+{
+    t_atom at[1];
+    SETFLOAT(&at[0], state);
+    sc_mouseover_canvas = x;
+    if (sendsym->s_thing) typedmess(sendsym->s_thing, gensym("mouseover"),
+        1, at);
+}
+
 extern void canvas_check_nlet_highlights(t_canvas *x);
 
 /*********** dpsaha@vt.edu resize move hooks ****************/
@@ -2203,6 +2213,9 @@ 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);
+
 /* ---------------------- list handling ------------------------ */
     class_addmethod(canvas_class, (t_method)glist_clear, gensym("clear"),
         A_NULL);
diff --git a/pd/src/g_scalar.c b/pd/src/g_scalar.c
index a391881b3..389e5a5ec 100644
--- a/pd/src/g_scalar.c
+++ b/pd/src/g_scalar.c
@@ -111,6 +111,9 @@ t_scalar *scalar_new(t_glist *owner, t_symbol *templatesym)
     x->sc_template = templatesym;
     gpointer_setglist(&gp, owner, x);
     word_init(x->sc_vec, template, &gp);
+    char buf[50];
+    sprintf(buf, ".x%lx", (long unsigned int)x);
+    pd_bind(&x->sc_gobj.g_pd, gensym(buf));
     return (x);
 }
 
@@ -157,29 +160,17 @@ extern int array_joc;
 extern void template_notifyforscalar(t_template *template, t_glist *owner,
     t_scalar *sc, t_symbol *s, int argc, t_atom *argv);
 
-static int sc_isentered = 0;
-static t_scalar *sc_entered = 0;
-
-static void scalar_leave(t_scalar *x, t_glist *owner, t_template *template,
-    int force_leave)
+t_canvas *sc_mouseover_canvas;
+static void scalar_mouseover(t_scalar *x, t_floatarg state)
 {
-    /* hack for enter/leave struct notifications */
-    if (sc_isentered == 1)
-    {
-        /* change value to see if there's a call
-           to scalar_click the next time around. Of
-           course it will be too late so we'll be
-           one pixel off, but it's better than nothing.
-        */
-        sc_isentered = -1;
-    }
-    else if (sc_isentered == -1 || force_leave)
-    {
-        t_atom at[1];
-        template_notifyforscalar(template, owner, x, gensym("leave"), 1, at);
-        sc_entered = 0;
-        sc_isentered = 0;
-    }
+    t_atom at[1];
+    t_template *template = template_findbyname(x->sc_template);
+    if (state)
+        template_notifyforscalar(template, sc_mouseover_canvas,
+            x, gensym("leave"), 1, at);
+    else
+        template_notifyforscalar(template, sc_mouseover_canvas,
+            x, gensym("enter"), 1, at);
 }
 
 static void scalar_getrect(t_gobj *z, t_glist *owner,
@@ -194,9 +185,6 @@ static void scalar_getrect(t_gobj *z, t_glist *owner,
     t_gobj *y;
     t_float basex, basey;
 
-    if (sc_entered == x)
-        scalar_leave(x, owner, template, 0);
-
     // EXPERIMENTAL: we assume that entire canvas is withing the rectangle--this is for arrays
     // with "jump on click" enabled TODO: test for other regressions (there shouuld not be any
     // provided the global variable array_joc is properly maintained)
@@ -260,10 +248,18 @@ void scalar_drawselectrect(t_scalar *x, t_glist *glist, int state)
        
         scalar_getrect(&x->sc_gobj, glist, &x1, &y1, &x2, &y2);
         x1--; x2++; y1--; y2++;
+                /* we're not giving the rectangle the "select" tag
+                   because we have to manually displace the scalar
+                   in scalar_displace_withtag. The reason for that
+                   is the "displace" message may trigger a redraw
+                   of the bbox at the new position, and Pd-l2ork's
+                   general "move selected" subcommand will end up
+                   offsetting such a rect by dx dy.
+                */
 		if (glist_istoplevel(glist))
-		    sys_vgui(".x%lx.c create polyline %d %d %d %d %d %d %d %d %d %d \
-		        -strokewidth 1 -stroke $pd_colors(selection) -tags {select%lx selected}\n",
-		            glist_getcanvas(glist), x1, y1, x1, y2, x2, y2, x2, y1, x1, y1,
+		    sys_vgui(".x%lx.c create prect %d %d %d %d \
+		        -strokewidth 1 -stroke $pd_colors(selection) -tags {select%lx}\n",
+		            glist_getcanvas(glist), x1, y1, x2, y2,
 		            x);
     }
     else
@@ -383,11 +379,19 @@ static void scalar_displace(t_gobj *z, t_glist *glist, int dx, int dy)
     if ((goty && (ytype != DT_FLOAT)) || select_owner != glist)
         goty = 0;
     if (gotx)
+    {
         *(t_float *)(((char *)(x->sc_vec)) + xonset) +=
             dx * (glist_pixelstox(glist, 1) - glist_pixelstox(glist, 0));
+        x->sc_x1 += dx;
+        x->sc_x2 += dx;
+    }
     if (goty)
+    {
         *(t_float *)(((char *)(x->sc_vec)) + yonset) +=
             dy * (glist_pixelstoy(glist, 1) - glist_pixelstoy(glist, 0));
+        x->sc_y1 += dy;
+        x->sc_y2 += dy;
+    }
     gpointer_init(&gp);
     gpointer_setglist(&gp, glist, x);
     SETPOINTER(&at[0], &gp);
@@ -414,6 +418,7 @@ static void scalar_displace_withtag(t_gobj *z, t_glist *glist, int dx, int dy)
     t_atom at[3];
     t_gpointer gp;
     int xonset, yonset, xtype, ytype, gotx, goty;
+    int bx1, bx2, by1, by2;
     t_float basex = 0, basey = 0;
     if (!template)
     {
@@ -448,6 +453,16 @@ static void scalar_displace_withtag(t_gobj *z, t_glist *glist, int dx, int dy)
     SETFLOAT(&at[2], (t_float)dy);
     template_notify(template, gensym("displace"), 2, at);
 
+    /* this is a hack to make sure the bbox gets drawn in
+       the right location.  If the scalar is selected
+       then it's possible that a "displace" message
+       from the [struct] will trigger a redraw of the
+       bbox. So we don't update the cached bbox until
+       after that redraw, so we can move the bbox below.
+    */
+    sys_vgui(".x%lx.c coords {select%lx} %d %d %d %d\n", glist, x,
+        x->sc_x1 - 1, x->sc_y1 - 1, x->sc_x2 + 1, x->sc_y2 + 1);
+
     t_float xscale = glist_xtopixels(glist, 1) - glist_xtopixels(glist, 0);
     t_float yscale = glist_ytopixels(glist, 1) - glist_ytopixels(glist, 0);
 
@@ -528,6 +543,9 @@ static void scalar_vis(t_gobj *z, t_glist *owner, int vis)
             );
         sys_vgui(".x%lx.c create group -tags {.dgroup%lx} -parent {.scalar%lx}\n",
             glist_getcanvas(owner), x->sc_vec, x->sc_vec);
+        sys_vgui("pdtk_bind_scalar_mouseover "
+                 ".x%lx.c .x%lx.x%lx.template%lx {.x%lx}\n",
+            glist_getcanvas(owner), glist_getcanvas(owner), owner, x->sc_vec, x);
     }
 
     for (y = templatecanvas->gl_list; y; y = y->g_next)
@@ -614,28 +632,11 @@ static int scalar_click(t_gobj *z, struct _glist *owner,
 {
 	//fprintf(stderr,"scalar_click %d %d\n", xpix, ypix);
     t_scalar *x = (t_scalar *)z;
-    t_template *template = template_findbyname(x->sc_template);
 
-    /* hack for enter/leave notifications. The second part
-       of the conditional is to catch edge cases where the
-       pointer enters a scalar in one window then moves to
-       an overlapping window before leaving the first one.
+    x->sc_bboxcache = 0;
+
+    t_template *template = template_findbyname(x->sc_template);
 
-       There is an edge case with this hack-- if the mouse
-       is inside a scalar in one window and then moves to
-    */
-    if (sc_isentered == 0 ||
-        (sc_entered && sc_entered != x))
-    {
-        t_atom at[1];
-        if (sc_entered && sc_entered !=x)
-            scalar_leave(sc_entered, owner, template, 1);
-        template_notifyforscalar(template, owner, x, gensym("enter"), 1, at);
-        sc_isentered = 1;
-        sc_entered = x;
-    }
-    else sc_isentered = 1;
-    
     return (scalar_doclick(x->sc_vec, template, x, 0,
         owner, 0, 0, xpix, ypix, shift, alt, dbl, doit));
 }
@@ -700,6 +701,9 @@ static void scalar_free(t_scalar *x)
         return;
     }
     word_free(x->sc_vec, template);
+    char buf[50];
+    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
         us automatically (see pd_free()) */
@@ -712,6 +716,8 @@ void g_scalar_setup(void)
 {
     scalar_class = class_new(gensym("scalar"), 0, (t_method)scalar_free, 0,
         CLASS_GOBJ, 0);
+    class_addmethod(scalar_class, (t_method)scalar_mouseover,
+        gensym("mouseover"), A_FLOAT, A_NULL);
     class_setwidget(scalar_class, &scalar_widgetbehavior);
     class_setsavefn(scalar_class, scalar_save);
     class_setpropertiesfn(scalar_class, scalar_properties);
diff --git a/pd/src/g_template.c b/pd/src/g_template.c
index cb5388b9f..35c52cdc5 100644
--- a/pd/src/g_template.c
+++ b/pd/src/g_template.c
@@ -1215,10 +1215,10 @@ static char *rgb_to_hex(int r, int g, int b)
 
 char *get_strokelinecap(int a)
 {
-    static char strokelinecap[8];
+    static char strokelinecap[15];
     if (a == 0) sprintf(strokelinecap, "butt");
     else if (a == 1) sprintf(strokelinecap, "round");
-    else if (a == 2) sprintf(strokelinecap, "square");
+    else if (a == 2) sprintf(strokelinecap, "projecting");
     else sprintf(strokelinecap, "butt");
     return (strokelinecap);
 }
@@ -2157,8 +2157,10 @@ static void draw_getpathrect(t_draw *x, t_glist *glist,
         path2_vec[1] = yy;
     }
     
-    /* loop through and get absolute values. I don't handle
-       transformations yet */
+    /* loop through and get absolute values. This is more
+       complicated than it needs to be. If there were explicit
+       single-letter cmds for each subset of path data then I
+       could just use the default below for C, S, Q, T, and L. */
     int i = 0;
     for(i = start; i < x->x_npathcmds; i++)
     {
@@ -2172,19 +2174,28 @@ static void draw_getpathrect(t_draw *x, t_glist *glist,
         switch (cmd)
         {
         case 'A':
-            *ia = fielddesc_getcoord(fd, template, data, 1);
-            *(ia+1) = fielddesc_getcoord(fd+1, template, data, 1);
-            *(ia+2) = fielddesc_getfloat(fd+2, template, data, 1);
-            *(ia+3) = fielddesc_getfloat(fd+3, template, data, 1);
-            *(ia+4) = fielddesc_getfloat(fd+4, template, data, 1);
-            *(ia+5) = fielddesc_getcoord(fd+5, template, data, 1) + (rel? xx : 0);
-            *(ia+6) = fielddesc_getcoord(fd+6, template, data, 1) + (rel? yy : 0);
+            for (j = 0; j < x->x_nargs_per_cmd[i]; j += 7)
+            {
+                *ia = fielddesc_getcoord(fd, template, data, 1);
+                *(ia+1) = fielddesc_getcoord(fd+1, template, data, 1);
+                *(ia+2) = fielddesc_getfloat(fd+2, template, data, 1);
+                *(ia+3) = fielddesc_getfloat(fd+3, template, data, 1);
+                *(ia+4) = fielddesc_getfloat(fd+4, template, data, 1);
+                xx = *(ia+5) = fielddesc_getcoord(fd+5, template, data, 1)
+                    + (rel? xx : 0);
+                yy = *(ia+6) = fielddesc_getcoord(fd+6, template, data, 1)
+                    + (rel? yy : 0);
+            }
             break;
         case 'V':
-            *ia = fielddesc_getcoord(fd, template, data, 1) + (rel? yy : 0);
+            for (j = 0; j < x->x_nargs_per_cmd[i]; j++)
+                yy = *ia = fielddesc_getcoord(fd, template, data, 1)
+                    + (rel? yy : 0);
             break;
         case 'H':
-            *ia = fielddesc_getcoord(fd, template, data, 1) + (rel? xx : 0);
+            for (j = 0; j < x->x_nargs_per_cmd[i]; j++)
+                xx = *ia = fielddesc_getcoord(fd, template, data, 1)
+                    + (rel? xx : 0);
             break;
         case 'L':
             for (j = 0; j < x->x_nargs_per_cmd[i]; j++)
@@ -2197,19 +2208,64 @@ static void draw_getpathrect(t_draw *x, t_glist *glist,
                         + (rel? yy : 0);
             }      
             break;
+        case 'C':
+            for (j = 0; j < x->x_nargs_per_cmd[i]; j++)
+            {
+                if (j%6 == 4)
+                    xx = *(ia+j) = fielddesc_getcoord(fd+j, template, data, 1)
+                        + (rel? xx : 0);
+                else if (j%6 == 5)
+                    yy = *(ia+j) = fielddesc_getcoord(fd+j, template, data, 1)
+                        + (rel? yy : 0);
+                else if (j%2 == 0)
+                    *(ia+j) = fielddesc_getcoord(fd+j, template, data, 1)
+                        + (rel? xx : 0);
+                else
+                    *(ia+j) = fielddesc_getcoord(fd+j, template, data, 1)
+                        + (rel? yy : 0);
+            }
+            break;
+        case 'Q':
+        case 'S':
+            for (j = 0; j < x->x_nargs_per_cmd[i]; j++)
+            {
+                if (j%4 == 2)
+                    xx = *(ia+j) = fielddesc_getcoord(fd+j, template, data, 1)
+                        + (rel? xx : 0);
+                else if (j%4 == 3)
+                    yy = *(ia+j) = fielddesc_getcoord(fd+j, template, data, 1)
+                        + (rel? yy : 0);
+                else if (j%2 == 0)
+                    *(ia+j) = fielddesc_getcoord(fd+j, template, data, 1)
+                        + (rel? xx : 0);
+                else
+                    *(ia+j) = fielddesc_getcoord(fd+j, template, data, 1)
+                        + (rel? yy : 0);
+            }
+            break;
         case 'M':
             mx = fielddesc_getcoord(fd, template, data, 1) + (rel? xx : 0);
             my = fielddesc_getcoord(fd+1, template, data, 1) + (rel? yy : 0);
+            for (j = 0; j < x->x_nargs_per_cmd[i]; j++)
+            {
+                if (j%2 == 0)
+                    xx = *(ia+j) = fielddesc_getcoord(fd+j, template, data, 1)
+                        + (rel? xx : 0);
+                else
+                    yy = *(ia+j) = fielddesc_getcoord(fd+j, template, data, 1)
+                        + (rel? yy : 0);
+            }
+            break;
         default:
             for (j = 0; j < x->x_nargs_per_cmd[i]; j++)
             {
                 if (j%2 == 0)
                 {
-                    *(ia+j) = fielddesc_getcoord(fd+j, template, data, 1) + (rel? xx : 0);
+                    xx = *(ia+j) = fielddesc_getcoord(fd+j, template, data, 1) + (rel? xx : 0);
                 }
                 else
                 {
-                   *(ia+j) = fielddesc_getcoord(fd+j, template, data, 1) + (rel? yy : 0);
+                   yy = *(ia+j) = fielddesc_getcoord(fd+j, template, data, 1) + (rel? yy : 0);
                 }
             }
             break;
@@ -2543,7 +2599,7 @@ static void draw_getrect(t_gobj *z, t_glist *glist,
     if (x->x_drawtype == gensym("path"))
     {
         /* this could get damned expensive with complex paths 
-        so a caching mechanism would be nice */
+        which is why there's a caching mechanism */
         draw_getpathrect(x, glist, data, template, basex, basey,
             &x1, &y1, &x2, &y2);
     }
@@ -4077,6 +4133,8 @@ static void plot_vis(t_gobj *z, t_glist *glist, t_scalar *sc,
             numbertocolor(dscolor, outline);
             symoutline = gensym(outline);
         }
+        if (symoutline == &s_) symoutline = gensym("#000000");
+        if (symfill == &s_) symfill = gensym("#000000");
         if (style == PLOTSTYLE_POINTS || style == PLOTSTYLE_BARS)
         {
             symfill = style == PLOTSTYLE_POINTS ? symoutline : symfill;
diff --git a/pd/src/pd.tk b/pd/src/pd.tk
index e7e90b23e..7ebbe165c 100644
--- a/pd/src/pd.tk
+++ b/pd/src/pd.tk
@@ -9321,3 +9321,29 @@ proc pdtk_alsa_midi_dialog {id indev1 indev2 indev3 indev4 \
         $id $indev1 $indev2 $indev3 $indev4 \
         $outdev1 $outdev2 $outdev3 $outdev4 $longform $alsa
 }
+
+set ::sc_entered ""
+
+proc scalar_mouseover_after {canvas sendsym state} {
+    pd [concat $canvas scalar_mouseover $sendsym $state \;]
+    set ::sc_entered {}
+}
+
+proc scalar_mouseover {scalar canvas sendsym state} {
+    if {$state == 0} {
+        after cancel "scalar_mouseover_after $canvas $sendsym 1"
+        if {$scalar ne $::sc_entered} {
+            pd [concat $canvas scalar_mouseover $sendsym 0 \;]
+        }
+        set ::sc_entered $scalar
+    } else {
+        after 0 "scalar_mouseover_after $canvas $sendsym 1"
+    }
+}
+
+proc pdtk_bind_scalar_mouseover {canvas scalar sendsym} {
+    $canvas bind $scalar <Enter> \
+        "scalar_mouseover $scalar [canvastosym $canvas] $sendsym 0"
+    $canvas bind $scalar <Leave> \
+        "scalar_mouseover $scalar [canvastosym $canvas] $sendsym 1"
+}
-- 
GitLab