A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
1/* Copyright (c) 1997-1999 Miller Puckette.
2* For information on usage and redistribution, and for a DISCLAIMER OF ALL
3* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
4
5/* changes by Thomas Musil IEM KUG Graz Austria 2001 */
6/* the methods for calling the gui-objects from menu are implemented */
7/* all changes are labeled with iemlib */
8
9#include "m_pd.h"
10#include "m_imp.h"
11#include "s_stuff.h"
12#include "t_tk.h"
13#include "g_canvas.h"
14
15#ifdef ROCKBOX
16#include "plugin.h"
17#include "../../pdbox.h"
18#else /* ROCKBOX */
19#include <stdlib.h>
20#include <stdio.h>
21#include <string.h>
22#include <math.h>
23#endif /* ROCKBOX */
24
25static t_class *text_class;
26static t_class *message_class;
27static t_class *gatom_class;
28static void text_vis(t_gobj *z, t_glist *glist, int vis);
29static void text_displace(t_gobj *z, t_glist *glist,
30 int dx, int dy);
31static void text_getrect(t_gobj *z, t_glist *glist,
32 int *xp1, int *yp1, int *xp2, int *yp2);
33
34void canvas_startmotion(t_canvas *x);
35t_widgetbehavior text_widgetbehavior;
36
37/* ----------------- the "text" object. ------------------ */
38
39 /* add a "text" object (comment) to a glist. While this one goes for any glist,
40 the other 3 below are for canvases only. (why?) This is called
41 without args if invoked from the GUI; otherwise at least x and y
42 are provided. */
43
44void glist_text(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
45{
46 t_text *x = (t_text *)pd_new(text_class);
47 t_atom at;
48
49#ifdef ROCKBOX
50 (void) s;
51#endif
52
53 x->te_width = 0; /* don't know it yet. */
54 x->te_type = T_TEXT;
55 x->te_binbuf = binbuf_new();
56 if (argc > 1)
57 {
58 x->te_xpix = atom_getfloatarg(0, argc, argv);
59 x->te_ypix = atom_getfloatarg(1, argc, argv);
60 if (argc > 2) binbuf_restore(x->te_binbuf, argc-2, argv+2);
61 else
62 {
63 SETSYMBOL(&at, gensym("comment"));
64 binbuf_restore(x->te_binbuf, 1, &at);
65 }
66 glist_add(gl, &x->te_g);
67 }
68 else
69 {
70 int xpix, ypix;
71 pd_vmess((t_pd *)glist_getcanvas(gl), gensym("editmode"), "i", 1);
72 SETSYMBOL(&at, gensym("comment"));
73 glist_noselect(gl);
74 glist_getnextxy(gl, &xpix, &ypix);
75 x->te_xpix = glist_pixelstox(gl, xpix-3);
76 x->te_ypix = glist_pixelstoy(gl, ypix-3);
77 binbuf_restore(x->te_binbuf, 1, &at);
78 glist_add(gl, &x->te_g);
79 glist_noselect(gl);
80 glist_select(gl, &x->te_g);
81 /* it would be nice to "activate" here, but then the second,
82 "put-me-down" click changes the text selection, which is quite
83 irritating, so I took this back out. It's OK in messages
84 and objects though since there's no text in them at menu
85 creation. */
86 /* gobj_activate(&x->te_g, gl, 1); */
87 canvas_startmotion(glist_getcanvas(gl));
88 }
89}
90
91/* ----------------- the "object" object. ------------------ */
92
93extern t_pd *newest;
94void canvas_getargs(int *argcp, t_atom **argvp);
95
96static void canvas_objtext(t_glist *gl, int xpix, int ypix, int selected,
97 t_binbuf *b)
98{
99 t_text *x;
100 int argc;
101 t_atom *argv;
102 newest = 0;
103 canvas_setcurrent((t_canvas *)gl);
104 canvas_getargs(&argc, &argv);
105 binbuf_eval(b, &pd_objectmaker, argc, argv);
106 if (binbuf_getnatom(b))
107 {
108 if (!newest)
109 {
110 binbuf_print(b);
111 post("... couldn't create");
112 x = 0;
113 }
114 else if (!(x = pd_checkobject(newest)))
115 {
116 binbuf_print(b);
117 post("... didn't return a patchable object");
118 }
119 }
120 else x = 0;
121 if (!x)
122 {
123
124 /* LATER make the color reflect this */
125 x = (t_text *)pd_new(text_class);
126 }
127 x->te_binbuf = b;
128 x->te_xpix = xpix;
129 x->te_ypix = ypix;
130 x->te_width = 0;
131 x->te_type = T_OBJECT;
132 glist_add(gl, &x->te_g);
133 if (selected)
134 {
135 /* this is called if we've been created from the menu. */
136 glist_select(gl, &x->te_g);
137 gobj_activate(&x->te_g, gl, 1);
138 }
139 if (pd_class(&x->ob_pd) == vinlet_class)
140 canvas_resortinlets(glist_getcanvas(gl));
141 if (pd_class(&x->ob_pd) == voutlet_class)
142 canvas_resortoutlets(glist_getcanvas(gl));
143 canvas_unsetcurrent((t_canvas *)gl);
144}
145
146 /* object creation routine. These are called without any arguments if
147 they're invoked from the
148 gui; when pasting or restoring from a file, we get at least x and y. */
149
150void canvas_obj(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
151{
152#ifdef ROCKBOX
153 (void) s;
154#else
155 t_text *x;
156#endif
157
158 if (argc >= 2)
159 {
160 t_binbuf *b = binbuf_new();
161 binbuf_restore(b, argc-2, argv+2);
162 canvas_objtext(gl, atom_getintarg(0, argc, argv),
163 atom_getintarg(1, argc, argv), 0, b);
164 }
165 else
166 {
167 t_binbuf *b = binbuf_new();
168 int xpix, ypix;
169 pd_vmess(&gl->gl_pd, gensym("editmode"), "i", 1);
170 glist_noselect(gl);
171 glist_getnextxy(gl, &xpix, &ypix);
172 canvas_objtext(gl, xpix, ypix, 1, b);
173 canvas_startmotion(glist_getcanvas(gl));
174 }
175}
176
177/* make an object box for an object that's already there. */
178
179/* iemlib */
180void canvas_iemguis(t_glist *gl, t_symbol *guiobjname)
181{
182 t_atom at;
183 t_binbuf *b = binbuf_new();
184 int xpix, ypix;
185
186 pd_vmess(&gl->gl_pd, gensym("editmode"), "i", 1);
187 glist_noselect(gl);
188 SETSYMBOL(&at, guiobjname);
189 binbuf_restore(b, 1, &at);
190 glist_getnextxy(gl, &xpix, &ypix);
191 canvas_objtext(gl, xpix, ypix, 1, b);
192 canvas_startmotion(glist_getcanvas(gl));
193}
194
195void canvas_bng(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
196{
197#ifdef ROCKBOX
198 (void) s;
199 (void) argc;
200 (void) argv;
201#endif
202 canvas_iemguis(gl, gensym("bng"));
203}
204
205void canvas_toggle(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
206{
207#ifdef ROCKBOX
208 (void) s;
209 (void) argc;
210 (void) argv;
211#endif
212 canvas_iemguis(gl, gensym("tgl"));
213}
214
215void canvas_vslider(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
216{
217#ifdef ROCKBOX
218 (void) s;
219 (void) argc;
220 (void) argv;
221#endif
222 canvas_iemguis(gl, gensym("vsl"));
223}
224
225void canvas_hslider(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
226{
227#ifdef ROCKBOX
228 (void) s;
229 (void) argc;
230 (void) argv;
231#endif
232 canvas_iemguis(gl, gensym("hsl"));
233}
234
235void canvas_hdial(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
236{
237#ifdef ROCKBOX
238 (void) s;
239 (void) argc;
240 (void) argv;
241#endif
242 canvas_iemguis(gl, gensym("hdl"));
243}
244
245void canvas_vdial(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
246{
247#ifdef ROCKBOX
248 (void) s;
249 (void) argc;
250 (void) argv;
251#endif
252 canvas_iemguis(gl, gensym("vdl"));
253}
254
255void canvas_hradio(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
256{
257#ifdef ROCKBOX
258 (void) s;
259 (void) argc;
260 (void) argv;
261#endif
262 canvas_iemguis(gl, gensym("hradio"));
263}
264
265void canvas_vradio(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
266{
267#ifdef ROCKBOX
268 (void) s;
269 (void) argc;
270 (void) argv;
271#endif
272 canvas_iemguis(gl, gensym("vradio"));
273}
274
275void canvas_vumeter(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
276{
277#ifdef ROCKBOX
278 (void) s;
279 (void) argc;
280 (void) argv;
281#endif
282 canvas_iemguis(gl, gensym("vu"));
283}
284
285void canvas_mycnv(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
286{
287#ifdef ROCKBOX
288 (void) s;
289 (void) argc;
290 (void) argv;
291#endif
292 canvas_iemguis(gl, gensym("cnv"));
293}
294
295void canvas_numbox(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
296{
297#ifdef ROCKBOX
298 (void) s;
299 (void) argc;
300 (void) argv;
301#endif
302 canvas_iemguis(gl, gensym("nbx"));
303}
304
305/* iemlib */
306
307void canvas_objfor(t_glist *gl, t_text *x, int argc, t_atom *argv)
308{
309 x->te_width = 0; /* don't know it yet. */
310 x->te_type = T_OBJECT;
311 x->te_binbuf = binbuf_new();
312 x->te_xpix = atom_getfloatarg(0, argc, argv);
313 x->te_ypix = atom_getfloatarg(1, argc, argv);
314 if (argc > 2) binbuf_restore(x->te_binbuf, argc-2, argv+2);
315 glist_add(gl, &x->te_g);
316}
317
318/* ---------------------- the "message" text item ------------------------ */
319
320typedef struct _messresponder
321{
322 t_pd mr_pd;
323 t_outlet *mr_outlet;
324} t_messresponder;
325
326typedef struct _message
327{
328 t_text m_text;
329 t_messresponder m_messresponder;
330 t_glist *m_glist;
331 t_clock *m_clock;
332} t_message;
333
334static t_class *message_class, *messresponder_class;
335
336static void messresponder_bang(t_messresponder *x)
337{
338 outlet_bang(x->mr_outlet);
339}
340
341static void messresponder_float(t_messresponder *x, t_float f)
342{
343 outlet_float(x->mr_outlet, f);
344}
345
346static void messresponder_symbol(t_messresponder *x, t_symbol *s)
347{
348 outlet_symbol(x->mr_outlet, s);
349}
350
351static void messresponder_list(t_messresponder *x,
352 t_symbol *s, int argc, t_atom *argv)
353{
354 outlet_list(x->mr_outlet, s, argc, argv);
355}
356
357static void messresponder_anything(t_messresponder *x,
358 t_symbol *s, int argc, t_atom *argv)
359{
360 outlet_anything(x->mr_outlet, s, argc, argv);
361}
362
363static void message_bang(t_message *x)
364{
365 binbuf_eval(x->m_text.te_binbuf, &x->m_messresponder.mr_pd, 0, 0);
366}
367
368static void message_float(t_message *x, t_float f)
369{
370 t_atom at;
371 SETFLOAT(&at, f);
372 binbuf_eval(x->m_text.te_binbuf, &x->m_messresponder.mr_pd, 1, &at);
373}
374
375static void message_symbol(t_message *x, t_symbol *s)
376{
377 t_atom at;
378 SETSYMBOL(&at, s);
379 binbuf_eval(x->m_text.te_binbuf, &x->m_messresponder.mr_pd, 1, &at);
380}
381
382static void message_list(t_message *x, t_symbol *s, int argc, t_atom *argv)
383{
384#ifdef ROCKBOX
385 (void) s;
386#endif
387 binbuf_eval(x->m_text.te_binbuf, &x->m_messresponder.mr_pd, argc, argv);
388}
389
390static void message_set(t_message *x, t_symbol *s, int argc, t_atom *argv)
391{
392#ifdef ROCKBOX
393 (void) s;
394#endif
395 binbuf_clear(x->m_text.te_binbuf);
396 binbuf_add(x->m_text.te_binbuf, argc, argv);
397 glist_retext(x->m_glist, &x->m_text);
398}
399
400static void message_add2(t_message *x, t_symbol *s, int argc, t_atom *argv)
401{
402#ifdef ROCKBOX
403 (void) s;
404#endif
405 binbuf_add(x->m_text.te_binbuf, argc, argv);
406 glist_retext(x->m_glist, &x->m_text);
407}
408
409static void message_add(t_message *x, t_symbol *s, int argc, t_atom *argv)
410{
411#ifdef ROCKBOX
412 (void) s;
413#endif
414 binbuf_add(x->m_text.te_binbuf, argc, argv);
415 binbuf_addsemi(x->m_text.te_binbuf);
416 glist_retext(x->m_glist, &x->m_text);
417}
418
419static void message_click(t_message *x,
420 t_floatarg xpos, t_floatarg ypos, t_floatarg shift,
421 t_floatarg ctrl, t_floatarg alt)
422{
423#ifdef ROCKBOX
424 (void) xpos;
425 (void) ypos;
426 (void) shift;
427 (void) ctrl;
428 (void) alt;
429#endif
430 message_float(x, 0);
431 if (glist_isvisible(x->m_glist))
432 {
433#ifndef ROCKBOX
434 t_rtext *y = glist_findrtext(x->m_glist, &x->m_text);
435 sys_vgui(".x%x.c itemconfigure %sR -width 5\n",
436 glist_getcanvas(x->m_glist), rtext_gettag(y));
437#endif
438 clock_delay(x->m_clock, 120);
439 }
440}
441
442static void message_tick(t_message *x)
443{
444 if (glist_isvisible(x->m_glist))
445 {
446#ifndef ROCKBOX
447 t_rtext *y = glist_findrtext(x->m_glist, &x->m_text);
448 sys_vgui(".x%x.c itemconfigure %sR -width 1\n",
449 glist_getcanvas(x->m_glist), rtext_gettag(y));
450#endif
451 }
452}
453
454static void message_free(t_message *x)
455{
456 clock_free(x->m_clock);
457}
458
459void canvas_msg(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
460{
461#ifdef ROCKBOX
462 (void) s;
463#endif
464 t_message *x = (t_message *)pd_new(message_class);
465 x->m_messresponder.mr_pd = messresponder_class;
466 x->m_messresponder.mr_outlet = outlet_new(&x->m_text, &s_float);
467 x->m_text.te_width = 0; /* don't know it yet. */
468 x->m_text.te_type = T_MESSAGE;
469 x->m_text.te_binbuf = binbuf_new();
470 x->m_glist = gl;
471 x->m_clock = clock_new(x, (t_method)message_tick);
472 if (argc > 1)
473 {
474 x->m_text.te_xpix = atom_getfloatarg(0, argc, argv);
475 x->m_text.te_ypix = atom_getfloatarg(1, argc, argv);
476 if (argc > 2) binbuf_restore(x->m_text.te_binbuf, argc-2, argv+2);
477 glist_add(gl, &x->m_text.te_g);
478 }
479 else
480 {
481 int xpix, ypix;
482 pd_vmess(&gl->gl_pd, gensym("editmode"), "i", 1);
483 glist_noselect(gl);
484 glist_getnextxy(gl, &xpix, &ypix);
485 x->m_text.te_xpix = xpix-3;
486 x->m_text.te_ypix = ypix-3;
487 glist_add(gl, &x->m_text.te_g);
488 glist_noselect(gl);
489 glist_select(gl, &x->m_text.te_g);
490 gobj_activate(&x->m_text.te_g, gl, 1);
491 canvas_startmotion(glist_getcanvas(gl));
492 }
493}
494
495/* ---------------------- the "atom" text item ------------------------ */
496
497#define ATOMBUFSIZE 40
498#define ATOM_LABELLEFT 0
499#define ATOM_LABELRIGHT 1
500#define ATOM_LABELUP 2
501#define ATOM_LABELDOWN 3
502
503typedef struct _gatom
504{
505 t_text a_text;
506 t_atom a_atom; /* this holds the value and the type */
507 t_glist *a_glist; /* owning glist */
508 t_float a_toggle; /* value to toggle to */
509 t_float a_draghi; /* high end of drag range */
510 t_float a_draglo; /* low end of drag range */
511 t_symbol *a_label; /* symbol to show as label next to box */
512 t_symbol *a_symfrom; /* "receive" name -- bind ourselvs to this */
513 t_symbol *a_symto; /* "send" name -- send to this on output */
514 char a_buf[ATOMBUFSIZE];/* string buffer for typing */
515 char a_shift; /* was shift key down when dragging started? */
516 char a_wherelabel; /* 0-3 for left, right, above, below */
517 t_symbol *a_expanded_to; /* a_symto after $0, $1, ... expansion */
518} t_gatom;
519
520 /* prepend "-" as necessary to avoid empty strings, so we can
521 use them in Pd messages. A more complete solution would be
522 to introduce some quoting mechanism; but then we'd be much more
523 complicated. */
524static t_symbol *gatom_escapit(t_symbol *s)
525{
526 if (!*s->s_name)
527 return (gensym("-"));
528 else if (*s->s_name == '-')
529 {
530 char shmo[100];
531 shmo[0] = '-';
532 strncpy(shmo+1, s->s_name, 99);
533 shmo[99] = 0;
534 return (gensym(shmo));
535 }
536 else return (iemgui_dollar2raute(s));
537}
538
539 /* undo previous operation: strip leading "-" if found. */
540static t_symbol *gatom_unescapit(t_symbol *s)
541{
542 if (*s->s_name == '-')
543 return (gensym(s->s_name+1));
544 else return (iemgui_raute2dollar(s));
545}
546
547#if 0 /* ??? */
548 /* expand leading $0, $1, etc. in the symbol */
549static t_symbol *gatom_realizedollar(t_gatom *x, t_symbol *s)
550{
551 return (canvas_realizedollar(x->a_glist, s));
552}
553#endif
554
555static void gatom_retext(t_gatom *x, int senditup)
556{
557 binbuf_clear(x->a_text.te_binbuf);
558 binbuf_add(x->a_text.te_binbuf, 1, &x->a_atom);
559 if (senditup)
560 glist_retext(x->a_glist, &x->a_text);
561}
562
563static void gatom_set(t_gatom *x, t_symbol *s, int argc, t_atom *argv)
564{
565 t_atom oldatom = x->a_atom;
566 int senditup = 0;
567#ifdef ROCKBOX
568 (void) s;
569#endif
570 if (!argc) return;
571 if (x->a_atom.a_type == A_FLOAT)
572 x->a_atom.a_w.w_float = atom_getfloat(argv),
573 senditup = (x->a_atom.a_w.w_float != oldatom.a_w.w_float);
574 else if (x->a_atom.a_type == A_SYMBOL)
575 x->a_atom.a_w.w_symbol = atom_getsymbol(argv),
576 senditup = (x->a_atom.a_w.w_symbol != oldatom.a_w.w_symbol);
577 gatom_retext(x, senditup);
578 x->a_buf[0] = 0;
579}
580
581static void gatom_bang(t_gatom *x)
582{
583 if (x->a_atom.a_type == A_FLOAT)
584 {
585 if (x->a_text.te_outlet)
586 outlet_float(x->a_text.te_outlet, x->a_atom.a_w.w_float);
587 if (*x->a_expanded_to->s_name && x->a_expanded_to->s_thing)
588 {
589 if (x->a_symto == x->a_symfrom)
590 pd_error(x,
591 "%s: atom with same send/receive name (infinite loop)",
592 x->a_symto->s_name);
593 else pd_float(x->a_expanded_to->s_thing, x->a_atom.a_w.w_float);
594 }
595 }
596 else if (x->a_atom.a_type == A_SYMBOL)
597 {
598 if (x->a_text.te_outlet)
599 outlet_symbol(x->a_text.te_outlet, x->a_atom.a_w.w_symbol);
600 if (*x->a_symto->s_name && x->a_expanded_to->s_thing)
601 {
602 if (x->a_symto == x->a_symfrom)
603 pd_error(x,
604 "%s: atom with same send/receive name (infinite loop)",
605 x->a_symto->s_name);
606 else pd_symbol(x->a_expanded_to->s_thing, x->a_atom.a_w.w_symbol);
607 }
608 }
609}
610
611static void gatom_float(t_gatom *x, t_float f)
612{
613 t_atom at;
614 SETFLOAT(&at, f);
615 gatom_set(x, 0, 1, &at);
616 gatom_bang(x);
617}
618
619static void gatom_clipfloat(t_gatom *x, t_float f)
620{
621 if (x->a_draglo != 0 || x->a_draghi != 0)
622 {
623 if (f < x->a_draglo)
624 f = x->a_draglo;
625 if (f > x->a_draghi)
626 f = x->a_draghi;
627 }
628 gatom_float(x, f);
629}
630
631static void gatom_symbol(t_gatom *x, t_symbol *s)
632{
633 t_atom at;
634 SETSYMBOL(&at, s);
635 gatom_set(x, 0, 1, &at);
636 gatom_bang(x);
637}
638
639static void gatom_motion(void *z, t_floatarg dx, t_floatarg dy)
640{
641#ifdef ROCKBOX
642 (void) dx;
643#endif
644 t_gatom *x = (t_gatom *)z;
645 if (dy == 0) return;
646 if (x->a_atom.a_type == A_FLOAT)
647 {
648 if (x->a_shift)
649 {
650 double nval = x->a_atom.a_w.w_float - 0.01 * dy;
651 double trunc = 0.01 * (floor(100. * nval + 0.5));
652 if (trunc < nval + 0.0001 && trunc > nval - 0.0001) nval = trunc;
653 gatom_clipfloat(x, nval);
654 }
655 else
656 {
657 double nval = x->a_atom.a_w.w_float - dy;
658 double trunc = 0.01 * (floor(100. * nval + 0.5));
659 if (trunc < nval + 0.0001 && trunc > nval - 0.0001) nval = trunc;
660 trunc = floor(nval + 0.5);
661 if (trunc < nval + 0.001 && trunc > nval - 0.001) nval = trunc;
662 gatom_clipfloat(x, nval);
663 }
664 }
665}
666
667static void gatom_key(void *z, t_floatarg f)
668{
669 t_gatom *x = (t_gatom *)z;
670 int c = f;
671 int len = strlen(x->a_buf);
672 t_atom at;
673 char sbuf[ATOMBUFSIZE + 4];
674 if (c == 0)
675 {
676 /* we're being notified that no more keys will come for this grab */
677 if (x->a_buf[0])
678 gatom_retext(x, 1);
679 return;
680 }
681 else if (c == ' ') return;
682 else if (c == '\b')
683 {
684 if (len > 0)
685 x->a_buf[len-1] = 0;
686 goto redraw;
687 }
688 else if (c == '\n')
689 {
690 if (x->a_atom.a_type == A_FLOAT)
691 x->a_atom.a_w.w_float = atof(x->a_buf);
692 else if (x->a_atom.a_type == A_SYMBOL)
693 x->a_atom.a_w.w_symbol = gensym(x->a_buf);
694 else bug("gatom_key");
695 gatom_bang(x);
696 gatom_retext(x, 1);
697 x->a_buf[0] = 0;
698 }
699 else if (len < (ATOMBUFSIZE-1))
700 {
701 /* for numbers, only let reasonable characters through */
702 if ((x->a_atom.a_type == A_SYMBOL) ||
703 ((c >= '0' && c <= '9') || c == '.' || c == '-'
704 || c == 'e' || c == 'E'))
705 {
706 x->a_buf[len] = c;
707 x->a_buf[len+1] = 0;
708 goto redraw;
709 }
710 }
711 return;
712redraw:
713 /* LATER figure out how to avoid creating all these symbols! */
714#ifdef ROCKBOX
715 snprintf(sbuf, sizeof(sbuf), "%s...", x->a_buf);
716#else /* ROCKBOX */
717 sprintf(sbuf, "%s...", x->a_buf);
718#endif
719 SETSYMBOL(&at, gensym(sbuf));
720 binbuf_clear(x->a_text.te_binbuf);
721 binbuf_add(x->a_text.te_binbuf, 1, &at);
722 glist_retext(x->a_glist, &x->a_text);
723}
724
725static void gatom_click(t_gatom *x,
726 t_floatarg xpos, t_floatarg ypos, t_floatarg shift, t_floatarg ctrl,
727 t_floatarg alt)
728{
729#ifdef ROCKBOX
730 (void) ctrl;
731#endif
732 if (x->a_text.te_width == 1)
733 {
734 if (x->a_atom.a_type == A_FLOAT)
735 gatom_float(x, (x->a_atom.a_w.w_float == 0));
736 }
737 else
738 {
739 if (alt)
740 {
741 if (x->a_atom.a_type != A_FLOAT) return;
742 if (x->a_atom.a_w.w_float != 0)
743 {
744 x->a_toggle = x->a_atom.a_w.w_float;
745 gatom_float(x, 0);
746 return;
747 }
748 else gatom_float(x, x->a_toggle);
749 }
750 x->a_shift = shift;
751 x->a_buf[0] = 0;
752 glist_grab(x->a_glist, &x->a_text.te_g, gatom_motion, gatom_key,
753 xpos, ypos);
754 }
755}
756
757 /* message back from dialog window */
758static void gatom_param(t_gatom *x, t_symbol *sel, int argc, t_atom *argv)
759{
760 t_float width = atom_getfloatarg(0, argc, argv);
761 t_float draglo = atom_getfloatarg(1, argc, argv);
762 t_float draghi = atom_getfloatarg(2, argc, argv);
763 t_symbol *label = gatom_unescapit(atom_getsymbolarg(3, argc, argv));
764 t_float wherelabel = atom_getfloatarg(4, argc, argv);
765 t_symbol *symfrom = gatom_unescapit(atom_getsymbolarg(5, argc, argv));
766 t_symbol *symto = gatom_unescapit(atom_getsymbolarg(6, argc, argv));
767
768#ifdef ROCKBOX
769 (void) sel;
770#endif
771
772 gobj_vis(&x->a_text.te_g, x->a_glist, 0);
773 if (!*symfrom->s_name && *x->a_symfrom->s_name)
774 inlet_new(&x->a_text, &x->a_text.te_pd, 0, 0);
775 else if (*symfrom->s_name && !*x->a_symfrom->s_name && x->a_text.te_inlet)
776 {
777 canvas_deletelinesforio(x->a_glist, &x->a_text,
778 x->a_text.te_inlet, 0);
779 inlet_free(x->a_text.te_inlet);
780 }
781 if (!*symto->s_name && *x->a_symto->s_name)
782 outlet_new(&x->a_text, 0);
783 else if (*symto->s_name && !*x->a_symto->s_name && x->a_text.te_outlet)
784 {
785 canvas_deletelinesforio(x->a_glist, &x->a_text,
786 0, x->a_text.te_outlet);
787 outlet_free(x->a_text.te_outlet);
788 }
789 if (draglo >= draghi)
790 draglo = draghi = 0;
791 x->a_draglo = draglo;
792 x->a_draghi = draghi;
793 if (width < 0)
794 width = 4;
795 else if (width > 80)
796 width = 80;
797 x->a_text.te_width = width;
798 x->a_wherelabel = ((int)wherelabel & 3);
799 x->a_label = label;
800 if (*x->a_symfrom->s_name)
801 pd_unbind(&x->a_text.te_pd,
802 canvas_realizedollar(x->a_glist, x->a_symfrom));
803 x->a_symfrom = symfrom;
804 if (*x->a_symfrom->s_name)
805 pd_bind(&x->a_text.te_pd,
806 canvas_realizedollar(x->a_glist, x->a_symfrom));
807 x->a_symto = symto;
808 x->a_expanded_to = canvas_realizedollar(x->a_glist, x->a_symto);
809 gobj_vis(&x->a_text.te_g, x->a_glist, 1);
810
811 /* glist_retext(x->a_glist, &x->a_text); */
812}
813
814 /* ---------------- gatom-specific widget functions --------------- */
815static void gatom_getwherelabel(t_gatom *x, t_glist *glist, int *xp, int *yp)
816{
817 int x1, y1, x2, y2 /*, width, height */;
818 text_getrect(&x->a_text.te_g, glist, &x1, &y1, &x2, &y2);
819 /* width = x2 - x1; */
820 /* height = y2 - y1; */
821 if (x->a_wherelabel == ATOM_LABELLEFT)
822 {
823 *xp = x1 - 3 -
824 strlen(canvas_realizedollar(x->a_glist, x->a_label)->s_name) *
825#ifdef ROCKBOX
826 8;
827#else
828 sys_fontwidth(glist_getfont(glist));
829#endif
830 *yp = y1 + 2;
831 }
832 else if (x->a_wherelabel == ATOM_LABELRIGHT)
833 {
834 *xp = x2 + 2;
835 *yp = y1 + 2;
836 }
837 else if (x->a_wherelabel == ATOM_LABELUP)
838 {
839 *xp = x1 - 1;
840#ifdef ROCKBOX
841 *yp = y1 - 1 - 10;
842#else
843 *yp = y1 - 1 - sys_fontheight(glist_getfont(glist));;
844#endif
845 }
846 else
847 {
848 *xp = x1 - 1;
849 *yp = y2 + 3;
850 }
851}
852
853static void gatom_displace(t_gobj *z, t_glist *glist,
854 int dx, int dy)
855{
856#ifndef ROCKBOX
857 t_gatom *x = (t_gatom*)z;
858#endif
859 text_displace(z, glist, dx, dy);
860#ifndef ROCKBOX
861 sys_vgui(".x%x.c move %x.l %d %d\n", glist_getcanvas(glist),
862 x, dx, dy);
863#endif
864}
865
866static void gatom_vis(t_gobj *z, t_glist *glist, int vis)
867{
868 t_gatom *x = (t_gatom*)z;
869 text_vis(z, glist, vis);
870 if (*x->a_label->s_name)
871 {
872 if (vis)
873 {
874 int x1, y1;
875 gatom_getwherelabel(x, glist, &x1, &y1);
876#ifndef ROCKBOX
877 sys_vgui("pdtk_text_new .x%x.c %x.l %f %f {%s} %d %s\n",
878 glist_getcanvas(glist), x,
879 (double)x1, (double)y1,
880 canvas_realizedollar(x->a_glist, x->a_label)->s_name,
881 sys_hostfontsize(glist_getfont(glist)),
882 "black");
883#endif
884 }
885#ifndef ROCKBOX
886 else sys_vgui(".x%x.c delete %x.l\n", glist_getcanvas(glist), x);
887#endif
888 }
889}
890
891void canvas_atom(t_glist *gl, t_atomtype type,
892 t_symbol *s, int argc, t_atom *argv)
893{
894 t_gatom *x = (t_gatom *)pd_new(gatom_class);
895 t_atom at;
896
897#ifdef ROCKBOX
898 (void) s;
899#endif
900
901 x->a_text.te_width = 0; /* don't know it yet. */
902 x->a_text.te_type = T_ATOM;
903 x->a_text.te_binbuf = binbuf_new();
904 x->a_glist = gl;
905 x->a_atom.a_type = type;
906 x->a_toggle = 1;
907 x->a_draglo = 0;
908 x->a_draghi = 0;
909 x->a_wherelabel = 0;
910 x->a_label = &s_;
911 x->a_symfrom = &s_;
912 x->a_symto = x->a_expanded_to = &s_;
913 if (type == A_FLOAT)
914 {
915 x->a_atom.a_w.w_float = 0;
916 x->a_text.te_width = 5;
917 SETFLOAT(&at, 0);
918 }
919 else
920 {
921 x->a_atom.a_w.w_symbol = &s_symbol;
922 x->a_text.te_width = 10;
923 SETSYMBOL(&at, &s_symbol);
924 }
925 binbuf_add(x->a_text.te_binbuf, 1, &at);
926 if (argc > 1)
927 /* create from file. x, y, width, low-range, high-range, flags,
928 label, receive-name, send-name */
929 {
930 x->a_text.te_xpix = atom_getfloatarg(0, argc, argv);
931 x->a_text.te_ypix = atom_getfloatarg(1, argc, argv);
932 x->a_text.te_width = atom_getintarg(2, argc, argv);
933 /* sanity check because some very old patches have trash in this
934 field... remove this in 2003 or so: */
935 if (x->a_text.te_width < 0 || x->a_text.te_width > 500)
936 x->a_text.te_width = 4;
937 x->a_draglo = atom_getfloatarg(3, argc, argv);
938 x->a_draghi = atom_getfloatarg(4, argc, argv);
939 x->a_wherelabel = (((int)atom_getfloatarg(5, argc, argv)) & 3);
940 x->a_label = gatom_unescapit(atom_getsymbolarg(6, argc, argv));
941 x->a_symfrom = gatom_unescapit(atom_getsymbolarg(7, argc, argv));
942 if (*x->a_symfrom->s_name)
943 pd_bind(&x->a_text.te_pd,
944 canvas_realizedollar(x->a_glist, x->a_symfrom));
945
946 x->a_symto = gatom_unescapit(atom_getsymbolarg(8, argc, argv));
947 x->a_expanded_to = canvas_realizedollar(x->a_glist, x->a_symto);
948 if (x->a_symto == &s_)
949 outlet_new(&x->a_text,
950 x->a_atom.a_type == A_FLOAT ? &s_float: &s_symbol);
951 if (x->a_symfrom == &s_)
952 inlet_new(&x->a_text, &x->a_text.te_pd, 0, 0);
953 glist_add(gl, &x->a_text.te_g);
954 }
955 else
956 {
957 int xpix, ypix;
958 outlet_new(&x->a_text,
959 x->a_atom.a_type == A_FLOAT ? &s_float: &s_symbol);
960 inlet_new(&x->a_text, &x->a_text.te_pd, 0, 0);
961 pd_vmess(&gl->gl_pd, gensym("editmode"), "i", 1);
962 glist_noselect(gl);
963 glist_getnextxy(gl, &xpix, &ypix);
964 x->a_text.te_xpix = xpix;
965 x->a_text.te_ypix = ypix;
966 glist_add(gl, &x->a_text.te_g);
967 glist_noselect(gl);
968 glist_select(gl, &x->a_text.te_g);
969 canvas_startmotion(glist_getcanvas(gl));
970 }
971}
972
973void canvas_floatatom(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
974{
975 canvas_atom(gl, A_FLOAT, s, argc, argv);
976}
977
978void canvas_symbolatom(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
979{
980 canvas_atom(gl, A_SYMBOL, s, argc, argv);
981}
982
983static void gatom_free(t_gatom *x)
984{
985 if (*x->a_symfrom->s_name)
986 pd_unbind(&x->a_text.te_pd,
987 canvas_realizedollar(x->a_glist, x->a_symfrom));
988#ifndef ROCKBOX
989 gfxstub_deleteforkey(x);
990#endif
991}
992
993static void gatom_properties(t_gobj *z, t_glist *owner)
994{
995#ifdef ROCKBOX
996 (void) z;
997 (void) owner;
998#else /* ROCKBOX */
999 t_gatom *x = (t_gatom *)z;
1000 char buf[200];
1001 sprintf(buf, "pdtk_gatom_dialog %%s %d %g %g %d %s %s %s\n",
1002 x->a_text.te_width, x->a_draglo, x->a_draghi,
1003 x->a_wherelabel, gatom_escapit(x->a_label)->s_name,
1004 gatom_escapit(x->a_symfrom)->s_name,
1005 gatom_escapit(x->a_symto)->s_name);
1006 gfxstub_new(&x->a_text.te_pd, x, buf);
1007#endif /* ROCKBOX */
1008}
1009
1010
1011/* -------------------- widget behavior for text objects ------------ */
1012
1013static void text_getrect(t_gobj *z, t_glist *glist,
1014 int *xp1, int *yp1, int *xp2, int *yp2)
1015{
1016 t_text *x = (t_text *)z;
1017 int width, height, iscomment = (x->te_type == T_TEXT);
1018 float x1, y1, x2, y2;
1019
1020 /* for number boxes, we know width and height a priori, and should
1021 report them here so that graphs can get swelled to fit. */
1022
1023 if (x->te_type == T_ATOM && x->te_width > 0)
1024 {
1025#ifdef ROCKBOX
1026 int fontwidth = 8, fontheight = 10;
1027#else
1028 int font = glist_getfont(glist);
1029 int fontwidth = sys_fontwidth(font), fontheight = sys_fontheight(font);
1030#endif
1031 width = (x->te_width > 0 ? x->te_width : 6) * fontwidth + 2;
1032 height = fontheight + 1; /* borrowed from TMARGIN, etc, in g_rtext.c */
1033 }
1034 /* if we're invisible we don't know our size so we just lie about
1035 it. This is called on invisible boxes to establish order of inlets
1036 and possibly other reasons.
1037 To find out if the box is visible we can't just check the "vis"
1038 flag because we might be within the vis() routine and not have set
1039 that yet. So we check directly whether the "rtext" list has been
1040 built. LATER reconsider when "vis" flag should be on and off? */
1041
1042 else if (glist->gl_editor && glist->gl_editor->e_rtext)
1043 {
1044 t_rtext *y = glist_findrtext(glist, x);
1045 width = rtext_width(y);
1046 height = rtext_height(y) - (iscomment << 1);
1047 }
1048 else width = height = 10;
1049 x1 = text_xpix(x, glist);
1050 y1 = text_ypix(x, glist);
1051 x2 = x1 + width;
1052 y2 = y1 + height;
1053 y1 += iscomment;
1054 *xp1 = x1;
1055 *yp1 = y1;
1056 *xp2 = x2;
1057 *yp2 = y2;
1058}
1059
1060static void text_displace(t_gobj *z, t_glist *glist,
1061 int dx, int dy)
1062{
1063 t_text *x = (t_text *)z;
1064 x->te_xpix += dx;
1065 x->te_ypix += dy;
1066 if (glist_isvisible(glist))
1067 {
1068 t_rtext *y = glist_findrtext(glist, x);
1069 rtext_displace(y, dx, dy);
1070 text_drawborder(x, glist, rtext_gettag(y),
1071 rtext_width(y), rtext_height(y), 0);
1072 canvas_fixlinesfor(glist_getcanvas(glist), x);
1073 }
1074}
1075
1076static void text_select(t_gobj *z, t_glist *glist, int state)
1077{
1078 t_text *x = (t_text *)z;
1079 t_rtext *y = glist_findrtext(glist, x);
1080 rtext_select(y, state);
1081 if (glist_isvisible(glist) && text_shouldvis(x, glist))
1082#ifdef ROCKBOX
1083 {
1084 }
1085#else /* ROCKBOX */
1086 sys_vgui(".x%x.c itemconfigure %sR -fill %s\n", glist,
1087 rtext_gettag(y), (state? "blue" : "black"));
1088#endif /* ROCKBOX */
1089}
1090
1091static void text_activate(t_gobj *z, t_glist *glist, int state)
1092{
1093 t_text *x = (t_text *)z;
1094 t_rtext *y = glist_findrtext(glist, x);
1095 if (z->g_pd != gatom_class) rtext_activate(y, state);
1096}
1097
1098static void text_delete(t_gobj *z, t_glist *glist)
1099{
1100 t_text *x = (t_text *)z;
1101 canvas_deletelinesfor(glist, x);
1102}
1103
1104 /* return true if the text box should be drawn.
1105 We don't show object boxes inside graphs. */
1106int text_shouldvis(t_text *x, t_glist *glist)
1107{
1108 return (glist->gl_havewindow ||
1109 (x->te_pd != canvas_class && x->te_pd->c_wb != &text_widgetbehavior) ||
1110 (x->te_pd == canvas_class && (((t_glist *)x)->gl_isgraph)));
1111}
1112
1113static void text_vis(t_gobj *z, t_glist *glist, int vis)
1114{
1115 t_text *x = (t_text *)z;
1116 if (vis)
1117 {
1118 if (text_shouldvis(x, glist))
1119 {
1120 t_rtext *y = glist_findrtext(glist, x);
1121 if (x->te_type == T_ATOM)
1122 glist_retext(glist, x);
1123 text_drawborder(x, glist, rtext_gettag(y),
1124 rtext_width(y), rtext_height(y), 1);
1125 rtext_draw(y);
1126 }
1127 }
1128 else
1129 {
1130 t_rtext *y = glist_findrtext(glist, x);
1131 if (text_shouldvis(x, glist))
1132 {
1133 text_eraseborder(x, glist, rtext_gettag(y));
1134 rtext_erase(y);
1135 }
1136 }
1137}
1138
1139static int text_click(t_gobj *z, struct _glist *glist,
1140 int xpix, int ypix, int shift, int alt, int dbl, int doit)
1141{
1142#ifdef ROCKBOX
1143 (void) glist;
1144 (void) dbl;
1145#endif
1146 t_text *x = (t_text *)z;
1147 if (x->te_type == T_OBJECT)
1148 {
1149 t_symbol *clicksym = gensym("click");
1150 if (zgetfn(&x->te_pd, clicksym))
1151 {
1152 if (doit)
1153 pd_vmess(&x->te_pd, clicksym, "fffff",
1154 (double)xpix, (double)ypix,
1155 (double)shift, 0, (double)alt);
1156 return (1);
1157 }
1158 else return (0);
1159 }
1160 else if (x->te_type == T_ATOM)
1161 {
1162 if (doit)
1163 gatom_click((t_gatom *)x, (t_floatarg)xpix, (t_floatarg)ypix,
1164 (t_floatarg)shift, 0, (t_floatarg)alt);
1165 return (1);
1166 }
1167 else if (x->te_type == T_MESSAGE)
1168 {
1169 if (doit)
1170 message_click((t_message *)x, (t_floatarg)xpix, (t_floatarg)ypix,
1171 (t_floatarg)shift, 0, (t_floatarg)alt);
1172 return (1);
1173 }
1174 else return (0);
1175}
1176
1177void text_save(t_gobj *z, t_binbuf *b)
1178{
1179 t_text *x = (t_text *)z;
1180 if (x->te_type == T_OBJECT)
1181 {
1182 /* if we have a "saveto" method, and if we don't happen to be
1183 a canvas that's an abstraction, the saveto method does the work */
1184 if (zgetfn(&x->te_pd, gensym("saveto")) &&
1185 !((pd_class(&x->te_pd) == canvas_class) &&
1186 (canvas_isabstraction((t_canvas *)x)
1187 || canvas_istable((t_canvas *)x))))
1188 {
1189 mess1(&x->te_pd, gensym("saveto"), b);
1190 binbuf_addv(b, "ssii", gensym("#X"), gensym("restore"),
1191 (t_int)x->te_xpix, (t_int)x->te_ypix);
1192 }
1193 else /* otherwise just save the text */
1194 {
1195 binbuf_addv(b, "ssii", gensym("#X"), gensym("obj"),
1196 (t_int)x->te_xpix, (t_int)x->te_ypix);
1197 }
1198 binbuf_addbinbuf(b, x->te_binbuf);
1199 binbuf_addv(b, ";");
1200 }
1201 else if (x->te_type == T_MESSAGE)
1202 {
1203 binbuf_addv(b, "ssii", gensym("#X"), gensym("msg"),
1204 (t_int)x->te_xpix, (t_int)x->te_ypix);
1205 binbuf_addbinbuf(b, x->te_binbuf);
1206 binbuf_addv(b, ";");
1207 }
1208 else if (x->te_type == T_ATOM)
1209 {
1210 t_atomtype t = ((t_gatom *)x)->a_atom.a_type;
1211 t_symbol *sel = (t == A_SYMBOL ? gensym("symbolatom") :
1212 (t == A_FLOAT ? gensym("floatatom") : gensym("intatom")));
1213 t_symbol *label = gatom_escapit(((t_gatom *)x)->a_label);
1214 t_symbol *symfrom = gatom_escapit(((t_gatom *)x)->a_symfrom);
1215 t_symbol *symto = gatom_escapit(((t_gatom *)x)->a_symto);
1216 binbuf_addv(b, "ssiiifffsss", gensym("#X"), sel,
1217 (t_int)x->te_xpix, (t_int)x->te_ypix, (t_int)x->te_width,
1218 (double)((t_gatom *)x)->a_draglo,
1219 (double)((t_gatom *)x)->a_draghi,
1220 (double)((t_gatom *)x)->a_wherelabel,
1221 label, symfrom, symto);
1222 binbuf_addv(b, ";");
1223 }
1224 else
1225 {
1226 binbuf_addv(b, "ssii", gensym("#X"), gensym("text"),
1227 (t_int)x->te_xpix, (t_int)x->te_ypix);
1228 binbuf_addbinbuf(b, x->te_binbuf);
1229 binbuf_addv(b, ";");
1230 }
1231}
1232
1233 /* this one is for everyone but "gatoms"; it's imposed in m_class.c */
1234t_widgetbehavior text_widgetbehavior =
1235{
1236 text_getrect,
1237 text_displace,
1238 text_select,
1239 text_activate,
1240 text_delete,
1241 text_vis,
1242 text_click,
1243};
1244
1245static t_widgetbehavior gatom_widgetbehavior =
1246{
1247 text_getrect,
1248 gatom_displace,
1249 text_select,
1250 text_activate,
1251 text_delete,
1252 gatom_vis,
1253 text_click,
1254};
1255
1256/* -------------------- the "text" class ------------ */
1257
1258#ifdef MACOSX
1259#define EXTRAPIX 2
1260#else
1261#define EXTRAPIX 1
1262#endif
1263
1264 /* draw inlets and outlets for a text object or for a graph. */
1265void glist_drawiofor(t_glist *glist, t_object *ob, int firsttime,
1266 char *tag, int x1, int y1, int x2, int y2)
1267{
1268#ifdef ROCKBOX
1269 (void) glist;
1270 (void) ob;
1271 (void) firsttime;
1272 (void) tag;
1273 (void) x1;
1274 (void) y1;
1275 (void) x2;
1276 (void) y2;
1277#else /* ROCKBOX */
1278 int n = obj_noutlets(ob), i;
1279 int width = x2 - x1;
1280 int nplus = (n == 1 ? 1 : n-1);
1281
1282 for (i = 0; i < n; i++)
1283 {
1284 int onset = x1 + (width - IOWIDTH) * i / nplus;
1285 if (firsttime)
1286 sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %so%d\n",
1287 glist_getcanvas(glist),
1288 onset, y2 - 1,
1289 onset + IOWIDTH, y2,
1290 tag, i);
1291 else
1292 sys_vgui(".x%x.c coords %so%d %d %d %d %d\n",
1293 glist_getcanvas(glist), tag, i,
1294 onset, y2 - 1,
1295 onset + IOWIDTH, y2);
1296 }
1297
1298 n = obj_ninlets(ob);
1299 nplus = (n == 1 ? 1 : n-1);
1300 for (i = 0; i < n; i++)
1301 {
1302 int onset = x1 + (width - IOWIDTH) * i / nplus;
1303 if (firsttime)
1304 sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %si%d\n",
1305 glist_getcanvas(glist),
1306 onset, y1,
1307 onset + IOWIDTH, y1 + EXTRAPIX,
1308 tag, i);
1309 else
1310 sys_vgui(".x%x.c coords %si%d %d %d %d %d\n",
1311 glist_getcanvas(glist), tag, i,
1312 onset, y1,
1313 onset + IOWIDTH, y1 + EXTRAPIX);
1314 }
1315#endif /* ROCKBOX */
1316}
1317
1318void text_drawborder(t_text *x, t_glist *glist,
1319 char *tag, int width2, int height2, int firsttime)
1320{
1321 t_object *ob;
1322 int x1, y1, x2, y2 /* , width, height */;
1323
1324#ifdef ROCKBOX
1325 (void) width2;
1326 (void) height2;
1327#endif
1328
1329 text_getrect(&x->te_g, glist, &x1, &y1, &x2, &y2);
1330 /* width = x2 - x1; */
1331 /* height = y2 - y1; */
1332 if (x->te_type == T_OBJECT)
1333 {
1334#ifndef ROCKBOX
1335 if (firsttime)
1336 sys_vgui(".x%x.c create line\
1337 %d %d %d %d %d %d %d %d %d %d -tags %sR\n",
1338 glist_getcanvas(glist),
1339 x1, y1, x2, y1, x2, y2, x1, y2, x1, y1, tag);
1340 else
1341 sys_vgui(".x%x.c coords %sR\
1342 %d %d %d %d %d %d %d %d %d %d\n",
1343 glist_getcanvas(glist), tag,
1344 x1, y1, x2, y1, x2, y2, x1, y2, x1, y1);
1345#endif
1346 }
1347 else if (x->te_type == T_MESSAGE)
1348 {
1349#ifndef ROCKBOX
1350 if (firsttime)
1351 sys_vgui(".x%x.c create line\
1352 %d %d %d %d %d %d %d %d %d %d %d %d %d %d -tags %sR\n",
1353 glist_getcanvas(glist),
1354 x1, y1, x2+4, y1, x2, y1+4, x2, y2-4, x2+4, y2,
1355 x1, y2, x1, y1,
1356 tag);
1357 else
1358 sys_vgui(".x%x.c coords %sR\
1359 %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
1360 glist_getcanvas(glist), tag,
1361 x1, y1, x2+4, y1, x2, y1+4, x2, y2-4, x2+4, y2,
1362 x1, y2, x1, y1);
1363#endif
1364 }
1365 else if (x->te_type == T_ATOM)
1366 {
1367#ifndef ROCKBOX
1368 if (firsttime)
1369 sys_vgui(".x%x.c create line\
1370 %d %d %d %d %d %d %d %d %d %d %d %d -tags %sR\n",
1371 glist_getcanvas(glist),
1372 x1, y1, x2-4, y1, x2, y1+4, x2, y2, x1, y2, x1, y1,
1373 tag);
1374 else
1375 sys_vgui(".x%x.c coords %sR\
1376 %d %d %d %d %d %d %d %d %d %d %d %d\n",
1377 glist_getcanvas(glist), tag,
1378 x1, y1, x2-4, y1, x2, y1+4, x2, y2, x1, y2, x1, y1);
1379#endif
1380 }
1381 /* draw inlets/outlets */
1382
1383 if ((ob = pd_checkobject(&x->te_pd)))
1384 glist_drawiofor(glist, ob, firsttime, tag, x1, y1, x2, y2);
1385}
1386
1387void glist_eraseiofor(t_glist *glist, t_object *ob, char *tag)
1388{
1389 int i, n;
1390#ifdef ROCKBOX
1391 (void) glist;
1392 (void) tag;
1393#endif
1394 n = obj_noutlets(ob);
1395 for (i = 0; i < n; i++)
1396#ifdef ROCKBOX
1397 ;
1398#else /* ROCKBOX */
1399 sys_vgui(".x%x.c delete %so%d\n",
1400 glist_getcanvas(glist), tag, i);
1401#endif /* ROCKBOX */
1402 n = obj_ninlets(ob);
1403 for (i = 0; i < n; i++)
1404#ifdef ROCKBOX
1405 ;
1406#else /* ROCKBOX */
1407 sys_vgui(".x%x.c delete %si%d\n",
1408 glist_getcanvas(glist), tag, i);
1409#endif /* ROCKBOX */
1410}
1411
1412void text_eraseborder(t_text *x, t_glist *glist, char *tag)
1413{
1414 if (x->te_type == T_TEXT) return;
1415#ifndef ROCKBOX
1416 sys_vgui(".x%x.c delete %sR\n",
1417 glist_getcanvas(glist), tag);
1418#endif
1419 glist_eraseiofor(glist, x, tag);
1420}
1421
1422 /* change text; if T_OBJECT, remake it. LATER we'll have an undo buffer
1423 which should be filled in here before making the change. */
1424
1425void text_setto(t_text *x, t_glist *glist, char *buf, int bufsize)
1426{
1427 if (x->te_type == T_OBJECT)
1428 {
1429 t_binbuf *b = binbuf_new();
1430 int natom1, natom2;
1431 t_atom *vec1, *vec2;
1432 binbuf_text(b, buf, bufsize);
1433 natom1 = binbuf_getnatom(x->te_binbuf);
1434 vec1 = binbuf_getvec(x->te_binbuf);
1435 natom2 = binbuf_getnatom(b);
1436 vec2 = binbuf_getvec(b);
1437 /* special case: if pd args change just pass the message on. */
1438 if (natom1 >= 1 && natom2 >= 1 && vec1[0].a_type == A_SYMBOL
1439 && !strcmp(vec1[0].a_w.w_symbol->s_name, "pd") &&
1440 vec2[0].a_type == A_SYMBOL
1441 && !strcmp(vec2[0].a_w.w_symbol->s_name, "pd"))
1442 {
1443 typedmess(&x->te_pd, gensym("rename"), natom2-1, vec2+1);
1444 binbuf_free(x->te_binbuf);
1445 x->te_binbuf = b;
1446 }
1447 else /* normally, just destroy the old one and make a new one. */
1448 {
1449 int xwas = x->te_xpix, ywas = x->te_ypix;
1450 glist_delete(glist, &x->te_g);
1451 canvas_objtext(glist, xwas, ywas, 0, b);
1452 /* if it's an abstraction loadbang it here */
1453 if (newest && pd_class(newest) == canvas_class)
1454 canvas_loadbang((t_canvas *)newest);
1455 canvas_restoreconnections(glist_getcanvas(glist));
1456 }
1457 /* if we made a new "pd" or changed a window name,
1458 update window list */
1459 if (natom2 >= 1 && vec2[0].a_type == A_SYMBOL
1460 && !strcmp(vec2[0].a_w.w_symbol->s_name, "pd"))
1461 canvas_updatewindowlist();
1462 }
1463 else binbuf_text(x->te_binbuf, buf, bufsize);
1464}
1465
1466void g_text_setup(void)
1467{
1468 text_class = class_new(gensym("text"), 0, 0, sizeof(t_text),
1469 CLASS_NOINLET | CLASS_PATCHABLE, 0);
1470
1471 message_class = class_new(gensym("message"), 0, (t_method)message_free,
1472 sizeof(t_message), CLASS_PATCHABLE, 0);
1473 class_addbang(message_class, message_bang);
1474 class_addfloat(message_class, message_float);
1475 class_addsymbol(message_class, message_symbol);
1476 class_addlist(message_class, message_list);
1477 class_addanything(message_class, message_list);
1478
1479 class_addmethod(message_class, (t_method)message_click, gensym("click"),
1480 A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
1481 class_addmethod(message_class, (t_method)message_set, gensym("set"),
1482 A_GIMME, 0);
1483 class_addmethod(message_class, (t_method)message_add, gensym("add"),
1484 A_GIMME, 0);
1485 class_addmethod(message_class, (t_method)message_add2, gensym("add2"),
1486 A_GIMME, 0);
1487
1488 messresponder_class = class_new(gensym("messresponder"), 0, 0,
1489 sizeof(t_text), CLASS_PD, 0);
1490 class_addbang(messresponder_class, messresponder_bang);
1491 class_addfloat(messresponder_class, (t_method) messresponder_float);
1492 class_addsymbol(messresponder_class, messresponder_symbol);
1493 class_addlist(messresponder_class, messresponder_list);
1494 class_addanything(messresponder_class, messresponder_anything);
1495
1496 gatom_class = class_new(gensym("gatom"), 0, (t_method)gatom_free,
1497 sizeof(t_gatom), CLASS_NOINLET | CLASS_PATCHABLE, 0);
1498 class_addbang(gatom_class, gatom_bang);
1499 class_addfloat(gatom_class, gatom_float);
1500 class_addsymbol(gatom_class, gatom_symbol);
1501 class_addmethod(gatom_class, (t_method)gatom_set, gensym("set"),
1502 A_GIMME, 0);
1503 class_addmethod(gatom_class, (t_method)gatom_click, gensym("click"),
1504 A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
1505 class_addmethod(gatom_class, (t_method)gatom_param, gensym("param"),
1506 A_GIMME, 0);
1507 class_setwidget(gatom_class, &gatom_widgetbehavior);
1508 class_setpropertiesfn(gatom_class, gatom_properties);
1509}
1510