From d6419fd9eef1de960b2f56187c8130b08b1a5296 Mon Sep 17 00:00:00 2001
From: Jonathan Wilkes <jon.w.wilkes@gmail.com>
Date: Fri, 3 Jun 2016 21:50:14 -0400
Subject: [PATCH] port c6771297b6f03887034c5f121d3dbf701623ab87 from Pd-l2ork:
 the big Vanilla forward port won't compile without this commit

---
 pd/doc/5.reference/array-object-help.txt | 100 ------------
 pd/doc/5.reference/scalar-object-help.pd |  60 +++++++
 pd/src/g_array.c                         |  37 ++++-
 pd/src/g_canvas.h                        |   5 +
 pd/src/g_editor.c                        |  13 +-
 pd/src/g_graph.c                         |   4 +-
 pd/src/g_readwrite.c                     |   9 +-
 pd/src/g_scalar.c                        |   4 +-
 pd/src/m_conf.c                          |   2 +
 pd/src/makefile.in                       |   2 +-
 pd/src/makefile.mingw                    |   2 +-
 pd/src/makefile.nt                       |   2 +-
 pd/src/x_array.c                         |  15 +-
 pd/src/x_scalar.c                        | 191 +++++++++++++++++++++++
 pd/src/x_vexp.h                          |  18 +--
 15 files changed, 338 insertions(+), 126 deletions(-)
 delete mode 100644 pd/doc/5.reference/array-object-help.txt
 create mode 100644 pd/doc/5.reference/scalar-object-help.pd
 create mode 100644 pd/src/x_scalar.c

