From 341d36c432e93d66a106f977d1758b0e624f4184 Mon Sep 17 00:00:00 2001
From: Jonathan Wilkes <jancsika@yahoo.com>
Date: Sun, 28 Sep 2014 22:53:12 -0400
Subject: [PATCH] first stab at generalizing gpointers to handle gobjs

---
 pd/src/g_array.c     |  7 +++---
 pd/src/g_canvas.h    |  2 +-
 pd/src/g_scalar.c    |  8 +++----
 pd/src/g_template.c  | 14 ++++++------
 pd/src/g_traversal.c | 52 ++++++++++++++++++++++++--------------------
 pd/src/m_pd.h        |  3 ++-
 pd/src/x_interface.c | 19 +++++++++++++++-
 7 files changed, 65 insertions(+), 40 deletions(-)

diff --git a/pd/src/g_array.c b/pd/src/g_array.c
index f9a45d520..796f1895f 100644
--- a/pd/src/g_array.c
+++ b/pd/src/g_array.c
@@ -101,10 +101,10 @@ static void array_resize_and_redraw(t_array *array, t_glist *glist, int n)
     while (a2->a_gp.gp_stub->gs_which == GP_ARRAY)
         a2 = a2->a_gp.gp_stub->gs_un.gs_array;
     if (vis)
-        gobj_vis(&a2->a_gp.gp_un.gp_scalar->sc_gobj, glist, 0);
+        gobj_vis(a2->a_gp.gp_un.gp_gobj, glist, 0);
     array_resize(array, n);
     if (vis)
-        gobj_vis(&a2->a_gp.gp_un.gp_scalar->sc_gobj, glist, 1);
+        gobj_vis(a2->a_gp.gp_un.gp_gobj, glist, 1);
 }
 
 void word_free(t_word *wp, t_template *template);
@@ -841,7 +841,8 @@ void array_redraw(t_array *a, t_glist *glist)
 {
     while (a->a_gp.gp_stub->gs_which == GP_ARRAY)
         a = a->a_gp.gp_stub->gs_un.gs_array;
-    scalar_redraw(a->a_gp.gp_un.gp_scalar, glist);
+    t_scalar *sc = (t_scalar *)(a->a_gp.gp_un.gp_gobj);
+    scalar_redraw(sc, glist);
 }
 
     /* routine to get screen coordinates of a point in an array */
diff --git a/pd/src/g_canvas.h b/pd/src/g_canvas.h
index d847b51b0..90574b3de 100644
--- a/pd/src/g_canvas.h
+++ b/pd/src/g_canvas.h
@@ -612,7 +612,7 @@ int array_joc; /* for "jump on click" array inside a graph */
 /* --------------------- gpointers and stubs ---------------- */
 EXTERN t_gstub *gstub_new(t_glist *gl, t_array *a);
 EXTERN void gstub_cutoff(t_gstub *gs);
-EXTERN void gpointer_setglist(t_gpointer *gp, t_glist *glist, t_scalar *x);
+EXTERN void gpointer_setglist(t_gpointer *gp, t_glist *glist, t_gobj *x);
 EXTERN void gpointer_setarray(t_gpointer *gp, t_array *array, t_word *w);
 
 /* --------------------- scalars ------------------------- */
diff --git a/pd/src/g_scalar.c b/pd/src/g_scalar.c
index f035bcf16..3483758fa 100644
--- a/pd/src/g_scalar.c
+++ b/pd/src/g_scalar.c
@@ -225,7 +225,7 @@ t_scalar *scalar_new(t_glist *owner, t_symbol *templatesym)
         (template->t_n - 1) * sizeof(*x->sc_vec));
     x->sc_gobj.g_pd = scalar_class;
     x->sc_template = templatesym;
-    gpointer_setglist(&gp, owner, x);
+    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);
@@ -457,7 +457,7 @@ void scalar_select(t_gobj *z, t_glist *owner, int state)
     //t_canvas *templatecanvas = NULL;
     t_gpointer gp;
     gpointer_init(&gp);
-    gpointer_setglist(&gp, owner, x);
+    gpointer_setglist(&gp, owner, &x->sc_gobj);
     SETPOINTER(&at, &gp);
     if (tmpl = template_findbyname(templatesym))
     {
@@ -523,7 +523,7 @@ static void scalar_displace(t_gobj *z, t_glist *glist, int dx, int dy)
         x->sc_y2 += dy;
     }
     gpointer_init(&gp);
