aboutsummaryrefslogtreecommitdiff
path: root/desiredata/src/desire.h
blob: f3cefe02ca3dee7173c7a73c7fd46c08069d1921 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
/*
  This file is part of PureData
  Copyright 2004-2006 by Mathieu Bouchard
  Copyright 2000-2001 IEM KUG Graz Austria (Thomas Musil)
  Copyright (c) 1997-1999 Miller Puckette.
  For information on usage and redistribution, and for a DISCLAIMER OF ALL
  WARRANTIES, see the file, "LICENSE.txt", in this distribution.

  this file declares the C interface for the second half of DesireData.
  this is where most of the differences between DesireData and PureData lie.

  SYNONYMS:
    1. glist = graph = canvas = patcher; those were not always synonymous.
       however, graph sometimes means a canvas that is displaying an array.
    2. outconnect = connection = patchcord = wire

  canvases have a few flags that determine their appearance:
    gl_havewindow: should open its own window (only if mapped? or...)
    gl_isgraph:    the GOP flag: show as graph-on-parent, vs TextBox.
    gl_owner==0:   it's a root canvas, should be in canvas_list.
                   In this case "gl_havewindow" is always set.

  canvas_list is a list of root windows only, which can be traversed using canvases_each.

  If a canvas has a window it may still not be "mapped."  Miniaturized
  windows aren't mapped, for example, but a window is also not mapped
  immediately upon creation.  In either case gl_havewindow is true but
  gl_mapped is false.

  Closing a non-root window makes it invisible; closing a root destroys it.
  A canvas that's just a text object on its parent is always "toplevel."  An
  embedded canvas can switch back and forth to appear as a toplevel by double-
  clicking on it.  Single-clicking a text box makes the toplevel become visible
  and raises the window it's in.

  If a canvas shows up as a graph on its parent, the graph is blanked while the
  canvas has its own window, even if miniaturized.
*/

#ifndef DESIRE
#define DESIRE
#endif
#ifndef __DESIRE_H
#define __DESIRE_H

#include "m_pd.h"
#include "s_stuff.h"