diff --git a/pd/doc/5.reference/array-object-help.txt b/pd/doc/5.reference/array-object-help.txt
deleted file mode 100644
index f7fe2464d..000000000
--- a/pd/doc/5.reference/array-object-help.txt
+++ /dev/null
@@ -1,100 +0,0 @@
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0.00666678
-0.060001
-0.173336
-0.540009
--0.0266671
--0.20667
--0.406674
--0.713345
--0.833347
--0.933349
--1.04668
--0.980017
--0.800014
--0.686678
--0.526676
--0.443341
--0.360006
--0.20667
--0.140002
--0.0733346
--0.00666678
-0.060001
-0.173336
-0.313339
-0.400007
-0.433341
-0.39334
-0.293338
-0.18667
-0.0800014
-0.0400007
-0.060001
-0.0733346
-0.0933349
-0.113335
-0.126669
-0.100002
-0.0666678
-0.0400007
-0.0200003
-0.0200003
--0.0400007
--0.0266671
--0.00666678
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
diff --git a/pd/doc/5.reference/scalar-object-help.pd b/pd/doc/5.reference/scalar-object-help.pd
new file mode 100644
index 000000000..cf468baa4
--- /dev/null
+++ b/pd/doc/5.reference/scalar-object-help.pd
@@ -0,0 +1,60 @@
+#N canvas 558 349 688 433 12;
+#X text 34 388 see also:;
+#X text 485 171 (click for details:), f 11;
+#N canvas 930 175 716 699 define 0;
+#X text 324 399 creation arguments:;
+#X text 217 152 send a pointer to a named receive object;
+#X floatatom 145 299 5 0 0 0 - - -, f 5;
+#X text 46 408 click to open or edit array:;
+#X msg 31 116 read scalar-object-help.txt;
+#X text 258 117 read/write a file TBW;
+#X obj 145 251 r scalar-help-send;
+#X text 359 457 template;
+#X text 360 478 optional name (TBW);
+#X obj 145 275 get scalar-help-template1 x;
+#N canvas 464 264 450 300 scalar-help-template1 0;
+#X obj 62 55 struct scalar-help-template1 float x float y;
+#X obj 55 99 drawpolygon 3 3 0 0 0 30 30 30 30 0 0 0;
+#X msg 89 193 traverse pd-scalar-help-template1 \, bang;
+#X obj 89 218 pointer;
+#X msg 20 195 40 40;
+#X obj 53 252 append scalar-help-template1 x y;
+#X connect 2 0 3 0;
+#X connect 3 0 5 2;
+#X connect 4 0 5 0;
+#X restore 471 57 pd scalar-help-template1;
+#X floatatom 404 244 3 0 500 0 - - -, f 3;
+#X obj 506 244 r scalar-help-send;
+#X obj 405 282 set scalar-help-template1 x y;
+#X floatatom 458 244 3 0 500 0 - - -, f 3;
+#X text 32 20 "scalar define" defines and maintains a scalar.;
+#X text 471 29 here's the template:;
+#X obj 145 324 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X msg 40 152 send scalar-help-send;
+#X obj 27 435 scalar define -k scalar-help-template1;
+#A set scalar-help-template1 175 150 \;;
+#X text 360 435 optional -k flag to keep contents;
+#X connect 2 0 17 0;
+#X connect 4 0 19 0;
+#X connect 6 0 9 0;
+#X connect 9 0 2 0;
+#X connect 11 0 13 0;
+#X connect 12 0 13 2;
+#X connect 14 0 13 1;
+#X connect 18 0 19 0;
+#X restore 486 212 pd define;
+#X obj 163 388 text;
+#X text 201 210 - create \, store \, and/or edit one;
+#X text 96 260 (later);
+#X obj 19 8 scalar;
+#X text 77 7 - create a scalar datum;
+#X obj 90 212 scalar define;
+#X text 194 261 - more stuff;
+#X text 81 180 The first argument sets the function:;
+#X obj 114 387 array;
+#X obj 204 388 list;
+#X text 101 57 experimental - doesn't do much yet. This is included
+in 0.45 to check that its design will work coherently with the array
+and text objects.;
+#X text 444 398 updated for Pd version 0.45;
diff --git a/pd/src/g_array.c b/pd/src/g_array.c
index a3e2d41b3..aa1b0e0b9 100644
--- a/pd/src/g_array.c
+++ b/pd/src/g_array.c
@@ -424,6 +424,7 @@ t_garray *graph_array(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
     t_symbol *fill;
     t_symbol *outline;
     int fflags;
+    t_symbol *asym = gensym("#A");
 
     if (argc < 3) {pd_error(gl, "garray: not enough args"); return 0;}
     t_symbol *name = atom_getsymbolarg(0, argc--, argv++);
@@ -503,9 +504,19 @@ t_garray *graph_array(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
         fill, 1);
     template_setsymbol(template, gensym("outlinecolor"), x->x_scalar->sc_vec,
         outline, 1);
-    if (x2 = pd_findbyclass(gensym("#A"), garray_class))
+
+           /* bashily unbind #A -- this would create garbage if #A were
+           multiply bound but we believe in this context it's at most
+           bound to whichever textobj or array was created most recently */
+    asym->s_thing = 0;
+        /* and now bind #A to us to receive following messages in the
+        saved file or copy buffer */
+    pd_bind(&x->x_gobj.g_pd, asym);
+
+    /*if (x2 = pd_findbyclass(gensym("#A"), garray_class))
         pd_unbind(x2, gensym("#A"));
-    pd_bind(&x->x_gobj.g_pd, gensym("#A"));
+    pd_bind(&x->x_gobj.g_pd, gensym("#A"));*/
+
     garray_redraw(x);
 
 /* todo: need to test to see if this is necessary
@@ -1415,6 +1426,28 @@ static int garray_click(t_gobj *z, t_glist *glist,
 
 #define ARRAYWRITECHUNKSIZE 1000
 
+void garray_savecontentsto(t_garray *x, t_binbuf *b)
+{
+    if (x->x_saveit)
+    {
+        t_array *array = garray_getarray(x);
+        int n = array->a_n, n2 = 0;
+        if (n > 200000)
+            post("warning: I'm saving an array with %d points!\n", n);
+        while (n2 < n)
+        {
+            int chunk = n - n2, i;
+            if (chunk > ARRAYWRITECHUNKSIZE)
+                chunk = ARRAYWRITECHUNKSIZE;
+            binbuf_addv(b, "si", gensym("#A"), n2);
+            for (i = 0; i < chunk; i++)
+                binbuf_addv(b, "f", ((t_word *)(array->a_vec))[n2+i].w_float);
+            binbuf_addv(b, ";");
+            n2 += chunk;
+        }
+    }
+}
+
 void garray_save(t_gobj *z, t_binbuf *b)
 {
     int filestyle;
diff --git a/pd/src/g_canvas.h b/pd/src/g_canvas.h
index 7af9a17a3..c58ba42eb 100644
--- a/pd/src/g_canvas.h
+++ b/pd/src/g_canvas.h
@@ -656,6 +656,11 @@ EXTERN t_scalar *scalar_new(t_glist *owner,
 EXTERN void word_free(t_word *wp, t_template *tmpl);
 EXTERN void scalar_getbasexy(t_scalar *x, t_float *basex, t_float *basey);
 EXTERN void scalar_redraw(t_scalar *x, t_glist *glist);
+EXTERN void canvas_writescalar(t_symbol *templatesym, t_word *w, t_binbuf *b,
+    int amarrayelement);
+EXTERN int canvas_readscalar(t_glist *x, int natoms, t_atom *vec,
+    int *p_nextmsg, int selectit);
+
 EXTERN int template_has_elemtemplate(t_template *t, t_template *tmp);
 
 /* ------helper routines for "garrays" and "plots" -------------- */
diff --git a/pd/src/g_editor.c b/pd/src/g_editor.c
index 6dd10f996..48f88b2af 100644
--- a/pd/src/g_editor.c
+++ b/pd/src/g_editor.c
@@ -46,7 +46,7 @@ static void canvas_reselect(t_canvas *x);
 static void canvas_cut(t_canvas *x);
 static int paste_xyoffset = 0; /* a counter of pastes to make x,y offsets */
 //static void canvas_mouseup_gop(t_canvas *x, t_gobj *g);
-static void canvas_done_popup(t_canvas *x, t_float which, t_float xpos,
+void canvas_done_popup(t_canvas *x, t_float which, t_float xpos,
     t_float ypos);
 static void canvas_doarrange(t_canvas *x, t_float which, t_gobj *oldy,
     t_gobj *oldy_prev, t_gobj *oldy_next);
@@ -2254,6 +2254,7 @@ t_gobj *canvas_findhitbox(t_canvas *x, int xpos, int ypos,
     return (rval);
 }
 
+extern t_class *array_define_class;
 extern int scalar_getcanvasfield(t_scalar *x);
 
     /* right-clicking on a canvas object pops up a menu. */
@@ -2306,6 +2307,14 @@ static void canvas_rightclick(t_canvas *x, int xpos, int ypos, t_gobj *y_sel)
         isobject = 1;
     }
     else isobject = 0;
+    if (x->gl_owner && ((t_gobj *)x)->g_pd == array_define_class)
+    {
+        //fprintf(stderr,"owner=%s\n", ((t_gobj *)x)->g_pd->c_name->s_name);
+        // special case: we are inside an array define and should not have
+        // access to any options, so we disable them all
+        // LATER: consider enabling help and perhaps even limited properties...
+        return;
+    }
     gui_vmess("gui_canvas_popup", "xiiiii",
         x,
         xpos,
@@ -2927,7 +2936,7 @@ static void canvas_doarrange(t_canvas *x, t_float which, t_gobj *oldy,
         "open," or "help." */
     /* Ivica Ico Bukvic <ico@bukvic.net> 2010-11-17
        also added "To Front" and "To Back" */
-static void canvas_done_popup(t_canvas *x, t_float which, t_float xpos,
+void canvas_done_popup(t_canvas *x, t_float which, t_float xpos,
     t_float ypos)
 {
     //fprintf(stderr,"x->gl_edit=%d\n", x->gl_edit);
diff --git a/pd/src/g_graph.c b/pd/src/g_graph.c
index 82abc96b4..eee928cd5 100644
--- a/pd/src/g_graph.c
+++ b/pd/src/g_graph.c
@@ -1078,7 +1078,7 @@ static void graph_vis(t_gobj *gr, t_glist *parent_glist, int vis)
                 (int)glist_ytopixels(x, x->gl_xlabely),
                 x->gl_xlabel[i]->s_name,
                 sys_font, 
-                glist_getfont(x),
+                sys_hostfontsize(glist_getfont(x)),
                 sys_fontweight,
                 x1,
                 y1);
@@ -1094,7 +1094,7 @@ static void graph_vis(t_gobj *gr, t_glist *parent_glist, int vis)
                 (int)glist_ytopixels(x, atof(x->gl_ylabel[i]->s_name)),
                 x->gl_ylabel[i]->s_name,
                 sys_font, 
-                glist_getfont(x),
+                sys_hostfontsize(glist_getfont(x)),
                 sys_fontweight,
                 x1,
                 y1);
diff --git a/pd/src/g_readwrite.c b/pd/src/g_readwrite.c
index 9eb213610..dd2f5ef7e 100644
--- a/pd/src/g_readwrite.c
+++ b/pd/src/g_readwrite.c
@@ -37,8 +37,9 @@ static int canvas_scanbinbuf(int natoms, t_atom *vec, int *p_indexout,
     return (i - indexwas);
 }
 
-int glist_readscalar(t_glist *x, int natoms, t_atom *vec,
-    int *p_nextmsg, int selectit);
+int canvas_readscalar(t_glist *x, int natoms, t_atom *vec,
+     int *p_nextmsg, int selectit);
+
 
 static void canvas_readerror(int natoms, t_atom *vec, int message, 
     int nline, char *s)
@@ -116,7 +117,7 @@ static void glist_readatoms(t_glist *x, int natoms, t_atom *vec,
 
 void scalar_doloadbang(t_scalar *x);
 
-int glist_readscalar(t_glist *x, int natoms, t_atom *vec,
+int canvas_readscalar(t_glist *x, int natoms, t_atom *vec,
     int *p_nextmsg, int selectit)
 {
     int message, nline;
@@ -249,7 +250,7 @@ void glist_readfrombinbuf(t_glist *x, t_binbuf *b, char *filename, int selectem)
     }
     while (nextmsg < natoms)
     {
-        glist_readscalar(x, natoms, vec, &nextmsg, selectem);
+        canvas_readscalar(x, natoms, vec, &nextmsg, selectem);
     }
 }
 
diff --git a/pd/src/g_scalar.c b/pd/src/g_scalar.c
index 3f1ace699..1cc3bff76 100644
--- a/pd/src/g_scalar.c
+++ b/pd/src/g_scalar.c
@@ -339,7 +339,7 @@ t_scalar *scalar_new(t_glist *owner, t_symbol *templatesym)
     /* Pd method to create a new scalar, add it to a glist, and initialize
     it from the message arguments. */
 
-int glist_readscalar(t_glist *x, int natoms, t_atom *vec,
+int canvas_readscalar(t_glist *x, int natoms, t_atom *vec,
     int *p_nextmsg, int selectit);
 
 void glist_scalar(t_glist *glist,
@@ -362,7 +362,7 @@ void glist_scalar(t_glist *glist,
     natoms = binbuf_getnatom(b);
     vec = binbuf_getvec(b);
     
-    glist_readscalar(glist, natoms, vec, &nextmsg, 0);
+    canvas_readscalar(glist, natoms, vec, &nextmsg, 0);
     binbuf_free(b);
 }
 
diff --git a/pd/src/m_conf.c b/pd/src/m_conf.c
index 607a69713..a7c7d3e22 100644
--- a/pd/src/m_conf.c
+++ b/pd/src/m_conf.c
@@ -39,6 +39,7 @@ void x_net_setup(void);
 void x_qlist_setup(void);
 void x_gui_setup(void);
 void x_list_setup(void);
+void x_scalar_setup(void);
 void expr_setup(void);
 void x_preset_setup(void);
 void d_arithmetic_setup(void);
@@ -91,6 +92,7 @@ void conf_init(void)
     x_qlist_setup();
     x_gui_setup();
     x_list_setup();
+    x_scalar_setup();
     expr_setup();
     x_preset_setup();
     d_arithmetic_setup();
diff --git a/pd/src/makefile.in b/pd/src/makefile.in
index 8cab7c70d..40e32b18e 100644
--- a/pd/src/makefile.in
+++ b/pd/src/makefile.in
@@ -75,7 +75,7 @@ OPT_SAFE_SRC = g_canvas.c g_graph.c g_text.c g_rtext.c g_array.c g_template.c g_
     d_resample.c \
     x_arithmetic.c x_connective.c x_interface.c x_midi.c x_misc.c \
     x_time.c x_acoustics.c x_net.c x_text.c x_gui.c x_list.c x_array.c x_preset.c\
-	x_vexp.c x_vexp_if.c x_vexp_fun.c import.c \
+	x_scalar.c x_vexp.c x_vexp_if.c x_vexp_fun.c import.c \
     $(SYSSRC)
 
 SRC = $(TYPE_PUNNING_SRC) $(OPT_SAFE_SRC)
diff --git a/pd/src/makefile.mingw b/pd/src/makefile.mingw
index 7b3131f0b..3f3d323ee 100755
--- a/pd/src/makefile.mingw
+++ b/pd/src/makefile.mingw
@@ -121,7 +121,7 @@ SRC = g_canvas.c g_graph.c g_text.c g_rtext.c g_array.c g_template.c g_io.c \
     d_delay.c d_resample.c x_arithmetic.c x_connective.c x_interface.c \
     x_midi.c x_misc.c x_time.c x_acoustics.c x_net.c x_text.c x_gui.c \
     x_list.c x_array.c d_soundfile.c g_vslider.c g_vdial.c import.c \
-    x_vexp.c x_vexp_if.c x_vexp_fun.c \
+    x_scalar.c x_vexp.c x_vexp_if.c x_vexp_fun.c \
     g_undo.c s_utf8.c
 
 SRSRC = u_pdsend.c u_pdreceive.c
diff --git a/pd/src/makefile.nt b/pd/src/makefile.nt
index ec514b792..e3af34af6 100644
--- a/pd/src/makefile.nt
+++ b/pd/src/makefile.nt
@@ -39,7 +39,7 @@ SRC = g_canvas.c g_graph.c g_text.c g_rtext.c g_array.c g_template.c g_io.c \
     d_delay.c d_resample.c \
     x_arithmetic.c x_connective.c x_interface.c x_midi.c x_misc.c \
     x_time.c x_acoustics.c x_net.c x_text.c x_gui.c x_list.c x_array.c d_soundfile.c \
-    x_vexp.c x_vexp_if.c x_vexp_fun.c $(SYSSRC)
+    x_scalar.c x_vexp.c x_vexp_if.c x_vexp_fun.c $(SYSSRC)
 
 PADIR = ..\portaudio
 INCPA = -I$(PADIR)\include -I$(PADIR)\src\common -I..\lib\asio
diff --git a/pd/src/x_array.c b/pd/src/x_array.c
index 954cd3d96..27c6d1b02 100644
--- a/pd/src/x_array.c
+++ b/pd/src/x_array.c
@@ -188,7 +188,7 @@ static void *array_define_new(t_symbol *s, int argc, t_atom *argv)
     return (x);
 }
 
-void garray_save(t_garray *x, t_binbuf *b);
+void garray_savecontentsto(t_garray *x, t_binbuf *b);
 
 void array_define_save(t_gobj *z, t_binbuf *bb)
 {
@@ -201,7 +201,7 @@ void array_define_save(t_gobj *z, t_binbuf *bb)
 
     if (gl)
     {
-        garray_save((t_gobj *)gl->gl_list, bb);
+        garray_savecontentsto((t_garray *)gl->gl_list, bb);
         obj_saveformat(&x->gl_obj, bb);
     }
     else
@@ -854,6 +854,8 @@ static void *arrayobj_new(t_symbol *s, int argc, t_atom *argv)
 }
 
 void canvas_add_for_class(t_class *c);
+extern void canvas_done_popup(t_canvas *x, t_float which, t_float xpos,
+    t_float ypos);
 
 /* ---------------- global setup function -------------------- */
 
@@ -871,6 +873,15 @@ void x_array_setup(void )
     class_addmethod(array_define_class, (t_method)array_define_ignore,
         gensym("editmode"), A_GIMME, 0);
 
+    // dummy calls to make it work with Jonathan's additions to the array
+    class_addmethod(array_define_class, (t_method)array_define_ignore,
+        gensym("relocate"), A_GIMME, 0);
+    class_addmethod(array_define_class, (t_method)array_define_ignore,
+        gensym("scalar_mouseover"), A_GIMME, 0);
+    // removes complaint that array define has no done-popup call
+    class_addmethod(array_define_class, (t_method)array_define_ignore,
+        gensym("done-popup"), A_GIMME, 0);
+
     class_addcreator((t_newmethod)arrayobj_new, gensym("array"), A_GIMME, 0);
 
     class_addcreator((t_newmethod)table_new, gensym("table"),
diff --git a/pd/src/x_scalar.c b/pd/src/x_scalar.c
new file mode 100644
index 000000000..48210e091
--- /dev/null
+++ b/pd/src/x_scalar.c
@@ -0,0 +1,191 @@
+/* Copyright (c) 1997-2013 Miller Puckette and others.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.  */
+
+/* The "scalar" object. */
+
+#include "m_pd.h"
+#include "g_canvas.h"
+#include <string.h>
+#include <stdio.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef _WIN32
+#include <io.h>
+#endif
+extern t_pd *newest;
+
+t_class *scalar_define_class;
+
+static void *scalar_define_new(t_symbol *s, int argc, t_atom *argv)
+{
+    t_atom a[9];
+    t_glist *gl;
+    t_canvas *x, *z = canvas_getcurrent();
+    t_symbol *templatesym = &s_float, *asym = gensym("#A");
+    t_template *template;
+    t_scalar *sc;
+    int keep = 0;
+    while (argc && argv->a_type == A_SYMBOL &&
+        *argv->a_w.w_symbol->s_name == '-')
+    {
+        if (!strcmp(argv->a_w.w_symbol->s_name, "-k"))
+            keep = 1;
+        else
+        {
+            error("scalar define: unknown flag ...");
+            postatom(argc, argv);
+        }
+        argc--; argv++;
+    }
+    if (argc && argv->a_type == A_SYMBOL)
+    {
+        templatesym = argv->a_w.w_symbol;
+        argc--; argv++;
+    }
+    if (argc)
+    {
+        post("warning: scalar define ignoring extra argument: ");
+        postatom(argc, argv);
+    }
+
+        /* make a canvas... */
+    SETFLOAT(a, 0);
+    SETFLOAT(a+1, 50);
+    SETFLOAT(a+2, 600);
+    SETFLOAT(a+3, 400);
+    SETSYMBOL(a+4, s);
+    SETFLOAT(a+5, 0);
+    x = canvas_new(0, 0, 6, a);
+
+    x->gl_owner = z;
+    x->gl_private = 0;
+        /* put a scalar in it */
+    template = template_findbyname(canvas_makebindsym(templatesym));
+    if (!template)
+    {
+        pd_error(x, "scalar define: couldn't find template %s",
+            templatesym->s_name);
+        goto noscalar;
+    }
+    sc = scalar_new(x, canvas_makebindsym(templatesym));
+    if (!sc)
+    {
+        pd_error(x, "%s: couldn't create scalar", templatesym->s_name);
+        goto noscalar;
+    }
+    sc->sc_gobj.g_next = 0;
+    x->gl_list = &sc->sc_gobj;
+    x->gl_private = keep;
+           /* bashily unbind #A -- this would create garbage if #A were
+           multiply bound but we believe in this context it's at most
+           bound to whichever text_define or array was created most recently */
+    asym->s_thing = 0;
+        /* and now bind #A to us to receive following messages in the
+        saved file or copy buffer */
+    pd_bind(&x->gl_obj.ob_pd, asym);
+noscalar:
+    newest = &x->gl_pd;     /* mimic action of canvas_pop() */
+    pd_popsym(&x->gl_pd);
+    x->gl_loading = 0;
+
+        /* bash the class to "scalar define" -- see comment in x_array,c */
+    x->gl_obj.ob_pd = scalar_define_class;
+    return (x);
+}
+
+    /* send a pointer to the scalar to whomever is bound to the symbol */
+static void scalar_define_send(t_glist *x, t_symbol *s)
+{
+    if (!s->s_thing)
+        pd_error(x, "scalar_define_send: %s: no such object", s->s_name);
+    else if (x->gl_list && pd_class(&x->gl_list->g_pd) == scalar_class)
+    {
+        t_gpointer gp;
+        gpointer_init(&gp);
+        // t_gobj is replaced with t_scalar in vanilla
+        gpointer_setglist(&gp, x, (t_gobj *)&x->gl_list->g_pd);
+        pd_pointer(s->s_thing, &gp);
+        gpointer_unset(&gp);
+    }
+    else bug("scalar_define_send");
+}
+
+    /* set to a list, used to restore from scalar_define_save()s below */
+static void scalar_define_set(t_glist *x, t_symbol *s, int argc, t_atom *argv)
+{
+    if (x->gl_list && pd_class(&x->gl_list->g_pd) == scalar_class)
+    {
+        t_binbuf *b = binbuf_new();
+        int nextmsg = 0, natoms;
+        t_atom *vec;
+        glist_clear(x);
+        binbuf_restore(b, argc, argv);
+        natoms = binbuf_getnatom(b);
+        vec = binbuf_getvec(b);
+        canvas_readscalar(x, natoms, vec, &nextmsg, 0);
+        binbuf_free(b);
+    }
+    else bug("scalar_define_set");
+}
+
+    /* save to a binbuf (for file save or copy) */
+static void scalar_define_save(t_gobj *z, t_binbuf *bb)
+{
+    t_glist *x = (t_glist *)z;
+    binbuf_addv(bb, "ssff", &s__X, gensym("obj"),
+        (float)x->gl_obj.te_xpix, (float)x->gl_obj.te_ypix);
+    binbuf_addbinbuf(bb, x->gl_obj.ob_binbuf);
+    binbuf_addsemi(bb);
+    if (x->gl_private && x->gl_list &&
+        pd_class(&x->gl_list->g_pd) == scalar_class)
+    {
+        t_binbuf *b2 = binbuf_new();
+        t_scalar *sc = (t_scalar *)(x->gl_list);
+        binbuf_addv(bb, "ss", gensym("#A"), gensym("set"));
+        canvas_writescalar(sc->sc_template, sc->sc_vec, b2, 0);
+        binbuf_addbinbuf(bb, b2);
+        binbuf_addsemi(bb);
+        binbuf_free(b2);
+    }
+}
+
+/* overall creator for "scalar" objects - dispatch to "scalar define" etc */
+static void *scalarobj_new(t_symbol *s, int argc, t_atom *argv)
+{
+    if (!argc || argv[0].a_type != A_SYMBOL)
+        newest = scalar_define_new(s, argc, argv);
+    else
+    {
+        char *str = argv[0].a_w.w_symbol->s_name;
+        if (!strcmp(str, "d") || !strcmp(str, "define"))
+            newest = scalar_define_new(s, argc-1, argv+1);
+        else
+        {
+            error("scalar %s: unknown function", str);
+            newest = 0;
+        }
+    }
+    return (newest);
+}
+
+void canvas_add_for_class(t_class *c);
+
+/* ---------------- global setup function -------------------- */
+
+void x_scalar_setup(void )
+{
+    scalar_define_class = class_new(gensym("scalar define"), 0,
+        (t_method)canvas_free, sizeof(t_canvas), 0, 0);
+    canvas_add_for_class(scalar_define_class);
+    class_addmethod(scalar_define_class, (t_method)scalar_define_send,
+        gensym("send"), A_SYMBOL, 0);
+    class_addmethod(scalar_define_class, (t_method)scalar_define_set,
+        gensym("set"), A_GIMME, 0);
+    class_sethelpsymbol(scalar_define_class, gensym("scalar-object"));
+    class_setsavefn(scalar_define_class, scalar_define_save);
+
+    class_addcreator((t_newmethod)scalarobj_new, gensym("scalar"), A_GIMME, 0);
+
+}
diff --git a/pd/src/x_vexp.h b/pd/src/x_vexp.h
index 322c0a58c..16f74ef5d 100644
--- a/pd/src/x_vexp.h
+++ b/pd/src/x_vexp.h
@@ -5,17 +5,17 @@
 /* "expr" was written by Shahrokh Yadegari c. 1989. -msp */
 /* "expr~" and "fexpr~" conversion by Shahrokh Yadegari c. 1999,2000 */
 
-#define MSP
-#ifdef PD
-#undef MSP
-#endif
+//#define MSP
+//#ifdef PD
+//#undef MSP
+//#endif
 
-#ifdef PD
+//#ifdef PD
 #include "m_pd.h"
-#else /* MSP */
-#include "ext.h"
-#include "z_dsp.h"
-#endif
+//#else /* MSP */
+//#include "ext.h"
+//#include "z_dsp.h"
+//#endif
 
 #define fts_malloc malloc
 #define fts_calloc calloc
-- 
GitLab