-    gpointer_setglist(&gp, glist, x);
+    gpointer_setglist(&gp, glist, &x->sc_gobj);
     SETPOINTER(&at[0], &gp);
     SETFLOAT(&at[1], (t_float)dx);
     SETFLOAT(&at[2], (t_float)dy);
@@ -576,7 +576,7 @@ static void scalar_displace_withtag(t_gobj *z, t_glist *glist, int dx, int dy)
     //fprintf(stderr,"gotx=%d goty=%d\n", gotx, goty);
     scalar_getbasexy(x, &basex, &basey);
     gpointer_init(&gp);
-    gpointer_setglist(&gp, glist, x);
+    gpointer_setglist(&gp, glist, &x->sc_gobj);
     SETPOINTER(&at[0], &gp);
     SETFLOAT(&at[1], (t_float)dx);
     SETFLOAT(&at[2], (t_float)dy);
diff --git a/pd/src/g_template.c b/pd/src/g_template.c
index ecc5bb7ad..b106a95d4 100644
--- a/pd/src/g_template.c
+++ b/pd/src/g_template.c
@@ -282,7 +282,7 @@ static t_scalar *template_conformscalar(t_template *tfrom, t_template *tto,
             (tto->t_n - 1) * sizeof(*x->sc_vec));
         x->sc_gobj.g_pd = scalar_class;
         x->sc_template = tfrom->t_sym;
-        gpointer_setglist(&gp, glist, x);
+        gpointer_setglist(&gp, glist, &x->sc_gobj);
             /* Here we initialize to the new template, but array and list
             elements will still belong to old template. */
         word_init(x->sc_vec, tto, &gp);