#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
//#include <map>
extern "C" {
#endif

/* ----------------------- m_imp.h ---------------------------------------------------*/

typedef struct _methodentry {
    t_symbol *me_name;
    t_gotfn me_fun;
    t_atomtype me_arg[MAXPDARG+1];
} t_methodentry;

typedef void (*t_bangmethod)   (t_pd *x);
typedef void (*t_pointermethod)(t_pd *x, t_gpointer *gp);
typedef void (*t_floatmethod)  (t_pd *x, t_float f);
typedef void (*t_symbolmethod) (t_pd *x, t_symbol *s);
typedef void (*t_stringmethod) (t_pd *x, const char *s);
typedef void (*t_listmethod)   (t_pd *x, t_symbol *s, int argc, t_atom *argv);
typedef void (*t_anymethod)    (t_pd *x, t_symbol *s, int argc, t_atom *argv);

t_pd *pd_new2(int argc, t_atom *argv);
t_pd *pd_new3(const char *s);

struct _class {
    t_symbol *name;                   /* name (mostly for error reporting) */
    t_symbol *helpname;               /* name of help file */
    t_symbol *externdir;              /* directory extern was loaded from */
    size_t size;                      /* size of an instance */
    t_methodentry *methods;           /* methods other than bang, etc below */
    int nmethod;                      /* number of methods */
    t_method        freemethod;       /* function to call before freeing */
    t_bangmethod    bangmethod;       /* common methods */
    t_pointermethod pointermethod;
    t_floatmethod   floatmethod;
    t_symbolmethod  symbolmethod; /* or t_stringmethod, but only C++ has anonymous unions, so... */
    t_listmethod    listmethod;
    t_anymethod     anymethod;
    t_savefn savefn;           /* function to call when saving */
    int floatsignalin;         /* onset to float for signal input */
    unsigned gobj:1;           /* true if is a gobj */
    unsigned patchable:1;      /* true if we have a t_object header */
    unsigned firstin:1;        /* if patchable, true if draw first inlet */
    unsigned drawcommand:1;    /* a drawing command for a template */
    unsigned newatoms:1;         /* can handle refcounting of atoms (future use) */
    unsigned use_stringmethod:1; /* the symbolmethod slot holds a stringmethod instead */
    t_symbol *firsttip;
    t_symbol **fields; /* names of fields aka attributes, and I don't mean the #V attributes. */
    int nfields; /* ... and how many of them */
    t_notice notice;             /* observer method */
    t_onsubscribe onsubscribe; /* observable method */
};

//#define c_methods methods /* for Cyclone */
//#define c_nmethod nmethod /* for Cyclone */
//#define c_externdir externdir /* for PDDP */
//#define c_name name /* for Cyclone,Creb,Pidip */
//#define c_size size /* for Cyclone,Flext */
//#define me_name name /* for Cyclone */
//#define me_fun fun /* for Cyclone */
//#define me_arg arg /* for Cyclone */

/* m_obj.c */
EXTERN int obj_noutlets(t_object *x);
EXTERN int obj_ninlets(t_object *x);
EXTERN t_outconnect *obj_starttraverseoutlet(t_object *x, t_outlet **op, int nout);
EXTERN t_outconnect *obj_nexttraverseoutlet(t_outconnect *lastconnect, t_object **destp, t_inlet **inletp, int *whichp);
EXTERN t_outconnect *obj_connect(t_object *source, int outno, t_object *sink, int inno);
EXTERN void obj_disconnect(t_object *source, int outno, t_object *sink, int inno);
EXTERN void outlet_setstacklim(void);
EXTERN int obj_issignalinlet(t_object *x, int m);
EXTERN int obj_issignaloutlet(t_object *x, int m);
EXTERN int obj_nsiginlets(t_object *x);
EXTERN int obj_nsigoutlets(t_object *x);
EXTERN int obj_siginletindex(t_object *x, int m);
EXTERN int obj_sigoutletindex(t_object *x, int m);

/* misc */
EXTERN void glob_evalfile(t_pd *ignore, t_symbol *name, t_symbol *dir);
EXTERN void glob_initfromgui(void *dummy, t_symbol *s);
EXTERN void glob_quit(void *dummy);

/* ----------------------- g_canvas.h ------------------------------------------------*/

/* i don't know whether this is currently used at all in DesireData. -- matju 2006.09 */
#ifdef GARRAY_THREAD_LOCK
#include <pthread.h> /* TB: for t_garray */
#endif

typedef struct t_gtemplate t_gtemplate;
typedef struct _canvasenvironment t_canvasenvironment;
typedef struct _slot t_slot;

/* the t_tick structure describes where to draw x and y "ticks" for a canvas */
typedef struct _tick {  /* where to put ticks on x or y axes */
    float point;      /* one point to draw a big tick at */
    float inc;        /* x or y increment per little tick */
    int lperb;        /* little ticks per big; 0 if no ticks to draw */
} t_tick;

typedef struct t_boxes t_boxes;

/* the t_canvas structure, which describes a list of elements that live on an area of a window.*/
#ifdef PD_PLUSPLUS_FACE
struct _glist : t_object {
#else
struct _glist {
    t_object gl_obj;         /* header in case we're a [pd] or abstraction */
#endif
    int pixwidth, pixheight; /* width in pixels (on parent, if a graph) */
    float x1,y1,x2,y2;       /* bounding rectangle in our own coordinates */
    int screenx1, screeny1, screenx2, screeny2; /* screen coordinates when toplevel */
    int xmargin, ymargin;    /* origin for GOP rectangle */
    /* ticks and tick labels */
    t_tick xtick; int nxlabels; t_symbol **xlabel; float xlabely;
    t_tick ytick; int nylabels; t_symbol **ylabel; float ylabelx;
    t_symbol *name;            /* symbol bound here */
    int font;                  /* nominal font size in points, e.g., 10 */
    t_canvasenvironment *env;  /* one of these per $0; env=0 for subpatches */
    unsigned int havewindow:1; /* this indicates whether we publish to the manager */
    unsigned int gop:1;
    unsigned int goprect:1;    /* gop version >= 0.39 */
    unsigned int hidetext:1;   /* hide object-name + args when doing graph on parent */
    long next_o_index;         /* next object index. to be incremented on each use */
    long next_w_index;         /* next wire   index. to be incremented on each use */
    t_boxes *boxes;
};

/* LATER consider adding font size to this struct (see canvas_getfont()) */
struct _canvasenvironment {
    t_symbol *dir;   /* directory patch lives in */
    int argc;        /* number of "$" arguments */
    t_atom *argv;    /* array of "$" arguments */
    long dollarzero; /* value of "$0" */
    t_namelist *path;/* search path (0.40) */
};

/* a data structure to describe a field in a pure datum */
#define DT_FLOAT 0
#define DT_SYMBOL 1
#define DT_CANVAS 2
#define DT_ARRAY 3

typedef struct t_dataslot {
    int type;
    t_symbol *name;
    t_symbol *arraytemplate;     /* filled in for arrays only */
} t_dataslot;

#ifdef PD_PLUSPLUS_FACE
typedef struct t_template : t_pd {
#else
typedef struct t_template {
    t_pd t_pdobj;               /* header */
#endif
    t_gtemplate *list;  /* list of "struct"/gtemplate objects */
    t_symbol *sym;            /* name */
    int n;                    /* number of dataslots (fields) */
    t_dataslot *vec;          /* array of dataslots */
} t_template;

/* this is not really a t_object, but it needs to be observable and have a refcount, so... */
#ifdef PD_PLUSPLUS_FACE
struct _array : t_object {
#else
struct _array {
    t_gobj gl_obj;
#endif
    int n;            /* number of elements */
    int elemsize;     /* size in bytes; LATER get this from template */
    char *vec;        /* array of elements */
    t_symbol *templatesym;    /* template for elements */
    t_gpointer gp;    /* pointer to scalar or array element we're in */
};

#ifdef PD_PLUSPLUS_FACE
struct _garray : t_gobj {
#else
struct _garray {
    t_gobj x_gobj;
#endif
    t_scalar *scalar;     /* scalar "containing" the array */
    t_canvas *canvas;     /* containing canvas */
    t_symbol *name;       /* unexpanded name (possibly with leading '$') */
    t_symbol *realname;   /* expanded name (symbol we're bound to) */
    unsigned int usedindsp:1;   /* true if some DSP routine is using this */
    unsigned int saveit:1;      /* true if we should save this with parent */
    unsigned int listviewing:1; /* true if list view window is open */
    unsigned int hidename:1;    /* don't print name above graph */
};

t_array *garray_getarray(t_garray *x);

/* structure for traversing all the connections in a canvas */
typedef struct t_linetraverser {
    t_canvas *canvas;
    t_object *from; int nout; int outlet; t_outlet *outletp;
    t_object *to;   int nin;  int inlet;  t_inlet  *inletp;
    t_outconnect *next;
    int nextoutno;
#ifdef __cplusplus
    t_linetraverser() {}
    t_linetraverser(t_canvas *canvas);
#endif
} t_linetraverser;

extern t_canvas *canvas_list; /* list of all root canvases */
extern t_class *vinlet_class, *voutlet_class, *canvas_class;
extern int canvas_valid;         /* incremented when pointers might be stale */
EXTERN int sys_noloadbang;
EXTERN t_symbol *s_empty;

#define PLOTSTYLE_POINTS 0     /* plotting styles for arrays */
#define PLOTSTYLE_POLY 1
#define PLOTSTYLE_BEZ 2

/* from kernel.c */
EXTERN void gobj_save(t_gobj *x, t_binbuf *b);
EXTERN void pd_eval_text(char *t, size_t size);
EXTERN int sys_syntax;

/* from desire.c */
EXTERN int pd_scanargs(int argc, t_atom *argv, char *fmt, ...);
EXTERN int pd_saveargs(t_binbuf *b, char *fmt, ...);
EXTERN void pd_upload(t_gobj *self);
EXTERN void sys_mgui(void *self,   const char *sel, const char *fmt, ...);
EXTERN void canvas_add(t_canvas *x, t_gobj *g, int index=-1);
EXTERN void canvas_delete(t_canvas *x, t_gobj *y);
EXTERN void canvas_deletelinesfor(t_canvas *x, t_text *text);
EXTERN void canvas_deletelinesforio(t_canvas *x, t_text *text, t_inlet *inp, t_outlet *outp);
EXTERN int canvas_isvisible(t_canvas *x);
EXTERN int canvas_istoplevel(t_canvas *x);
EXTERN int canvas_istable(t_canvas *x);
EXTERN int canvas_isabstraction(t_canvas *x);
EXTERN t_canvas *canvas_getcanvas(t_canvas *x);
EXTERN t_canvas *canvas_getrootfor(t_canvas *x);
EXTERN t_canvas *canvas_getcurrent(void);
EXTERN t_canvasenvironment *canvas_getenv(t_canvas *x);
EXTERN int canvas_getdollarzero(void);
EXTERN t_symbol *canvas_realizedollar(t_canvas *x, t_symbol *s);
EXTERN t_symbol *canvas_makebindsym(t_symbol *s);

EXTERN void linetraverser_start(t_linetraverser *t, t_canvas *x);
EXTERN t_outconnect *linetraverser_next(t_linetraverser *t);

/* -------------------- TO BE SORTED OUT --------------------- */
EXTERN void canvas_redrawallfortemplatecanvas(t_canvas *x, int action);
EXTERN void array_resize(t_array *x, int n);
EXTERN void word_init(t_word *wp, t_template *tmpl, t_gpointer *gp);
EXTERN void word_restore(t_word *wp, t_template *tmpl, int argc, t_atom *argv);
EXTERN t_scalar *scalar_new(t_canvas *owner, t_symbol *templatesym);
EXTERN void word_free(t_word *wp, t_template *tmpl);
EXTERN void scalar_redraw(t_scalar *x, t_canvas *canvas);
//EXTERN int pd_pickle(t_foo *foo, char *fmt, ...);
EXTERN void pd_set_newest (t_pd *x);
char* inlet_tip(t_inlet* i,int num);

extern t_hash<t_pd *,long> *object_table;
extern t_hash<t_symbol *,t_class *> *class_table;

/* some kernel.c stuff that wasn't in any header, when shifting to C++. */
void obj_moveinletfirst(t_object *x, t_inlet *i);
void obj_moveoutletfirst(t_object *x, t_outlet *o);
int inlet_getsignalindex(t_inlet *x);
int outlet_getsignalindex(t_outlet *x);
void text_save(t_gobj *z, t_binbuf *b);
t_sample *obj_findsignalscalar(t_object *x, int m);
void class_set_extern_dir(t_symbol *s);
void glob_update_class_info (t_pd *bogus, t_symbol *s, t_symbol *cb_recv, t_symbol *cb_sel);
void pd_free_zombie(t_pd *x);

/* some other stuff that wasn't in any header */
void glob_watchdog(t_pd *dummy);

#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
}
#endif

#ifdef __cplusplus
#include<iostream>
template <class T> static T min(T a, T b) {return a<b?a:b;}
template <class T> static T max(T a, T b) {return a>b?a:b;}
template <class T> T clip(T a, T b, T c) {return min(max(a,b),c);}
void  oprintf(std::ostream &buf, const char *s, ...);
void voprintf(std::ostream &buf, const char *s, va_list args);
EXTERN std::ostringstream lost_posts;
#endif

#define L post("%s:%d in %s",__FILE__,__LINE__,__PRETTY_FUNCTION__);
#define LS(self) post("%s:%d in %s (self=%lx class=%s)",__FILE__,__LINE__,__PRETTY_FUNCTION__,(long)self, \
	((t_gobj *)self)->_class->name->name);

#define STACKSIZE 1024
struct t_call {
	t_pd *self;  /* receiver */
	t_symbol *s; /* selector */
	/* insert temporary profiling variables here */
};

EXTERN t_call pd_stack[STACKSIZE];
EXTERN int pd_stackn;

EXTERN int gstack_empty(); /* that's a completely different stack: see pd_pushsym,pd_popsym */

#endif /* __DESIRE_H */