Add the identifying header
[kugel-rb.git] / apps / plugins / pdbox / PDa / src / x_gui.c
blobc54fef948d09cb7fe4a5509ed419274426ccecb6
1 /* Copyright (c) 1997-2000 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. */
5 /* dialogs. LATER, deal with the situation where the object goes
6 away before the panel does... */
8 #include "m_pd.h"
9 #include <stdio.h>
10 #include <string.h>
11 #ifdef UNIX
12 #include <unistd.h>
13 #endif
15 /* --------------------- graphics responder ---------------- */
17 /* make one of these if you want to put up a dialog window but want to be
18 protected from getting deleted and then having the dialog call you back. In
19 this design the calling object doesn't have to keep the address of the dialog
20 window around; instead we keep a list of all open dialogs. Any object that
21 might have dialogs, when it is deleted, simply checks down the dialog window
22 list and breaks off any dialogs that might later have sent messages to it.
23 Only when the dialog window itself closes do we delete the gfxstub object. */
25 static t_class *gfxstub_class;
27 typedef struct _gfxstub
29 t_pd x_pd;
30 t_pd *x_owner;
31 void *x_key;
32 t_symbol *x_sym;
33 struct _gfxstub *x_next;
34 } t_gfxstub;
36 static t_gfxstub *gfxstub_list;
38 /* create a new one. the "key" is an address by which the owner
39 will identify it later; if the owner only wants one dialog, this
40 could just be a pointer to the owner itself. The string "cmd"
41 is a TK command to create the dialog, with "%s" embedded in
42 it so we can provide a name by which the GUI can send us back
43 messages; e.g., "pdtk_canvas_dofont %s 10". */
45 void gfxstub_new(t_pd *owner, void *key, const char *cmd)
47 char buf[MAXPDSTRING];
48 char namebuf[80];
49 t_gfxstub *x;
50 t_symbol *s;
51 /* if any exists with matching key, no need to make a
52 new one; just tell tk to send it front. */
53 for (x = gfxstub_list; x; x = x->x_next)
55 if (x->x_key == key)
57 sys_vgui("raise .gfxstub%x\n", x);
58 sys_vgui("focus .gfxstub%x\n", x);
59 return;
62 if (strlen(cmd) + 84 > MAXPDSTRING)
63 return;
64 x = (t_gfxstub *)pd_new(gfxstub_class);
65 sprintf(namebuf, ".gfxstub%x", (t_int)x);
67 s = gensym(namebuf);
68 pd_bind(&x->x_pd, s);
69 x->x_owner = owner;
70 x->x_sym = s;
71 x->x_key = key;
72 x->x_next = gfxstub_list;
73 gfxstub_list = x;
74 sprintf(buf, cmd, s->s_name);
75 sys_gui(buf);
78 static void gfxstub_offlist(t_gfxstub *x)
80 t_gfxstub *y1, *y2;
81 if (gfxstub_list == x)
82 gfxstub_list = x->x_next;
83 else for (y1 = gfxstub_list; y2 = y1->x_next; y1 = y2)
84 if (y2 == x)
86 y1->x_next = y2->x_next;
87 break;
91 /* if the owner disappears, we still may have to stay around until our
92 dialog window signs off. Anyway we can now tell the GUI to destroy the
93 window. */
94 void gfxstub_deleteforkey(void *key)
96 t_gfxstub *y;
97 int didit = 1;
98 while (didit)
100 didit = 0;
101 for (y = gfxstub_list; y; y = y->x_next)
103 if (y->x_key == key)
105 sys_vgui("destroy .gfxstub%x\n", y);
106 y->x_owner = 0;
107 gfxstub_offlist(y);
108 didit = 1;
109 break;
115 /* --------- pd messages for gfxstub (these come from the GUI) ---------- */
117 /* "cancel" to request that we close the dialog window. */
118 static void gfxstub_cancel(t_gfxstub *x)
120 gfxstub_deleteforkey(x->x_key);
123 /* "signoff" comes from the GUI to say the dialog window closed. */
124 static void gfxstub_signoff(t_gfxstub *x)
126 gfxstub_offlist(x);
127 pd_free(&x->x_pd);
130 static t_binbuf *gfxstub_binbuf;
132 /* a series of "data" messages rebuilds a scalar */
133 static void gfxstub_data(t_gfxstub *x, t_symbol *s, int argc, t_atom *argv)
135 if (!gfxstub_binbuf)
136 gfxstub_binbuf = binbuf_new();
137 binbuf_add(gfxstub_binbuf, argc, argv);
138 binbuf_addsemi(gfxstub_binbuf);
140 /* the "end" message terminates rebuilding the scalar */
141 static void gfxstub_end(t_gfxstub *x)
143 canvas_dataproperties((t_canvas *)x->x_owner,
144 (t_scalar *)x->x_key, gfxstub_binbuf);
145 binbuf_free(gfxstub_binbuf);
146 gfxstub_binbuf = 0;
149 /* anything else is a message from the dialog window to the owner;
150 just forward it. */
151 static void gfxstub_anything(t_gfxstub *x, t_symbol *s, int argc, t_atom *argv)
153 if (x->x_owner)
154 pd_typedmess(x->x_owner, s, argc, argv);
157 static void gfxstub_free(t_gfxstub *x)
159 pd_unbind(&x->x_pd, x->x_sym);
162 static void gfxstub_setup(void)
164 gfxstub_class = class_new(gensym("gfxstub"), (t_newmethod)gfxstub_new,
165 (t_method)gfxstub_free,
166 sizeof(t_gfxstub), CLASS_PD, 0);
167 class_addanything(gfxstub_class, gfxstub_anything);
168 class_addmethod(gfxstub_class, (t_method)gfxstub_signoff,
169 gensym("signoff"), 0);
170 class_addmethod(gfxstub_class, (t_method)gfxstub_data,
171 gensym("data"), A_GIMME, 0);
172 class_addmethod(gfxstub_class, (t_method)gfxstub_end,
173 gensym("end"), 0);
174 class_addmethod(gfxstub_class, (t_method)gfxstub_cancel,
175 gensym("cancel"), 0);
178 /* -------------------------- openpanel ------------------------------ */
180 static t_class *openpanel_class;
182 typedef struct _openpanel
184 t_object x_obj;
185 t_symbol *x_s;
186 } t_openpanel;
188 static void *openpanel_new(void)
190 char buf[50];
191 t_openpanel *x = (t_openpanel *)pd_new(openpanel_class);
192 sprintf(buf, "d%x", (t_int)x);
193 x->x_s = gensym(buf);
194 pd_bind(&x->x_obj.ob_pd, x->x_s);
195 outlet_new(&x->x_obj, &s_symbol);
196 return (x);
199 static void openpanel_bang(t_openpanel *x)
201 sys_vgui("pdtk_openpanel %s\n", x->x_s->s_name);
204 static void openpanel_symbol(t_openpanel *x, t_symbol *s)
206 outlet_symbol(x->x_obj.ob_outlet, s);
209 static void openpanel_free(t_openpanel *x)
211 pd_unbind(&x->x_obj.ob_pd, x->x_s);
214 static void openpanel_setup(void)
216 openpanel_class = class_new(gensym("openpanel"),
217 (t_newmethod)openpanel_new, (t_method)openpanel_free,
218 sizeof(t_openpanel), 0, A_DEFFLOAT, 0);
219 class_addbang(openpanel_class, openpanel_bang);
220 class_addsymbol(openpanel_class, openpanel_symbol);
223 /* -------------------------- savepanel ------------------------------ */
225 static t_class *savepanel_class;
227 typedef struct _savepanel
229 t_object x_obj;
230 t_symbol *x_s;
231 } t_savepanel;
233 static void *savepanel_new(void)
235 char buf[50];
236 t_savepanel *x = (t_savepanel *)pd_new(savepanel_class);
237 sprintf(buf, "d%x", (t_int)x);
238 x->x_s = gensym(buf);
239 pd_bind(&x->x_obj.ob_pd, x->x_s);
240 outlet_new(&x->x_obj, &s_symbol);
241 return (x);
244 static void savepanel_bang(t_savepanel *x)
246 sys_vgui("pdtk_savepanel %s\n", x->x_s->s_name);
249 static void savepanel_symbol(t_savepanel *x, t_symbol *s)
251 outlet_symbol(x->x_obj.ob_outlet, s);
254 static void savepanel_free(t_savepanel *x)
256 pd_unbind(&x->x_obj.ob_pd, x->x_s);
259 static void savepanel_setup(void)
261 savepanel_class = class_new(gensym("savepanel"),
262 (t_newmethod)savepanel_new, (t_method)savepanel_free,
263 sizeof(t_savepanel), 0, A_DEFFLOAT, 0);
264 class_addbang(savepanel_class, savepanel_bang);
265 class_addsymbol(savepanel_class, savepanel_symbol);
268 /* ---------------------- key and its relatives ------------------ */
270 static t_symbol *key_sym, *keyup_sym, *keyname_sym;
271 static t_class *key_class, *keyup_class, *keyname_class;
273 typedef struct _key
275 t_object x_obj;
276 } t_key;
278 static void *key_new( void)
280 t_key *x = (t_key *)pd_new(key_class);
281 outlet_new(&x->x_obj, &s_float);
282 pd_bind(&x->x_obj.ob_pd, key_sym);
283 return (x);
286 static void key_float(t_key *x, t_floatarg f)
288 outlet_float(x->x_obj.ob_outlet, f);
291 static void key_free(t_key *x)
293 pd_unbind(&x->x_obj.ob_pd, key_sym);
296 typedef struct _keyup
298 t_object x_obj;
299 } t_keyup;
301 static void *keyup_new( void)
303 t_keyup *x = (t_keyup *)pd_new(keyup_class);
304 outlet_new(&x->x_obj, &s_float);
305 pd_bind(&x->x_obj.ob_pd, keyup_sym);
306 return (x);
309 static void keyup_float(t_keyup *x, t_floatarg f)
311 outlet_float(x->x_obj.ob_outlet, f);
314 static void keyup_free(t_keyup *x)
316 pd_unbind(&x->x_obj.ob_pd, keyup_sym);
319 typedef struct _keyname
321 t_object x_obj;
322 t_outlet *x_outlet1;
323 t_outlet *x_outlet2;
324 } t_keyname;
326 static void *keyname_new( void)
328 t_keyname *x = (t_keyname *)pd_new(keyname_class);
329 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
330 x->x_outlet2 = outlet_new(&x->x_obj, &s_symbol);
331 pd_bind(&x->x_obj.ob_pd, keyname_sym);
332 return (x);
335 static void keyname_list(t_keyname *x, t_symbol *s, int ac, t_atom *av)
337 outlet_symbol(x->x_outlet2, atom_getsymbolarg(1, ac, av));
338 outlet_float(x->x_outlet1, atom_getfloatarg(0, ac, av));
341 static void keyname_free(t_keyname *x)
343 pd_unbind(&x->x_obj.ob_pd, keyname_sym);
346 static void key_setup(void)
348 key_class = class_new(gensym("key"),
349 (t_newmethod)key_new, (t_method)key_free,
350 sizeof(t_key), CLASS_NOINLET, 0);
351 class_addfloat(key_class, key_float);
352 key_sym = gensym("#key");
354 keyup_class = class_new(gensym("keyup"),
355 (t_newmethod)keyup_new, (t_method)keyup_free,
356 sizeof(t_keyup), CLASS_NOINLET, 0);
357 class_addfloat(keyup_class, keyup_float);
358 keyup_sym = gensym("#keyup");
359 class_sethelpsymbol(keyup_class, gensym("key"));
361 keyname_class = class_new(gensym("keyname"),
362 (t_newmethod)keyname_new, (t_method)keyname_free,
363 sizeof(t_keyname), CLASS_NOINLET, 0);
364 class_addlist(keyname_class, keyname_list);
365 keyname_sym = gensym("#keyname");
366 class_sethelpsymbol(keyname_class, gensym("key"));
369 /* -------------------------- setup routine ------------------------------ */
371 void x_gui_setup(void)
373 gfxstub_setup();
374 openpanel_setup();
375 savepanel_setup();
376 key_setup();