@@ -503,7 +503,7 @@ void template_notifyforscalar(t_template *template, t_glist *owner,
 {
     t_gpointer gp;
     gpointer_init(&gp);
-    gpointer_setglist(&gp, owner, sc);
+    gpointer_setglist(&gp, owner, &sc->sc_gobj);
     SETPOINTER(argv, &gp);
     template_notify(template, s, argc, argv);
     gpointer_unset(&gp);
@@ -3717,7 +3717,7 @@ static int draw_click(t_gobj *z, t_glist *glist,
         draw_motion_template = template;
         if (draw_motion_scalar)
             gpointer_setglist(&draw_motion_gpointer, draw_motion_glist,
-                draw_motion_scalar);
+                &draw_motion_scalar->sc_gobj);
         else gpointer_setarray(&draw_motion_gpointer,
                 draw_motion_array, draw_motion_wp);
         glist_grab(glist, z, draw_motion, 0, xpix, ypix);
@@ -4323,7 +4323,7 @@ static int curve_click(t_gobj *z, t_glist *glist,
         curve_motion_template = template;
         if (curve_motion_scalar)
             gpointer_setglist(&curve_motion_gpointer, curve_motion_glist,
-                curve_motion_scalar);
+                &curve_motion_scalar->sc_gobj);
         else gpointer_setarray(&curve_motion_gpointer,
                 curve_motion_array, curve_motion_wp);
         glist_grab(glist, z, curve_motion, 0, xpix, ypix);
@@ -6551,7 +6551,7 @@ static int drawnumber_click(t_gobj *z, t_glist *glist,
             drawnumber_motion_symbol = ((x->x_flags & DRAW_SYMBOL) != 0);
             if (drawnumber_motion_scalar)
                 gpointer_setglist(&drawnumber_motion_gpointer, 
-                    drawnumber_motion_glist, drawnumber_motion_scalar);
+                    drawnumber_motion_glist, &drawnumber_motion_scalar->sc_gobj);
             else gpointer_setarray(&drawnumber_motion_gpointer,
                     drawnumber_motion_array, drawnumber_motion_wp);
            glist_grab(glist, z, drawnumber_motion, drawnumber_key,
@@ -6977,7 +6977,7 @@ static int drawsymbol_click(t_gobj *z, t_glist *glist,
             drawsymbol_motion_symbol = ((x->x_flags & DRAW_SYMBOL) != 0);
             if (drawsymbol_motion_scalar)
                 gpointer_setglist(&drawsymbol_motion_gpointer, 
-                    drawsymbol_motion_glist, drawsymbol_motion_scalar);
+                    drawsymbol_motion_glist, &drawsymbol_motion_scalar->sc_gobj);
             else gpointer_setarray(&drawsymbol_motion_gpointer,
                     drawsymbol_motion_array, drawsymbol_motion_wp);
            glist_grab(glist, z, drawsymbol_motion, drawsymbol_key,
@@ -7439,7 +7439,7 @@ static int drawimage_click(t_gobj *z, t_glist *glist,
             drawimage_motion_sprite = ((x->x_flags & DRAW_SPRITE) != 0);
             if (drawimage_motion_scalar)
                 gpointer_setglist(&drawimage_motion_gpointer, 
-                    drawimage_motion_glist, drawimage_motion_scalar);
+                    drawimage_motion_glist, &drawimage_motion_scalar->sc_gobj);
             else gpointer_setarray(&drawimage_motion_gpointer,
                     drawimage_motion_array, drawimage_motion_wp);
            glist_grab(glist, z, drawimage_motion, drawimage_key,
diff --git a/pd/src/g_traversal.c b/pd/src/g_traversal.c
index 731ecbdd0..42402f8fc 100644
--- a/pd/src/g_traversal.c
+++ b/pd/src/g_traversal.c
@@ -83,9 +83,15 @@ int gpointer_check(const t_gpointer *gp, int headok)
     }
     else if (gs->gs_which == GP_GLIST)
     {
-        if (!headok && !gp->gp_un.gp_scalar) return (0);
-        else if (gs->gs_un.gs_glist->gl_valid != gp->gp_valid) return (0);
-        else return (1);
+        if (!headok && !((t_scalar *)(gp->gp_un.gp_gobj)))
+            return (0);
+        else if (gp->gp_un.gp_gobj &&
+                 pd_class(&gp->gp_un.gp_gobj->g_pd) != scalar_class)
+            return (0);
+        else if (gs->gs_un.gs_glist->gl_valid != gp->gp_valid)
+            return (0);
+        else
+            return (1);
     }
     else return (0);
 }
@@ -98,7 +104,7 @@ static t_symbol *gpointer_gettemplatesym(const t_gpointer *gp)
     t_gstub *gs = gp->gp_stub;
     if (gs->gs_which == GP_GLIST)
     {
-        t_scalar *sc = gp->gp_un.gp_scalar;
+        t_scalar *sc = (t_scalar *)(gp->gp_un.gp_gobj);
         if (sc)
             return (sc->sc_template);
         else return (0);
@@ -133,13 +139,13 @@ void gpointer_unset(t_gpointer *gp)
     }
 }
 
-void gpointer_setglist(t_gpointer *gp, t_glist *glist, t_scalar *x)
+void gpointer_setglist(t_gpointer *gp, t_glist *glist, t_gobj *x)
 {
     t_gstub *gs;
     if (gs = gp->gp_stub) gstub_dis(gs);
     gp->gp_stub = gs = glist->gl_stub;
     gp->gp_valid = glist->gl_valid;
-    gp->gp_un.gp_scalar = x;
+    gp->gp_un.gp_gobj = x;
     gs->gs_refcount++;
 }
 
@@ -157,7 +163,7 @@ void gpointer_init(t_gpointer *gp)
 {
     gp->gp_stub = 0;
     gp->gp_valid = 0;
-    gp->gp_un.gp_scalar = 0;
+    gp->gp_un.gp_gobj = 0;
 }
 
 /* ---------------------- pointers ----------------------------- */
@@ -236,7 +242,7 @@ static void ptrobj_vnext(t_ptrobj *x, t_float f)
             "ptrobj_vnext: next-selected only works for a visible window");
         return;
     }
-    gobj = &gp->gp_un.gp_scalar->sc_gobj;
+    gobj = gp->gp_un.gp_gobj;
     
     if (!gobj) gobj = glist->gl_list;
     else gobj = gobj->g_next;
@@ -251,7 +257,7 @@ static void ptrobj_vnext(t_ptrobj *x, t_float f)
         t_scalar *sc = (t_scalar *)gobj;
         t_symbol *templatesym = sc->sc_template;
 
-        gp->gp_un.gp_scalar = sc; 
+        gp->gp_un.gp_gobj = &sc->sc_gobj; 
         for (n = x->x_ntypedout, to = x->x_typedout; n--; to++)
         {
             if (to->to_type == templatesym)
@@ -431,7 +437,7 @@ static void get_pointer(t_get *x, t_gpointer *gp)
         return;
     }
     if (gs->gs_which == GP_ARRAY) vec = gp->gp_un.gp_w;
