Commit 08003774 authored by Ivica Bukvic's avatar Ivica Bukvic
Browse files

backported Jonathan Wilkes' info classes

parent 7f11fa36
......@@ -555,6 +555,8 @@ EXTERN void canvas_rename(t_canvas *x, t_symbol *s, t_symbol *dir);
EXTERN void canvas_loadbang(t_canvas *x);
EXTERN int canvas_hitbox(t_canvas *x, t_gobj *y, int xpos, int ypos,
int *x1p, int *y1p, int *x2p, int *y2p);
EXTERN t_gobj *canvas_findhitbox(t_canvas *x, int xpos, int ypos,
int *x1p, int *y1p, int *x2p, int *y2p);
EXTERN int canvas_setdeleting(t_canvas *x, int flag);
/* ---- for parsing @pd_extra and other sys paths in filenames --------------------- */
......
......@@ -2057,7 +2057,7 @@ int canvas_hitbox(t_canvas *x, t_gobj *y, int xpos, int ypos,
}
/* find the last gobj, if any, containing the point. */
static t_gobj *canvas_findhitbox(t_canvas *x, int xpos, int ypos,
t_gobj *canvas_findhitbox(t_canvas *x, int xpos, int ypos,
int *x1p, int *y1p, int *x2p, int *y2p)
{
t_gobj *y, *rval = 0;
......
......@@ -33,6 +33,14 @@ static void pd_defaultlist(t_pd *x, t_symbol *s, int argc, t_atom *argv);
t_pd pd_objectmaker; /* factory for creating "object" boxes */
t_pd pd_canvasmaker; /* factory for creating canvases */
typedef struct _classtable
{
t_class *ct_class;
struct _classtable *ct_next;
} t_classtable;
t_classtable *ct;
static t_symbol *class_extern_dir = &s_;
static void pd_defaultanything(t_pd *x, t_symbol *s, int argc, t_atom *argv)
......@@ -165,6 +173,28 @@ static void pd_defaultlist(t_pd *x, t_symbol *s, int argc, t_atom *argv)
extern void text_save(t_gobj *z, t_binbuf *b);
void classtable_register(t_class *c)
{
t_classtable *t;
for(t = ct; t; t = t->ct_next)
if (t->ct_class == c) post("already registered %s", c->c_name->s_name);
t = (t_classtable *)t_getbytes(sizeof(*t));
t->ct_class = c;
t->ct_next = ct;
ct = t;
}
// todo-- make accessors so m_imp.h isn't needed by x_interface.c
t_class *classtable_findbyname(t_symbol *s)
{
t_classtable *t;
for (t = ct; t; t = t->ct_next)
if (t->ct_class->c_name == s)
return t->ct_class;
return NULL;
}
t_class *class_new(t_symbol *s, t_newmethod newmethod, t_method freemethod,
size_t size, int flags, t_atomtype type1, ...)
{
......@@ -233,6 +263,8 @@ t_class *class_new(t_symbol *s, t_newmethod newmethod, t_method freemethod,
#if 0
post("class: %s", c->c_name->s_name);
#endif
classtable_register(c);
// post("class: %s", c->c_name->s_name);
return (c);
}
......
......@@ -11,7 +11,7 @@ extern "C" {
#define PD_MAJOR_VERSION 0
#define PD_MINOR_VERSION 42
#define PD_BUGFIX_VERSION 7
#define PD_TEST_VERSION "20130724"
#define PD_TEST_VERSION "20130830"
#define PDL2ORK
/* old name for "MSW" flag -- we have to take it for the sake of many old
......
......@@ -813,6 +813,16 @@ void sys_setblocksize(int n)
sys_blocksize = n;
}
void sys_get_audio_devs(char *indevlist, int *nindevs,
char *outdevlist, int *noutdevs, int *canmulti, int *cancallback,
int maxndev, int devdescsize)
{
audio_getdevs(indevlist, nindevs,
outdevlist, noutdevs,
canmulti, cancallback,
maxndev, devdescsize);
}
void sys_set_audio_api(int which)
{
sys_audioapi = which;
......
......@@ -771,3 +771,17 @@ void glob_midi_dialog(t_pd *dummy, t_symbol *s, int argc, t_atom *argv)
}
}
void sys_get_midi_devs(char *indevlist, int *nindevs,
char *outdevlist, int *noutdevs,
int maxndevs, int devdescsize)
{
#ifdef USEAPI_ALSA
if (sys_midiapi == API_ALSA)
midi_alsa_getdevs(indevlist, nindevs, outdevlist, noutdevs,
maxndevs, devdescsize);
else
#endif /* ALSA */
midi_getdevs(indevlist, nindevs, outdevlist, noutdevs, maxndevs, devdescsize);
}
......@@ -731,4 +731,44 @@ void glob_startup_dialog(t_pd *dummy, t_symbol *s, int argc, t_atom *argv)
}
}
t_symbol *pd_getdirname(void)
{
char buf[MAXPDSTRING], buf2[MAXPDSTRING];
int len;
#ifdef _WIN32
if ((len = GetModuleFileName(NULL, buf, sizeof(buf))) == 0)
strcpy(buf, ".");
else
buf[len] = '\0';
sys_unbashfilename(buf, buf);
#elif defined(__APPLE__)
len = sizeof(buf);
_NSGetExecutablePath(buf, &len);
if (len != -1) buf[len] = '\0';
#elif defined(__FreeBSD__)
len = (ssize_t)(readlink("/proc/curproc/file", buf, sizeof(buf)-1));
if (len != -1) buf[len] = '\0';
#else
len = (ssize_t)(readlink("/proc/self/exe", buf, sizeof(buf)-1));
if (len != -1) buf[len] = '\0';
#endif
if (len != -1)
{
char *lastslash;
lastslash = strrchr(buf, '/');
if (lastslash)
{
lastslash++;
*lastslash= '\0';
strncpy(buf2, buf, lastslash-buf);
buf2[lastslash-buf] = '\0';
}
else strcpy(buf2, ".");
}
else
{
return 0;
}
t_symbol *foo = gensym(buf2);
return foo;
}
......@@ -94,9 +94,15 @@ void sys_getmeters(t_sample *inmax, t_sample *outmax);
void sys_listdevs(void);
void sys_setblocksize(int n);
EXTERN void sys_get_audio_devs(char *indevlist, int *nindevs,
char *outdevlist, int *noutdevs, int *canmulti, int *cancallback,
int maxndev, int devdescsize);
EXTERN void sys_get_audio_apis(char *buf);
/* s_midi.c */
#define MAXMIDIINDEV 16 /* max. number of input ports */
#define MAXMIDIOUTDEV 16 /* max. number of output ports */
extern int sys_midiapi;
extern int sys_nmidiin;
extern int sys_nmidiout;
extern int sys_midiindevlist[];
......@@ -104,6 +110,11 @@ extern int sys_midioutdevlist[];
void sys_open_midi(int nmidiin, int *midiinvec,
int nmidiout, int *midioutvec, int enable);
EXTERN void sys_get_midi_apis(char *buf);
EXTERN void sys_get_midi_devs(char *indevlist, int *nindevs,
char *outdevlist, int *noutdevs,
int maxndev, int devdescsize);
void sys_get_midi_params(int *pnmidiindev, int *pmidiindev,
int *pnmidioutdev, int *pmidioutdev);
......
......@@ -5,11 +5,20 @@
/* interface objects */
#include "m_pd.h"
#include "m_imp.h"
#include "g_canvas.h"
#include "s_stuff.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
/* we need the following for [pdinfo] ... */
#define MAXNDEV 20
#define DEVDESCSIZE 80
extern t_class *classtable_findbyname(t_symbol *s);
/* -------------------------- print ------------------------------ */
t_class *print_class;
......@@ -114,13 +123,17 @@ static t_class *classinfo_class;
typedef struct _classinfo {
t_object x_obj;
t_float x_depth;
t_outlet *x_out2;
t_symbol *x_name;
} t_classinfo;
/* used by all the *info objects */
void info_out(t_text *te, t_int all, t_symbol *s, int argc, t_atom *argv)
static t_int info_to_console = 0;
void info_out(t_text *te, t_symbol *s, int argc, t_atom *argv)
{
if (all)
if (info_to_console)
{
startpost("%s:", s->s_name);
if (argc > 0)
......@@ -133,6 +146,24 @@ void info_out(t_text *te, t_int all, t_symbol *s, int argc, t_atom *argv)
}
}
void info_print(t_text *te)
{
t_class *c = classtable_findbyname(te->ob_pd->c_name);
if(c == NULL)
{
pd_error(te, "s: can't find entry in classtable");
return;
}
info_to_console = 1;
t_int i;
t_methodentry *m;
for(i = c->c_nmethod, m = c->c_methods; i; i--, m++)
if(m->me_name != gensym("print"))
(m->me_fun)(te, m->me_name, 0, 0);
/* pd_forwardmess(te->te_pd, 0, 0); not sure why this doesn't work */
info_to_console = 0;
}
/* -------------------------- canvasinfo ------------------------------ */
t_canvas *canvasinfo_dig(t_canvasinfo *x)
{
......@@ -147,189 +178,176 @@ t_canvas *canvasinfo_dig(t_canvasinfo *x)
return c;
}
void canvasinfo_get(t_canvasinfo *x, t_symbol *s, t_int all)
void canvasinfo_args(t_canvasinfo *x, t_symbol *s, int argc, t_atom *argv)
{
t_canvas *c = canvasinfo_dig(x);
if(s == gensym("args"))
{
int argc = 0;
t_atom *argv = 0;
t_binbuf *b;
if(!c) return;
c = canvas_getrootfor(c);
b = c->gl_obj.te_binbuf;
if(!b)
{
info_out((t_text *)x, all, s, 0, 0);
}
else
{
argc = binbuf_getnatom(b);
argv = binbuf_getvec(b);
info_out((t_text *)x, all, s, argc-1, argv+1);
}
}
else if(s == gensym("coords"))
{
t_int gop = c->gl_isgraph + c->gl_hidetext;
t_atom at[9];
SETFLOAT(at, (c->gl_isgraph) ? c->gl_x1 : 0);
SETFLOAT(at+1, (c->gl_isgraph) ? c->gl_y1 : 0);
SETFLOAT(at+2, (c->gl_isgraph) ? c->gl_x2 : 0);
SETFLOAT(at+3, (c->gl_isgraph) ? c->gl_y2 : 0);
SETFLOAT(at+4, (c->gl_isgraph) ? c->gl_pixwidth : 0);
SETFLOAT(at+5, (c->gl_isgraph) ? c->gl_pixheight : 0);
SETFLOAT(at+6, (c->gl_isgraph) ? gop : 0);
SETFLOAT(at+7, (c->gl_isgraph) ? c->gl_xmargin : 0);
SETFLOAT(at+8, (c->gl_isgraph) ? c->gl_ymargin : 0);
info_out((t_text *)x, all, s, 9, at);
}
else if(s == gensym("dir"))
{
c = canvas_getrootfor(c);
t_atom at[1];
SETSYMBOL(at, canvas_getdir(c));
info_out((t_text *)x, all, s, 1, at);
}
else if (s == gensym("dirty"))
{
t_atom at[1];
SETFLOAT(at, c->gl_dirty);
info_out((t_text *)x, all, s, 1, at);
}
else if (s == gensym("dollarzero"))
{
c = canvas_getrootfor(c);
t_symbol *d = gensym("$0");
t_symbol *ret = canvas_realizedollar(c, d);
float f = (float)strtod(ret->s_name,NULL);
t_atom at[1];
SETFLOAT(at, f);
info_out((t_text *)x, all, s, 1, at);
}
else if (s == gensym("editmode"))
{
t_atom at[1];
SETFLOAT(at, c->gl_edit);
info_out((t_text *)x, all, s, 1, at);
}
else if (s == gensym("filename"))
{
c = canvas_getrootfor(c);
t_atom at[1];
SETSYMBOL(at, c->gl_name);
info_out((t_text *)x, all, s, 1, at);
}
else if (s == gensym("name"))
int n = 0;
t_atom *a = 0;
t_binbuf *b;
if(!c) return;
if (s == gensym("args")) c = canvas_getrootfor(c);
b = c->gl_obj.te_binbuf;
if(!b)
{
char buf[MAXPDSTRING];
snprintf(buf, MAXPDSTRING, ".x%lx", (long unsigned int)c);
t_atom at[1];
SETSYMBOL(at, gensym(buf));
info_out((t_text *)x, all, s, 1, at);
info_out((t_text *)x, s, 0, 0);
}
else if (s == gensym("parent"))
else
{
t_atom at[1];
if (c->gl_owner)
{
t_gpointer gp;
gpointer_init(&gp);
gpointer_setglist(&gp, c->gl_owner, 0);
SETPOINTER(at, &gp);
info_out((t_text *)x, all, s, 1, at);
gpointer_unset(&gp);
}
n = binbuf_getnatom(b);
a = binbuf_getvec(b);
if (s == gensym("args"))
info_out((t_text *)x, s, n-1, a+1);
else
{
SETFLOAT(at, 0);
info_out((t_text *)x, all, s, 1, at);
}
}
else if (s == gensym("posonparent"))
{
t_atom at[2];
SETFLOAT(at, c->gl_obj.te_xpix);
SETFLOAT(at+1, c->gl_obj.te_ypix);
info_out((t_text *)x, all, s, 2, at);
}
else if (s == gensym("screenpos"))
{
t_atom at[4];
SETFLOAT(at, c->gl_screenx1);
SETFLOAT(at+1, c->gl_screeny1);
SETFLOAT(at+2, c->gl_screenx2);
SETFLOAT(at+3, c->gl_screeny2);
info_out((t_text *)x, all, s, 4, at);
}
else if (s == gensym("self"))
{
t_atom at[1];
t_gpointer gp;
gpointer_init(&gp);
gpointer_setglist(&gp, c, 0);
SETPOINTER(at, &gp);
info_out((t_text *)x, all, s, 1, at);
gpointer_unset(&gp);
info_out((t_text *)x, s, n, a);
}
else if (s == gensym("vis"))
}
void canvasinfo_coords(t_canvasinfo *x, t_symbol *s, int argc, t_atom *argv)
{
t_canvas *c = canvasinfo_dig(x);
t_int gop = c->gl_isgraph + c->gl_hidetext;
t_atom at[9];
SETFLOAT(at, (c->gl_isgraph) ? c->gl_x1 : 0);
SETFLOAT(at+1, (c->gl_isgraph) ? c->gl_y1 : 0);
SETFLOAT(at+2, (c->gl_isgraph) ? c->gl_x2 : 0);
SETFLOAT(at+3, (c->gl_isgraph) ? c->gl_y2 : 0);
SETFLOAT(at+4, (c->gl_isgraph) ? c->gl_pixwidth : 0);
SETFLOAT(at+5, (c->gl_isgraph) ? c->gl_pixheight : 0);
SETFLOAT(at+6, (c->gl_isgraph) ? gop : 0);
SETFLOAT(at+7, (c->gl_isgraph) ? c->gl_xmargin : 0);
SETFLOAT(at+8, (c->gl_isgraph) ? c->gl_ymargin : 0);
info_out((t_text *)x, s, 9, at);
}
void canvasinfo_dir(t_canvasinfo *x, t_symbol *s, int argc, t_atom *argv)
{
t_canvas *c = canvasinfo_dig(x);
c = canvas_getrootfor(c);
t_atom at[1];
SETSYMBOL(at, canvas_getdir(c));
info_out((t_text *)x, s, 1, at);
}
void canvasinfo_dirty(t_canvasinfo *x, t_symbol *s, int argc, t_atom *argv)
{
t_canvas *c = canvasinfo_dig(x);
t_atom at[1];
SETFLOAT(at, c->gl_dirty);
info_out((t_text *)x, s, 1, at);
}
void canvasinfo_dollarzero(t_canvasinfo *x, t_symbol *s, int argc, t_atom *argv)
{
t_canvas *c = canvasinfo_dig(x);
c = canvas_getrootfor(c);
t_symbol *d = gensym("$0");
t_symbol *ret = canvas_realizedollar(c, d);
float f = (float)strtod(ret->s_name,NULL);
t_atom at[1];
SETFLOAT(at, f);
info_out((t_text *)x, s, 1, at);
}
void canvasinfo_editmode(t_canvasinfo *x, t_symbol *s, int argc, t_atom *argv)
{
t_canvas *c = canvasinfo_dig(x);
t_atom at[1];
SETFLOAT(at, c->gl_edit);
info_out((t_text *)x, s, 1, at);
}
void canvasinfo_filename(t_canvasinfo *x, t_symbol *s, int argc, t_atom *argv)
{
t_canvas *c = canvasinfo_dig(x);
c = canvas_getrootfor(c);
t_atom at[1];
SETSYMBOL(at, c->gl_name);
info_out((t_text *)x, s, 1, at);
}
void canvasinfo_hitbox(t_canvasinfo *x, t_floatarg xpos, t_floatarg ypos)
{
t_canvas *c = canvasinfo_dig(x);
int x1, y1, x2, y2;
t_gobj *ob = canvas_findhitbox(c, xpos, ypos, &x1, &y1, &x2, &y2);
if (ob)
{
t_atom at[1];
SETFLOAT(at, glist_isvisible(c));
info_out((t_text *)x, all, s, 1, at);
t_atom at[5];
char *classname = class_getname(ob->g_pd);
SETSYMBOL(at, gensym(classname));
SETFLOAT(at+1, (t_float)x1);
SETFLOAT(at+2, (t_float)y1);
SETFLOAT(at+3, (t_float)x2);
SETFLOAT(at+4, (t_float)y2);
info_out((t_text *)x, gensym("hitbox"), 5, at);
}
else
{
pd_error(x, "canvasinfo: no %s property", s->s_name);
}
info_out((t_text *)x, gensym("hitbox"), 0, 0);
}
void canvasinfo_symbol(t_canvasinfo *x, t_symbol *s)
void canvasinfo_name(t_canvasinfo *x, t_symbol *s, int argc, t_atom *argv)
{
canvasinfo_get(x, s, 0);
t_canvas *c = canvasinfo_dig(x);
char buf[MAXPDSTRING];
snprintf(buf, MAXPDSTRING, ".x%lx", (long unsigned int)c);
t_atom at[1];
SETSYMBOL(at, gensym(buf));
info_out((t_text *)x, s, 1, at);
}
void canvasinfo_bang(t_canvasinfo *x)
void canvasinfo_pointer(t_canvasinfo *x, t_symbol *s, int argc, t_atom *argv)
{
canvasinfo_get(x, gensym("args"), 1);
canvasinfo_get(x, gensym("coords"), 1);
canvasinfo_get(x, gensym("dir"), 1);
canvasinfo_get(x, gensym("dollarzero"), 1);
canvasinfo_get(x, gensym("editmode"), 1);
canvasinfo_get(x, gensym("filename"), 1);
canvasinfo_get(x, gensym("name"), 1);
canvasinfo_get(x, gensym("parent"), 1);
canvasinfo_get(x, gensym("posonparent"), 1);
canvasinfo_get(x, gensym("screenpos"), 1);
canvasinfo_get(x, gensym("self"), 1);
canvasinfo_get(x, gensym("vis"), 1);
t_canvas *c = canvasinfo_dig(x);
t_atom at[1];
t_gpointer gp;
gpointer_init(&gp);
gpointer_setglist(&gp, c, 0);
SETPOINTER(at, &gp);
info_out((t_text *)x, s, 1, at);
gpointer_unset(&gp);
}
void canvasinfo_pointer(t_canvasinfo *x, t_gpointer *gp)
void canvasinfo_posonparent(t_canvasinfo *x, t_symbol *s,
int argc, t_atom *argv)
{
pd_error(x, "canvasinfo: no method for pointer");
t_canvas *c = canvasinfo_dig(x);
t_atom at[2];
SETFLOAT(at, c->gl_obj.te_xpix);
SETFLOAT(at+1, c->gl_obj.te_ypix);
info_out((t_text *)x, s, 2, at);
}
void canvasinfo_float(t_canvasinfo *x, t_float f)
void canvasinfo_screenpos(t_canvasinfo *x, t_symbol *s, int argc, t_atom *argv)
{
pd_error(x, "canvasinfo: no method for float");
t_canvas *c = canvasinfo_dig(x);
t_atom at[4];
SETFLOAT(at, c->gl_screenx1);
SETFLOAT(at+1, c->gl_screeny1);
SETFLOAT(at+2, c->gl_screenx2);
SETFLOAT(at+3, c->gl_screeny2);
info_out((t_text *)x, s, 4, at);
}
static void canvasinfo_list(t_canvasinfo *x, t_symbol *s, int ac, t_atom *av)
void canvasinfo_toplevel(t_canvasinfo *x, t_symbol *s, int argc, t_atom *argv)
{
obj_list(&x->x_obj, 0, ac, av);
t_canvas *c = canvasinfo_dig(x);
t_float f = c->gl_owner ? 0 : 1;
t_atom at[1];
SETFLOAT(at, f);
info_out((t_text *)x, s, 1, at);
}
static void canvasinfo_anything(t_canvasinfo *x, t_symbol *s, int ac, t_atom *av)
void canvasinfo_vis(t_canvasinfo *x, t_symbol *s, int argc, t_atom *argv)
{
t_atom *av2 = (t_atom *)getbytes((ac + 1) * sizeof(t_atom));
int i;
for (i = 0; i < ac; i++)
av2[i + 1] = av[i];
SETSYMBOL(av2, s);
obj_list(&x->x_obj, 0, ac+1, av2);
freebytes(av2, (ac + 1) * sizeof(t_atom));
t_canvas *c = canvasinfo_dig(x);
t_atom at[1];
SETFLOAT(at, glist_isvisible(c));
info_out((t_text *)x, s, 1, at);
}
void canvasinfo_print(t_canvasinfo *x)
{
info_print((t_text *)x);
}
void *canvasinfo_new(t_floatarg f)
......@@ -351,67 +369,352 @@ void canvasinfo_setup(void)
sizeof(t_canvasinfo),
CLASS_DEFAULT, A_DEFFLOAT, 0);
class_addbang(canvasinfo_class, canvasinfo_bang);
class_addpointer(canvasinfo_class, canvasinfo_pointer);
class_addfloat(canvasinfo_class, canvasinfo_float);
class_addsymbol(canvasinfo_class, canvasinfo_symbol);
class_addlist(canvasinfo_class, canvasinfo_list);
class_addanything(canvasinfo_class, canvasinfo_anything);
class_addmethod(canvasinfo_class, (t_method)canvasinfo_args,