-    else vec = gp->gp_un.gp_scalar->sc_vec;
+    else vec = ((t_scalar *)(gp->gp_un.gp_gobj))->sc_vec;
     for (i = nitems - 1, vp = x->x_variables + i; i >= 0; i--, vp--)
     {
         int onset, type;
@@ -552,20 +558,20 @@ static void set_bang(t_set *x)
         return;
     if (gs->gs_which == GP_ARRAY)
         vec = gp->gp_un.gp_w;
-    else vec = gp->gp_un.gp_scalar->sc_vec;
+    else vec = ((t_scalar *)(gp->gp_un.gp_gobj))->sc_vec;
     if (x->x_issymbol)
         for (i = 0, vp = x->x_variables; i < nitems; i++, vp++)
             template_setsymbol(template, vp->gv_sym, vec, vp->gv_w.w_symbol, 1);
     else for (i = 0, vp = x->x_variables; i < nitems; i++, vp++)
         template_setfloat(template, vp->gv_sym, vec, vp->gv_w.w_float, 1);
     if (gs->gs_which == GP_GLIST)
-        scalar_redraw(gp->gp_un.gp_scalar, gs->gs_un.gs_glist);  
+        scalar_redraw((t_scalar *)(gp->gp_un.gp_gobj), gs->gs_un.gs_glist);  
     else
     {
         t_array *owner_array = gs->gs_un.gs_array;
         while (owner_array->a_gp.gp_stub->gs_which == GP_ARRAY)
             owner_array = owner_array->a_gp.gp_stub->gs_un.gs_array;
-        scalar_redraw(owner_array->a_gp.gp_un.gp_scalar,
+        scalar_redraw((t_scalar *)(owner_array->a_gp.gp_un.gp_gobj),
             owner_array->a_gp.gp_stub->gs_un.gs_glist);  
     }
 }
@@ -654,7 +660,7 @@ static void elem_float(t_elem *x, t_float f)
         return;
     }
     if (gparent->gp_stub->gs_which == GP_ARRAY) w = gparent->gp_un.gp_w;
-    else w = gparent->gp_un.gp_scalar->sc_vec;
+    else w = ((t_scalar *)(gparent->gp_un.gp_gobj))->sc_vec;
     if (!template)
     {
         pd_error(x, "element: couldn't find template %s", templatesym->s_name);
@@ -761,7 +767,7 @@ static void getsize_pointer(t_getsize *x, t_gpointer *gp)
         return;
     }
     if (gs->gs_which == GP_ARRAY) w = gp->gp_un.gp_w;
-    else w = gp->gp_un.gp_scalar->sc_vec;
+    else w = ((t_scalar *)(gp->gp_un.gp_gobj))->sc_vec;
     
     array = *(t_array **)(((char *)w) + onset);
     outlet_float(x->x_obj.ob_outlet, (t_float)(array->a_n));
@@ -824,7 +830,7 @@ static void setsize_float(t_setsize *x, t_float f)
         return;
     }
     if (gs->gs_which == GP_ARRAY) w = gp->gp_un.gp_w;
-    else w = gp->gp_un.gp_scalar->sc_vec;
+    else w = ((t_scalar *)(gp->gp_un.gp_gobj))->sc_vec;
 
     if (!template)
     {
@@ -869,7 +875,7 @@ static void setsize_float(t_setsize *x, t_float f)
     if (gs->gs_which == GP_GLIST)
     {
         if (glist_isvisible(gs->gs_un.gs_glist))
-            gobj_vis((t_gobj *)(gp->gp_un.gp_scalar), gs->gs_un.gs_glist, 0);  
+            gobj_vis(gp->gp_un.gp_gobj, gs->gs_un.gs_glist, 0);  
     }
     else
     {
@@ -877,7 +883,7 @@ static void setsize_float(t_setsize *x, t_float f)
         while (owner_array->a_gp.gp_stub->gs_which == GP_ARRAY)
             owner_array = owner_array->a_gp.gp_stub->gs_un.gs_array;
         if (glist_isvisible(owner_array->a_gp.gp_stub->gs_un.gs_glist))
-            gobj_vis((t_gobj *)(owner_array->a_gp.gp_un.gp_scalar),
+            gobj_vis(owner_array->a_gp.gp_un.gp_gobj,
                 owner_array->a_gp.gp_stub->gs_un.gs_glist, 0);  
     }
         /* now do the resizing and, if growing, initialize new scalars */
@@ -901,7 +907,7 @@ static void setsize_float(t_setsize *x, t_float f)
     if (gs->gs_which == GP_GLIST)
     {
         if (glist_isvisible(gs->gs_un.gs_glist))
-            gobj_vis((t_gobj *)(gp->gp_un.gp_scalar), gs->gs_un.gs_glist, 1);  
+            gobj_vis(gp->gp_un.gp_gobj, gs->gs_un.gs_glist, 1);  
     }
     else
     {
@@ -909,7 +915,7 @@ static void setsize_float(t_setsize *x, t_float f)
         while (owner_array->a_gp.gp_stub->gs_which == GP_ARRAY)
             owner_array = owner_array->a_gp.gp_stub->gs_un.gs_array;
         if (glist_isvisible(owner_array->a_gp.gp_stub->gs_un.gs_glist))
-            gobj_vis((t_gobj *)(owner_array->a_gp.gp_un.gp_scalar),
+            gobj_vis(owner_array->a_gp.gp_un.gp_gobj,
                 owner_array->a_gp.gp_stub->gs_un.gs_glist, 1);  
     }
 }
@@ -1013,7 +1019,7 @@ static void append_float(t_append *x, t_float f)
         pd_error(x, "%s: couldn't create scalar", templatesym->s_name);
         return;
     }
-    oldsc = gp->gp_un.gp_scalar;
+    oldsc = (t_scalar *)(gp->gp_un.gp_gobj);
     
     if (oldsc)
     {
@@ -1026,7 +1032,7 @@ static void append_float(t_append *x, t_float f)
         glist->gl_list = &sc->sc_gobj;
     }
 
-    gp->gp_un.gp_scalar = sc;
+    gp->gp_un.gp_gobj = (t_gobj *)sc;
     vec = sc->sc_vec;
     for (i = 0, vp = x->x_variables; i < nitems; i++, vp++)
     {
@@ -1106,7 +1112,7 @@ static void sublist_pointer(t_sublist *x, t_gpointer *gp)
         return;
     }
     if (gs->gs_which == GP_ARRAY) w = gp->gp_un.gp_w;
-    else w = gp->gp_un.gp_scalar->sc_vec;
+    else w = ((t_scalar *)(gp->gp_un.gp_gobj))->sc_vec;
     
     gpointer_setglist(&x->x_gp, *(t_glist **)(((char *)w) + onset), 0);
 
diff --git a/pd/src/m_pd.h b/pd/src/m_pd.h
index 5f6f1e1e2..d36eee4e0 100644
--- a/pd/src/m_pd.h
+++ b/pd/src/m_pd.h
@@ -111,7 +111,8 @@ typedef struct _gpointer           /* pointer to a gobj in a glist */
 {
     union
     {   
-        struct _scalar *gp_scalar;  /* scalar we're in (if glist) */
+        struct _gobj *gp_gobj;      /* header for the t_text or
+                                       scalar we're in (if glist) */
         union word *gp_w;           /* raw data (if array) */
     } gp_un;
     int gp_valid;                   /* number which must match gpointee */
diff --git a/pd/src/x_interface.c b/pd/src/x_interface.c
index 479da8f4c..52396fbd8 100644
--- a/pd/src/x_interface.c
+++ b/pd/src/x_interface.c
@@ -131,6 +131,7 @@ typedef struct _objectinfo {
     t_canvas *x_canvas;
     t_float x_index;
     t_float x_depth;
+    t_gobj *x_test;
 } t_objectinfo;
 
 /* used by all the *info objects */
@@ -1004,9 +1005,24 @@ t_gobj *objectinfo_getobject(t_canvas *c, int index)
     return y;
 }
 
-void objectinfo_float(t_floatarg f)
+void objectinfo_bang(t_objectinfo *x)
 {
+    t_canvas *c = canvas_climb(x->x_canvas, x->x_depth);
+    t_atom at[1];
+    t_gpointer gp;
+    gpointer_init(&gp);
+    gpointer_setglist(&gp, c, (t_gobj *)x);
+    SETPOINTER(at, &gp);
+    info_out((t_text *)x, &s_pointer, 1, at);
+    gpointer_unset(&gp);
+}
 
+void objectinfo_float(t_objectinfo *x, t_floatarg f)
+{
+    t_canvas *c = canvas_climb(x->x_canvas, x->x_depth);
+    t_gobj *obj = objectinfo_getobject(c, (int)f);
+    post("object is .%x", obj);
+    x->x_test = obj;
 }
 
 void objectinfo_parseargs(t_objectinfo *x, int argc, t_atom *argv)
@@ -1156,6 +1172,7 @@ void objectinfo_setup(void)
         sizeof(t_objectinfo),
         CLASS_DEFAULT, A_DEFFLOAT, 0);
 
+    class_addbang(objectinfo_class, objectinfo_bang);
     class_addfloat(objectinfo_class, objectinfo_float);
     class_addmethod(objectinfo_class, (t_method)objectinfo_bbox,
         gensym("bbox"), A_GIMME, 0);
-- 
GitLab