1 /*
2 widgets.cpp:
3
4 Copyright (C) 2002 Gabriel Maldonado
5
6 This file is part of Csound.
7
8 The Csound Library is free software; you can redistribute it
9 and/or modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
12
13 Csound is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with Csound; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 02110-1301 USA
22 */
23
24 #if defined(WIN32)
25 # include <FL/Fl_Output.H>
26 #endif
27 #ifndef _MSC_VER
28 # include <unistd.h>
29 #endif
30 #if !defined(_MSC_VER)
31 #include <unistd.h>
32 #endif
33 #include <csound.h>
34 #include "widglobals.h"
35 #include <FL/x.H>
36
37 Fl_Font FONT_TABLE[] = { FL_HELVETICA, FL_HELVETICA,
38 FL_HELVETICA_BOLD, FL_HELVETICA_ITALIC,
39 FL_HELVETICA_BOLD_ITALIC, FL_COURIER,
40 FL_COURIER_BOLD, FL_COURIER_ITALIC,
41 FL_COURIER_BOLD_ITALIC, FL_TIMES,
42 FL_TIMES_BOLD, FL_TIMES_ITALIC,
43 FL_TIMES_BOLD_ITALIC, FL_SYMBOL,
44 FL_SCREEN, FL_SCREEN_BOLD,
45 FL_ZAPF_DINGBATS };
46
47 Fl_Align ALIGN_TABLE[] = { FL_ALIGN_BOTTOM, FL_ALIGN_CENTER,
48 FL_ALIGN_TOP, FL_ALIGN_BOTTOM,
49 FL_ALIGN_LEFT, FL_ALIGN_RIGHT,
50 FL_ALIGN_TOP_LEFT, FL_ALIGN_TOP_RIGHT,
51 FL_ALIGN_BOTTOM_LEFT, FL_ALIGN_BOTTOM_RIGHT };
52
53 Fl_Boxtype BOX_TABLE[] = { FL_FLAT_BOX, FL_FLAT_BOX,
54 FL_UP_BOX, FL_DOWN_BOX,
55 FL_THIN_UP_BOX, FL_THIN_DOWN_BOX,
56 FL_ENGRAVED_BOX, FL_EMBOSSED_BOX,
57 FL_BORDER_BOX, _FL_SHADOW_BOX,
58 _FL_ROUNDED_BOX, _FL_RSHADOW_BOX,
59 _FL_RFLAT_BOX, _FL_ROUND_UP_BOX,
60 _FL_ROUND_DOWN_BOX, _FL_DIAMOND_UP_BOX,
61 _FL_DIAMOND_DOWN_BOX,_FL_OVAL_BOX,
62 _FL_OSHADOW_BOX, _FL_OFLAT_BOX};
63
widget_init(CSOUND * csound)64 void widget_init(CSOUND *csound)
65 {
66 WIDGET_GLOBALS *widgetGlobals =
67 (WIDGET_GLOBALS *) csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
68 if (widgetGlobals == NULL) {
69 csound->CreateGlobalVariable(csound, "WIDGET_GLOBALS",
70 sizeof(WIDGET_GLOBALS));
71 widgetGlobals =
72 (WIDGET_GLOBALS *) csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
73
74 //csound->widgetGlobals = new WIDGET_GLOBALS;
75 //csound->Calloc(csound, sizeof(WIDGET_GLOBALS));
76 // widgetGlobals->indrag = 0;
77 // widgetGlobals->sldrag = 0;
78 // widgetGlobals->stack_count) = 0;
79
80 widgetGlobals->FLcontrol_iheight = 15;
81 widgetGlobals->FLroller_iheight = 18;
82 widgetGlobals->FLcontrol_iwidth = 400;
83 widgetGlobals->FLroller_iwidth = 150;
84 widgetGlobals->FLvalue_iwidth = 100;
85
86 widgetGlobals->FLcolor = -1;
87 widgetGlobals->FLcolor2 = -1;
88 // below was commented out, why? VL 24-04-08
89 widgetGlobals->FLtext_size = 0;
90 widgetGlobals->FLtext_color = -1;
91 widgetGlobals->FLtext_font = -1;
92 // below was commented out, why? VL 24-04-08
93 widgetGlobals->FLtext_align = 0;
94
95 widgetGlobals->FL_ix = 10;
96 widgetGlobals->FL_iy = 10;
97 widgetGlobals->currentSnapGroup = 0;
98 widgetGlobals->last_KEY=0;
99 widgetGlobals->isKeyDown=0;
100 }
101 }
102
103 extern void graphs_reset(CSOUND *csound);
104
widget_reset(CSOUND * csound,void * pp)105 int widget_reset(CSOUND *csound, void *pp)
106 {
107 (void) pp;
108 WIDGET_GLOBALS *widgetGlobals =
109 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
110 if (widgetGlobals != NULL) {
111 widgetGlobals->AddrSetValue.~vector<ADDR_SET_VALUE>();
112 widgetGlobals->AddrStack.~vector<ADDR_STACK>();
113 widgetGlobals->allocatedStrings.~vector<char*>();
114 widgetGlobals->fl_windows.~vector<PANELS>();
115 csound->DestroyGlobalVariable(csound, "WIDGET_GLOBALS");
116 }
117 graphs_reset(csound);
118 return OK;
119 }
120
121 #ifndef NO_FLTK_THREADS
122 extern "C" {
123 /* called by sensevents() once in every control period */
evt_callback(CSOUND * csound,widgetsGlobals_t * p)124 static void evt_callback(CSOUND *csound, widgetsGlobals_t *p)
125 {
126 /* flush any pending real time events */
127 if (UNLIKELY(p->eventQueue != NULL)) {
128 csound->LockMutex(p->mutex_);
129 while (p->eventQueue != NULL) {
130 rtEvt_t *ep = p->eventQueue;
131 p->eventQueue = ep->nxt;
132 ep->evt.pinstance = NULL;
133 csound->UnlockMutex(p->mutex_);
134 csound->insert_score_event_at_sample(csound, &(ep->evt),
135 csound->GetCurrentTimeSamples(csound));
136 free(ep);
137 csound->LockMutex(p->mutex_);
138 }
139 csound->UnlockMutex(p->mutex_);
140 }
141 /* if all windows have been closed, terminate performance */
142 if (UNLIKELY(p->exit_now)) {
143 EVTBLK e;
144 memset(&e, 0, sizeof(EVTBLK));
145 e.opcod = 'e';
146 csound->insert_score_event_at_sample(csound, &e,
147 csound->GetCurrentTimeSamples(csound));
148 }
149 }
150 } // extern "C"
151 #endif // NO_FLTK_THREADS
152
153 // ---- IV - Aug 23 2002 ---- included file: Fl_linux_stubs.cpp
154
155 /*
156 * this is a file used in the linux distribution to be able to use
157 * the DirectCsound 5.1 widget code by Gabriel Maldonado on linux
158 * systems.
159 *
160 * This code has been written by Nicola Bernardini (nicb@centrotemporeale.it)
161 * mostly based on ideas by Dave Phillips (dlphip@bright.net)
162 */
163
164 extern "C" {
ButtonSched(CSOUND * csound,MYFLT * args[],int numargs)165 void ButtonSched(CSOUND *csound, MYFLT *args[], int numargs)
166 { /* based on code by rasmus */
167 #ifndef NO_FLTK_THREADS
168 widgetsGlobals_t *p;
169 /* this is still not fully thread safe... */
170 /* hope that no global variable is created just while this fn is called */
171 p = (widgetsGlobals_t*) csound->QueryGlobalVariable(csound,
172 "_widgets_globals");
173 if (p != NULL) {
174 rtEvt_t *evt;
175 int i;
176
177 /* Create the new event */
178 evt = (rtEvt_t*) malloc(sizeof(rtEvt_t));
179 evt->nxt = NULL;
180 evt->evt.pinstance = NULL;
181 evt->evt.strarg = NULL; evt->evt.scnt = 0;
182 evt->evt.opcod = (char) *args[0];
183 if (evt->evt.opcod == '\0')
184 evt->evt.opcod = 'i';
185 evt->evt.pcnt = numargs - 1;
186 evt->evt.p[1] = evt->evt.p[2] = evt->evt.p[3] = MYFLT(0.0);
187 for (i = 1; i < numargs; i++)
188 evt->evt.p[i] = *args[i];
189 if (evt->evt.p[2] < MYFLT(0.0))
190 evt->evt.p[2] = MYFLT(0.0);
191 /* queue event for insertion by main Csound thread */
192 csound->LockMutex(p->mutex_);
193 if (p->eventQueue == NULL)
194 p->eventQueue = evt;
195 else {
196 rtEvt_t *ep = p->eventQueue;
197 while (ep->nxt != NULL)
198 ep = ep->nxt;
199 ep->nxt = evt;
200 }
201 csound->UnlockMutex(p->mutex_);
202 }
203 else
204 #endif // NO_FLTK_THREADS
205 {
206 EVTBLK e;
207 int i;
208 /* Create the new event */
209 e.strarg = NULL; e.scnt = 0;
210 e.opcod = (char) *args[0];
211 if (e.opcod == '\0')
212 e.opcod = 'i';
213 e.pcnt = numargs - 1;
214 e.p[1] = e.p[2] = e.p[3] = MYFLT(0.0);
215 for (i = 1; i < numargs; i++)
216 e.p[i] = *args[i];
217 if (e.p[2] < MYFLT(0.0))
218 e.p[2] = MYFLT(0.0);
219 e.pinstance = NULL;
220 csound->insert_score_event_at_sample(csound, &e,
221 csound->GetCurrentTimeSamples(csound));
222 }
223 }
224 }
225
226 // ---- IV - Aug 23 2002 ---- included file: Fl_Knob.cxx
227
228 // generated by Fast Light User Interface Designer (fluid) version 2.00
229
Fl_Knob(CSOUND * cs,int xx,int yy,int ww,int hh,const char * l)230 Fl_Knob::Fl_Knob(CSOUND *cs, int xx,int yy,int ww,int hh,const char *l)
231 : Fl_Valuator(xx,yy,ww,hh,l)
232 {
233 csound = cs;
234 a1 = 35;
235 a2 = 325;
236 _type = DOTLIN;
237 _percent = 0.3f;
238 _scaleticks = 10;
239 }
240
~Fl_Knob(void)241 Fl_Knob::~Fl_Knob(void)
242 {
243 }
244
draw(void)245 void Fl_Knob::draw(void)
246 {
247 int ox,oy,ww,hh,side;
248 unsigned char rr,gg,bb;
249
250 ox = x();
251 oy = y();
252 ww = w();
253 hh = h();
254 draw_label();
255 fl_clip(ox,oy,ww,hh);
256 if (ww > hh) {
257 side = hh;
258 ox = ox + (ww - side) / 2;
259 }
260 else {
261 side = ww;
262 oy = oy + (hh - side) / 2;
263 }
264 side = w() > h () ? hh:ww;
265 int dam = damage();
266 if (dam & FL_DAMAGE_ALL) {
267 int col = parent()->color();
268 fl_color(col);
269 fl_rectf(ox,oy,side,side);
270 Fl::get_color((Fl_Color)col,rr,gg,bb);
271 shadow(-60,rr,gg,bb);
272 fl_pie(ox+9,oy+9,side-12,side-12,0,360);
273 draw_scale(ox,oy,side);
274 col = color();
275 Fl::get_color((Fl_Color)col,rr,gg,bb);
276 shadow(15,rr,gg,bb);
277 fl_pie(ox+6,oy+6,side-12,side-12,40,80);
278 shadow(30,rr,gg,bb);
279 fl_pie(ox+6,oy+6,side-12,side-12,80,220);
280 shadow(-15,rr,gg,bb);
281 fl_pie(ox+6,oy+6,side-12,side-12,220,260);
282 shadow(-30,rr,gg,bb);
283 fl_pie(ox+6,oy+6,side-12,side-12,260,400);
284 fl_color(FL_BLACK);
285 fl_arc(ox+6,oy+6,side-11,side-11,0,360);
286 fl_color(col);
287 fl_pie(ox+10,oy+10,side-20,side-20,0,360);
288 }
289 else {
290 fl_color(color());
291 fl_pie(ox+10,oy+10,side-20,side-20,0,360);
292 }
293 Fl::get_color((Fl_Color)color(),rr,gg,bb);
294 shadow(10,rr,gg,bb);
295 fl_pie(ox+10,oy+10,side-20,side-20,110,150);
296 fl_pie(ox+10,oy+10,side-20,side-20,290,330);
297 shadow(17,rr,gg,bb);
298 fl_pie(ox+10,oy+10,side-20,side-20,120,140);
299 fl_pie(ox+10,oy+10,side-20,side-20,300,320);
300 shadow(25,rr,gg,bb);
301 fl_pie(ox+10,oy+10,side-20,side-20,127,133);
302 fl_pie(ox+10,oy+10,side-20,side-20,307,313);
303 draw_cursor(ox,oy,side);
304 fl_pop_clip();
305 }
306
handle(int event)307 int Fl_Knob::handle(int event)
308 {
309 int ox,oy,ww,hh;
310
311 ox = x() + 10; oy = y() + 10;
312 ww = w() - 20;
313 hh = h() - 20;
314 switch (event) {
315 case FL_PUSH:
316 handle_push();
317 return 1; // CHECKME ***JPff added this; is that right?***
318 case FL_DRAG:
319 {
320 int mx = Fl::event_x()-ox-ww/2;
321 int my = Fl::event_y()-oy-hh/2;
322 if (!mx && !my) return 1;
323 double angle = 270-atan2((float)-my, (float)mx)*180.0/PI;
324 double oldangle = (a2-a1)*(value()-minimum())/(maximum()-minimum()) + a1;
325 while (angle < oldangle-180) angle += 360.0;
326 while (angle > oldangle+180) angle -= 360.0;
327 double val;
328 if ((a1<a2) ? (angle <= a1) : (angle >= a1)) {
329 val = minimum();
330 }
331 else if ((a1<a2) ? (angle >= a2) : (angle <= a2)) {
332 val = maximum();
333 }
334 else {
335 val = minimum() + (maximum()-minimum())*(angle-a1)/(a2-a1);
336 }
337 handle_drag(clamp(round(val)));
338 }
339 return 1;
340 case FL_RELEASE:
341 handle_release();
342 return 1;
343 default:
344 return 0;
345 }
346 return 0;
347 }
348
type(int ty)349 void Fl_Knob::type(int ty)
350 {
351 _type = ty;
352 }
353
shadow(const int offs,const uchar r,uchar g,uchar b)354 void Fl_Knob::shadow(const int offs,const uchar r,uchar g,uchar b)
355 {
356 int rr,gg,bb;
357
358 rr = r + offs;
359 rr = rr > 255 ? 255 : rr;
360 rr = rr < 0 ? 0:rr;
361 gg = g + offs;
362 gg = gg > 255 ? 255 : gg;
363 gg = gg < 0 ? 0 :gg ;
364 bb = b + offs;
365 bb = bb > 255 ? 255 : bb;
366 bb = bb < 0 ? 0 : bb;
367 fl_color((uchar)rr,(uchar)gg,(uchar)bb);
368 }
369
draw_scale(const int ox,const int oy,const int side)370 void Fl_Knob::draw_scale(const int ox,const int oy,const int side)
371 {
372 float x1,y1,x2,y2,rds,cx,cy,ca,sa;
373
374 rds = side * 0.5f;
375 cx = ox + side * 0.5f;
376 cy = oy + side * 0.5f;
377 if (!(_type & DOTLOG_3)) {
378 if (_scaleticks == 0) return;
379 double a_step = (10.0*PI/6.0) / _scaleticks;
380 double a_orig = -(PI/3.0);
381 for (int a = 0; a <= _scaleticks; a++) {
382 double na = a_orig + a * a_step;
383 ca = cos(na);
384 sa = sin(na);
385 x1 = cx + rds * ca;
386 y1 = cy - rds * sa;
387 x2 = cx + (rds-6) * ca;
388 y2 = cy - (rds-6) * sa;
389 fl_color(FL_BLACK);
390 fl_line((int)x1,(int)y1,(int)x2,(int)y2);
391 fl_color(FL_WHITE);
392 if (sa*ca >=0)
393 fl_line((int)x1+1,(int)y1+1,(int)x2+1,(int)y2+1);
394 else
395 fl_line((int)x1+1,(int)y1-1,(int)x2+1,(int)y2-1);
396 }
397 }
398 else {
399 int nb_dec = (_type & DOTLOG_3);
400 for (int k = 0; k < nb_dec; k++) {
401 double a_step = (10.0*PI/6.0) / nb_dec;
402 double a_orig = -(PI/3.0) + k * a_step;
403 for (int a = (k) ? 2:1; a <= 10; ) {
404 double na = a_orig + log10((double)a) * a_step;
405 ca = cos(na);
406 sa = sin(na);
407 x1 = cx - rds * ca;
408 y1 = cy - rds * sa;
409 x2 = cx - (rds-6) * ca;
410 y2 = cy - (rds-6) * sa;
411 fl_color(FL_BLACK);
412 fl_line((int)x1,(int)y1,(int)x2,(int)y2);
413 fl_color(FL_WHITE);
414 if (sa*ca <0)
415 fl_line((int)x1+1,(int)y1+1,(int)x2+1,(int)y2+1);
416 else
417 fl_line((int)x1+1,(int)y1-1,(int)x2+1,(int)y2-1);
418 if ((a == 1) || (nb_dec == 1))
419 a += 1;
420 else
421 a += 2;
422 }
423 }
424 }
425 }
426
draw_cursor(const int ox,const int oy,const int side)427 void Fl_Knob::draw_cursor(const int ox,const int oy,const int side)
428 {
429 float rds,cur,cx,cy;
430 double angle;
431
432 rds = (side - 20.0f) * 0.5f;
433 cur = _percent * rds * 0.5f;
434 cx = ox + side * 0.5f;
435 cy = oy + side * 0.5f;
436 angle = (a2-a1)*(value()-minimum())/(maximum()-minimum()) + a1;
437 fl_push_matrix();
438 fl_scale(1,1);
439 fl_translate(cx,cy);
440 fl_rotate(-angle);
441 fl_translate(0,rds-cur-2.0f);
442 if (_type<LINELIN) {
443 fl_begin_polygon();
444 fl_color(selection_color());
445 fl_circle(0.0,0.0,cur);
446 fl_end_polygon();
447 fl_begin_loop();
448 fl_color(FL_BLACK);
449 fl_circle(0.0,0.0,cur);
450 fl_end_loop();
451 }
452 else {
453 fl_begin_polygon();
454 fl_color(selection_color());
455 fl_vertex(-1.5,-cur);
456 fl_vertex(-1.5,cur);
457 fl_vertex(1.5,cur);
458 fl_vertex(1.5,-cur);
459 fl_end_polygon();
460 fl_begin_loop();
461 fl_color(FL_BLACK);
462 fl_vertex(-1.5,-cur);
463 fl_vertex(-1.5,cur);
464 fl_vertex(1.5,cur);
465 fl_vertex(1.5,-cur);
466 fl_end_loop();
467 }
468 fl_pop_matrix();
469 }
470
cursor(const int pc)471 void Fl_Knob::cursor(const int pc)
472 {
473 _percent = (float)pc*0.01f;
474
475 if (_percent < 0.05f) _percent = 0.05f;
476 if (_percent > 1.0f) _percent = 1.0f;
477 if (visible()) damage(FL_DAMAGE_CHILD);
478 }
479
scaleticks(const int tck)480 void Fl_Knob::scaleticks(const int tck)
481 {
482 _scaleticks = tck;
483 if (_scaleticks < 0) _scaleticks = 0;
484 if (_scaleticks > 31) _scaleticks = 31;
485 if (visible()) damage(FL_DAMAGE_ALL);
486 }
487
488 // ---- IV - Aug 23 2002 ---- included file: Fl_Spin.cpp
489
draw()490 void Fl_Spin::draw()
491 {
492 int sxx = x(), syy = y(), sww = w(), shh = h();
493 Fl_Boxtype box1 = (Fl_Boxtype)(box());
494 int border_size=Fl::box_dx(box());
495 WIDGET_GLOBALS *widgetGlobals =
496 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
497
498 if (damage()&~FL_DAMAGE_CHILD) clear_damage(FL_DAMAGE_ALL);
499
500 if (!box1) box1 = (Fl_Boxtype)(box()&-2);
501
502 if ((widgetGlobals->indrag || mouseobj) && deltadir!=0) {
503 if (deltadir>0) {
504 draw_box(fl_down(box1),sxx,syy,sww,shh/2,color());
505 draw_box(box1,sxx,syy+shh/2,sww,shh/2,color());
506 }
507 else {
508 draw_box(box1,sxx,syy,sww,shh/2,color());
509 draw_box(fl_down(box1),sxx,syy+shh/2,sww,shh/2,color());
510 }
511 }
512 else {
513 draw_box(box1,sxx,syy,sww,shh/2,color());
514 draw_box(box1,sxx,syy+shh/2,sww,shh/2,color());
515 }
516 sxx+=border_size;
517 syy+=border_size;
518 sww-=border_size*2;
519 shh-=border_size*2;
520 if (active_r()) {
521 fl_color(selection_color());
522 }
523 else {
524 fl_color(selection_color() | 8);
525 }
526 int w1 = (sww-1)|1; // use odd sizes only
527 int X = sxx+w1/2;
528 int W = w1/3;
529 int h1 = shh/2-border_size-2;
530 int Y= syy;
531 fl_polygon(X, Y, X+W,Y+h1 , X-W, Y+h1);
532 Y=syy+shh/2+border_size+1+h1;
533 fl_polygon(X, Y, X-W, Y-h1, X+W, Y-h1);
534 clear_damage();
535 }
536
repeat_callback(void * v)537 void Fl_Spin::repeat_callback(void* v)
538 {
539 Fl_Spin* b = (Fl_Spin*)v;
540 if (b->mouseobj) {
541 Fl::add_timeout(0.1, repeat_callback, b);
542 b->increment_cb();
543 }
544 }
545
increment_cb(void)546 void Fl_Spin::increment_cb(void)
547 {
548 if (!mouseobj) return;
549 delta += deltadir;
550 double v;
551 switch (drag) {
552 case 3: v = increment(value(), deltadir*100); break;
553 case 2: v = increment(value(), deltadir*10); break;
554 default:v = increment(value(), deltadir); break;
555 }
556 v = round(v);
557 handle_drag(soft()?softclamp(v):clamp(v));
558 }
559
handle(int event)560 int Fl_Spin::handle(int event)
561 {
562 double v;
563 int olddelta;
564 int mx = Fl::event_x();
565 int my = Fl::event_y();
566 int sxx = x(), syy = y(), sww = w(), shh = h();
567 WIDGET_GLOBALS *widgetGlobals =
568 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
569
570 switch (event) {
571 case FL_PUSH:
572 // if (!step()) goto DEFAULT;
573 iy = my;
574 ix = mx;
575 drag = Fl::event_button();
576 handle_push();
577 widgetGlobals->indrag=1;
578 mouseobj=1;
579 Fl::add_timeout(0.5, repeat_callback, this);
580 delta=0;
581 if (Fl::event_inside(sxx,syy,sww,shh/2)) {
582 deltadir=1;
583 }
584 else if (Fl::event_inside(sxx,syy+shh/2,sww,shh/2)) {
585 deltadir=-1;
586 }
587 else {
588 deltadir=0;
589 }
590 increment_cb();
591 redraw();
592 return 1;
593 case FL_DRAG:
594 if (mouseobj) {
595 mouseobj=0;
596 Fl::remove_timeout(repeat_callback, this);
597 }
598 // if (!step()) goto DEFAULT;
599 olddelta=delta;
600 delta = - (Fl::event_y()-iy);
601 if ((delta>5) || (delta<-5)) {
602 deltadir=((olddelta-delta)>0)?-1:(((olddelta-delta)<0)?1:0);
603 }
604 else {
605 deltadir=0; delta = olddelta;
606 }
607 switch (drag) {
608 case 3: v = increment(value(), deltadir*100); break;
609 case 2: v = increment(value(), deltadir*10); break;
610 default:v = increment(value(), deltadir); break;
611 }
612 v = round(v);
613 handle_drag(soft()?softclamp(v):clamp(v));
614 widgetGlobals->indrag=1;
615 return 1;
616 case FL_RELEASE:
617 if (mouseobj) {
618 Fl::remove_timeout(repeat_callback, this);
619 }
620 // if (!step()) goto DEFAULT;
621 widgetGlobals->indrag=0;
622 delta=0;
623 deltadir=0;
624 mouseobj=0;
625 handle_release();
626 redraw();
627 return 1;
628 default:
629 widgetGlobals->indrag=0;
630 return Fl_Valuator::handle(event);
631 }
632 }
633
~Fl_Spin(void)634 Fl_Spin::~Fl_Spin(void)
635 {
636 Fl::remove_timeout(repeat_callback, this);
637 }
638
Fl_Spin(CSOUND * cs,int x,int y,int w,int h,const char * l)639 Fl_Spin::Fl_Spin(CSOUND *cs, int x, int y, int w, int h, const char* l)
640 : Fl_Valuator(x,y,w,h,l)
641 {
642
643 csound = cs;
644 WIDGET_GLOBALS *widgetGlobals =
645 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
646 soft_ = 0;
647 align(FL_ALIGN_LEFT);
648 ix=x;
649 iy=y;
650 drag=0;
651 widgetGlobals->indrag=0;
652 mouseobj = 0;
653 deltadir=0;
654 delta=0;
655 indrag=0;
656 }
657
658 // ---- IV - Aug 23 2002 ---- included file: Fl_Value_Input_Spin.cpp
659
input_cb(Fl_Widget *,void * v)660 void Fl_Value_Input_Spin::input_cb(Fl_Widget*, void* v)
661 {
662 Fl_Value_Input_Spin& t = *(Fl_Value_Input_Spin*)v;
663
664 CSOUND *csound = t.csound;
665 WIDGET_GLOBALS *widgetGlobals =
666 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
667 double nv;
668 if (t.step()>=1.0) nv = strtol(t.input.value(), 0, 0);
669 else nv = csound->strtod((char*)t.input.value(), 0);
670 widgetGlobals->hack_o_rama1 = 1;
671 t.handle_push();
672 t.handle_drag(nv);
673 t.handle_release();
674 widgetGlobals->hack_o_rama1 = 0;
675 }
676
draw(void)677 void Fl_Value_Input_Spin::draw(void)
678 {
679 int sxx = x(), syy = y(), sww = w(), shh = h();
680 sxx += sww - buttonssize(); sww = buttonssize();
681 Fl_Boxtype box1 = (Fl_Boxtype)(box()&-2);
682 int border_size=Fl::box_dx(box());
683 WIDGET_GLOBALS *widgetGlobals =
684 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
685
686 if (damage()&~FL_DAMAGE_CHILD) input.clear_damage(FL_DAMAGE_ALL);
687 input.box(box());
688 input.color(FL_WHITE, selection_color());
689 input.redraw();
690 input.clear_damage();
691 sxx+=border_size;
692 syy+=border_size;
693 sww-=border_size*2;
694 shh-=border_size*2;
695
696 if (!box1) box1 = (Fl_Boxtype)(box()&-2);
697
698 if ((widgetGlobals->indrag || mouseobj) && deltadir!=0) {
699 if (deltadir>0) {
700 draw_box(fl_down(box1),sxx,syy,sww,shh/2,color());
701 draw_box(box1,sxx,syy+shh/2,sww,shh/2,color());
702 }
703 else {
704 draw_box(box1,sxx,syy,sww,shh/2,color());
705 draw_box(fl_down(box1),sxx,syy+shh/2,sww,shh/2,color());
706 }
707 }
708 else {
709 draw_box(box1,sxx,syy,sww,shh/2,color());
710 draw_box(box1,sxx,syy+shh/2,sww,shh/2,color());
711 }
712 sxx+=border_size;
713 syy+=border_size;
714 sww-=border_size*2;
715 shh-=border_size*2;
716 if (active_r()) {
717 fl_color(labelcolor());
718 }
719 else {
720 fl_color(labelcolor() | 8);
721 }
722 int w1 = (sww-1)|1; // use odd sizes only
723 int X = sxx+w1/2;
724 int W = w1/3;
725 int h1 = shh/2-border_size-2;
726 int Y= syy;
727 fl_polygon(X, Y, X+W,Y+h1 , X-W, Y+h1);
728 Y=syy+shh/2+border_size+1+h1;
729 fl_polygon(X, Y, X-W, Y-h1, X+W, Y-h1);
730 clear_damage();
731 }
732
resize(int X,int Y,int W,int H)733 void Fl_Value_Input_Spin::resize(int X, int Y, int W, int H)
734 {
735 input.resize(X,Y,W,H);
736 Fl_Valuator::resize(X,Y,W,H);
737 }
738
value_damage(void)739 void Fl_Value_Input_Spin::value_damage(void)
740 {
741 WIDGET_GLOBALS *widgetGlobals =
742 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
743 if (widgetGlobals->hack_o_rama1) return;
744 char buf[128];
745 format(buf);
746 input.value(buf);
747 input.mark(input.position()); // turn off selection highlight
748 }
749
repeat_callback(void * v)750 void Fl_Value_Input_Spin::repeat_callback(void* v)
751 {
752 Fl_Value_Input_Spin* b = (Fl_Value_Input_Spin*)v;
753 if (b->mouseobj) {
754 Fl::add_timeout(.1, repeat_callback, b);
755 b->increment_cb();
756 }
757 }
758
increment_cb(void)759 void Fl_Value_Input_Spin::increment_cb(void)
760 {
761 if (!mouseobj) return;
762 delta+=deltadir;
763 double v;
764 switch (drag) {
765 case 3: v = increment(value(), deltadir*100); break;
766 case 2: v = increment(value(), deltadir*10); break;
767 default:v = increment(value(), deltadir); break;
768 }
769 v = round(v);
770 handle_drag(soft()?softclamp(v):clamp(v));
771 }
772
handle(int event)773 int Fl_Value_Input_Spin::handle(int event)
774 {
775 double v;
776 int olddelta;
777 int mx = Fl::event_x();
778 int my = Fl::event_y();
779 int sxx = x(), syy = y(), sww = w(), shh = h();
780 sxx += sww - buttonssize(); sww = buttonssize();
781 WIDGET_GLOBALS *widgetGlobals =
782 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
783
784 if (!widgetGlobals->indrag &&
785 ( !widgetGlobals->sldrag || !((mx>=sxx && mx<=(sxx+sww)) &&
786 (my>=syy && my<=(syy+shh)))) ) {
787 widgetGlobals->indrag=0;
788 switch(event) {
789 case FL_PUSH:
790 case FL_DRAG:
791 widgetGlobals->sldrag=1;
792 break;
793 case FL_FOCUS:
794 input.take_focus();
795 break;
796 case FL_UNFOCUS:
797 redraw();
798 break;
799 default:
800 widgetGlobals->sldrag=0;
801 }
802 input.type(step()>=1.0 ? FL_INT_INPUT : FL_FLOAT_INPUT);
803 return input.handle(event);
804 }
805
806 switch (event) {
807 case FL_PUSH:
808 // if (!step()) goto DEFAULT;
809 iy = my;
810 ix = mx;
811 drag = Fl::event_button();
812 handle_push();
813 widgetGlobals->indrag=1;
814 mouseobj=1;
815 Fl::add_timeout(.5, repeat_callback, this);
816 delta=0;
817 if (Fl::event_inside(sxx,syy,sww,shh/2)) {
818 deltadir=1;
819 }
820 else if (Fl::event_inside(sxx,syy+shh/2,sww,shh/2)) {
821 deltadir=-1;
822 }
823 else {
824 deltadir=0;
825 }
826 increment_cb();
827 redraw();
828 return 1;
829 case FL_DRAG:
830 if (mouseobj) {
831 mouseobj=0;
832 Fl::remove_timeout(repeat_callback, this);
833 }
834 // if (!step()) goto DEFAULT;
835 olddelta=delta;
836 delta = - (Fl::event_y()-iy);
837 if ((delta>5) || (delta<-5) ) {
838 deltadir=((olddelta-delta)>0)?-1:(((olddelta-delta)<0)?1:0);
839 }
840 else {
841 deltadir=0; delta = olddelta;
842 }
843 switch (drag) {
844 case 3: v = increment(value(), deltadir*100); break;
845 case 2: v = increment(value(), deltadir*10); break;
846 default:v = increment(value(), deltadir); break;
847 }
848 v = round(v);
849 handle_drag(soft()?softclamp(v):clamp(v));
850 widgetGlobals->indrag=1;
851 return 1;
852 case FL_RELEASE:
853 if (mouseobj) {
854 Fl::remove_timeout(repeat_callback, this);
855 }
856 // if (!step()) goto DEFAULT;
857 widgetGlobals->indrag=0;
858 delta=0;
859 deltadir=0;
860 mouseobj=0;
861 handle_release();
862 redraw();
863 return 1;
864 case FL_FOCUS:
865 widgetGlobals->indrag=0;
866 return input.take_focus();
867 default:
868 widgetGlobals->indrag=0;
869 input.type(step()>=1.0 ? FL_INT_INPUT : FL_FLOAT_INPUT);
870 return 1;
871 }
872 }
873
~Fl_Value_Input_Spin(void)874 Fl_Value_Input_Spin::~Fl_Value_Input_Spin(void)
875 {
876 Fl::remove_timeout(repeat_callback, this);
877 }
878
Fl_Value_Input_Spin(CSOUND * cs,int x,int y,int w,int h,const char * l)879 Fl_Value_Input_Spin::Fl_Value_Input_Spin(CSOUND * cs, int x, int y,
880 int w, int h, const char* l)
881 : Fl_Valuator(x,y,w,h,l), input(x, y, w, h, 0)
882 {
883 csound = cs;
884 WIDGET_GLOBALS *widgetGlobals =
885 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
886 soft_ = 0;
887 // if (input.parent()) // defeat automatic-add
888 // ((Fl_Group*)input.parent())->remove(input);
889 // input.parent(this); // kludge!
890 this->parent()->add(input);
891 input.callback(input_cb, this);
892 input.when(FL_WHEN_CHANGED);
893 selection_color(input.selection_color());
894 align(FL_ALIGN_LEFT);
895 box(input.box());
896 value_damage();
897 buttonssize(15);
898 ix = x;
899 iy = y;
900 drag = 0;
901 widgetGlobals->indrag = 0;
902 widgetGlobals->sldrag = 0;
903 mouseobj = 0;
904 deltadir = 0;
905 delta = 0;
906 }
907
908 // ---- IV - Aug 23 2002 ---- included file: Fl_Value_Slider_Input.cpp
909
input_cb(Fl_Widget *,void * v)910 void Fl_Value_Slider_Input::input_cb(Fl_Widget*, void* v) {
911 Fl_Value_Slider_Input& t = *(Fl_Value_Slider_Input*)v;
912 CSOUND *csound = t.csound;
913 WIDGET_GLOBALS *widgetGlobals =
914 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
915 double nv;
916 if (t.step()>=1.0) nv = strtol(t.input.value(), 0, 0);
917 else nv = csound->strtod((char*)t.input.value(), 0);
918 widgetGlobals->hack_o_rama2 = 1;
919 t.handle_push();
920 t.handle_drag(nv);
921 t.handle_release();
922 widgetGlobals->hack_o_rama2 = 0;
923 }
924
draw(void)925 void Fl_Value_Slider_Input::draw(void)
926 {
927 int sxx = x(), syy = y(), sww = w(), shh = h();
928 //int bww = w();
929 int X = x(), Y = y(), W = w(), H = h();
930
931 int border_size=Fl::box_dx(box());
932
933 if (horizontal()) {
934 //bww = textboxsize();
935 sxx += textboxsize(); sww -= textboxsize();
936 input.resize(X,Y,W-sww,shh);
937 }
938 else {
939 fl_font(input.textfont(), input.textsize());
940 syy += fl_height()+(border_size+1)*2; shh -= fl_height()+(border_size+1)*2;
941 input.resize(X,Y,W,H-shh);
942 }
943 if (damage()&~FL_DAMAGE_CHILD) input.clear_damage(FL_DAMAGE_ALL);
944 input.box(box());
945 input.color(FL_WHITE, selection_color());
946 input.redraw();
947 input.resize(X,Y,W,H);
948 input.clear_damage();
949 // if (horizontal()) input.draw();
950 clear_damage();
951 draw_box(box(),sxx,syy,sww,shh,color());
952 sxx+=border_size;
953 syy+=border_size;
954 sww-=border_size*2;
955 shh-=border_size*2;
956 if (border_size<2) {
957 sxx++;
958 syy++;
959 sww--;
960 shh--;
961 }
962 Fl_Slider::draw(sxx,syy,sww,shh);
963 }
964
resize(int X,int Y,int W,int H)965 void Fl_Value_Slider_Input::resize(int X, int Y, int W, int H)
966 {
967 input.resize(X,Y,W,H);
968 Fl_Value_Slider::resize(X,Y,W,H);
969 }
970
value_damage()971 void Fl_Value_Slider_Input::value_damage()
972 {
973 WIDGET_GLOBALS *widgetGlobals =
974 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
975 if (widgetGlobals->hack_o_rama2) return;
976 char buf[128];
977 format(buf);
978 input.value(buf);
979 input.mark(input.position()); // turn off selection highlight
980 }
981
handle(int event)982 int Fl_Value_Slider_Input::handle(int event)
983 {
984 int mx = Fl::event_x();
985 int my = Fl::event_y();
986 int sxx = x(), syy = y(), sww = w(), shh = h();
987 int border_size=Fl::box_dx(box());
988 WIDGET_GLOBALS *widgetGlobals =
989 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
990 if (horizontal()) {
991 sxx += textboxsize(); sww -= textboxsize();
992 }
993 else {
994 fl_font(input.textfont(), input.textsize());
995 syy += fl_height()+(border_size+1)*2; shh -= fl_height()+(border_size+1)*2;
996 }
997 if ( !widgetGlobals->indrag &&
998 ( !widgetGlobals->sldrag || !((mx>=sxx && mx<=(sxx+sww)) &&
999 (my>=syy && my<=(syy+shh)))) ) {
1000 widgetGlobals->indrag=0;
1001 switch(event) {
1002 case FL_PUSH:
1003 case FL_DRAG:
1004 widgetGlobals->sldrag=1;
1005 break;
1006 case FL_FOCUS:
1007 input.take_focus();
1008 break;
1009 case FL_UNFOCUS:
1010 redraw();
1011 break;
1012 default:
1013 widgetGlobals->sldrag=0;
1014 }
1015 input.type(step()>=1.0 ? FL_INT_INPUT : FL_FLOAT_INPUT);
1016 return input.handle(event);
1017 }
1018 switch (event) {
1019 case FL_PUSH:
1020 widgetGlobals->ix = mx;
1021 widgetGlobals->drag = Fl::event_button();
1022 widgetGlobals->indrag=1;
1023 return Fl_Slider::handle(event,sxx,syy,sww,shh);
1024 case FL_DRAG:
1025 widgetGlobals->indrag=1;
1026 return Fl_Slider::handle(event,sxx,syy,sww,shh);
1027 case FL_RELEASE:
1028 // if (!step()) goto DEFAULT;
1029 if (value() != previous_value() || !Fl::event_is_click())
1030 handle_release();
1031 else {
1032 input.handle(FL_PUSH);
1033 input.handle(FL_RELEASE);
1034 }
1035 widgetGlobals->indrag=0;
1036 return 1;
1037 case FL_FOCUS:
1038 widgetGlobals->indrag=0;
1039 input.take_focus();
1040 return Fl_Slider::handle(event,sxx,syy,sww,shh);
1041 default:
1042 widgetGlobals->indrag=0;
1043 input.type(step()>=1.0 ? FL_INT_INPUT : FL_FLOAT_INPUT);
1044 input.handle(event);
1045 return Fl_Slider::handle(event,sxx,syy,sww,shh);
1046 }
1047 }
1048
Fl_Value_Slider_Input(CSOUND * cs,int x,int y,int w,int h,const char * l)1049 Fl_Value_Slider_Input::Fl_Value_Slider_Input(CSOUND *cs, int x, int y,
1050 int w, int h, const char* l)
1051 : Fl_Value_Slider(x,y,w,h,l),input(x, y, w, h, 0)
1052 {
1053 csound = cs;
1054 soft_ = 0;
1055 // if (input.parent()) // defeat automatic-add
1056 // ((Fl_Group*)input.parent())->remove(input);
1057 // input.parent(this); // kludge!
1058 // input.callback(input_cb, this);
1059 parent()->add(input);
1060 // input.when(FL_WHEN_CHANGED | FL_WHEN_ENTER_KEY);
1061 input.when(FL_WHEN_CHANGED );
1062 selection_color(input.selection_color());
1063 input.align(FL_ALIGN_LEFT);
1064 align(FL_ALIGN_LEFT);
1065 textboxsize(35);
1066 value_damage();
1067 }
1068
1069 // ---- IV - Aug 23 2002 ---- end of included files
1070
1071 //static char *GetString(CSOUND *csound, MYFLT *pname, int is_string);
1072
1073 //---------------
1074
set_butbank_value(Fl_Group * o,MYFLT value)1075 static void set_butbank_value(Fl_Group *o, MYFLT value)
1076 {
1077 int childr = o->children();
1078 Fl_Button *b;
1079 int ival = (int) value, j, label;
1080
1081 if (ival < 0 || ival >= childr || (MYFLT) ival != value)
1082 return;
1083 for (j = 0; j < childr; j++) {
1084 b = (Fl_Button *) o->child(j);
1085 label = atoi(b->label());
1086 if (label == ival) {
1087 b->value(1);
1088 b->do_callback();
1089 }
1090 else
1091 b->value(0);
1092 }
1093 }
1094
FLlock()1095 inline void FLlock() { //gab
1096 Fl::lock();
1097 }
1098
FLunlock()1099 inline void FLunlock() { //gab
1100 Fl::unlock();
1101 Fl::awake((void*) 0);
1102 }
1103
SNAPSHOT(vector<ADDR_SET_VALUE> & valuators,int snapGroup)1104 SNAPSHOT::SNAPSHOT (vector<ADDR_SET_VALUE>& valuators, int snapGroup)
1105 { // the constructor captures current values of all widgets
1106 // by copying all current values from "valuators" vector (AddrSetValue)
1107 // to the "fields" vector
1108 is_empty = 0;
1109 FLlock(); //<=================
1110 int i,k;
1111 int vsize = valuators.size();
1112 for (i = 0, k = 0; i < vsize && k < vsize; i++, k++) {
1113 while (valuators[k].group != snapGroup ) {
1114 k++;
1115 if (UNLIKELY(k >=vsize)) goto err;
1116 }
1117 ADDR_SET_VALUE& v = valuators[k];
1118 CSOUND *csound = (CSOUND*) (((OPDS *) (v.opcode))->insdshead->csound);
1119 string opcode_name, widg_name;
1120 fields.resize(i+1);
1121 if ((int) fields.size() < i+1)
1122 fields.resize(i+1);
1123 VALUATOR_FIELD* fld = &(fields[i]);
1124 float val, min, max;
1125 opcode_name = fld->opcode_name = ((OPDS *) (v.opcode))->optext->t.opcod;
1126 if (UNLIKELY(opcode_name.c_str() == NULL))
1127 {
1128 csound->InitError(csound, "%s",
1129 Str("Invalid snapshot. Perhaps you modified "
1130 "orchestra widget code after you saved "
1131 "the snapshot bank."));
1132 goto err;
1133 }
1134 else if (opcode_name == "FLslider") {
1135 FLSLIDER *p = (FLSLIDER *) (v.opcode);
1136 fld->widg_name = p->name->data;
1137 fld->exp = (int) *p->iexp;
1138 min = fld->min = *p->imin; max = fld->max = *p->imax;
1139 switch (fld->exp) {
1140 case LIN_:
1141 case EXP_:
1142 val = *p->kout;
1143 if (min < max) {
1144 if (val < min) val=min;
1145 else if(val>max) val=max;
1146 }
1147 else {
1148 if (val < max) val=max;
1149 else if(val>min) val=min;
1150 }
1151 break;
1152 default: val = ((Fl_Valuator *)v.WidgAddress)->value();
1153 }
1154 fld->value = val;
1155 }
1156 else if (opcode_name == "FLslidBnk" || opcode_name == "FLvslidBnk") {
1157 FLSLIDERBANK *p = (FLSLIDERBANK *) (v.opcode);
1158 fld->widg_name = ((STRINGDAT *)p->names)->data;
1159 int numsliders = (int) *p->inumsliders;
1160 fld->sldbnk = p->slider_data;
1161 // fld->sldbnkValues = new MYFLT[numsliders];
1162 // widgetGlobals->allocatedStrings.push_back((char *) fld->sldbnkValues);
1163 fld->exp = numsliders; // EXCEPTIONAL CASE! fld->exp contains the number
1164 // of sliders and not the exponential flag
1165 for (int j =0; j < numsliders; j++) {
1166 switch (fld->sldbnk[j].exp) {
1167 case LIN_: case EXP_:
1168 val = *fld->sldbnk[j].out;
1169 min = fld->sldbnk[j].min; max = fld->sldbnk[j].max;
1170 if (min < max) {
1171 if (val < min) val=min;
1172 else if(val>max) val=max;
1173 }
1174 else {
1175 if (val < max) val=max;
1176 else if(val>min) val=min;
1177 }
1178 break;
1179 default:
1180 val = ((Fl_Valuator *) ((Fl_Group*)v.WidgAddress)->
1181 child(j))->value();
1182 }
1183 fld->set_sldbnk(j, val);
1184 }
1185 }
1186 else if (opcode_name == "FLslidBnk2" || opcode_name == "FLvslidBnk2") {
1187 FLSLIDERBANK2 *p = (FLSLIDERBANK2 *) (v.opcode);
1188 fld->widg_name = ((STRINGDAT *)p->names)->data;
1189 int numsliders = (int) *p->inumsliders;
1190 fld->sldbnk = p->slider_data;
1191 // EXCEPTIONAL CASE! fld->exp contains the number of sliders
1192 // and not the exponential flag
1193 fld->exp = numsliders;
1194 for (int j =0; j < numsliders; j++) {
1195 switch (fld->sldbnk[j].exp) {
1196 case LIN_: case EXP_:
1197 val = *fld->sldbnk[j].out;
1198 min = fld->sldbnk[j].min; max = fld->sldbnk[j].max;
1199 if (min < max) {
1200 if (val < min) val=min;
1201 else if(val>max) val=max;
1202 }
1203 else {
1204 if (val < max) val=max;
1205 else if(val>min) val=min;
1206 }
1207 break;
1208 default:
1209 val = ((Fl_Valuator *) ((Fl_Group*) v.WidgAddress)->child(j))->value();
1210 }
1211 fld->set_sldbnk(j, val);
1212 }
1213 }
1214 else if (opcode_name == "FLknob") {
1215 FLKNOB *p = (FLKNOB *) (v.opcode);
1216 fld->widg_name = p->name->data;
1217 fld->exp = (int) *p->iexp;
1218 min = fld->min = *p->imin; max = fld->max = *p->imax;
1219 switch (fld->exp) {
1220 case LIN_:
1221 case EXP_:
1222 val = *p->kout;
1223 if (min < max) {
1224 if (val < min) val=min;
1225 else if(val>max) val=max;
1226 }
1227 else {
1228 if (val < max) val=max;
1229 else if(val>min) val=min;
1230 }
1231 break;
1232 default: val = ((Fl_Valuator *)v.WidgAddress)->value();
1233 }
1234 fld->value = val;
1235 }
1236 else if (opcode_name == "FLroller") {
1237 FLROLLER *p = (FLROLLER *) (v.opcode);
1238 fld->widg_name = p->name->data;
1239 fld->exp = (int) *p->iexp;
1240 min = fld->min = *p->imin; max = fld->max = *p->imax;
1241 switch (fld->exp) {
1242 case LIN_:
1243 case EXP_:
1244 val = *p->kout;
1245 if (min < max) {
1246 if (val < min) val=min;
1247 else if(val>max) val=max;
1248 }
1249 else {
1250 if (val < max) val=max;
1251 else if(val>min) val=min;
1252 }
1253 break;
1254 default: val = ((Fl_Valuator *)v.WidgAddress)->value();
1255 }
1256 fld->value = val;
1257 }
1258 else if (opcode_name == "FLtext") {
1259 FLTEXT *p = (FLTEXT *) (v.opcode);
1260 fld->widg_name = p->name->data;
1261 val = *p->kout; min = fld->min = *p->imin; max = fld->max = *p->imax;
1262 if (min < max) {
1263 if (val < min) val=min;
1264 else if(val>max) val=max;
1265 }
1266 else {
1267 if (val < max) val=max;
1268 else if(val>min) val=min;
1269 }
1270 fld->value = val;
1271 fld->exp = LIN_;
1272 }
1273 else if (opcode_name == "FLjoy") {
1274 FLJOYSTICK *p = (FLJOYSTICK *) (v.opcode);
1275 fld->widg_name = p->name->data;
1276 fld->exp = (int) *p->iexpx;
1277 min = fld->min = *p->iminx; max = fld->max = *p->imaxx;
1278 switch (fld->exp) {
1279 case LIN_:
1280 case EXP_:
1281 val = *p->koutx;
1282 if (min < max) {
1283 if (val < min) val=min;
1284 else if(val>max) val=max;
1285 }
1286 else {
1287 if (val < max) val=max;
1288 else if(val>min) val=min;
1289 }
1290 break;
1291 default:
1292 val = ((Fl_Positioner *)v.WidgAddress)->xvalue();
1293 }
1294 fld->value = val;
1295 fld->exp2 = (int) *p->iexpy;
1296 min = fld->min2 = *p->iminy; max = fld->max2 = *p->imaxy;
1297 switch (fld->exp2) {
1298 case LIN_: case EXP_:
1299 val = *p->kouty;
1300 if (min < max) {
1301 if (val < min) val=min;
1302 else if(val>max) val=max;
1303 }
1304 else {
1305 if (val < max) val=max;
1306 else if(val>min) val=min;
1307 }
1308 break;
1309 default:
1310 val = ((Fl_Positioner *)v.WidgAddress)->yvalue();
1311 }
1312 fld->value2 =val;
1313 }
1314 else if (opcode_name == "FLbutton") {
1315 FLBUTTON *p = (FLBUTTON *) (v.opcode);
1316 fld->widg_name = p->name->data;
1317 fld->value = *p->kout;
1318 fld->min = 0; fld->max = 1; fld->exp = LIN_;
1319 }
1320 else if (opcode_name == "FLbutBank") {
1321 FLBUTTONBANK *p = (FLBUTTONBANK *) (v.opcode);
1322 fld->widg_name = Str("No name for FLbutbank");
1323 //fld->widg_name = GetString(csound, p->name, p->XSTRCODE);
1324 fld->value = *p->kout;
1325 fld->min = 0; fld->max = 1; fld->exp = LIN_;
1326 }
1327 else if (opcode_name == "FLcount") {
1328 FLCOUNTER *p = (FLCOUNTER *) (v.opcode);
1329 fld->widg_name = p->name->data;
1330 val = *p->kout; min = *p->imin; max =*p->imax;
1331 if (min != max) {
1332 if (val < min) val=min;
1333 else if (val>max) val=max;
1334 }
1335 fld->value = val;
1336 fld->min = *p->imin; fld->max = *p->imax; fld->exp = LIN_;
1337 }
1338 else if (opcode_name == "FLvalue") {
1339 FLVALUE *p = (FLVALUE *) (v.opcode);
1340 fld->widg_name = p->name->data;
1341 }
1342 else if (opcode_name == "FLbox") {
1343 FL_BOX *p = (FL_BOX *) (v.opcode);
1344 fld->widg_name = p->itext->data;
1345 }
1346 }
1347 FLunlock();
1348 return;
1349 err:
1350 FLunlock(); //<=================
1351 is_empty = 1;
1352 }
1353
get(vector<ADDR_SET_VALUE> & valuators,int snapGroup)1354 int SNAPSHOT::get(vector<ADDR_SET_VALUE>& valuators, int snapGroup)
1355 {
1356 if (UNLIKELY(is_empty == 1)) {
1357 /* FIXME: should have CSOUND* pointer here */
1358 /* return csound->InitError(csound, "%s", Str("empty snapshot")); */
1359 //printf("SNAPSHOT IS EMPTY\n");
1360 return -1;
1361 }
1362 FLlock(); //<=================
1363 int j,k;
1364 int siz =valuators.size();
1365 for (j = 0, k = 0; j< siz && k < siz; j++, k++) {
1366 // int grp = valuators[k].group; //Not used
1367 while (valuators[k].group != snapGroup) {
1368 k++;
1369 if (k >= (int) valuators.size()) goto end_func;
1370 }
1371 Fl_Widget* o = (Fl_Widget*) (valuators[k].WidgAddress);
1372 void *opcode = valuators[k].opcode;
1373 //CSOUND *csound = (CSOUND*) (((OPDS*) opcode)->insdshead->csound); //Not used
1374 VALUATOR_FIELD* fld = &fields[j];
1375 string opcode_name = fld->opcode_name;
1376
1377 MYFLT val = fld->value, valtab = fld->value, min=fld->min,
1378 max=fld->max, range,base;
1379 if (min < max) {
1380 if (val < min) val = min;
1381 else if (val >max) val = max;
1382 }
1383 else {
1384 if (val < max) val=max;
1385 else if(val>min) val=min;
1386 }
1387
1388 if (opcode_name == "FLjoy") {
1389 switch(fld->exp) {
1390 case LIN_:
1391 ((Fl_Positioner*) o)->xvalue(val);
1392 break;
1393 case EXP_:
1394 range = fld->max - fld->min;
1395 #if defined(sun)
1396 base = ::pow(fld->max / (double)fld->min, 1.0/(double)range);
1397 #else
1398 base = ::pow(fld->max / fld->min, 1.0/(double)range);
1399 #endif
1400 ((Fl_Positioner*) o)->xvalue(log(val/fld->min) / log(base)) ;
1401 break;
1402 default:
1403 ((Fl_Positioner*) o)->xvalue(valtab);
1404 break;
1405 }
1406 val = fld->value2; min = fld->min2; max = fld->max2;
1407 // if (val < min) val = min;
1408 // else if (val >max) val = max;
1409 switch(fld->exp2) {
1410 case LIN_:
1411 ((Fl_Positioner*) o)->yvalue(val);
1412 break;
1413 case EXP_:
1414 range = fld->max2 - fld->min2;
1415 #if defined(sun)
1416 base = ::pow(fld->max2 / (double)fld->min2, 1.0/(double)range);
1417 #else
1418 base = ::pow(fld->max2 / fld->min2, 1.0/(double)range);
1419 #endif
1420 ((Fl_Positioner*) o)->yvalue(log(val/fld->min2) / log(base)) ;
1421 break;
1422 default:
1423 ((Fl_Positioner*) o)->yvalue(valtab);
1424 break;
1425 }
1426 o->do_callback(o, opcode);
1427 }
1428 else if (opcode_name == "FLbutton") {
1429 FLBUTTON *p = (FLBUTTON*) (opcode);
1430 // don't allow to retreive its value if >= 10 or between 21 and 29
1431 if ((*p->itype < 10) || (*p->itype < 30 && *p->itype > 20)) {
1432 if(fld->value >= *p->ioff - 0.0001 &&
1433 fld->value <= *p->ioff + 0.0001) // to avoid eventual math rounding
1434 ((Fl_Button*) o)->value(0);
1435 else
1436 if (fld->value >= *p->ion - 0.0001 &&
1437 fld->value <= *p->ion + 0.0001) // to avoid eventual math rounding
1438 ((Fl_Button*) o)->value(1);
1439 else
1440 ((Fl_Button*) o)->value((int)fld->value);
1441 o->do_callback(o, opcode);
1442 }
1443 }
1444 else if (opcode_name == "FLbutBank") {
1445 FLBUTTONBANK *p = (FLBUTTONBANK*) (opcode);
1446 if (*p->itype < 10 || (*p->itype < 30 && *p->itype > 20)) {
1447 // don't allow to retreive its value if >= 10
1448 //((Fl_Group*) o)->value(fld->value);
1449 set_butbank_value((Fl_Group*) o, fld->value);
1450 //o->do_callback(o, opcode);
1451 *p->kout=fld->value;
1452 if (*p->args[0] >= 0) ButtonSched(p->h.insdshead->csound,
1453 p->args, p->INOCOUNT-7);
1454 }
1455 }
1456 else if (opcode_name == "FLcount") {
1457 FLCOUNTER *p = (FLCOUNTER*) (opcode);
1458 if (*p->itype < 10 || (*p->itype < 30 && *p->itype > 20)) {
1459 // don't allow to retreive its value if >= 10
1460 ((Fl_Counter*) o)->value(fld->value);
1461 o->do_callback(o, opcode);
1462 }
1463 }
1464 else if (opcode_name == "FLslidBnk" || opcode_name == "FLvslidBnk") {
1465 FLSLIDERBANK *p = (FLSLIDERBANK*) (opcode);
1466 int numsliders = (int) *p->inumsliders;
1467 Fl_Group * grup = (Fl_Group *) o;
1468 for (int j =0; j < numsliders; j++) {
1469 MYFLT val = fld->get_sldbnk(j);
1470 switch (p->slider_data[j].exp) {
1471 case LIN_:
1472 ((Fl_Valuator *) grup->child(j))->value(val);
1473 break;
1474 case EXP_:
1475 range = p->slider_data[j].max - p->slider_data[j].min;
1476 #if defined(sun)
1477 base = ::pow(p->slider_data[j].max / (double)p->slider_data[j].min,
1478 1.0/(double)range);
1479 #else
1480 base = ::pow(p->slider_data[j].max / p->slider_data[j].min,
1481 1.0/(double)range);
1482 #endif
1483 ((Fl_Valuator*) grup->child(j))->
1484 value(log(val/p->slider_data[j].min) / log(base)) ;
1485 break;
1486 default:// TABLE the value must be in the 0 to 1 range...
1487 val = (val - fld->min ) / (fld->max - fld->min);
1488 ((Fl_Valuator *) grup->child(j))->value(val);
1489 break;
1490 }
1491 grup->child(j)->do_callback( grup->child(j),
1492 (void *) &(p->slider_data[j]));
1493 }
1494 }
1495 else if (opcode_name == "FLslidBnk2" || opcode_name == "FLvslidBnk2") {
1496 FLSLIDERBANK2 *p = (FLSLIDERBANK2*) (opcode);
1497 int numsliders = (int) *p->inumsliders;
1498 Fl_Group * grup = (Fl_Group *) o;
1499 for (int j =0; j < numsliders; j++) {
1500 MYFLT val = fld->get_sldbnk(j);
1501 switch (p->slider_data[j].exp) {
1502 case LIN_:
1503 ((Fl_Valuator *) grup->child(j))->value(val);
1504 break;
1505 case EXP_:
1506 range = p->slider_data[j].max - p->slider_data[j].min;
1507 base = pow(p->slider_data[j].max / p->slider_data[j].min, 1/range);
1508 ((Fl_Valuator*) grup->child(j))->value(log(val/p->slider_data[j].min) /
1509 log(base)) ;
1510 break;
1511 default:// TABLE the value must be in the 0 to 1 range...
1512 val = (val - fld->min ) / (fld->max - fld->min);
1513 ((Fl_Valuator *) grup->child(j))->value(val);
1514 break;
1515 }
1516 grup->child(j)->do_callback( grup->child(j),
1517 (void *) &(p->slider_data[j]));
1518 }
1519 }
1520 else {
1521 switch(fld->exp) {
1522 case LIN_:
1523 if (opcode_name == "FLbox" || opcode_name == "FLvalue" ) continue;
1524 else if (opcode_name == "FLtext" &&
1525 *((FLTEXT *)opcode)->itype == 1) {
1526 ((Fl_Valuator*) o)->value(val);
1527 continue;
1528 }
1529 ((Fl_Valuator*) o)->value(val);
1530 break;
1531 case EXP_:
1532 range = fld->max - fld->min;
1533 #if defined(sun)
1534 base = ::pow(fld->max / (double)fld->min, 1.0/(double)range);
1535 #else
1536 base = ::pow(fld->max / fld->min, 1.0/(double)range);
1537 #endif
1538 ((Fl_Valuator*) o)->value(log(val/fld->min) / log(base)) ;
1539 break;
1540 default: // TABLE the value must be in the 0 to 1 range...
1541 ((Fl_Valuator*) o)->value(valtab);
1542 break;
1543 }
1544 o->do_callback(o, opcode);
1545 }
1546 }
1547 end_func:
1548 FLunlock(); //<=================
1549 return OK;
1550 }
1551
1552 extern "C" {
1553
set_snap(CSOUND * csound,FLSETSNAP * p)1554 static int set_snap(CSOUND *csound, FLSETSNAP *p)
1555 {
1556 WIDGET_GLOBALS *widgetGlobals =
1557 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
1558 SNAPSHOT snap(widgetGlobals->AddrSetValue, (int) *p->group );
1559 int numfields = snap.fields.size();
1560 int index = (int) *p->index;
1561 int group = (int) *p->group;
1562 SNAPVEC snapvec_init;
1563 SNAPSHOT snap_init;
1564
1565 snap_init.fields.resize(1,VALUATOR_FIELD());
1566 snapvec_init.resize(1,snap_init);
1567 if (group+1 > (int) widgetGlobals->snapshots.size())
1568 widgetGlobals->snapshots.resize(group+1, snapvec_init);
1569 // *p->inum_snap = widgetGlobals->snapshots.size();
1570 *p->inum_val = numfields; // number of snapshots
1571 if (*p->ifn >= 1) { // if the table number is valid
1572 FUNC *ftp; // store the snapshot into the table
1573 if (LIKELY((ftp = csound->FTnp2Finde(csound, p->ifn)) != NULL)) {
1574 MYFLT *table = ftp->ftable;
1575 for (int j = 0; j < numfields; j++) {
1576 table[index*numfields+j] = snap.fields[j].value;
1577 }
1578 }
1579 else return csound->InitError(csound,
1580 "%s", Str("FLsetsnap: invalid table"));
1581 }
1582 else { // else store it into snapshot bank
1583 if ((int) widgetGlobals->snapshots[group].size() < index+1)
1584 widgetGlobals->snapshots[group].resize(index+1);
1585 csound->Message(csound, "%s", Str("setsnap saving\n"));
1586 widgetGlobals->snapshots[group][index]=snap;
1587 *p->inum_snap = widgetGlobals->snapshots[group].size();
1588 }
1589 return OK;
1590 }
1591
get_snap(CSOUND * csound,FLGETSNAP * p)1592 static int get_snap(CSOUND *csound, FLGETSNAP *p)
1593 {
1594 int index = (int) *p->index;
1595 int group = (int) *p->group;
1596 SNAPVEC snapvec_init;
1597 SNAPSHOT snap_init;
1598 WIDGET_GLOBALS *widgetGlobals =
1599 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
1600 snap_init.fields.resize(1,VALUATOR_FIELD());
1601 snapvec_init.resize(1,snap_init);
1602 if (group+1 > (int) widgetGlobals->snapshots.size())
1603 widgetGlobals->snapshots.resize(group+1, snapvec_init);
1604 if (!widgetGlobals->snapshots[group].empty()) {
1605 if (index >= (int) widgetGlobals->snapshots[group].size())
1606 index = widgetGlobals->snapshots[group].size()-1;
1607 else if (index < 0) index=0;
1608 if (widgetGlobals->snapshots[group][index].get(widgetGlobals->AddrSetValue,
1609 (int) *p->group)!=OK) {
1610 csound->Warning(csound, "could not get snapshot from group %d index %d \n",
1611 group, index);
1612 return OK;
1613 }
1614 }
1615 *p->inum_el = widgetGlobals->snapshots[group].size();
1616 return OK;
1617 }
1618
save_snap(CSOUND * csound,FLSAVESNAPS * p)1619 static int save_snap(CSOUND *csound, FLSAVESNAPS *p)
1620 {
1621 char s[MAXNAME], *s2;
1622 string filename;
1623 #ifdef WIN32
1624 int id = MessageBox(NULL, Str("Saving could overwrite the old file.\n"
1625 "Are you sure to save ?"), Str("Warning"),
1626 MB_SYSTEMMODAL | MB_ICONWARNING | MB_OKCANCEL);
1627 if (id != IDOK)
1628 return OK;
1629 #else
1630 # if !defined(NO_FLTK_THREADS)
1631 if (!((getFLTKFlags(csound) & 260) ^ 4))
1632 # endif
1633 {
1634 int n;
1635 Fl_lock(csound);
1636 n = fl_choice("%s", Str("Saving could overwrite the old file.\n"
1637 "Are you sure you want to save ?"),
1638 Str("No"), Str("Yes"), (const char*)""); // used to be NULL
1639 Fl_unlock(csound);
1640 if (!n)
1641 return OK;
1642 }
1643 #endif
1644 csound->strarg2name(csound, s, p->filename->data, "snap.", 1);
1645 s2 = csound->FindOutputFile(csound, s, "SNAPDIR");
1646 if (UNLIKELY(s2 == NULL))
1647 return csound->InitError(csound,"%s",
1648 Str("FLsavesnap: cannot open file"));
1649 strncpy(s, s2, MAXNAME-1);
1650 csound->Free(csound, s2);
1651 filename = s;
1652
1653 fstream file(filename.c_str(), ios::out);
1654 int group = (int) *p->group;
1655 WIDGET_GLOBALS *widgetGlobals =
1656 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
1657 for (int j =0; j < (int) widgetGlobals->snapshots[group].size(); j++) {
1658 file << "----------- "<< j << " -----------\n";
1659 int siz = widgetGlobals->snapshots[group][j].fields.size();
1660 for ( int k = 0; k < siz; k++) {
1661 VALUATOR_FIELD& f = widgetGlobals->snapshots[group][j].fields[k];
1662 // if (f.group != group) continue;
1663 if (f.opcode_name == "FLjoy") {
1664 file <<f.opcode_name<<" "<< f.value <<" "<< f.value2
1665 <<" "<< f.min <<" "<< f.max <<" "<< f.min2 <<" "
1666 << f.max2<<" "<<f.exp<<" "<<f.exp2<<" \"" <<f.widg_name<<"\"\n";
1667 }
1668 else if (f.opcode_name == "FLslidBnk" ||
1669 f.opcode_name == "FLvslidBnk" ||
1670 f.opcode_name == "FLslidBnk2" ||
1671 f.opcode_name == "FLvslidBnk2") {
1672 file << f.opcode_name << " " << f.exp
1673 << " "; // EXCEPTIONAL CASE! fld.exp contains the
1674 //number of sliders and not the exponential flag
1675 for (int i=0; i < f.exp; i++) {
1676 file << f.get_sldbnk(i) << " ";
1677 }
1678 file << " \"" << f.widg_name << "\"\n";
1679 }
1680 else {
1681 const char *s = f.opcode_name.c_str();
1682 if (*s != '\0') {
1683 file <<f.opcode_name<<" "<< f.value
1684 <<" "<< f.min <<" "<< f.max <<" "<<f.exp
1685 <<" \"" <<f.widg_name<<"\"\n";
1686 }
1687 }
1688 }
1689 }
1690 file << "---------------------------";
1691 file.close();
1692 return OK;
1693 }
1694
load_snap(CSOUND * csound,FLLOADSNAPS * p)1695 static int load_snap(CSOUND *csound, FLLOADSNAPS* p)
1696 {
1697 char s[MAXNAME], *s2;
1698 string filename;
1699 WIDGET_GLOBALS *widgetGlobals =
1700 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
1701 csound->strarg2name(csound, s, p->filename->data, "snap.", 1);
1702 s2 = csound->FindInputFile(csound, s, "SNAPDIR");
1703 if (UNLIKELY(s2 == NULL))
1704 return csound->InitError(csound,
1705 "%s", Str("FLloadsnap: cannot open file"));
1706 strncpy(s, s2, MAXNAME-1);
1707 csound->Free(csound, s2);
1708 filename = s;
1709
1710 fstream file(filename.c_str(), ios::in);
1711 int group = (int) *p->group;
1712 int j=0,k=-1,q=0;
1713 SNAPVEC snapvec_init;
1714 SNAPSHOT snap_init;
1715 snap_init.fields.resize(1,VALUATOR_FIELD());
1716 snapvec_init.resize(1,snap_init);
1717 if (group+1 > (int) widgetGlobals->snapshots.size())
1718 widgetGlobals->snapshots.resize(group+1, snapvec_init);
1719 while (!(file.eof())) {
1720 char buf[MAXNAME];
1721 file.getline(buf,MAXNAME-1);
1722
1723 stringstream sbuf;
1724 sbuf << buf;
1725
1726 string opc, opc_orig;
1727 getline(sbuf, opc, ' ');
1728 const char *ss = opc.c_str();
1729 if (*ss == '-') { // if it is a separation line
1730 k++; j=0; q=0;
1731 if ((int) widgetGlobals->snapshots[group].size() < k+1)
1732 widgetGlobals->snapshots[group].resize(k+1);
1733 }
1734 else if (*ss != '\0' && *ss != ' ' && *ss != '\n'){ //ignore blank lines
1735 ADDR_SET_VALUE* v = &(widgetGlobals->AddrSetValue[q]);
1736 while (widgetGlobals->AddrSetValue[q].group != group) {
1737 q++;
1738 if (q >= (int) widgetGlobals->AddrSetValue.size()) continue;
1739 v = &(widgetGlobals->AddrSetValue[q]);
1740 }
1741 if (k<0) return NOTOK;
1742 if ((int) widgetGlobals->snapshots[group][k].fields.size() < j+1)
1743 widgetGlobals->snapshots[group][k].fields.resize(j+1);
1744 widgetGlobals->snapshots[group][k].is_empty = 0;
1745 VALUATOR_FIELD& fld = widgetGlobals->snapshots[group][k].fields[j];
1746 opc_orig = ((OPDS *) (v->opcode))->optext->t.opcod;
1747
1748 if (UNLIKELY(!(opc_orig == opc))) {
1749 //return csound->InitError(csound,
1750 csound->Message(csound,
1751 "%s", Str("unmatched widget, probably due to a "
1752 "modified orchestra. Modifying an "
1753 "orchestra makes it incompatible with "
1754 "old snapshot files"));
1755 }
1756 else if (opc == "FLjoy") {
1757 fld.opcode_name = opc;
1758 string s;
1759 getline(sbuf,s, ' '); fld.value = atof(s.c_str());
1760 getline(sbuf,s, ' '); fld.value2 = atof(s.c_str());
1761 getline(sbuf,s, ' '); fld.min = atof(s.c_str());
1762 getline(sbuf,s, ' '); fld.max = atof(s.c_str());
1763 getline(sbuf,s, ' '); fld.min2 = atof(s.c_str());
1764 getline(sbuf,s, ' '); fld.max2 = atof(s.c_str());
1765 getline(sbuf,s, ' '); fld.exp = atoi(s.c_str());
1766 getline(sbuf,s, ' '); fld.exp2 = atoi(s.c_str());
1767 getline(sbuf,s, '\"');
1768 getline(sbuf,s, '\"'); fld.widg_name = s;
1769 }
1770 else if (opc == "FLslidBnk" || opc == "FLvslidBnk"
1771 || opc == "FLslidBnk2" || opc == "FLvslidBnk2" ) {
1772 fld.opcode_name = opc;
1773 string s;
1774 getline(sbuf,s, ' ');
1775 // EXCEPTIONAL CASE! fld.exp contains the number of sliders
1776 // and not the exponential flag
1777 fld.exp = atoi(s.c_str());
1778 // fld.sldbnkValues = new MYFLT[fld.exp];
1779 // fld.insert_sldbnk(fld.exp);
1780 // allocatedStrings.push_back((char *) fld.sldbnkValues);
1781 // widgetGlobals->allocatedStrings.push_back((char *) fld.sldbnkValues);
1782
1783 for (int kk =0; kk < fld.exp; kk++) {
1784 getline(sbuf,s, ' ');
1785 // fld.sldbnkValues[kk] = atof(s.c_str());
1786 fld.set_sldbnk(kk,atof(s.c_str()));
1787
1788 }
1789 getline(sbuf,s, '\"');
1790 getline(sbuf,s, '\"'); fld.widg_name = s;
1791 }
1792 else {
1793 fld.opcode_name = opc;
1794 string s;
1795 getline(sbuf,s, ' '); fld.value = atof(s.c_str());
1796 getline(sbuf,s, ' '); fld.min = atof(s.c_str());
1797 getline(sbuf,s, ' '); fld.max = atof(s.c_str());
1798 getline(sbuf,s, ' '); fld.exp = atoi(s.c_str());
1799 getline(sbuf,s, '\"');
1800 getline(sbuf,s, '\"'); fld.widg_name = s;
1801 }
1802 j++; q++;
1803 }
1804 }
1805
1806 file.close();
1807 return OK;
1808 }
1809
1810 static int fltkKeyboardCallback(void *, void *, unsigned int);
1811
1812 } // extern "C"
1813
1814 // -----------
1815
1816 /* unused
1817 static char *GetString(CSOUND *csound, MYFLT *pname, int is_string)
1818 {
1819 char *Name = new char[MAXNAME];
1820 WIDGET_GLOBALS *widgetGlobals =
1821 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
1822 widgetGlobals->allocatedStrings.push_back(Name);
1823 return csound->strarg2name(csound, Name, pname, "", is_string);
1824 }
1825 */
1826
1827 class CsoundFLTKKeyboardBuffer {
1828 private:
1829 CSOUND *csound;
1830 WIDGET_GLOBALS *widgetGlobals;
1831 void *mutex_;
1832 char kbdTextBuf[64];
1833 int kbdEvtBuf[64];
1834 int kbdTextBufRPos;
1835 int kbdTextBufWPos;
1836 int kbdEvtBufRPos;
1837 int kbdEvtBufWPos;
1838 std::map<int, unsigned char> keyboardState;
lockMutex()1839 void lockMutex()
1840 {
1841 if (mutex_)
1842 csound->LockMutex(mutex_);
1843 }
unlockMutex()1844 void unlockMutex()
1845 {
1846 if (mutex_)
1847 csound->UnlockMutex(mutex_);
1848 }
1849 public:
CsoundFLTKKeyboardBuffer(CSOUND * csound)1850 CsoundFLTKKeyboardBuffer(CSOUND *csound)
1851 {
1852 this->csound = csound;
1853 widgetGlobals =
1854 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
1855 mutex_ = csound->Create_Mutex(0);
1856 kbdTextBufRPos = 0;
1857 kbdTextBufWPos = 0;
1858 kbdEvtBufRPos = 0;
1859 kbdEvtBufWPos = 0;
1860 }
~CsoundFLTKKeyboardBuffer()1861 ~CsoundFLTKKeyboardBuffer()
1862 {
1863 if (mutex_) {
1864 csound->DestroyMutex(mutex_);
1865 mutex_ = (void*) 0;
1866 }
1867 }
GetCsound()1868 CSOUND *GetCsound()
1869 {
1870 return csound;
1871 }
writeFLEvent(int evt)1872 void writeFLEvent(int evt)
1873 {
1874 const char *s;
1875 int keyCode;
1876 keyCode = (int) Fl::event_key() & (int) 0xFFFF;
1877 if (keyCode) {
1878 lockMutex();
1879 if (evt == FL_KEYDOWN) {
1880 s = Fl::event_text();
1881 while (*s != (char) 0) {
1882 kbdTextBuf[kbdTextBufWPos] = *(s++);
1883 kbdTextBufWPos = (kbdTextBufWPos + 1) & 63;
1884 }
1885 if (keyboardState[keyCode] == (unsigned char) 0) {
1886 keyboardState[keyCode] = (unsigned char) 1;
1887 kbdEvtBuf[kbdEvtBufWPos] = keyCode;
1888 kbdEvtBufWPos = (kbdEvtBufWPos + 1) & 63;
1889 }
1890 }
1891 else if (keyboardState[keyCode] != (unsigned char) 0) {
1892 keyboardState[keyCode] = (unsigned char) 0;
1893 kbdEvtBuf[kbdEvtBufWPos] = keyCode | (int) 0x10000;
1894 kbdEvtBufWPos = (kbdEvtBufWPos + 1) & 63;
1895 }
1896 unlockMutex();
1897 }
1898 }
getKeyboardText()1899 int getKeyboardText()
1900 {
1901 int retval = 0;
1902 lockMutex();
1903 if (kbdTextBufRPos != kbdTextBufWPos) {
1904 retval = (int) ((unsigned char) kbdTextBuf[kbdTextBufRPos]);
1905 kbdTextBufRPos = (kbdTextBufRPos + 1) & 63;
1906 }
1907 unlockMutex();
1908 return retval;
1909 }
getKeyboardEvent()1910 int getKeyboardEvent()
1911 {
1912 int retval = 0;
1913 lockMutex();
1914 if (kbdEvtBufRPos != kbdEvtBufWPos) {
1915 retval = kbdEvtBuf[kbdEvtBufRPos];
1916 kbdEvtBufRPos = (kbdEvtBufRPos + 1) & 63;
1917 }
1918 unlockMutex();
1919 return retval;
1920 }
1921 };
1922
1923 class CsoundFLWindow : public Fl_Double_Window {
1924 public:
1925 CSOUND *csound_; //gab
1926 WIDGET_GLOBALS *widgetGlobals;
1927 CsoundFLTKKeyboardBuffer fltkKeyboardBuffer;
CsoundFLWindow(CSOUND * csound,int w,int h,const char * title=0)1928 CsoundFLWindow(CSOUND *csound, int w, int h, const char *title = 0)
1929 : Fl_Double_Window(w, h, title),
1930 csound_(csound),
1931 fltkKeyboardBuffer(csound)//gab
1932 {
1933 widgetGlobals =
1934 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
1935 csound->Set_KeyCallback(csound, fltkKeyboardCallback, (void*) this,
1936 CSOUND_CALLBACK_KBD_EVENT | CSOUND_CALLBACK_KBD_TEXT);
1937 }
CsoundFLWindow(CSOUND * csound,int x,int y,int w,int h,const char * title=0)1938 CsoundFLWindow(CSOUND *csound,
1939 int x, int y, int w, int h, const char *title = 0)
1940 : Fl_Double_Window(x, y, w, h, title),
1941 csound_(csound),
1942 fltkKeyboardBuffer(csound)//gab
1943 {
1944 widgetGlobals =
1945 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
1946 csound->Set_KeyCallback(csound, fltkKeyboardCallback, (void*) this,
1947 CSOUND_CALLBACK_KBD_EVENT | CSOUND_CALLBACK_KBD_TEXT);
1948 }
~CsoundFLWindow()1949 virtual ~CsoundFLWindow()
1950 {
1951 CSOUND *csound = fltkKeyboardBuffer.GetCsound();
1952 csound->Remove_KeyCallback(csound, fltkKeyboardCallback);
1953 }
handle(int evt)1954 virtual int handle(int evt)
1955 {
1956 switch (evt) {
1957 case FL_FOCUS:
1958 Fl::focus(this);
1959 /* FALLTHRU */
1960 case FL_UNFOCUS:
1961 return 1;
1962 case FL_KEYDOWN:
1963 widgetGlobals->last_KEY = Fl::event_key(); //gab
1964 widgetGlobals->isKeyDown = true; //gab
1965 break;
1966 case FL_KEYUP:
1967 widgetGlobals->last_KEY = Fl::event_key(); //gab
1968 widgetGlobals->isKeyDown = false; //gab
1969 if (Fl::focus() == this)
1970 fltkKeyboardBuffer.writeFLEvent(evt);
1971 break;
1972 }
1973 return Fl_Window::handle(evt);
1974 }
1975 };
1976
1977 extern "C"
1978 {
fltkKeyboardCallback(void * userData,void * p,unsigned int type)1979 static int fltkKeyboardCallback(void *userData, void *p, unsigned int type)
1980 {
1981 switch (type) {
1982 case CSOUND_CALLBACK_KBD_EVENT:
1983 *((int*) p) =
1984 ((CsoundFLWindow*) userData)->fltkKeyboardBuffer.getKeyboardEvent();
1985 break;
1986 case CSOUND_CALLBACK_KBD_TEXT:
1987 *((int*) p) =
1988 ((CsoundFLWindow*) userData)->fltkKeyboardBuffer.getKeyboardText();
1989 break;
1990 default:
1991 return 1;
1992 }
1993 return 0;
1994 }
1995
csoundModuleDestroy(CSOUND * csound)1996 PUBLIC int csoundModuleDestroy(CSOUND *csound)
1997 {
1998 int j;
1999 WIDGET_GLOBALS *widgetGlobals =
2000 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
2001 #ifndef NO_FLTK_THREADS
2002 int *fltkflags = getFLTKFlagsPtr(csound);
2003 if (fltkflags) {
2004 if ((*fltkflags & 260) ^ 4) {
2005 widgetsGlobals_t *p =
2006 (widgetsGlobals_t*) csound->QueryGlobalVariable(csound,
2007 "_widgets_globals");
2008 if (p) {
2009 if (!(*fltkflags & 256)) {
2010 /* if window(s) still open: */
2011 if (!p->exit_now) {
2012 /* notify GUI thread... */
2013 p->end_of_perf = -1;
2014 Fl_lock(csound);
2015 Fl_awake(csound);
2016 Fl_unlock(csound);
2017 /* ...and wait for it to close */
2018 csound->JoinThread(p->threadHandle);
2019 p->threadHandle = NULL;
2020 }
2021 }
2022 /* clean up */
2023 csound->LockMutex(p->mutex_);
2024 while (p->eventQueue != NULL) {
2025 rtEvt_t *nxt = p->eventQueue->nxt;
2026 free(p->eventQueue);
2027 p->eventQueue = nxt;
2028 }
2029 csound->UnlockMutex(p->mutex_);
2030 csound->DestroyMutex(p->mutex_);
2031 csound->DestroyGlobalVariable(csound, "_widgets_globals");
2032 }
2033 }
2034 }
2035 #endif // NO_FLTK_THREADS
2036 if(widgetGlobals != NULL) {
2037 for (j = widgetGlobals->allocatedStrings.size() - 1; j >= 0; j--) {
2038 delete[] widgetGlobals->allocatedStrings[j];
2039 widgetGlobals->allocatedStrings.pop_back();
2040 }
2041 j = widgetGlobals->fl_windows.size();
2042 if (j > 0) {
2043 // destroy all opened panels
2044 do {
2045 j--;
2046 if (widgetGlobals->fl_windows[j].is_subwindow == 0)
2047 delete widgetGlobals->fl_windows[j].panel;
2048 // VL: this might leak memory, needs checking.
2049 widgetGlobals->fl_windows.pop_back();
2050 } while (j);
2051 Fl_wait_locked(csound, 0.0);
2052 }
2053 widgetGlobals->AddrStack.~vector<ADDR_STACK>();
2054 widgetGlobals->allocatedStrings.~vector<char*>();
2055 widgetGlobals->fl_windows.~vector<PANELS>();
2056 for (size_t si = 0, sn = widgetGlobals->snapshots.size(); si < sn; ++si) {
2057 SNAPVEC &svec = widgetGlobals->snapshots[si];
2058 int ss = svec.size();
2059 for (j = 0; j < ss; j++) {
2060 svec[j].fields.erase(svec[j].fields.begin(),
2061 svec[j].fields.end());
2062 // VL: probably leaks memory, needs checking.
2063 svec.resize(svec.size() + 1);
2064 }
2065 }
2066 widgetGlobals->AddrSetValue.clear(); // VL: leaks memory, needs fixing.
2067 widgetGlobals->stack_count = 0;
2068 widgetGlobals->FLcontrol_iheight = 15;
2069 widgetGlobals->FLroller_iheight = 18;
2070 widgetGlobals->FLcontrol_iwidth = 400;
2071 widgetGlobals->FLroller_iwidth = 150;
2072 widgetGlobals->FLvalue_iwidth = 100;
2073 widgetGlobals->FLcolor = -1;
2074 widgetGlobals->FLcolor2 = -1;
2075 widgetGlobals->FLtext_size = 0;
2076 widgetGlobals->FLtext_color = -1;
2077 widgetGlobals->FLtext_font = -1;
2078 widgetGlobals->FLtext_align = 0;
2079 widgetGlobals->FL_ix = 10;
2080 widgetGlobals->FL_iy = 10;
2081
2082 //delete (WIDGET_GLOBALS*)csound->widgetGlobals;
2083 csound->DestroyGlobalVariable(csound, "WIDGET_GLOBALS");
2084 //csound->widgetGlobals = NULL;
2085 }
2086 return 0;
2087 }
2088 } // extern "C"
2089
2090 //-----------
2091
2092 #ifndef NO_FLTK_THREADS
2093
2094 extern "C" {
2095
fltkRun(void * userdata)2096 static uintptr_t fltkRun(void *userdata)
2097 {
2098 volatile widgetsGlobals_t *p;
2099 CSOUND *csound = (CSOUND*) userdata;
2100 int j;
2101 WIDGET_GLOBALS *widgetGlobals =
2102 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
2103 p = (widgetsGlobals_t*) csound->QueryGlobalVariable(csound,
2104 "_widgets_globals");
2105 #ifdef LINUX
2106 {
2107 struct sched_param sp;
2108 // IV - Aug 27 2002: widget thread is always run with normal priority
2109 memset(&sp, 0, sizeof(struct sched_param));
2110 pthread_setschedparam(pthread_self(), SCHED_OTHER, &sp);
2111 }
2112 #endif
2113
2114 if (!(p->fltkFlags & 8))
2115 Fl::lock();
2116 for (j = 0; j < (int) widgetGlobals->fl_windows.size(); j++) {
2117 widgetGlobals->fl_windows[j].panel->show();
2118 }
2119 // #ifdef CS_VSTHOST
2120 // for (size_t k=0; k < widgetGlobals->VSTplugEditors.size(); k++) {
2121 // int panelNum = widgetGlobals->VSTplugEditors[k]->targetFLpanel;
2122 // #ifdef WIN32
2123 // HWND xid = fl_xid(widgetGlobals->fl_windows[panelNum].panel);
2124 // widgetGlobals->VSTplugEditors[k]->SetEditWindow(xid);
2125 // #elif defined (LINUX) || defined(MACOSX)
2126 // // put some appropriate alternative code here
2127 // Fl_Window * xid =
2128 // fl_find(fl_xid(widgetGlobals->fl_windows[panelNum].panel));
2129 // widgetGlobals->VSTplugEditors[k]->SetEditWindow(xid);
2130 // #endif // WIN32
2131 // }
2132 // #endif // CS_VSTHOST
2133 if (!(p->fltkFlags & 16))
2134 Fl::awake();
2135 if (!(p->fltkFlags & 8))
2136 Fl::unlock();
2137 do {
2138 if (!(p->fltkFlags & 8))
2139 Fl::lock();
2140 Fl::wait(0.02);
2141 j = (Fl::first_window() != (Fl_Window*) 0);
2142 if (!(p->fltkFlags & 8))
2143 Fl::unlock();
2144 } while (j && !p->end_of_perf);
2145 csound->Message(csound, "%s", Str("end of widget thread\n"));
2146 // IV - Jun 07 2005: exit if all windows are closed
2147 p->exit_now = -1;
2148 return (uintptr_t) 0;
2149 }
2150
2151 } // extern "C"
2152
2153 #endif // NO_FLTK_THREADS
2154
2155 extern "C" {
2156
2157 int CsoundYield_FLTK(CSOUND *csound);
2158
FL_run(CSOUND * csound,FLRUN * p)2159 int FL_run(CSOUND *csound, FLRUN *p)
2160 {
2161 IGN(p);
2162 int *fltkFlags;
2163 WIDGET_GLOBALS *widgetGlobals =
2164 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
2165 fltkFlags = getFLTKFlagsPtr(csound);
2166 (*fltkFlags) |= 32;
2167 #ifndef NO_FLTK_THREADS
2168 if (((*fltkFlags) & 260) ^ 4) {
2169 widgetsGlobals_t *pp;
2170
2171 if (UNLIKELY(csound->QueryGlobalVariable(csound,
2172 "_widgets_globals") != NULL))
2173 return csound->InitError(csound, "%s", Str("FLrun was already called"));
2174 if (UNLIKELY(csound->CreateGlobalVariable(csound, "_widgets_globals",
2175 sizeof(widgetsGlobals_t)) != 0))
2176 csound->Die(csound, "%s", Str("FL_run: memory allocation failure"));
2177 pp = (widgetsGlobals_t*) csound->QueryGlobalVariable(csound,
2178 "_widgets_globals");
2179 pp->fltkFlags = *fltkFlags;
2180 /* create thread lock */
2181 pp->mutex_ = csound->Create_Mutex(0);
2182 /* register callback function to be called by sensevents() */
2183 csound->RegisterSenseEventCallback(csound, (void (*)(CSOUND *, void *))
2184 evt_callback,
2185 (void*) pp);
2186 if (!((*fltkFlags) & 256)) {
2187 pp->threadHandle = csound->CreateThread(fltkRun, (void*) csound);
2188 return OK;
2189 }
2190 }
2191 #endif // NO_FLTK_THREADS
2192 {
2193 int j;
2194
2195 Fl_lock(csound);
2196 for (j = 0; j < (int) widgetGlobals->fl_windows.size(); j++) {
2197 widgetGlobals->fl_windows[j].panel->show();
2198 }
2199 Fl_wait(csound, 0.0);
2200 Fl_unlock(csound);
2201
2202
2203 if (!((*fltkFlags) & 256))
2204 csound->SetInternalYieldCallback(csound, CsoundYield_FLTK);
2205 }
2206 return OK;
2207 }
2208
fl_update(CSOUND * csound,FLRUN * p)2209 int fl_update(CSOUND *csound, FLRUN *p)
2210 {
2211 IGN(p);
2212 WIDGET_GLOBALS *widgetGlobals =
2213 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
2214 Fl_lock(csound);
2215 for (int j=0; j< (int) widgetGlobals->AddrSetValue.size()-1; j++) {
2216 ADDR_SET_VALUE v = widgetGlobals->AddrSetValue[j];
2217 Fl_Valuator *o = (Fl_Valuator *) v.WidgAddress;
2218 o->do_callback(o, v.opcode);
2219 }
2220 Fl_unlock(csound);
2221 return OK;
2222 }
2223 } // extern "C"
2224
2225 //----------------------------------------------
2226
displ(MYFLT val,MYFLT index,CSOUND * csound)2227 static inline void displ(MYFLT val, MYFLT index, CSOUND *csound)
2228 {
2229 WIDGET_GLOBALS *widgetGlobals =
2230 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
2231 if (index >= 0) { // display current value of valuator
2232 char valString[MAXNAME];
2233 sprintf(valString, "%.5g", val);
2234 ((Fl_Output*) (widgetGlobals->AddrSetValue[(long) index]).WidgAddress)->
2235 value(valString);
2236 }
2237 }
2238
fl_callbackButton1(Fl_Button * w,void * a)2239 static void fl_callbackButton1(Fl_Button* w, void *a)
2240 {
2241 IGN(w);
2242 FLBUTTON *p = (FLBUTTON *) a;
2243 *((FLBUTTON*) a)->kout = *p->ion;
2244 if (*p->args[0] >= 0) ButtonSched(p->h.insdshead->csound,
2245 p->args, p->INOCOUNT-8);
2246 }
2247
fl_callbackCloseButton(Fl_Button * w,void * a)2248 static void fl_callbackCloseButton(Fl_Button* w, void *a)
2249 {
2250 IGN(w);
2251 Fl_Window *p = (Fl_Window *) a;
2252 p->hide();
2253 }
2254
fl_callbackExecButton(Fl_Button * w,void * a)2255 static void fl_callbackExecButton(Fl_Button* w, void *a)
2256 {
2257 IGN(w);
2258 FLEXECBUTTON *p = (FLEXECBUTTON *)a;
2259 CSOUND *csound = p->csound;
2260 char *command = (char *)csound->Malloc(csound, strlen(p->commandString) + 1);
2261
2262 #if defined(LINUX) || defined (MACOSX)
2263
2264
2265 pid_t pId = vfork();
2266 if (pId == 0) {
2267 char *th;
2268 char *v[40];
2269 int i = 0;
2270
2271 strcpy(command, p->commandString);
2272
2273 char *tok = csound->strtok_r(command,(char *) " ", &th);
2274
2275 if(tok != NULL) {
2276 v[i++] = tok;
2277 while((tok = csound->strtok_r(NULL,(char *) " ", &th)) != NULL) {
2278 v[i++] = tok;
2279 }
2280 v[i] = NULL;
2281 execvp(v[0], v);
2282 }
2283
2284 _exit(0);
2285 } else if (UNLIKELY(pId < 0)) {
2286 p->csound->Message(p->csound,
2287 "%s", Str("Error: Unable to fork process\n"));
2288 }
2289
2290 csound->Free(csound, command);
2291 #elif defined(WIN32)
2292 {
2293 #undef strtok_r // undefine from pthread.h on Windows
2294 char *th;
2295 char *v[40];
2296 int i = 0;
2297
2298 strcpy(command, p->commandString);
2299 char *tok = csound->strtok_r(command,(char *) " ", &th);
2300
2301 if(tok != NULL) {
2302 v[i++] = tok;
2303 while((tok = csound->strtok_r(NULL,(char *) " ", &th)) != NULL) {
2304 v[i++] = tok;
2305 }
2306 v[i] = NULL;
2307 csound->Free(csound, command); // Otherwise will lose space
2308 if (UNLIKELY(csound->RunCommand(v, 1)<0))
2309 p->csound->Message(p->csound, "%s",
2310 Str("Error: Unable to fork process\n"));
2311 }
2312 }
2313 #endif
2314 }
2315
fl_callbackButton(Fl_Button * w,void * a)2316 static void fl_callbackButton(Fl_Button* w, void *a)
2317 {
2318 FLBUTTON *p = (FLBUTTON *) a;
2319 *((FLBUTTON*) a)->kout = (w->value()) ? *p->ion : *p->ioff;
2320 if (*p->args[0] >= 0) ButtonSched(p->h.insdshead->csound,
2321 p->args, p->INOCOUNT-8);
2322 }
2323
fl_callbackButtonBank(Fl_Button * w,void * a)2324 static void fl_callbackButtonBank(Fl_Button* w, void *a)
2325 {
2326 FLBUTTONBANK *p = (FLBUTTONBANK *) a;
2327 *((FLBUTTONBANK*) a)->kout = (MYFLT) atoi(w->label());
2328 if (*p->args[0] >= 0) ButtonSched(p->h.insdshead->csound,
2329 p->args, p->INOCOUNT-7);
2330 }
2331
fl_callbackCounter(Fl_Counter * w,void * a)2332 static void fl_callbackCounter(Fl_Counter* w, void *a)
2333 {
2334 FLCOUNTER *p = (FLCOUNTER *) a;
2335 *((FLCOUNTER*) a)->kout = w->value();
2336 if (*p->args[0] >= 0) ButtonSched(p->h.insdshead->csound,
2337 p->args, p->INOCOUNT-10);
2338 }
2339
fl_callbackLinearSlider(Fl_Valuator * w,void * a)2340 static void fl_callbackLinearSlider(Fl_Valuator* w, void *a)
2341 {
2342 FLSLIDER *p = ((FLSLIDER*) a);
2343 displ(*p->kout = w->value(), *p->idisp, p->h.insdshead->csound);
2344 }
2345
fl_callbackExponentialSlider(Fl_Valuator * w,void * a)2346 static void fl_callbackExponentialSlider(Fl_Valuator* w, void *a)
2347 {
2348 FLSLIDER *p = ((FLSLIDER*) a);
2349 #if defined(sun)
2350 displ(*p->kout = p->min * ::pow ((double)p->base, w->value()),
2351 *p->idisp, p->h.insdshead->csound);
2352 #else
2353 displ(*p->kout = p->min * ::pow (p->base, w->value()),
2354 *p->idisp, p->h.insdshead->csound);
2355 #endif
2356 }
2357
fl_callbackInterpTableSlider(Fl_Valuator * w,void * a)2358 static void fl_callbackInterpTableSlider(Fl_Valuator* w, void *a)
2359 {
2360 FLSLIDER *p = ((FLSLIDER*) a);
2361 MYFLT ndx = w->value() * (p->tablen-1);
2362 int index = (int) ndx;
2363 MYFLT v1 = p->table[index];
2364 displ(*p->kout = p->min+ ( v1 + (p->table[index+1] - v1) *
2365 (ndx - index)) * (*p->imax - p->min),
2366 *p->idisp, p->h.insdshead->csound);
2367 }
2368
fl_callbackTableSlider(Fl_Valuator * w,void * a)2369 static void fl_callbackTableSlider(Fl_Valuator* w, void *a)
2370 {
2371 FLSLIDER *p = ((FLSLIDER*) a);
2372 displ(*p->kout = p->min+ p->table[(long) (w->value() * p->tablen)] *
2373 (*p->imax - p->min),
2374 *p->idisp, p->h.insdshead->csound);
2375 }
2376
fl_callbackLinearSliderBank(Fl_Valuator * w,void * a)2377 static void fl_callbackLinearSliderBank(Fl_Valuator* w, void *a)
2378 {
2379 SLDBK_ELEMENT* p = (SLDBK_ELEMENT*) a;
2380 *p->out = w->value();
2381 }
2382
fl_callbackExponentialSliderBank(Fl_Valuator * w,void * a)2383 static void fl_callbackExponentialSliderBank(Fl_Valuator* w, void *a)
2384 {
2385 SLDBK_ELEMENT* p = (SLDBK_ELEMENT*) a;
2386 #if defined(sun)
2387 *p->out = p->min * ::pow ((double)p->base, w->value());
2388 #else
2389 *p->out = p->min * ::pow (p->base, w->value());
2390 #endif
2391 }
2392
fl_callbackInterpTableSliderBank(Fl_Valuator * w,void * a)2393 static void fl_callbackInterpTableSliderBank(Fl_Valuator* w, void *a)
2394 {
2395 SLDBK_ELEMENT *p = ((SLDBK_ELEMENT*) a);
2396
2397 MYFLT ndx = w->value() * (p->tablen-1);
2398 int index = (int) ndx;
2399 MYFLT v1 = p->table[index];
2400 *p->out = p->min + ( v1 + (p->table[index+1] - v1) * (ndx - index)) *
2401 (p->max - p->min);
2402 }
2403
fl_callbackTableSliderBank(Fl_Valuator * w,void * a)2404 static void fl_callbackTableSliderBank(Fl_Valuator* w, void *a)
2405 {
2406 SLDBK_ELEMENT *p = ((SLDBK_ELEMENT*) a);
2407 *p->out = p->min + p->table[(long)(w->value() * p->tablen)] *
2408 (p->max - p->min);
2409 }
2410
fl_callbackJoystick(Fl_Widget * w,void * a)2411 static void fl_callbackJoystick(Fl_Widget* w, void *a)
2412 {
2413 FLJOYSTICK *p = (FLJOYSTICK*) a;
2414 Fl_Positioner *j = (Fl_Positioner*) w;
2415 MYFLT val;
2416 int iexpx = (int) *p->iexpx, iexpy = (int) *p->iexpy;
2417 switch (iexpx) {
2418 case LIN_:
2419 val = j->xvalue();
2420 break;
2421 case EXP_:
2422 #if defined(sun)
2423 val = *p->iminx * ::pow ((double)p->basex, j->xvalue());
2424 #else
2425 val = *p->iminx * ::pow (p->basex, j->xvalue());
2426 #endif
2427 break;
2428 default:
2429 if (iexpx > 0) { //interpolated
2430 MYFLT ndx = j->xvalue() * (p->tablenx-1);
2431 int index = (int) ndx;
2432 MYFLT v1 = p->tablex[index];
2433 val = *p->iminx + ( v1 + (p->tablex[index+1] - v1) *
2434 (ndx - index)) * (*p->imaxx - *p->iminx);
2435 }
2436 else // non-interpolated
2437 val = *p->iminx+ p->tablex[(long) (j->xvalue() * p->tablenx)] *
2438 (*p->imaxx - *p->iminx);
2439 }
2440 displ(*p->koutx = val,*p->idispx, p->h.insdshead->csound);
2441 switch (iexpy) {
2442 case LIN_:
2443 val = j->yvalue();
2444 break;
2445 case EXP_:
2446 #if defined(sun)
2447 val = *p->iminy * ::pow ((double)p->basey, j->yvalue());
2448 #else
2449 val = *p->iminy * ::pow (p->basey, j->yvalue());
2450 #endif
2451 break;
2452 default:
2453 if (iexpy > 0) { //interpolated
2454 MYFLT ndx = j->yvalue() * (p->tableny-1);
2455 long index = (long) ndx;
2456 MYFLT v1 = p->tabley[index];
2457 val = *p->iminy + ( v1 + (p->tabley[index+1] - v1) * (ndx - index))
2458 * (*p->imaxy - *p->iminy);
2459 }
2460 else { // non-interpolated
2461 long index = (long) (j->yvalue()* p->tableny);
2462 val = *p->iminy+ p->tabley[index] * (*p->imaxy - *p->iminy);
2463
2464 }
2465 }
2466 displ(*p->kouty = val, *p->idispy, p->h.insdshead->csound);
2467 }
2468
fl_callbackLinearRoller(Fl_Valuator * w,void * a)2469 static void fl_callbackLinearRoller(Fl_Valuator* w, void *a)
2470 {
2471 FLROLLER *p = ((FLROLLER*) a);
2472 displ(*p->kout = w->value(),*p->idisp, p->h.insdshead->csound);
2473 }
2474
fl_callbackExponentialRoller(Fl_Valuator * w,void * a)2475 static void fl_callbackExponentialRoller(Fl_Valuator* w, void *a)
2476 {
2477 FLROLLER *p = ((FLROLLER*) a);
2478 #if defined(sun)
2479 displ(*p->kout = ((FLROLLER*) a)->min * ::pow ((double)p->base, w->value()),
2480 *p->idisp, p->h.insdshead->csound);
2481 #else
2482 displ(*p->kout = ((FLROLLER*) a)->min * ::pow (p->base, w->value()),
2483 *p->idisp, p->h.insdshead->csound);
2484 #endif
2485 }
2486
fl_callbackInterpTableRoller(Fl_Valuator * w,void * a)2487 static void fl_callbackInterpTableRoller(Fl_Valuator* w, void *a)
2488 {
2489 FLROLLER *p = ((FLROLLER*) a);
2490 MYFLT ndx = w->value() * (p->tablen-1);
2491 int index = (int) ndx;
2492 MYFLT v1 = p->table[index];
2493 displ(*p->kout = p->min+ ( v1 + (p->table[index+1] - v1) * (ndx - index)) *
2494 (*p->imax - p->min), *p->idisp, p->h.insdshead->csound);
2495 }
2496
fl_callbackTableRoller(Fl_Valuator * w,void * a)2497 static void fl_callbackTableRoller(Fl_Valuator* w, void *a)
2498 {
2499 FLROLLER *p = ((FLROLLER*) a);
2500 displ(*p->kout = p->min+ p->table[(long) (w->value() * p->tablen)] *
2501 (*p->imax - p->min), *p->idisp, p->h.insdshead->csound);
2502 }
2503
fl_callbackLinearKnob(Fl_Valuator * w,void * a)2504 static void fl_callbackLinearKnob(Fl_Valuator* w, void *a)
2505 {
2506 FLKNOB *p = ((FLKNOB*) a);
2507 displ( *p->kout = w->value(), *p->idisp, p->h.insdshead->csound);
2508 }
2509
fl_callbackExponentialKnob(Fl_Valuator * w,void * a)2510 static void fl_callbackExponentialKnob(Fl_Valuator* w, void *a)
2511 {
2512 FLKNOB *p = ((FLKNOB*) a);
2513 #if defined(sun)
2514 displ(*p->kout = ((FLKNOB*) a)->min * ::pow ((double)p->base, w->value()),
2515 *p->idisp, p->h.insdshead->csound);
2516 #else
2517 displ(*p->kout = ((FLKNOB*) a)->min * ::pow (p->base, w->value()),
2518 *p->idisp, p->h.insdshead->csound);
2519 #endif
2520 }
2521
fl_callbackInterpTableKnob(Fl_Valuator * w,void * a)2522 static void fl_callbackInterpTableKnob(Fl_Valuator* w, void *a)
2523 {
2524 FLKNOB *p = ((FLKNOB*) a);
2525 MYFLT ndx = w->value() * (p->tablen-1);
2526 int index = (int) ndx;
2527 MYFLT v1 = p->table[index];
2528 displ(*p->kout = p->min+ ( v1 + (p->table[index+1] - v1) * (ndx - index)) *
2529 (*p->imax - p->min), *p->idisp, p->h.insdshead->csound);
2530 }
2531
fl_callbackTableKnob(Fl_Valuator * w,void * a)2532 static void fl_callbackTableKnob(Fl_Valuator* w, void *a)
2533 {
2534 FLKNOB *p = ((FLKNOB*) a);
2535 displ(*p->kout = p->min+ p->table[(long) (w->value() * p->tablen)] *
2536 (*p->imax - p->min), *p->idisp, p->h.insdshead->csound);
2537 }
2538
fl_callbackLinearValueInput(Fl_Valuator * w,void * a)2539 static void fl_callbackLinearValueInput(Fl_Valuator* w, void *a)
2540 {
2541 *((FLTEXT*) a)->kout = w->value();
2542 }
2543
2544 //-----------
2545
rand_31_i(CSOUND * csound,int maxVal)2546 static int rand_31_i(CSOUND *csound, int maxVal)
2547 {
2548 int seed = csound->GetRandSeed(csound,2);
2549 double x = (double) (csound->Rand31(&seed) - 1);
2550 return (int) (x * (double) (maxVal + 1) / 2147483646.0);
2551 }
2552
widget_attributes(CSOUND * csound,Fl_Widget * o)2553 static void widget_attributes(CSOUND *csound, Fl_Widget *o)
2554 {
2555 WIDGET_GLOBALS *widgetGlobals =
2556 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
2557 if (widgetGlobals->FLtext_size == -2 ) {
2558 widgetGlobals->FLtext_size = -1;
2559 widgetGlobals->FLtext_color= -1;
2560 widgetGlobals->FLtext_font = -1;
2561 widgetGlobals->FLtext_align= -1;
2562 widgetGlobals->FLcolor = -1;
2563 }
2564 if (widgetGlobals->FLtext_size > 0)
2565 // if > 0 assign it, else skip, leaving default
2566 o->labelsize(widgetGlobals->FLtext_size);
2567 switch ((int) widgetGlobals->FLtext_color) {
2568 case -2: // random color
2569 o->labelcolor(fl_rgb_color(rand_31_i(csound, 255), rand_31_i(csound, 255),
2570 rand_31_i(csound, 255)));
2571 break;
2572 case -1:
2573 // if FLtext_color is == -1, color assignment is skipped,
2574 // leaving default color
2575 break;
2576 default:
2577 o->labelcolor(widgetGlobals->FLtext_color);
2578 break;
2579 }
2580 if (widgetGlobals->FLtext_font> 0) {
2581 Fl_Font font;
2582 if (widgetGlobals->FLtext_font<0 ||
2583 widgetGlobals->FLtext_font>16) font = FL_HELVETICA;
2584 else font = FONT_TABLE[widgetGlobals->FLtext_font];
2585 // switch (FLtext_font) {
2586 // case 1: font = FL_HELVETICA; break;
2587 // case 2: font = FL_HELVETICA_BOLD; break;
2588 // case 3: font = FL_HELVETICA_ITALIC; break;
2589 // case 4: font = FL_HELVETICA_BOLD_ITALIC; break;
2590 // case 5: font = FL_COURIER; break;
2591 // case 6: font = FL_COURIER_BOLD; break;
2592 // case 7: font = FL_COURIER_ITALIC; break;
2593 // case 8: font = FL_COURIER_BOLD_ITALIC; break;
2594 // case 9: font = FL_TIMES; break;
2595 // case 10: font = FL_TIMES_BOLD; break;
2596 // case 11: font = FL_TIMES_ITALIC; break;
2597 // case 12: font = FL_TIMES_BOLD_ITALIC; break;
2598 // case 13: font = FL_SYMBOL; break;
2599 // case 14: font = FL_SCREEN; break;
2600 // case 15: font = FL_SCREEN_BOLD; break;
2601 // case 16: font = FL_ZAPF_DINGBATS; break;
2602 // default: font = FL_HELVETICA; break;
2603 // }
2604 o->labelfont(font);
2605 }
2606 if (widgetGlobals->FLtext_align > 0) {
2607 Fl_Align type;
2608 if (widgetGlobals->FLtext_align<0 ||
2609 widgetGlobals->FLtext_align>9) type = FL_ALIGN_BOTTOM;
2610 else type = ALIGN_TABLE[widgetGlobals->FLtext_align];
2611 // switch (widgetGlobals->FLtext_align) {
2612 // case 1: type = FL_ALIGN_CENTER; break;
2613 // case 2: type = FL_ALIGN_TOP; break;
2614 // case 3: type = FL_ALIGN_BOTTOM; break;
2615 // case 4: type = FL_ALIGN_LEFT; break;
2616 // case 5: type = FL_ALIGN_RIGHT; break;
2617 // case 6: type = FL_ALIGN_TOP_LEFT; break;
2618 // case 7: type = FL_ALIGN_TOP_RIGHT; break;
2619 // case 8: type = FL_ALIGN_BOTTOM_LEFT; break;
2620 // case 9: type = FL_ALIGN_BOTTOM_RIGHT; break;
2621 // case -1: // What type is this?
2622 // default: type = FL_ALIGN_BOTTOM; break;
2623 // }
2624 o->align(type);
2625 }
2626 switch ((int) widgetGlobals->FLcolor) { // random color
2627 case -2:
2628 o->color(FL_GRAY,
2629 fl_rgb_color(rand_31_i(csound, 255), rand_31_i(csound, 255),
2630 rand_31_i(csound, 255)));
2631 break;
2632 case -1:
2633 // if FLcolor is == -1, color assignment is skipped,
2634 // leaving widget default color
2635 break;
2636 default:
2637 o->color(widgetGlobals->FLcolor, widgetGlobals->FLcolor2);
2638 break;
2639 }
2640 }
2641
2642 //-----------
2643
2644 extern "C" {
2645
2646 // static int FLkeyb(CSOUND *csound, FLKEYB *p)
2647 // {
2648 // (void) csound;
2649 // (void) p;
2650 // return OK;
2651 // }
2652
2653 //-----------
2654
flpanel_cb(Fl_Widget *,void *)2655 void flpanel_cb(Fl_Widget *,void *) { //suppresses the close button
2656 }
2657
StartPanel(CSOUND * csound,FLPANEL * p)2658 static int StartPanel(CSOUND *csound, FLPANEL *p)
2659 {
2660 char *panelName;
2661 panelName = p->name->data;
2662 WIDGET_GLOBALS *widgetGlobals =
2663 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
2664
2665 *(getFLTKFlagsPtr(csound)) |= 32;
2666 int x = (int) *p->ix, y = (int) *p->iy;
2667 int width = (int) *p->iwidth, height = (int) *p->iheight;
2668 if (width < 0) width = 400; // default
2669 if (height < 0) height = 300;
2670
2671 Fl_Boxtype borderType;
2672 int iborder = (int) *p->border;
2673 if (iborder<0 || iborder>7) borderType = FL_FLAT_BOX;
2674 else borderType = BOX_TABLE[iborder];
2675 // switch( (int) *p->border ) {
2676 // case 0: borderType = FL_FLAT_BOX; break;
2677 // case 1: borderType = FL_DOWN_BOX; break;
2678 // case 2: borderType = FL_UP_BOX; break;
2679 // case 3: borderType = FL_ENGRAVED_BOX; break;
2680 // case 4: borderType = FL_EMBOSSED_BOX; break;
2681 // case 5: borderType = FL_BORDER_BOX; break;
2682 // case 6: borderType = FL_THIN_DOWN_BOX; break;
2683 // case 7: borderType = FL_THIN_UP_BOX; break;
2684 // default: borderType = FL_FLAT_BOX;
2685 // }
2686
2687 Fl_Window *o;
2688 if (*(p->ikbdsense) == MYFLT(0.0)) {
2689 if (x < 0)
2690 o = new Fl_Window(width, height, panelName);
2691 else
2692 o = new Fl_Window(x, y, width, height, panelName);
2693 }
2694 else if (x < 0)
2695 o = new CsoundFLWindow(csound, width, height, panelName);
2696 else
2697 o = new CsoundFLWindow(csound, x, y, width, height, panelName);
2698 widget_attributes(csound, o);
2699 o->box(borderType);
2700 o->resizable(o);
2701 if (*p->iclose != 0)
2702 o->callback(flpanel_cb);
2703 widget_attributes(csound, o);
2704 ADDR_STACK adrstk(&p->h, (void *) o, widgetGlobals->stack_count);
2705 widgetGlobals->AddrStack.push_back(adrstk);
2706 PANELS panel(o, (widgetGlobals->stack_count > 0) ? 1 : 0);
2707 widgetGlobals->fl_windows.push_back(panel);
2708 widgetGlobals->stack_count++;
2709
2710 return OK;
2711 }
2712
EndPanel(CSOUND * csound,FLPANELEND * p)2713 static int EndPanel(CSOUND *csound, FLPANELEND *p)
2714 {
2715 IGN(p);
2716 WIDGET_GLOBALS *widgetGlobals =
2717 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
2718 widgetGlobals->stack_count--;
2719 ADDR_STACK adrstk = widgetGlobals->AddrStack.back();
2720 if (UNLIKELY(adrstk.h->optext->t.opcod &&
2721 strcmp( adrstk.h->optext->t.opcod, "FLpanel")))
2722 return csound->InitError(csound,
2723 "%s", Str("FLpanel_end: invalid stack pointer: "
2724 "verify its placement"));
2725 if (UNLIKELY(adrstk.count != widgetGlobals->stack_count))
2726 return csound->InitError(csound,
2727 "%s", Str("FLpanel_end: invalid stack count: "
2728 "verify FLpanel/FLpanel_end count and"
2729 " placement"));
2730 ((Fl_Window*) adrstk.WidgAddress)->end();
2731 widgetGlobals->AddrStack.pop_back();
2732 return OK;
2733 }
2734
2735 //-----------
StartScroll(CSOUND * csound,FLSCROLL * p)2736 static int StartScroll(CSOUND *csound, FLSCROLL *p)
2737 {
2738 WIDGET_GLOBALS *widgetGlobals =
2739 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
2740 Fl_Scroll *o = new Fl_Scroll ((int) *p->ix, (int) *p->iy,
2741 (int) *p->iwidth, (int) *p->iheight);
2742 ADDR_STACK adrstk(&p->h,o,widgetGlobals->stack_count);
2743 widgetGlobals->AddrStack.push_back(adrstk);
2744 widgetGlobals->stack_count++;
2745 return OK;
2746 }
2747
EndScroll(CSOUND * csound,FLSCROLLEND * p)2748 static int EndScroll(CSOUND *csound, FLSCROLLEND *p)
2749 {
2750 IGN(p);
2751 WIDGET_GLOBALS *widgetGlobals =
2752 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
2753 widgetGlobals->stack_count--;
2754 ADDR_STACK adrstk = widgetGlobals->AddrStack.back();
2755 if (UNLIKELY(strcmp( adrstk.h->optext->t.opcod, "FLscroll")))
2756 return
2757 csound->InitError(csound,
2758 "%s", Str("FLscroll_end: invalid stack pointer: "
2759 "verify its placement"));
2760 if (UNLIKELY(adrstk.count != widgetGlobals->stack_count))
2761 return csound->InitError(csound,
2762 "%s", Str("FLscroll_end: invalid stack count: "
2763 "verify FLscroll/FLscroll_end count "
2764 "and placement"));
2765 ((Fl_Scroll*) adrstk.WidgAddress)->end();
2766
2767 widgetGlobals->AddrStack.pop_back();
2768 return OK;
2769 }
2770
2771 //-----------
StartTabs(CSOUND * csound,FLTABS * p)2772 static int StartTabs(CSOUND *csound, FLTABS *p)
2773 {
2774 WIDGET_GLOBALS *widgetGlobals =
2775 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
2776 Fl_Tabs *o = new Fl_Tabs ((int) *p->ix, (int) *p->iy,
2777 (int) *p->iwidth, (int) *p->iheight);
2778 widget_attributes(csound, o);
2779 // o->box(FL_PLASTIC_UP_BOX);
2780 ADDR_STACK adrstk(&p->h,o,widgetGlobals->stack_count);
2781 widgetGlobals->AddrStack.push_back(adrstk);
2782 widgetGlobals->stack_count++;
2783 return OK;
2784 }
2785
EndTabs(CSOUND * csound,FLTABSEND * p)2786 static int EndTabs(CSOUND *csound, FLTABSEND *p)
2787 {
2788 IGN(p);
2789 WIDGET_GLOBALS *widgetGlobals =
2790 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
2791 widgetGlobals->stack_count--;
2792 ADDR_STACK adrstk = widgetGlobals->AddrStack.back();
2793 if (UNLIKELY(strcmp( adrstk.h->optext->t.opcod, "FLtabs")))
2794 return
2795 csound->InitError(csound,
2796 "%s", Str("FLscroll_end: invalid stack pointer: "
2797 "verify its placement"));
2798 if (UNLIKELY(adrstk.count != widgetGlobals->stack_count))
2799 return csound->InitError(csound,
2800 "%s", Str("FLtabs_end: invalid stack count: "
2801 "verify FLtabs/FLtabs_end count and "
2802 "placement"));
2803 ((Fl_Scroll*) adrstk.WidgAddress)->end();
2804
2805 widgetGlobals->AddrStack.pop_back();
2806 return OK;
2807 }
2808
2809 //-----------
StartGroup(CSOUND * csound,FLGROUP * p)2810 static int StartGroup(CSOUND *csound, FLGROUP *p)
2811 {
2812 WIDGET_GLOBALS *widgetGlobals =
2813 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
2814 char *Name = p->name->data;
2815 Fl_Group *o = new Fl_Group ((int) *p->ix, (int) *p->iy,
2816 (int) *p->iwidth, (int) *p->iheight,Name);
2817 widget_attributes(csound, o);
2818 Fl_Boxtype borderType;
2819 int iborder = (int)*p->border;
2820 if (iborder<0 || iborder>7) borderType = FL_FLAT_BOX;
2821 else borderType = BOX_TABLE[iborder];
2822 // switch((int)*p->border ) {
2823 // case 0: borderType = FL_FLAT_BOX; break;
2824 // case 1: borderType = FL_DOWN_BOX; break;
2825 // case 2: borderType = FL_UP_BOX; break;
2826 // case 3: borderType = FL_ENGRAVED_BOX; break;
2827 // case 4: borderType = FL_EMBOSSED_BOX; break;
2828 // case 5: borderType = FL_BORDER_BOX; break;
2829 // case 6: borderType = FL_THIN_DOWN_BOX; break;
2830 // case 7: borderType = FL_THIN_UP_BOX; break;
2831 // default: borderType = FL_FLAT_BOX;
2832 // }
2833 o->box(borderType);
2834 widget_attributes(csound, o);
2835 ADDR_STACK adrstk(&p->h,o,widgetGlobals->stack_count);
2836 widgetGlobals->AddrStack.push_back(adrstk);
2837 widgetGlobals->stack_count++;
2838 return OK;
2839 }
2840
EndGroup(CSOUND * csound,FLGROUPEND * p)2841 static int EndGroup(CSOUND *csound, FLGROUPEND *p)
2842 {
2843 IGN(p);
2844 WIDGET_GLOBALS *widgetGlobals =
2845 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
2846 widgetGlobals->stack_count--;
2847 ADDR_STACK adrstk = widgetGlobals->AddrStack.back();
2848 if (UNLIKELY(strcmp( adrstk.h->optext->t.opcod, "FLgroup")))
2849 return csound->InitError(csound,
2850 "%s", Str("FLgroup_end: invalid stack pointer: "
2851 "verify its placement"));
2852 if (UNLIKELY(adrstk.count != widgetGlobals->stack_count))
2853 return csound->InitError(csound,
2854 "%s", Str("FLgroup_end: invalid stack count: "
2855 "verify FLgroup/FLgroup_end count and"
2856 " placement"));
2857 ((Fl_Scroll*) adrstk.WidgAddress)->end();
2858
2859 widgetGlobals->AddrStack.pop_back();
2860 return OK;
2861 }
2862
2863 //-----------
2864
StartPack(CSOUND * csound,FLPACK * p)2865 static int StartPack(CSOUND *csound, FLPACK *p)
2866 {
2867 WIDGET_GLOBALS *widgetGlobals =
2868 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
2869 Fl_Pack *o = new Fl_Pack ((int) *p->ix, (int) *p->iy,
2870 (int) *p->iwidth, (int) *p->iheight);
2871 Fl_Boxtype borderType = FL_FLAT_BOX;
2872 int iborder = (int)*p->iborder;
2873 // fl_window->resizable(o);
2874 if (!((iborder<0 || iborder>7)))
2875 borderType = BOX_TABLE[iborder];
2876 o->box(borderType); // JPff added March 2012
2877 o->type((int)*p->itype);
2878 o->spacing((int)*p->ispace);
2879
2880 ADDR_STACK adrstk(&p->h,o,widgetGlobals->stack_count);
2881 widgetGlobals->AddrStack.push_back(adrstk);
2882 widgetGlobals->stack_count++;
2883 return OK;
2884 }
2885
EndPack(CSOUND * csound,FLSCROLLEND * p)2886 static int EndPack(CSOUND *csound, FLSCROLLEND *p)
2887 {
2888 IGN(p);
2889 WIDGET_GLOBALS *widgetGlobals =
2890 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
2891 widgetGlobals->stack_count--;
2892 ADDR_STACK adrstk = widgetGlobals->AddrStack.back();
2893 if (UNLIKELY(strcmp( adrstk.h->optext->t.opcod, "FLpack")))
2894 return csound->InitError(csound,
2895 "%s", Str("FLpack_end: invalid stack pointer: "
2896 "verify its placement"));
2897 if (UNLIKELY(adrstk.count != widgetGlobals->stack_count))
2898 return csound->InitError(csound,
2899 "%s", Str("FLpack_end: invalid stack count: "
2900 "verify FLpack/FLpack_end count and "
2901 "placement"));
2902 ((Fl_Pack*) adrstk.WidgAddress)->end();
2903
2904 widgetGlobals->AddrStack.pop_back();
2905 return OK;
2906 }
2907
2908 //-----------
2909
fl_widget_color(CSOUND * csound,FLWIDGCOL * p)2910 static int fl_widget_color(CSOUND *csound, FLWIDGCOL *p)
2911 {
2912 WIDGET_GLOBALS *widgetGlobals =
2913 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
2914 if (*p->red1 < 0) { // reset colors to default
2915 widgetGlobals->FLcolor = (int) *p->red1; //when called without arguments
2916 widgetGlobals->FLcolor2 =(int) *p->red1;
2917 }
2918 else {
2919 widgetGlobals->FLcolor = fl_rgb_color((int) *p->red1,
2920 (int) *p->green1,
2921 (int) *p->blue1);
2922 widgetGlobals->FLcolor2 = fl_rgb_color((int) *p->red2,
2923 (int) *p->green2,
2924 (int) *p->blue2);
2925 }
2926 return OK;
2927 }
2928
fl_widget_color2(CSOUND * csound,FLWIDGCOL2 * p)2929 static int fl_widget_color2(CSOUND *csound, FLWIDGCOL2 *p)
2930 {
2931 WIDGET_GLOBALS *widgetGlobals =
2932 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
2933 if (*p->red < 0) { // reset colors to default
2934 widgetGlobals->FLcolor2 =(int) *p->red;
2935 }
2936 else {
2937 widgetGlobals->FLcolor2 = fl_rgb_color((int) *p->red,
2938 (int) *p->green,
2939 (int) *p->blue);
2940 }
2941 return OK;
2942 }
2943
fl_widget_label(CSOUND * csound,FLWIDGLABEL * p)2944 static int fl_widget_label(CSOUND *csound, FLWIDGLABEL *p)
2945 {
2946 WIDGET_GLOBALS *widgetGlobals =
2947 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
2948 if (*p->size <= 0) { // reset settings to default
2949 widgetGlobals->FLtext_size = 0; //when called without arguments
2950 widgetGlobals->FLtext_font = -1;
2951 widgetGlobals->FLtext_align = 0;
2952 widgetGlobals->FLtext_color = -1;
2953 }
2954 else {
2955 widgetGlobals->FLtext_size = (int) *p->size;
2956
2957 if (*p->font > -1) widgetGlobals->FLtext_font = (int) *p->font;
2958 if (*p->align > 0) widgetGlobals->FLtext_align = (int) *p->align;
2959 if (*p->red > -1 && *p->green > -1 && *p->blue > -1) {
2960 widgetGlobals->FLtext_color = fl_rgb_color((int) *p->red,
2961 (int) *p->green,
2962 (int) *p->blue);
2963 }
2964 }
2965 return OK;
2966 }
2967
2968 } // extern "C"
2969
2970 // -----------
2971
fl_getWidgetTypeFromOpcodeName(CSOUND * csound,void * p)2972 static int fl_getWidgetTypeFromOpcodeName(CSOUND *csound, void *p)
2973 {
2974 const char *opname = csound->GetOpcodeName(p);
2975
2976 if (strcmp(opname, "FLbutton") == 0)
2977 return 1;
2978 if (strcmp(opname, "FLbutBank") == 0)
2979 return 2;
2980 if (strcmp(opname, "FLjoy") == 0)
2981 return 3;
2982 if (strcmp(opname, "FLvalue") == 0)
2983 return 4;
2984 if (strcmp(opname, "FLbox") != 0)
2985 return 0;
2986 csound->Warning(csound, "%s", Str("System error: value() method called from "
2987 "non-valuator object"));
2988 return -1;
2989 }
2990
fl_setWidgetValue_(CSOUND * csound,ADDR_SET_VALUE & v,int widgetType,MYFLT val,MYFLT log_base)2991 static void fl_setWidgetValue_(CSOUND *csound,
2992 ADDR_SET_VALUE &v, int widgetType,
2993 MYFLT val, MYFLT log_base)
2994 {
2995 Fl_Widget *o = (Fl_Widget *) v.WidgAddress;
2996 void *p = v.opcode;
2997 bool fltkLockingIsEnabled;
2998
2999 if ((!widgetType || widgetType > 2) &&
3000 (v.exponential == LIN_ || v.exponential == EXP_)) {
3001 if (val < v.min)
3002 val = v.min;
3003 else if (val > v.max)
3004 val = v.max;
3005 if (v.exponential == EXP_)
3006 val = (MYFLT) (log(val / v.min) / log_base);
3007 }
3008 fltkLockingIsEnabled = ((getFLTKFlags(csound) & 8) == 0);
3009 if (fltkLockingIsEnabled)
3010 Fl_lock(csound);
3011 switch (widgetType) {
3012 case 0: // valuator
3013 ((Fl_Valuator *) o)->value(val);
3014 break;
3015 case 1: // FLbutton
3016 if (val == *(((FLBUTTON *) v.opcode)->ion))
3017 ((Fl_Button *) o)->value(1);
3018 else if (val == *(((FLBUTTON *) v.opcode)->ioff))
3019 ((Fl_Button *) o)->value(0);
3020 break;
3021 case 2: // FLbutBank
3022 set_butbank_value((Fl_Group *) o, val);
3023 break;
3024 case 3: // FLjoy
3025 {
3026 static int flag = 0;
3027 // FLsetVal always requires two adjacent calls when setting FLjoy
3028 if (!flag) {
3029 ((Fl_Positioner *) o)->xvalue(val);
3030 flag = 1;
3031 }
3032 else {
3033 ((Fl_Positioner *) o)->yvalue(val);
3034 flag = 0;
3035 }
3036 }
3037 break;
3038 default: // invalid
3039 if (fltkLockingIsEnabled)
3040 Fl_unlock(csound);
3041 return;
3042 }
3043 o->do_callback(o, p);
3044 if (fltkLockingIsEnabled)
3045 Fl_unlock(csound);
3046 }
3047
3048 extern "C" {
3049
fl_setWidgetValuei(CSOUND * csound,FL_SET_WIDGET_VALUE_I * p)3050 static int fl_setWidgetValuei(CSOUND *csound, FL_SET_WIDGET_VALUE_I *p)
3051 {
3052 WIDGET_GLOBALS *widgetGlobals =
3053 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
3054 MYFLT log_base = MYFLT(1.0);
3055 ADDR_SET_VALUE &v = widgetGlobals->AddrSetValue[(int) *p->ihandle];
3056 int widgetType;
3057
3058 widgetType = fl_getWidgetTypeFromOpcodeName(csound, v.opcode);
3059 if (UNLIKELY(widgetType == 4)) {
3060 csound->InitError(csound,
3061 "%s", Str("FLvalue cannot be set by FLsetVal.\n"));
3062 return NOTOK;
3063 }
3064 if (widgetType < 0)
3065 return OK;
3066 if (!widgetType || widgetType > 2) {
3067 switch (v.exponential) {
3068 case LIN_: // linear
3069 break;
3070 case EXP_: // exponential
3071 #if defined(sun)
3072 log_base = (MYFLT) log(::pow(v.max / (double)v.min,
3073 1.0 / (v.max - v.min)));
3074 #else
3075 log_base = (MYFLT) log(::pow(v.max / v.min, 1.0 / (v.max - v.min)));
3076 #endif
3077 break;
3078 default:
3079 csound->Warning(csound, Str("(fl_setWidgetValuei): "
3080 "not fully implemented yet; exp=%d"),
3081 v.exponential);
3082 }
3083 }
3084 fl_setWidgetValue_(csound, v, widgetType, *(p->ivalue), log_base);
3085 return OK;
3086 }
3087
fl_setWidgetValue_set(CSOUND * csound,FL_SET_WIDGET_VALUE * p)3088 static int fl_setWidgetValue_set(CSOUND *csound, FL_SET_WIDGET_VALUE *p)
3089 {
3090 p->handle = (int) *(p->ihandle);
3091 WIDGET_GLOBALS *widgetGlobals =
3092 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
3093 MYFLT log_base = MYFLT(1.0);
3094 ADDR_SET_VALUE &v = widgetGlobals->AddrSetValue[p->handle];
3095 int widgetType;
3096
3097 widgetType = fl_getWidgetTypeFromOpcodeName(csound, v.opcode);
3098 if (UNLIKELY(widgetType == 4)) {
3099 csound->InitError(csound,
3100 "%s", Str("FLvalue cannot be set by FLsetVal\n"));
3101 return NOTOK;
3102 }
3103 if (widgetType < 0)
3104 return OK;
3105 if (!widgetType || widgetType > 2) {
3106 switch (v.exponential) {
3107 case LIN_: // linear
3108 break;
3109 case EXP_: // exponential
3110 #if defined(sun)
3111 log_base = (MYFLT) log(::pow(v.max / (double)v.min,
3112 1.0 / (v.max - v.min)));
3113 #else
3114 log_base = (MYFLT) log(::pow(v.max / v.min, 1.0 / (v.max - v.min)));
3115 #endif
3116 break;
3117 default:
3118 csound->Warning(csound, Str("(fl_setWidgetValue_set): "
3119 "not fully implemented yet; exp=%d"),
3120 v.exponential);
3121 }
3122 }
3123 p->widgetType = widgetType;
3124 p->log_base = log_base;
3125
3126 return OK;
3127 }
3128
fl_setWidgetValue(CSOUND * csound,FL_SET_WIDGET_VALUE * p)3129 static int fl_setWidgetValue(CSOUND *csound, FL_SET_WIDGET_VALUE *p)
3130 {
3131 WIDGET_GLOBALS *widgetGlobals =
3132 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
3133 if (*p->ktrig != MYFLT(0.0))
3134 fl_setWidgetValue_(csound,
3135 widgetGlobals->AddrSetValue[p->handle], p->widgetType,
3136 *(p->kvalue), p->log_base);
3137 return OK;
3138 }
3139
3140 //-----------
3141 //-----------
3142
fl_setColor1(CSOUND * csound,FL_SET_COLOR * p)3143 static int fl_setColor1(CSOUND *csound, FL_SET_COLOR *p)
3144 {
3145 WIDGET_GLOBALS *widgetGlobals =
3146 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
3147 ADDR_SET_VALUE v = widgetGlobals->AddrSetValue[(int) *p->ihandle];
3148 Fl_Widget *o = (Fl_Widget *) v.WidgAddress;
3149 int color = fl_rgb_color((int) *p->red,
3150 (int) *p->green,
3151 (int) *p->blue);
3152 o->color(color);
3153 o->redraw();
3154 return OK;
3155 }
3156
fl_setColor2(CSOUND * csound,FL_SET_COLOR * p)3157 static int fl_setColor2(CSOUND *csound, FL_SET_COLOR *p)
3158 {
3159 WIDGET_GLOBALS *widgetGlobals =
3160 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
3161 ADDR_SET_VALUE v = widgetGlobals->AddrSetValue[(int) *p->ihandle];
3162 Fl_Widget *o = (Fl_Widget *) v.WidgAddress;
3163 int color = fl_rgb_color((int) *p->red, (int) *p->green, (int) *p->blue);
3164 o->selection_color(color);
3165 o->redraw();
3166 return OK;
3167 }
3168
fl_setTextColor(CSOUND * csound,FL_SET_COLOR * p)3169 static int fl_setTextColor(CSOUND *csound, FL_SET_COLOR *p)
3170 {
3171 WIDGET_GLOBALS *widgetGlobals =
3172 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
3173 ADDR_SET_VALUE v = widgetGlobals->AddrSetValue[(int) *p->ihandle];
3174 Fl_Widget *o = (Fl_Widget *) v.WidgAddress;
3175 int color = fl_rgb_color((int) *p->red, (int) *p->green, (int) *p->blue);
3176 o->labelcolor(color);
3177 o->window()->redraw();
3178 return OK;
3179 }
3180
fl_setTextSize(CSOUND * csound,FL_SET_TEXTSIZE * p)3181 static int fl_setTextSize(CSOUND *csound, FL_SET_TEXTSIZE *p)
3182 {
3183 WIDGET_GLOBALS *widgetGlobals =
3184 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
3185 ADDR_SET_VALUE v = widgetGlobals->AddrSetValue[(int) *p->ihandle];
3186 Fl_Widget *o = (Fl_Widget *) v.WidgAddress;
3187 o->labelsize((uchar) *p->ivalue);
3188 return OK;
3189 }
3190
fl_setFont(CSOUND * csound,FL_SET_FONT * p)3191 static int fl_setFont(CSOUND *csound, FL_SET_FONT *p)
3192 {
3193 WIDGET_GLOBALS *widgetGlobals =
3194 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
3195 ADDR_SET_VALUE v = widgetGlobals->AddrSetValue[(int) *p->ihandle];
3196 Fl_Widget *o = (Fl_Widget *) v.WidgAddress;
3197 Fl_Font font;
3198 int ifnt = (int) *p->itype;
3199 if (ifnt<0 || ifnt>16) font = FL_HELVETICA;
3200 else font = FONT_TABLE[ifnt];
3201 // switch ((int) *p->itype) {
3202 // case 1: font = FL_HELVETICA; break;
3203 // case 2: font = FL_HELVETICA_BOLD; break;
3204 // case 3: font = FL_HELVETICA_ITALIC; break;
3205 // case 4: font = FL_HELVETICA_BOLD_ITALIC; break;
3206 // case 5: font = FL_COURIER; break;
3207 // case 6: font = FL_COURIER_BOLD; break;
3208 // case 7: font = FL_COURIER_ITALIC; break;
3209 // case 8: font = FL_COURIER_BOLD_ITALIC; break;
3210 // case 9: font = FL_TIMES; break;
3211 // case 10: font = FL_TIMES_BOLD; break;
3212 // case 11: font = FL_TIMES_ITALIC; break;
3213 // case 12: font = FL_TIMES_BOLD_ITALIC; break;
3214 // case 13: font = FL_SYMBOL; break;
3215 // case 14: font = FL_SCREEN; break;
3216 // case 15: font = FL_SCREEN_BOLD; break;
3217 // case 16: font = FL_ZAPF_DINGBATS; break;
3218 // default: font = FL_SCREEN;
3219 // }
3220 o->labelfont(font);
3221 return OK;
3222 }
3223
fl_setTextType(CSOUND * csound,FL_SET_FONT * p)3224 static int fl_setTextType(CSOUND *csound, FL_SET_FONT *p)
3225 {
3226 WIDGET_GLOBALS *widgetGlobals =
3227 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
3228 ADDR_SET_VALUE v = widgetGlobals->AddrSetValue[(int) *p->ihandle];
3229 Fl_Widget *o = (Fl_Widget *) v.WidgAddress;
3230 Fl_Labeltype type;
3231 switch ((int) *p->itype) {
3232 case 0: type = FL_NORMAL_LABEL; break;
3233 case 1: type = FL_NO_LABEL; break;
3234 case 2: type = FL_SYMBOL_LABEL; break;
3235 case 3: type = FL_SHADOW_LABEL; break;
3236 case 4: type = FL_ENGRAVED_LABEL; break;
3237 case 5: type = FL_EMBOSSED_LABEL; break;
3238 /* case 6: type = _FL_BITMAP_LABEL; break;
3239 case 7: type = _FL_PIXMAP_LABEL; break;
3240 case 8: type = _FL_IMAGE_LABEL; break;
3241 case 9: type = _FL_MULTI_LABEL; break; */
3242 case 10: type = FL_FREE_LABELTYPE; break;
3243 default: type = FL_NORMAL_LABEL;
3244 }
3245 o->labeltype(type);
3246 o->window()->redraw();
3247 return OK;
3248 }
3249
fl_box_(CSOUND * csound,FL_BOX * p,char * text)3250 static int fl_box_(CSOUND *csound, FL_BOX *p, char *text)
3251 {
3252 //char *text = p->itext->data;
3253 Fl_Box *o = new Fl_Box((int)*p->ix, (int)*p->iy,
3254 (int)*p->iwidth, (int)*p->iheight, strdup(text));
3255 widget_attributes(csound, o);
3256 Fl_Boxtype type;
3257 int itype = (int) *p->itype;
3258 if (itype<0 || itype>19) type = FL_FLAT_BOX;
3259 else type = BOX_TABLE[itype];
3260 // switch ((int) *p->itype) {
3261 // case 1: type = FL_FLAT_BOX; break;
3262 // case 2: type = FL_UP_BOX; break;
3263 // case 3: type = FL_DOWN_BOX; break;
3264 // case 4: type = FL_THIN_UP_BOX; break;
3265 // case 5: type = FL_THIN_DOWN_BOX; break;
3266 // case 6: type = FL_ENGRAVED_BOX; break;
3267 // case 7: type = FL_EMBOSSED_BOX; break;
3268 // case 8: type = FL_BORDER_BOX; break;
3269 // case 9: type = _FL_SHADOW_BOX; break;
3270 // case 10: type = _FL_ROUNDED_BOX; break;
3271 // case 11: type = _FL_RSHADOW_BOX; break;
3272 // case 12: type = _FL_RFLAT_BOX; break;
3273 // case 13: type = _FL_ROUND_UP_BOX; break;
3274 // case 14: type = _FL_ROUND_DOWN_BOX; break;
3275 // case 15: type = _FL_DIAMOND_UP_BOX; break;
3276 // case 16: type = _FL_DIAMOND_DOWN_BOX; break;
3277 // case 17: type = _FL_OVAL_BOX; break;
3278 // case 18: type = _FL_OSHADOW_BOX; break;
3279 // case 19: type = _FL_OFLAT_BOX; break;
3280 // default: type = FL_FLAT_BOX;
3281 // }
3282 o->box(type);
3283 Fl_Font font;
3284 int ifnt = (int) *p->ifont;
3285 if (ifnt<0 || ifnt>16) font = FL_HELVETICA;
3286 else font = FONT_TABLE[ifnt];
3287 // switch ((int) *p->ifont) {
3288 // case 1: font = FL_HELVETICA; break;
3289 // case 2: font = FL_HELVETICA_BOLD; break;
3290 // case 3: font = FL_HELVETICA_ITALIC; break;
3291 // case 4: font = FL_HELVETICA_BOLD_ITALIC; break;
3292 // case 5: font = FL_COURIER; break;
3293 // case 6: font = FL_COURIER_BOLD; break;
3294 // case 7: font = FL_COURIER_ITALIC; break;
3295 // case 8: font = FL_COURIER_BOLD_ITALIC; break;
3296 // case 9: font = FL_TIMES; break;
3297 // case 10: font = FL_TIMES_BOLD; break;
3298 // case 11: font = FL_TIMES_ITALIC; break;
3299 // case 12: font = FL_TIMES_BOLD_ITALIC; break;
3300 // case 13: font = FL_SYMBOL; break;
3301 // case 14: font = FL_SCREEN; break;
3302 // case 15: font = FL_SCREEN_BOLD; break;
3303 // case 16: font = FL_ZAPF_DINGBATS; break;
3304 // default: font = FL_HELVETICA;
3305 // }
3306 o->labelfont(font);
3307 o->labelsize((unsigned char)*p->isize);
3308 o->align(FL_ALIGN_WRAP);
3309 WIDGET_GLOBALS *widgetGlobals =
3310 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
3311 widgetGlobals->AddrSetValue.push_back(ADDR_SET_VALUE(0, 0, 0, (void *)o,
3312 (void *)p,
3313 widgetGlobals->currentSnapGroup));
3314 *p->ihandle = widgetGlobals->AddrSetValue.size()-1;
3315 return OK;
3316 }
3317
fl_box_s(CSOUND * csound,FL_BOX * p)3318 static int fl_box_s(CSOUND *csound, FL_BOX *p)
3319 {
3320 return fl_box_(csound, p, p->itext->data);
3321 }
fl_box_i(CSOUND * csound,FL_BOX * p)3322 static int fl_box_i(CSOUND *csound, FL_BOX *p)
3323 {
3324 int i = (int)*((MYFLT*)p->itext);
3325 char* text;
3326 if (i<0 || i>csound->GetStrsmax(csound)) text = (char *) "???";
3327 else if ((text=csound->GetStrsets(csound,i))==NULL) text = (char *) "???";
3328 return fl_box_(csound, p, text);
3329 }
3330
fl_setText(CSOUND * csound,FL_SET_TEXT * p)3331 static int fl_setText(CSOUND *csound, FL_SET_TEXT *p)
3332 {
3333 WIDGET_GLOBALS *widgetGlobals =
3334 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
3335 char *text = strdup(p->itext->data);
3336 ADDR_SET_VALUE v = widgetGlobals->AddrSetValue[(int) *p->ihandle];
3337 Fl_Widget *o = (Fl_Widget *) v.WidgAddress;
3338 free((void*)o->label());
3339 o->label(text);
3340 return OK;
3341 }
3342
fl_setTexti(CSOUND * csound,FL_SET_TEXTi * p)3343 static int fl_setTexti(CSOUND *csound, FL_SET_TEXTi *p)
3344 {
3345 WIDGET_GLOBALS *widgetGlobals =
3346 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
3347 int i = (int)(*p->ndx);
3348 char *text ;
3349 ADDR_SET_VALUE v = widgetGlobals->AddrSetValue[(int) *p->ihandle];
3350 Fl_Widget *o = (Fl_Widget *) v.WidgAddress;
3351 if (i<0 || i>csound->GetStrsmax(csound)) text = (char *) "???";
3352 else if ((text=csound->GetStrsets(csound,i))==NULL) text = (char *) "???";
3353 free((void*)o->label());
3354 o->label(strdup(text));
3355 return OK;
3356 }
3357
fl_setSize(CSOUND * csound,FL_SET_SIZE * p)3358 static int fl_setSize(CSOUND *csound, FL_SET_SIZE *p)
3359 {
3360 WIDGET_GLOBALS *widgetGlobals =
3361 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
3362 ADDR_SET_VALUE v = widgetGlobals->AddrSetValue[(int) *p->ihandle];
3363 Fl_Widget *o = (Fl_Widget *) v.WidgAddress;
3364 o->size((short) *p->iwidth, (short) *p->iheight);
3365 return OK;
3366 }
3367
fl_setPosition(CSOUND * csound,FL_SET_POSITION * p)3368 static int fl_setPosition(CSOUND *csound, FL_SET_POSITION *p)
3369 {
3370 WIDGET_GLOBALS *widgetGlobals =
3371 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
3372 ADDR_SET_VALUE v = widgetGlobals->AddrSetValue[(int) *p->ihandle];
3373 Fl_Widget *o = (Fl_Widget *) v.WidgAddress;
3374 o->position((short) *p->ix, (short) *p->iy);
3375 return OK;
3376 }
3377
fl_hide(CSOUND * csound,FL_WIDHIDE * p)3378 static int fl_hide(CSOUND *csound, FL_WIDHIDE *p)
3379 {
3380 WIDGET_GLOBALS *widgetGlobals =
3381 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
3382 Fl_lock(csound);
3383 ADDR_SET_VALUE v = widgetGlobals->AddrSetValue[(int) *p->ihandle];
3384 Fl_Widget *o = (Fl_Widget *) v.WidgAddress;
3385 o->hide();
3386 Fl_unlock(csound);
3387 return OK;
3388 }
3389
fl_show(CSOUND * csound,FL_WIDSHOW * p)3390 static int fl_show(CSOUND *csound, FL_WIDSHOW *p)
3391 {
3392 WIDGET_GLOBALS *widgetGlobals =
3393 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
3394 Fl_lock(csound);
3395 ADDR_SET_VALUE v = widgetGlobals->AddrSetValue[(int) *p->ihandle];
3396 Fl_Widget *o = (Fl_Widget *) v.WidgAddress;
3397 o->show();
3398 Fl_unlock(csound);
3399 return OK;
3400 }
3401
fl_setBox(CSOUND * csound,FL_SETBOX * p)3402 static int fl_setBox(CSOUND *csound, FL_SETBOX *p)
3403 {
3404 WIDGET_GLOBALS *widgetGlobals =
3405 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
3406 ADDR_SET_VALUE v = widgetGlobals->AddrSetValue[(int) *p->ihandle];
3407 Fl_Widget *o = (Fl_Widget *) v.WidgAddress;
3408 Fl_Boxtype type;
3409 int itype = (int) *p->itype;
3410 if (itype<0||itype>19) type = FL_FLAT_BOX;
3411 else type = BOX_TABLE[itype];
3412 // switch ((int) *p->itype) {
3413 // case 1: type = FL_FLAT_BOX; break;
3414 // case 2: type = FL_UP_BOX; break;
3415 // case 3: type = FL_DOWN_BOX; break;
3416 // case 4: type = FL_THIN_UP_BOX; break;
3417 // case 5: type = FL_THIN_DOWN_BOX; break;
3418 // case 6: type = FL_ENGRAVED_BOX; break;
3419 // case 7: type = FL_EMBOSSED_BOX; break;
3420 // case 8: type = FL_BORDER_BOX; break;
3421 // case 9: type = FL_SHADOW_BOX; break;
3422 // case 10: type = FL_ROUNDED_BOX; break;
3423 // case 11: type = FL_RSHADOW_BOX; break;
3424 // case 12: type = FL_RFLAT_BOX; break;
3425 // case 13: type = FL_ROUND_UP_BOX; break;
3426 // case 14: type = FL_ROUND_DOWN_BOX; break;
3427 // case 15: type = FL_DIAMOND_UP_BOX; break;
3428 // case 16: type = FL_DIAMOND_DOWN_BOX; break;
3429 // case 17: type = FL_OVAL_BOX; break;
3430 // case 18: type = FL_OSHADOW_BOX; break;
3431 // case 19: type = FL_OFLAT_BOX; break;
3432 // default: type = FL_FLAT_BOX;
3433 // }
3434 o->box(type);
3435 return OK;
3436 }
3437
fl_align(CSOUND * csound,FL_TALIGN * p)3438 static int fl_align(CSOUND *csound, FL_TALIGN *p)
3439 {
3440 WIDGET_GLOBALS *widgetGlobals =
3441 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
3442 ADDR_SET_VALUE v = widgetGlobals->AddrSetValue[(int) *p->ihandle];
3443 Fl_Widget *o = (Fl_Widget *) v.WidgAddress;
3444 Fl_Align type;
3445 int itype= (int) *p->itype;
3446 if (itype<0 || itype>9) type = FL_ALIGN_BOTTOM;
3447 else type = ALIGN_TABLE[itype];
3448 // switch ((int) *p->itype) {
3449 // case 1: type = FL_ALIGN_CENTER; break;
3450 // case 2: type = FL_ALIGN_TOP; break;
3451 // case 3: type = FL_ALIGN_BOTTOM; break;
3452 // case 4: type = FL_ALIGN_LEFT; break;
3453 // case 5: type = FL_ALIGN_RIGHT; break;
3454 // case 6: type = FL_ALIGN_TOP_LEFT; break;
3455 // case 7: type = FL_ALIGN_TOP_RIGHT; break;
3456 // case 8: type = FL_ALIGN_BOTTOM_LEFT; break;
3457 // case 9: type = FL_ALIGN_BOTTOM_RIGHT; break;
3458 // default: type = FL_ALIGN_BOTTOM;
3459 // }
3460 o->align(type);
3461 return OK;
3462 }
3463
3464 //-----------
3465 //-----------
3466
fl_value(CSOUND * csound,FLVALUE * p)3467 static int fl_value(CSOUND *csound, FLVALUE *p)
3468 {
3469 WIDGET_GLOBALS *widgetGlobals =
3470 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
3471 char *controlName = p->name->data;
3472 int ix, iy, iwidth, iheight;
3473 if (*p->ix<0) ix = widgetGlobals->FL_ix;
3474 else widgetGlobals->FL_ix = ix = (int) *p->ix;
3475 if (*p->iy<0) iy = widgetGlobals->FL_iy;
3476 else widgetGlobals->FL_iy = iy = (int) *p->iy;
3477 if (*p->iwidth<0) iwidth = widgetGlobals->FLvalue_iwidth;
3478 else widgetGlobals->FLvalue_iwidth = iwidth = (int) *p->iwidth;
3479 if (*p->iheight<0) iheight = widgetGlobals->FLroller_iheight;
3480 else widgetGlobals->FLroller_iheight = iheight = (int) *p->iheight;
3481
3482 Fl_Output *o = new Fl_Output(ix, iy, iwidth, iheight,controlName);
3483 o->align(FL_ALIGN_BOTTOM | FL_ALIGN_WRAP);
3484 if (widgetGlobals->FLcolor < 0 )
3485 o->color(FL_GRAY );
3486 else
3487 o->color(widgetGlobals->FLcolor, widgetGlobals->FLcolor2);
3488 widget_attributes(csound, o);
3489 //AddrValue.push_back((void *) o);
3490 widgetGlobals->AddrSetValue.push_back(ADDR_SET_VALUE(0, 0, 0, (void *) o,
3491 (void *) p,
3492 widgetGlobals->currentSnapGroup));
3493 // *p->ihandle = AddrValue.size()-1;
3494 *p->ihandle = widgetGlobals->AddrSetValue.size()-1;
3495 return OK;
3496 }
3497
3498 //-----------
3499
fl_slider(CSOUND * csound,FLSLIDER * p)3500 static int fl_slider(CSOUND *csound, FLSLIDER *p)
3501 {
3502 WIDGET_GLOBALS *widgetGlobals =
3503 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
3504 char *controlName = p->name->data;
3505 int ix,iy,iwidth, iheight,itype, iexp;
3506 bool plastic = false;
3507
3508 if (*p->iy < 0) {
3509 iy = widgetGlobals->FL_iy;
3510 widgetGlobals->FL_iy += widgetGlobals->FLcontrol_iheight + 5;
3511 }
3512 else {
3513 iy = (int) *p->iy;
3514 widgetGlobals->FL_iy = iy + widgetGlobals->FLcontrol_iheight + 5;
3515 }
3516 if (*p->ix < 0) ix = widgetGlobals->FL_ix; // omitted options: set default
3517 else widgetGlobals->FL_ix = ix = (int) *p->ix;
3518 if (*p->iwidth < 0) iwidth = widgetGlobals->FLcontrol_iwidth;
3519 else widgetGlobals->FLcontrol_iwidth = iwidth = (int) *p->iwidth;
3520 if (*p->iheight < 0) iheight = widgetGlobals->FLcontrol_iheight;
3521 else widgetGlobals->FLcontrol_iheight = iheight = (int) *p->iheight;
3522 if (*p->itype < 1) itype = 1;
3523 else itype = (int) *p->itype;
3524
3525 //if (*p->iexp == LIN_) iexp = LIN_;
3526 //else iexp = (int) *p->iexp;
3527 switch((int) *p->iexp) {
3528 case -1: iexp = EXP_; break;
3529 case 0: iexp = LIN_; break;
3530 default: iexp = (int) *p->iexp;
3531 }
3532 if (itype > 19) {
3533 plastic = true;
3534 itype = itype - 20;
3535 }
3536 if (UNLIKELY(itype > 10 && iexp == EXP_)) {
3537 csound->Warning(csound,
3538 "%s", Str("FLslider exponential, using non-labeled slider"));
3539 itype -= 10;
3540 }
3541
3542 Fl_Slider *o;
3543 if (itype <= 10) o = new Fl_Slider(ix, iy, iwidth, iheight, controlName);
3544 else {
3545 o = new Fl_Value_Slider_Input(csound, ix, iy,
3546 iwidth, iheight, controlName);
3547 itype -=10;
3548 //o->labelsize(20);
3549 ((Fl_Value_Slider_Input*) o)->textboxsize(50);
3550 ((Fl_Value_Slider_Input*) o)->textsize(13);
3551 o->align(FL_ALIGN_BOTTOM | FL_ALIGN_WRAP);
3552 }
3553 switch (itype) {
3554 case 1: o->type(FL_HOR_FILL_SLIDER); break;
3555 case 2: o->type(FL_VERT_FILL_SLIDER); break;
3556 case 3: o->type(FL_HOR_SLIDER); break;
3557 case 4: o->type(FL_VERT_SLIDER); break;
3558 case 5: o->type(FL_HOR_NICE_SLIDER); o->box(FL_FLAT_BOX); break;
3559 case 6: o->type(FL_VERT_NICE_SLIDER); o->box(FL_FLAT_BOX); break;
3560 default: return csound->InitError(csound,
3561 "%s", Str("FLslider: invalid slider type"));
3562 }
3563 if (plastic) o->box(FL_PLASTIC_DOWN_BOX);
3564 widget_attributes(csound, o);
3565 MYFLT min = p->min = *p->imin, max = *p->imax, range;
3566 switch (iexp) {
3567 case LIN_: //linear
3568 o->range(min,max);
3569 o->callback((Fl_Callback*)fl_callbackLinearSlider,(void *) p);
3570 break;
3571 case EXP_ : //exponential
3572 if (UNLIKELY(min == 0 || max == 0))
3573 return csound->InitError(csound,
3574 "%s", Str("FLslider: zero is illegal "
3575 "in exponential operations"));
3576 range = max - min;
3577 o->range(0,range);
3578 #if defined(sun)
3579 p->base = ::pow((max / (double)min), 1.0/(double)range);
3580 #else
3581 p->base = ::pow((max / min), 1.0/(double)range);
3582 #endif
3583 o->callback((Fl_Callback*)fl_callbackExponentialSlider,(void *) p);
3584 break;
3585 default:
3586 {
3587 FUNC *ftp;
3588 MYFLT fnum = abs(iexp);
3589 if ((ftp = csound->FTnp2Finde(csound, &fnum)) != NULL) {
3590 p->table = ftp->ftable;
3591 p->tablen = ftp->flen;
3592 }
3593 else return NOTOK;
3594 o->range(0,0.99999999);
3595 if (iexp > 0) //interpolated
3596 o->callback((Fl_Callback*)fl_callbackInterpTableSlider,(void *) p);
3597 else // non-interpolated
3598 o->callback((Fl_Callback*)fl_callbackTableSlider,(void *) p);
3599 }
3600 }
3601 widgetGlobals->AddrSetValue.push_back(ADDR_SET_VALUE(iexp, *p->imin,
3602 *p->imax, (void *) o, (void*) p));
3603 /*widgetGlobals->currentSnapGroup;*/
3604 *p->ihandle = widgetGlobals->AddrSetValue.size()-1;
3605 return OK;
3606 }
3607
fl_slider_bank_(CSOUND * csound,FLSLIDERBANK * p,int istring)3608 static int fl_slider_bank_(CSOUND *csound, FLSLIDERBANK *p, int istring)
3609 {
3610 WIDGET_GLOBALS *widgetGlobals =
3611 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
3612 char s[MAXNAME];
3613 bool plastic = false;
3614 if (istring)
3615 strncpy(s, ((STRINGDAT*) p->names)->data, MAXNAME-1);
3616 else if ((long) *p->names <= csound->GetStrsmax(csound) &&
3617 csound->GetStrsets(csound,(long) *p->names)) {
3618 strncpy(s, csound->GetStrsets(csound,(long) *p->names), MAXNAME-1);
3619 }
3620 string tempname(s);
3621 stringstream sbuf;
3622 sbuf << tempname;
3623
3624 int width = (int) *p->iwidth;
3625 if (width <=0) width = 100;
3626
3627 Fl_Group* w = new Fl_Group((int)*p->ix, (int)*p->iy,
3628 width, (int)*p->inumsliders*10);
3629 FUNC *ftp;
3630 MYFLT *minmaxtable = NULL, *typetable = NULL, *outable, *exptable = NULL;
3631
3632 MYFLT *zkstart;
3633 int zklast = csound->GetZakBounds(csound, &zkstart);
3634 if (*p->ioutable < 1) {
3635 if (LIKELY(zkstart != NULL &&
3636 zklast > (long)(*p->inumsliders+*p->ioutablestart_ndx)))
3637 outable = zkstart + (long) *p->ioutablestart_ndx;
3638 else {
3639 return csound->InitError(csound,
3640 "%s", Str("invalid ZAK space allocation"));
3641 }
3642 }
3643 else {
3644 if (LIKELY((ftp = csound->FTnp2Finde(csound, p->ioutable)) != NULL))
3645 outable = ftp->ftable + (long) *p->ioutablestart_ndx;
3646 else
3647 return NOTOK;
3648 }
3649 if ((int) *p->iminmaxtable > 0) {
3650 if (LIKELY((ftp = csound->FTnp2Finde(csound, p->iminmaxtable)) != NULL))
3651 minmaxtable = ftp->ftable;
3652 else return NOTOK;
3653 }
3654 if ((int) *p->iexptable > 0) {
3655 if (LIKELY((ftp = csound->FTnp2Finde(csound, p->iexptable)) != NULL))
3656 exptable = ftp->ftable;
3657 else return NOTOK;
3658 }
3659 if ((int) *p->itypetable > 0) {
3660 if (LIKELY((ftp = csound->FTnp2Finde(csound, p->itypetable)) != NULL))
3661 typetable = ftp->ftable;
3662 else return NOTOK;
3663 }
3664
3665 for (int j =0; j< *p->inumsliders; j++) {
3666 string stemp;
3667 if (tempname == " ") {
3668 char s[40];
3669 sprintf(s, "%d", j);
3670 stemp = s;
3671 }
3672 else
3673 getline(sbuf, stemp, '@');
3674 char *Name = new char[stemp.size()+2];
3675 strcpy(Name,stemp.c_str());
3676 widgetGlobals->allocatedStrings.push_back(Name);
3677
3678 int x = (int) *p->ix, y = (int) *p->iy + j*10;
3679 Fl_Slider *o;
3680 int slider_type;
3681 if ((int) *p->itypetable <= 0) { // no slider type table
3682 if (*p->itypetable >= -7) // all sliders are of the same type
3683 slider_type = -((int) *p->itypetable);
3684 else if (*p->itypetable >= -27 && *p->itypetable < -20) {
3685 slider_type = -((int) *p->itypetable) - 20;
3686 plastic = true;
3687 }
3688 else // random type
3689 slider_type = rand_31_i(csound, 7) | 1;
3690 }
3691 else
3692 slider_type = (int) typetable[j];
3693 if (slider_type > 20) {
3694 plastic = true;
3695 slider_type -= 20;
3696 }
3697 if (slider_type < 10)
3698 o = new Fl_Slider(x, y, width, 10, Name);
3699 else {
3700 o = new Fl_Value_Slider_Input(csound, x, y, width, 10, Name);
3701 slider_type -=10;
3702 ((Fl_Value_Slider_Input*) o)->textboxsize(50);
3703 ((Fl_Value_Slider_Input*) o)->textsize(13);
3704 }
3705 switch((int) slider_type) { //type
3706 case 1: o->type(FL_HOR_FILL_SLIDER); break;
3707 case 3: o->type(FL_HOR_SLIDER); break;
3708 case 5: o->type(FL_HOR_NICE_SLIDER); o->box(FL_FLAT_BOX); break;
3709 case 7: o->type(FL_HOR_NICE_SLIDER); o->box(FL_DOWN_BOX); break;
3710 default: o->type(FL_HOR_NICE_SLIDER); o->box(FL_FLAT_BOX); break;
3711 }
3712 if (plastic) o->box(FL_PLASTIC_DOWN_BOX);
3713 o->align(FL_ALIGN_LEFT);
3714 widget_attributes(csound, o);
3715 MYFLT min, max, range;
3716 if ((int) *p->iminmaxtable > 0) {
3717 min = minmaxtable[j*2];
3718 max = minmaxtable[j*2+1];
3719 }
3720 else {
3721 min = MYFLT(0.0);
3722 max = MYFLT(1.0);
3723 }
3724 int iexp;
3725
3726 p->slider_data[j].min=min;
3727 p->slider_data[j].max=max;
3728 p->slider_data[j].out=&outable[j];
3729
3730 if ((int) *p->iexptable <=0)
3731 // no table, all sliders have the same behaviour
3732 iexp = (int) *p->iexptable;
3733 else
3734 iexp = (int) exptable[j];
3735 switch (iexp) {
3736 case -1: iexp = EXP_; break;
3737 case 0: iexp = LIN_; break;
3738 }
3739
3740 MYFLT val = 0;
3741 p->slider_data[j].exp = iexp;
3742 switch (iexp) {
3743 case LIN_: //linear
3744 o->range(min,max);
3745 o->callback((Fl_Callback*)fl_callbackLinearSliderBank,
3746 (void *) &(p->slider_data[j]));
3747 val = outable[j];
3748 if (val > max) val = max;
3749 else if (val < min) val = min;
3750 break;
3751 case EXP_ : //exponential
3752 if (UNLIKELY(min == 0 || max == 0))
3753 return
3754 csound->InitError(csound,
3755 "%s", Str("FLslidBnk: zero is illegal "
3756 "in exponential operations"));
3757 range = max - min;
3758 o->range(0,range);
3759 #if defined(sun)
3760 p->slider_data[j].base = ::pow((max / (double)min), 1.0/(double)range);
3761 #else
3762 p->slider_data[j].base = ::pow((max / min), 1.0/(double)range);
3763 #endif
3764 o->callback((Fl_Callback*)fl_callbackExponentialSliderBank,
3765 (void *) &(p->slider_data[j]));
3766 {
3767 val = outable[j];
3768 MYFLT range = max-min;
3769 #if defined(sun)
3770 MYFLT base = ::pow(max / (double)min, 1.0/(double)range);
3771 #else
3772 MYFLT base = ::pow(max / min, 1.0/(double)range);
3773 #endif
3774 val = (log(val/min) / log(base)) ;
3775 }
3776 break;
3777 default:
3778 {
3779 FUNC *ftp;
3780 MYFLT fnum = abs(iexp);
3781 if ((ftp = csound->FTnp2Finde(csound, &fnum)) != NULL)
3782 p->slider_data[j].table = ftp->ftable;
3783 else return NOTOK;
3784 p->slider_data[j].tablen = ftp->flen;
3785 o->range(0,0.99999999);
3786 if (iexp > 0) //interpolated
3787 o->callback((Fl_Callback*)fl_callbackInterpTableSliderBank,
3788 (void *) &(p->slider_data[j]));
3789 else // non-interpolated
3790 o->callback((Fl_Callback*)fl_callbackTableSliderBank,
3791 (void *) &(p->slider_data[j]));
3792 }
3793 }
3794 o->value(val);
3795 }
3796 w->resizable(w);
3797 if (*p->iwidth <=0 || *p->iheight <=0) {// default width and height
3798 int a,b;
3799 w->size( a= w->parent()->w() -50, b= w->parent()->h());
3800 w->position(50, 0);
3801 }
3802 else {
3803 w->size( (int)*p->iwidth, (int)*p->iheight);
3804 w->position((int)*p->ix, (int)*p->iy);
3805 }
3806 w->end();
3807 widgetGlobals->AddrSetValue.push_back(ADDR_SET_VALUE(LIN_, 0, 0, (void *) w,
3808 (void *) p,
3809 widgetGlobals->currentSnapGroup));
3810 // *p->ihandle = widgetGlobals->AddrSetValue.size()-1;
3811 widgetGlobals->last_sldbnk = widgetGlobals->AddrSetValue.size()-1; //gab
3812 return OK;
3813 }
3814
fl_slider_bank(CSOUND * csound,FLSLIDERBANK * p)3815 static int fl_slider_bank(CSOUND *csound, FLSLIDERBANK *p){
3816 return fl_slider_bank_(csound,p,0);
3817 }
3818
fl_slider_bank_S(CSOUND * csound,FLSLIDERBANK * p)3819 static int fl_slider_bank_S(CSOUND *csound, FLSLIDERBANK *p){
3820 return fl_slider_bank_(csound,p,1);
3821 }
3822
fl_joystick(CSOUND * csound,FLJOYSTICK * p)3823 static int fl_joystick(CSOUND *csound, FLJOYSTICK *p)
3824 {
3825 WIDGET_GLOBALS *widgetGlobals =
3826 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
3827 char *Name = p->name->data;
3828 int ix,iy,iwidth, iheight, iexpx, iexpy;
3829
3830 if (*p->ix < 0) ix = 10; // omitted options: set default
3831 else widgetGlobals->FL_ix = ix = (int) *p->ix;
3832 if (*p->iy < 0) iy = 10; // omitted options: set default
3833 else iy = (int) *p->iy;
3834 if (*p->iwidth < 0) iwidth = 130;
3835 else iwidth = (int) *p->iwidth;
3836 if (*p->iheight < 0) iheight = 130;
3837 else iheight = (int) *p->iheight;
3838
3839 switch((int) *p->iexpx) {
3840 case -1: iexpx = EXP_; break;
3841 case 0: iexpx = LIN_; break;
3842 default: iexpx = (int) *p->iexpx;
3843 }
3844 switch((int) *p->iexpy) {
3845 case -1: iexpy = EXP_; break;
3846 case 0: iexpy = LIN_; break;
3847 default: iexpy = (int) *p->iexpy;
3848 }
3849 /*
3850 if (*p->iexpx == LIN_) iexpx = LIN_;
3851 else iexpx = (int) *p->iexpx;
3852 if (*p->iexpy == LIN_) iexpy = LIN_;
3853 else iexpy = (int) *p->iexpy;
3854 */
3855
3856 Fl_Positioner *o = new Fl_Positioner(ix, iy, iwidth, iheight, Name);
3857 widget_attributes(csound, o);
3858 switch (iexpx) {
3859 case LIN_: //linear
3860 o->xbounds(*p->iminx,*p->imaxx); break;
3861 case EXP_: //exponential
3862 { if (UNLIKELY(*p->iminx == 0 || *p->imaxx == 0))
3863 return csound->InitError(csound,
3864 "%s", Str("FLjoy X axe: zero is illegal "
3865 "in exponential operations"));
3866 MYFLT range = *p->imaxx - *p->iminx;
3867 o->xbounds(0,range);
3868 #if defined(sun)
3869 p->basex = ::pow((*p->imaxx / (double)*p->iminx), 1.0/(double)range);
3870 #else
3871 p->basex = ::pow((*p->imaxx / *p->iminx), 1.0/(double)range);
3872 #endif
3873 } break;
3874 default:
3875 {
3876 FUNC *ftp;
3877 MYFLT fnum = abs(iexpx);
3878 if ((ftp = csound->FTnp2Finde(csound, &fnum)) != NULL) {
3879 p->tablex = ftp->ftable;
3880 p->tablenx = ftp->flen;
3881 }
3882 else return NOTOK;
3883 o->xbounds(0,0.99999999);
3884 /*
3885 if (iexp > 0) //interpolated
3886 o->callback((Fl_Callback*)fl_callbackInterpTableSlider,(void *) p);
3887 else // non-interpolated
3888 o->callback((Fl_Callback*)fl_callbackTableSlider,(void *) p);
3889 */
3890 }
3891 }
3892 switch (iexpy) {
3893 case LIN_: //linear
3894 o->ybounds(*p->imaxy,*p->iminy); break;
3895 case EXP_ : //exponential
3896 { if (UNLIKELY(*p->iminy == 0 || *p->imaxy == 0))
3897 return csound->InitError(csound,
3898 "%s", Str("FLjoy X axe: zero is illegal "
3899 "in exponential operations"));
3900 MYFLT range = *p->imaxy - *p->iminy;
3901 o->ybounds(range,0);
3902 #if defined(sun)
3903 p->basey = ::pow((*p->imaxy / (double)*p->iminy), 1.0/(double)range);
3904 #else
3905 p->basey = ::pow((*p->imaxy / *p->iminy), 1.0/(double)range);
3906 #endif
3907 } break;
3908 default:
3909 {
3910 FUNC *ftp;
3911 MYFLT fnum = abs(iexpy);
3912 if (LIKELY((ftp = csound->FTnp2Finde(csound, &fnum)) != NULL)) {
3913 p->tabley = ftp->ftable;
3914 p->tableny = ftp->flen;
3915 }
3916 else return NOTOK;
3917 o->ybounds(0,0.99999999);
3918 /* if (iexp > 0) //interpolated
3919 o->callback((Fl_Callback*)fl_callbackInterpTableSlider,(void *) p);
3920 else // non-interpolated
3921 o->callback((Fl_Callback*)fl_callbackTableSlider,(void *) p);
3922 */
3923 }
3924 }
3925 o->align(FL_ALIGN_BOTTOM | FL_ALIGN_WRAP);
3926 o->callback((Fl_Callback*)fl_callbackJoystick,(void *) p);
3927 widgetGlobals->AddrSetValue.push_back(ADDR_SET_VALUE(iexpx, *p->iminx,
3928 *p->imaxx, (void *) o, (void *) p,
3929 widgetGlobals->currentSnapGroup));
3930 *p->ihandle1 = widgetGlobals->AddrSetValue.size()-1;
3931 ADDR_SET_VALUE *asv = &widgetGlobals->AddrSetValue[(int) *p->ihandle1];
3932 asv->widg_type = FL_JOY;
3933 asv->joy = JOY_X;
3934 widgetGlobals->AddrSetValue.push_back(ADDR_SET_VALUE(iexpy, *p->iminy,
3935 *p->imaxy, (void *) o, (void *) p,
3936 widgetGlobals->currentSnapGroup));
3937 *p->ihandle2 = widgetGlobals->AddrSetValue.size()-1;
3938 asv = &widgetGlobals->AddrSetValue[(int) *p->ihandle2];
3939 asv->widg_type = FL_JOY;
3940 asv->joy = JOY_Y;
3941 return OK;
3942 }
3943
fl_knob(CSOUND * csound,FLKNOB * p)3944 static int fl_knob(CSOUND *csound, FLKNOB *p)
3945 {
3946 WIDGET_GLOBALS *widgetGlobals =
3947 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
3948 char *controlName = p->name->data;
3949 int ix, iy, iwidth, itype, iexp;
3950
3951 if (*p->iy < 0) iy = widgetGlobals->FL_iy;
3952 else widgetGlobals->FL_iy = iy = (int) *p->iy;
3953 if (*p->ix < 0) ix = widgetGlobals->FL_ix;
3954 else widgetGlobals->FL_ix = ix = (int) *p->ix;
3955 if (*p->iwidth < 0) iwidth = widgetGlobals->FLcontrol_iwidth;
3956 else widgetGlobals->FLcontrol_iwidth = iwidth = (int) *p->iwidth;
3957 if (*p->itype < 1) itype = 1;
3958 else itype = (int) *p->itype;
3959 /*
3960 if (*p->iexp < LIN_) iexp = LIN_;
3961 else iexp = (int) *p->iexp;
3962 */
3963 switch((int) *p->iexp) {
3964 case -1: iexp = EXP_; break;
3965 case 0: iexp = LIN_; break;
3966 default: iexp = (int) *p->iexp;
3967 }
3968
3969 Fl_Valuator* o;
3970 switch (itype) {
3971 case 1:
3972 o = new Fl_Knob(csound, ix, iy, iwidth, iwidth, controlName);
3973 o->box(FL_NO_BOX);
3974 if (*p->icursorsize > MYFLT(0.5))
3975 ((Fl_Knob*) o)->cursor((int) (*p->icursorsize + MYFLT(0.5)));
3976 break;
3977 case 2:
3978 o = new Fl_Dial(ix, iy, iwidth, iwidth, controlName);
3979 o->type(FL_FILL_DIAL);
3980 o->box(_FL_OSHADOW_BOX);
3981 ((Fl_Dial*) o)->angles(20, 340);
3982 break;
3983 case 3:
3984 o = new Fl_Dial(ix, iy, iwidth, iwidth, controlName);
3985 o->type(FL_LINE_DIAL);
3986 o->box(_FL_OSHADOW_BOX);
3987 break;
3988 case 4:
3989 o = new Fl_Dial(ix, iy, iwidth, iwidth, controlName);
3990 o->type(FL_NORMAL_DIAL);
3991 o->box(_FL_OSHADOW_BOX);
3992 break;
3993 default:
3994 return csound->InitError(csound,
3995 "%s", Str("FLknob: invalid knob type"));
3996 }
3997 widget_attributes(csound, o);
3998 o->align(FL_ALIGN_BOTTOM | FL_ALIGN_WRAP);
3999 o->range(*p->imin, *p->imax);
4000 switch (iexp) {
4001 case LIN_: //linear
4002 o->range(*p->imin,*p->imax);
4003 o->callback((Fl_Callback*)fl_callbackLinearKnob,(void *) p);
4004 o->step(0.001);
4005 break;
4006 case EXP_ : //exponential
4007 {
4008 MYFLT min = p->min = *p->imin, max = *p->imax;
4009 if (UNLIKELY(min == 0 || max == 0))
4010 return csound->InitError(csound,
4011 "%s", Str("FLknob: zero is illegal "
4012 "in exponential operations"));
4013 MYFLT range = max - min;
4014 o->range(0,range);
4015 #if defined(sun)
4016 p->base = ::pow((max / (double)min), 1.0/(double)range);
4017 #else
4018 p->base = ::pow((max / min), 1.0/(double)range);
4019 #endif
4020 o->callback((Fl_Callback*)fl_callbackExponentialKnob,(void *) p);
4021 } break;
4022 default:
4023 {
4024 FUNC *ftp;
4025 p->min = *p->imin;
4026 MYFLT fnum = abs(iexp);
4027 if ((ftp = csound->FTnp2Finde(csound, &fnum)) != NULL) {
4028 p->table = ftp->ftable;
4029 p->tablen = ftp->flen;
4030 }
4031 else return OK;
4032 o->range(0,0.99999999);
4033 if (iexp > 0) //interpolated
4034 o->callback((Fl_Callback*)fl_callbackInterpTableKnob,(void *) p);
4035 else // non-interpolated
4036 o->callback((Fl_Callback*)fl_callbackTableKnob,(void *) p);
4037 }
4038 }
4039 widgetGlobals->AddrSetValue.push_back(ADDR_SET_VALUE(iexp, *p->imin, *p->imax,
4040 (void *) o, (void *) p));
4041 *p->ihandle = widgetGlobals->AddrSetValue.size()-1;
4042 return OK;
4043 }
4044
fl_text(CSOUND * csound,FLTEXT * p)4045 static int fl_text(CSOUND *csound, FLTEXT *p)
4046 {
4047 WIDGET_GLOBALS *widgetGlobals =
4048 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
4049 char *controlName = p->name->data;
4050 int ix,iy,iwidth,iheight,itype;
4051 MYFLT istep;
4052
4053 if (*p->iy < 0) iy = widgetGlobals->FL_iy;
4054 else widgetGlobals->FL_iy = iy = (int) *p->iy;
4055 if (*p->ix < 0) ix = widgetGlobals->FL_ix;
4056 else widgetGlobals->FL_ix = ix = (int) *p->ix;
4057 if (*p->iwidth < 0) iwidth = widgetGlobals->FLcontrol_iwidth;
4058 else widgetGlobals->FLcontrol_iwidth = iwidth = (int) *p->iwidth;
4059 if (*p->iheight < 0) iheight = widgetGlobals->FLcontrol_iheight;
4060 else widgetGlobals->FLcontrol_iheight = iheight = (int) *p->iheight;
4061 if (*p->itype < 1) itype = 1;
4062 else itype = (int) *p->itype;
4063 if (*p->istep < 0) istep = MYFLT(.1);
4064 else istep = *p->istep;
4065
4066 Fl_Valuator* o;
4067 switch(itype) {
4068 case 1:
4069 {
4070 o = new Fl_Value_Input(ix, iy, iwidth, iheight, controlName);
4071 ((Fl_Value_Input *) o)->step(istep);
4072 ((Fl_Value_Input *) o)->range(*p->imin,*p->imax);
4073 }
4074 break;
4075 case 2:
4076 {
4077 o = new Fl_Value_Input_Spin(csound, ix, iy,
4078 iwidth, iheight, controlName);
4079 ((Fl_Value_Input *) o)->step(istep);
4080 ((Fl_Value_Input *) o)->range(*p->imin,*p->imax);
4081 }
4082 break;
4083 case 3:
4084 {
4085 o = new Fl_Value_Output(ix, iy, iwidth, iheight, controlName);
4086 ((Fl_Value_Output *) o)->step(istep);
4087 ((Fl_Value_Output *) o)->range(*p->imin,*p->imax);
4088 }
4089 break;
4090 default:
4091 return NOTOK;
4092 }
4093 o->align(FL_ALIGN_BOTTOM | FL_ALIGN_WRAP);
4094 widget_attributes(csound, o);
4095 o->callback((Fl_Callback*)fl_callbackLinearValueInput,(void *) p);
4096 widgetGlobals->AddrSetValue.push_back(ADDR_SET_VALUE(1, *p->imin, *p->imax,
4097 (void *) o, (void *) p,
4098 widgetGlobals->currentSnapGroup));
4099 *p->ihandle = widgetGlobals->AddrSetValue.size()-1;
4100 return OK;
4101 }
4102
fl_button(CSOUND * csound,FLBUTTON * p)4103 static int fl_button(CSOUND *csound, FLBUTTON *p)
4104 {
4105 WIDGET_GLOBALS *widgetGlobals =
4106 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
4107 char *Name = p->name->data;
4108 int type = (int) *p->itype;
4109 bool plastic = false;
4110 if (type > 19) {
4111 type = type - 20;
4112 plastic = true;
4113 }
4114 if (UNLIKELY(type > 9)) { // ignored when getting widgetGlobals->snapshots
4115 csound->Warning(csound,
4116 Str("FLbutton \"%s\" ignoring snapshot capture retrieve"),
4117 Name);
4118 type = type - 10;
4119 }
4120 Fl_Button *w;
4121 *p->kout = *p->ioff; // IV - Aug 27 2002
4122
4123 switch (type) {
4124 case 1:
4125 w = new Fl_Button((int)*p->ix, (int)*p->iy,
4126 (int)*p->iwidth, (int)*p->iheight, Name);
4127 if (plastic) {
4128 w->box(FL_PLASTIC_UP_BOX);
4129 w->down_box(FL_PLASTIC_DOWN_BOX);
4130 }
4131 break;
4132 case 2:
4133 w = new Fl_Light_Button((int)*p->ix, (int)*p->iy,
4134 (int)*p->iwidth, (int)*p->iheight, Name);
4135 if (plastic) {
4136 w->box(FL_PLASTIC_UP_BOX);
4137 // w->down_box(FL_PLASTIC_DOWN_BOX); //Doesn't work
4138 }
4139 break;
4140 case 3:
4141 w = new Fl_Check_Button((int)*p->ix, (int)*p->iy,
4142 (int)*p->iwidth, (int)*p->iheight, Name);
4143 if (plastic) {
4144 w->box(FL_PLASTIC_UP_BOX);
4145 w->down_box(FL_PLASTIC_DOWN_BOX);
4146 }
4147 break;
4148 case 4:
4149 w = new Fl_Round_Button((int)*p->ix, (int)*p->iy,
4150 (int)*p->iwidth, (int)*p->iheight, Name);
4151 if (plastic) {
4152 w->box(FL_PLASTIC_UP_BOX);
4153 w->down_box(FL_PLASTIC_DOWN_BOX);
4154 }
4155 break;
4156 default:
4157 return csound->InitError(csound,
4158 "%s", Str("FLbutton: invalid button type"));
4159 }
4160 Fl_Button *o = w;
4161 o->align(FL_ALIGN_WRAP);
4162 widget_attributes(csound, o);
4163 if (type == 1)
4164 o->callback((Fl_Callback*) fl_callbackButton1, (void*) p);
4165 else
4166 o->callback((Fl_Callback*) fl_callbackButton, (void*) p);
4167 widgetGlobals->AddrSetValue.push_back(ADDR_SET_VALUE(0, 0, 0, (void *) o,
4168 (void *) p,
4169 widgetGlobals->currentSnapGroup));
4170 *p->ihandle = widgetGlobals->AddrSetValue.size() - 1;
4171
4172 return OK;
4173 }
4174
fl_close_button(CSOUND * csound,FLCLOSEBUTTON * p)4175 static int fl_close_button(CSOUND *csound, FLCLOSEBUTTON *p)
4176 {
4177 WIDGET_GLOBALS *widgetGlobals =
4178 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
4179 char *Name = p->name->data;
4180
4181 Fl_Button *w;
4182
4183 w = new Fl_Button((int)*p->ix, (int)*p->iy,
4184 (int)*p->iwidth, (int)*p->iheight, Name);
4185
4186 Fl_Button *o = w;
4187
4188 o->align(FL_ALIGN_WRAP);
4189 widget_attributes(csound, o);
4190
4191 ADDR_STACK adrstk = widgetGlobals->AddrStack.back();
4192 if (UNLIKELY(strcmp( adrstk.h->optext->t.opcod, "FLpanel")))
4193 return csound->InitError(csound,
4194 "%s", Str("FLcloseButton: invalid stack"
4195 " pointer: verify its placement"));
4196
4197 o->callback((Fl_Callback*) fl_callbackCloseButton,
4198 (void*) adrstk.WidgAddress);
4199
4200 widgetGlobals->AddrSetValue.push_back(ADDR_SET_VALUE(0, 0, 0, (void *) o,
4201 (void *) p));
4202 *p->ihandle = widgetGlobals->AddrSetValue.size() - 1;
4203
4204 return OK;
4205 }
4206
fl_exec_button(CSOUND * csound,FLEXECBUTTON * p)4207 static int fl_exec_button(CSOUND *csound, FLEXECBUTTON *p)
4208 {
4209 WIDGET_GLOBALS *widgetGlobals =
4210 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
4211 p->csound = csound;
4212 Fl_Button *w;
4213
4214 p->commandString = p->command->data;
4215
4216 csound->Message(csound, Str("Command Found: %s\n"), p->commandString);
4217
4218 w = new Fl_Button((int)*p->ix, (int)*p->iy,
4219 (int)*p->iwidth, (int)*p->iheight, Str("About"));
4220
4221 Fl_Button *o = w;
4222
4223 o->align(FL_ALIGN_WRAP);
4224 widget_attributes(csound, o);
4225
4226 o->callback((Fl_Callback*) fl_callbackExecButton, (void*) p);
4227
4228 widgetGlobals->AddrSetValue.push_back(ADDR_SET_VALUE(0, 0, 0,
4229 (void *) o, (void *) p,
4230 widgetGlobals->currentSnapGroup));
4231 *p->ihandle = widgetGlobals->AddrSetValue.size() - 1;
4232
4233 return OK;
4234 }
4235
fl_button_bank(CSOUND * csound,FLBUTTONBANK * p)4236 static int fl_button_bank(CSOUND *csound, FLBUTTONBANK *p)
4237 {
4238 WIDGET_GLOBALS *widgetGlobals =
4239 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
4240 char *Name = (char*)"/0";
4241 int type = (int) *p->itype;
4242 bool plastic = false;
4243 if (type > 20) {
4244 plastic = true;
4245 type = type - 20;
4246 }
4247 if (UNLIKELY(type > 9)) { // ignored when getting widgetGlobals->snapshots
4248 csound->Warning(csound,
4249 Str("FLbutton \"%s\" ignoring snapshot capture retrieve"),
4250 Name);
4251 type = type - 10;
4252 }
4253 Fl_Group* o = new Fl_Group((int)*p->ix, (int)*p->iy,
4254 (int)*p->inumx * 10, (int)*p->inumy*10);
4255 int z = 0;
4256 for (int j = 0; j < *p->inumx; j++) {
4257 for (int k = 0; k < *p->inumy; k++) {
4258 int x = (int) *p->ix + j*10, y = (int) *p->iy + k*10;
4259 Fl_Button *w;
4260 char *btName = new char[30];
4261 widgetGlobals->allocatedStrings.push_back(btName);
4262 sprintf(btName, "%d", z);
4263 switch (type) {
4264 case 1:
4265 w = new Fl_Button(x, y, 10, 10, btName);
4266 if (plastic) {
4267 w->box(FL_PLASTIC_UP_BOX);
4268 w->down_box(FL_PLASTIC_DOWN_BOX);
4269 }
4270 break;
4271 case 2:
4272 w = new Fl_Light_Button(x, y, 10, 10, btName);
4273 if (plastic) {
4274 w->box(FL_PLASTIC_UP_BOX);
4275 }
4276 break;
4277 case 3:
4278 w = new Fl_Check_Button(x, y, 10, 10, btName);
4279 if (plastic) {
4280 w->box(FL_PLASTIC_UP_BOX);
4281 w->down_box(FL_PLASTIC_DOWN_BOX);
4282 }
4283 break;
4284 case 4:
4285 w = new Fl_Round_Button(x, y, 10, 10, btName);
4286 if (plastic) {
4287 w->box(FL_PLASTIC_UP_BOX);
4288 w->down_box(FL_PLASTIC_DOWN_BOX);
4289 }
4290 break;
4291 default: return csound->InitError(csound,
4292 "%s", Str("FLbuttonBank: "
4293 "invalid button type"));
4294 }
4295 widget_attributes(csound, w);
4296 w->type(FL_RADIO_BUTTON);
4297 w->callback((Fl_Callback*) fl_callbackButtonBank, (void *) p);
4298 if (!z)
4299 w->value(1);
4300 z++;
4301 }
4302 }
4303 o->resizable(o);
4304 // *p->ix, *p->iy,
4305 o->size( (int)*p->iwidth, (int)*p->iheight);
4306 o->position((int)*p->ix, (int)*p->iy);
4307 o->align(FL_ALIGN_BOTTOM | FL_ALIGN_WRAP);
4308 o->end();
4309
4310 widgetGlobals->AddrSetValue.push_back(ADDR_SET_VALUE(0, 0, 0,
4311 (void *) o, (void *) p,
4312 widgetGlobals->currentSnapGroup));
4313 *p->kout = MYFLT(0.0);
4314 *p->ihandle = widgetGlobals->AddrSetValue.size()-1;
4315 return OK;
4316 }
4317
fl_counter(CSOUND * csound,FLCOUNTER * p)4318 static int fl_counter(CSOUND *csound, FLCOUNTER *p)
4319 {
4320 char *controlName = p->name->data;
4321 // int ix,iy,iwidth,iheight,itype;
4322 // MYFLT istep1, istep2;
4323 WIDGET_GLOBALS *widgetGlobals =
4324 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
4325 Fl_Counter* o = new Fl_Counter((int)*p->ix, (int)*p->iy,
4326 (int)*p->iwidth, (int)*p->iheight,
4327 controlName);
4328 widget_attributes(csound, o);
4329 int type = (int) *p->itype;
4330 if (UNLIKELY(type >9 )) { // ignored when getting widgetGlobals->snapshots
4331 csound->Warning(csound,
4332 Str("FLcount \"%s\" ignoring snapshot capture retrieve"),
4333 controlName);
4334 type = type-10;
4335 }
4336 switch(type) {
4337 case 1: o->type(FL_NORMAL_COUNTER); break;
4338 case 2: o->type(FL_SIMPLE_COUNTER); break;
4339 default:o->type(FL_NORMAL_COUNTER); break;
4340 }
4341
4342 o->step(*p->istep1);
4343 o->lstep(*p->istep2);
4344 o->align(FL_ALIGN_BOTTOM | FL_ALIGN_WRAP);
4345 // range is accepted only if min and max are different
4346 if (*p->imin != *p->imax)
4347 o->range(*p->imin,*p->imax); //otherwise no-range
4348 widget_attributes(csound, o);
4349 o->callback((Fl_Callback*)fl_callbackCounter,(void *) p);
4350 widgetGlobals->AddrSetValue.push_back(ADDR_SET_VALUE(1, 0, 100000, (void *) o,
4351 (void *) p,
4352 widgetGlobals->currentSnapGroup));
4353 *p->ihandle = widgetGlobals->AddrSetValue.size()-1;
4354 return OK;
4355 }
4356
fl_roller(CSOUND * csound,FLROLLER * p)4357 static int fl_roller(CSOUND *csound, FLROLLER *p)
4358 {
4359 char *controlName = p->name->data;
4360 int ix,iy,iwidth, iheight,itype, iexp ;
4361 double istep;
4362 WIDGET_GLOBALS *widgetGlobals =
4363 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
4364 if (*p->iy < 0) {
4365 iy = widgetGlobals->FL_iy;
4366 widgetGlobals->FL_iy += widgetGlobals->FLroller_iheight + 15;
4367 }
4368 else {
4369 iy = (int) *p->iy;
4370 widgetGlobals->FL_iy = iy + widgetGlobals->FLroller_iheight + 15;
4371 }
4372 // omitted options: set defaults
4373 if (*p->ix<0) ix = widgetGlobals->FL_ix;
4374 else widgetGlobals->FL_ix = ix = (int) *p->ix;
4375 if (*p->iy<0) iy = widgetGlobals->FL_iy;
4376 else widgetGlobals->FL_iy = iy = (int) *p->iy;
4377 if (*p->iwidth<0) iwidth = widgetGlobals->FLroller_iwidth;
4378 else widgetGlobals->FLroller_iwidth = iwidth = (int) *p->iwidth;
4379 if (*p->iheight<0) iheight = widgetGlobals->FLroller_iheight;
4380 else widgetGlobals->FLroller_iheight = iheight = (int) *p->iheight;
4381 if (*p->itype<1) itype = 1;
4382 else itype = (int) *p->itype;
4383 //if (*p->iexp<LIN_) iexp = LIN_;
4384 //else iexp = (int) *p->iexp;
4385 switch((int) *p->iexp) {
4386 case -1: iexp = EXP_; break;
4387 case 0: iexp = LIN_; break;
4388 default: iexp = (int) *p->iexp;
4389 }
4390
4391 if (*p->istep<0) istep = 1; else istep = *p->istep;
4392 p->min = *p->imin;
4393 Fl_Roller *o;
4394 switch (itype) {
4395 case 1:
4396 o = new Fl_Roller(ix, iy, iwidth, iheight, controlName);
4397 o->type(FL_HORIZONTAL);
4398 break;
4399 case 2:
4400 o = new Fl_Roller(ix, iy, iwidth, iheight, controlName);
4401 o->type(FL_VERTICAL);
4402 break;
4403 default:
4404 return csound->InitError(csound,
4405 "%s", Str("FLroller: invalid roller type"));
4406 }
4407 widget_attributes(csound, o);
4408 o->step(istep);
4409 switch (iexp) {
4410 case LIN_: //linear
4411 o->range(*p->imin,*p->imax);
4412 o->callback((Fl_Callback*)fl_callbackLinearRoller,(void *) p);
4413 break;
4414 case EXP_ : //exponential
4415 {
4416 MYFLT min = p->min, max = *p->imax;
4417 if (UNLIKELY(min == 0 || max == 0))
4418 return csound->InitError(csound,
4419 "%s", Str("FLslider: zero is illegal "
4420 "in exponential operations"));
4421 MYFLT range = max - min;
4422 o->range(0,range);
4423 #if defined(sun)
4424 p->base = ::pow((max / (double)min), 1.0/(double)range);
4425 #else
4426 p->base = ::pow((max / min), 1.0/(double)range);
4427 #endif
4428 o->callback((Fl_Callback*)fl_callbackExponentialRoller,(void *) p);
4429 }
4430 break;
4431 default:
4432 {
4433 FUNC *ftp;
4434 MYFLT fnum = abs(iexp);
4435 if ((ftp = csound->FTnp2Finde(csound, &fnum)) != NULL) {
4436 p->table = ftp->ftable;
4437 p->tablen = ftp->flen;
4438 }
4439 else return NOTOK;
4440 o->range(0,0.99999999);
4441 if (iexp > 0) //interpolated
4442 o->callback((Fl_Callback*)fl_callbackInterpTableRoller,(void *) p);
4443 else // non-interpolated
4444 o->callback((Fl_Callback*)fl_callbackTableRoller,(void *) p);
4445 }
4446 }
4447 widgetGlobals->AddrSetValue.push_back(ADDR_SET_VALUE(iexp, *p->imin, *p->imax,
4448 (void *) o, (void *) p,
4449 widgetGlobals->currentSnapGroup));
4450 *p->ihandle = widgetGlobals->AddrSetValue.size()-1;
4451 return OK;
4452 }
4453
FLprintkset(CSOUND * csound,FLPRINTK * p)4454 static int FLprintkset(CSOUND *csound, FLPRINTK *p)
4455 {
4456 //WIDGET_GLOBALS *widgetGlobals =
4457 //(WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
4458 if (*p->ptime < MYFLT(1.0) / CS_EKR)
4459 p->ctime = MYFLT(1.0) / CS_EKR;
4460 else p->ctime = *p->ptime;
4461
4462 p->initime = (MYFLT) csound->GetKcounter(csound) * (1.0/CS_EKR);
4463 p->cysofar = -1;
4464 return OK;
4465 }
4466
FLprintk(CSOUND * csound,FLPRINTK * p)4467 static int FLprintk(CSOUND *csound, FLPRINTK *p)
4468 {
4469 MYFLT timel;
4470 long cycles;
4471 WIDGET_GLOBALS *widgetGlobals =
4472 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
4473
4474 timel = ((MYFLT) csound->GetKcounter(csound) *
4475 (1.0/CS_EKR)) - p->initime;
4476 cycles = (long)(timel / p->ctime);
4477 if (p->cysofar < cycles) {
4478 p->cysofar = cycles;
4479 char valString[MAXNAME];
4480 sprintf(valString,"%.5g", *p->val);
4481 ((Fl_Output*) (widgetGlobals->AddrSetValue[(long) *p->idisp]).WidgAddress)->
4482 value(valString );
4483 }
4484 return OK;
4485 }
4486
FLprintk2set(CSOUND * csound,FLPRINTK2 * p)4487 static int FLprintk2set(CSOUND *csound, FLPRINTK2 *p) // IV - Aug 27 2002
4488 {
4489 IGN(csound);
4490 p->oldvalue = MYFLT(-1.12123e35); // hack to force printing first value
4491 return OK;
4492 }
4493
FLprintk2(CSOUND * csound,FLPRINTK2 * p)4494 static int FLprintk2(CSOUND *csound, FLPRINTK2 *p)
4495 {
4496 MYFLT value = *p->val;
4497 WIDGET_GLOBALS *widgetGlobals =
4498 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
4499 if (p->oldvalue != value) {
4500 char valString[MAXNAME];
4501 sprintf(valString,"%.5g", *p->val);
4502 ((Fl_Output*) (widgetGlobals->AddrSetValue[(long) *p->idisp]).WidgAddress)->
4503 value(valString );
4504 p->oldvalue = value;
4505 }
4506 return OK;
4507 }
4508
4509 // New opcodes for Csound5.06 by Gabriel Maldonado, ported by Andres Cabrera
4510
skin(CSOUND * csound,Fl_Widget * o,int imgNum,bool isTiled)4511 void skin(CSOUND* csound, Fl_Widget *o, int imgNum, bool isTiled)
4512 {
4513 IGN(csound); IGN(o); IGN(imgNum); IGN(isTiled);
4514 // WIDGET_GLOBALS *widgetGlobals =
4515 // (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
4516 #ifdef CS_IMAGE
4517 extern void* get_image(CSOUND* csound, int imgNum);
4518 ImageSTRUCT *bmp = (ImageSTRUCT*) get_image(csound, imgNum);
4519 FLlock();
4520 Fl_RGB_Image *img = new Fl_RGB_Image((BYTE*) (bmp->data),
4521 bmp->xsize,bmp->ysize,bmp->csize);
4522 widgetGlobals->allocatedStrings.push_back((char *) img);
4523 if (isTiled) {
4524 Fl_Tiled_Image *t_img = new Fl_Tiled_Image(img);
4525 o->image(t_img);
4526 widgetGlobals->allocatedStrings.push_back((char *) t_img);
4527 }
4528 else {
4529 o->image(img);
4530 }
4531 o->align(FL_ALIGN_INSIDE);
4532 FLunlock();
4533 #endif
4534 }
4535
4536 class HVS_BOX : public Fl_Box{
4537 int rx,ry,rw,rh;
4538 int red, green, blue;
4539 // Fl_PNG_Image *img;
4540 public:
4541
4542 int numLinesX,numLinesY;
4543 MYFLT valueX, valueY;
4544
HVS_BOX(int numLinesX_,int numLinesY_,int x,int y,int w,int h)4545 HVS_BOX(int numLinesX_, int numLinesY_, int x, int y, int w, int h) :
4546 Fl_Box(x,y,w,h) {
4547 numLinesX = numLinesX_ - 1;
4548 numLinesY = numLinesY_ - 1;
4549 valueX = valueY = .5;
4550 rx = rw = ry = rh = 0;
4551 red = green = blue = 0;
4552 // if (filename != NULL) {
4553 // img = new Fl_PNG_Image(filename);
4554 // this->image(img);
4555 // }
4556 }
draw()4557 void draw() {
4558 Fl_Box::draw();
4559
4560 fl_color(selection_color());
4561 MYFLT Xincr = w()/(MYFLT) numLinesX;
4562 MYFLT Yincr = h()/(MYFLT) numLinesY;
4563 fl_color(FL_RED);
4564 for (int j = 1; j < numLinesX; j++) {
4565 fl_yxline((int) (j*Xincr+x()), y(), h()+y());
4566 }
4567 for (int k = 1; k <numLinesY; k++) {
4568 fl_xyline(x(), (int) (k*Yincr+y()), w()+x()-2);
4569 }
4570 fl_color(FL_CYAN);
4571 fl_yxline((int) (valueX*w()+x()), y(), h()+y());
4572 fl_xyline(x(), (int) (valueY*h()+y()), w()+x()-2);
4573 fl_color(FL_BLACK);
4574 fl_rect((int) (valueX*w()+x()-6), (int) (valueY*h()+y()-6), 12, 12);
4575 fl_color(FL_WHITE);
4576 fl_rect((int) (valueX*w()+x()-10), (int) (valueY*h()+y()-10), 20, 20);
4577 }
4578
handle(int event)4579 virtual int handle(int event) {
4580 switch (event) {
4581 case FL_PUSH:
4582 case FL_DRAG:
4583 case FL_RELEASE:
4584 valueX = (MYFLT) (Fl::event_x() - x()) / (MYFLT) w();
4585 valueY = (MYFLT) (Fl::event_y() - y()) / (MYFLT) h();
4586 redraw();
4587 return 1;
4588 default:
4589 return 0;
4590
4591 }
4592 }
setXY(MYFLT xx,MYFLT yy)4593 void setXY(MYFLT xx, MYFLT yy) {
4594 valueX = xx;
4595 valueY = yy;
4596 damage(FL_DAMAGE_ALL);
4597 redraw();
4598 }
4599
4600 /*
4601 void set_rect (int newrx, int newry, int newrw, int newrh) {
4602 rx = newrx; ry=newry; rw=newrw; rh=newrh;
4603 redraw();
4604 }
4605 void set_color (int newred, int newgreen, int newblue){
4606 red=newred; blue=newblue; green=newgreen;
4607 }
4608 */
4609 };
4610
fl_hvsbox(CSOUND * csound,FL_HVSBOX * p)4611 static int fl_hvsbox(CSOUND *csound,FL_HVSBOX *p)
4612 {
4613 WIDGET_GLOBALS *widgetGlobals =
4614 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
4615 if (UNLIKELY(*p->numlinesX < 2 || *p->numlinesY < 2))
4616 return csound->InitError(csound,
4617 "%s", Str("FLhvsBox: a square area must be"
4618 " delimited by 2 lines at least"));
4619
4620 HVS_BOX *o = new HVS_BOX((int) *p->numlinesX,(int) *p->numlinesY,
4621 (int) *p->ix,(int) *p->iy,
4622 (int) *p->iwidth, (int) *p->iheight);
4623 widget_attributes(csound,o);
4624 o->box(FL_DOWN_BOX);
4625 if (*p->image >= 0) skin(csound, o, (int) *p->image, false);
4626
4627 widgetGlobals->AddrSetValue.push_back(ADDR_SET_VALUE(0, 0, 0,
4628 (void *) o, (void *) p,
4629 widgetGlobals->currentSnapGroup));
4630 *p->ihandle = widgetGlobals->AddrSetValue.size()-1;
4631 return OK;
4632
4633 }
4634
fl_setHvsValue_set(CSOUND * csound,FL_SET_HVS_VALUE * p)4635 static int fl_setHvsValue_set(CSOUND *csound,FL_SET_HVS_VALUE *p)
4636 {
4637 IGN(csound);
4638 WIDGET_GLOBALS *widgetGlobals =
4639 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
4640 ADDR_SET_VALUE v = widgetGlobals->AddrSetValue[(int) *p->ihandle];
4641 p->WidgAddress = v.WidgAddress;
4642 p->opcode = v.opcode;
4643 return OK;
4644 }
4645
fl_setHvsValue(CSOUND * csound,FL_SET_HVS_VALUE * p)4646 static int fl_setHvsValue(CSOUND *csound,FL_SET_HVS_VALUE *p)
4647 {
4648 IGN(csound);
4649 if(*p->kx != p->old_x || *p->ky != p->old_y ) {
4650 HVS_BOX *o = (HVS_BOX *) p->WidgAddress;
4651 FLlock();
4652 o->setXY(*p->kx, *p->ky);
4653 FLunlock();
4654 p->old_x = *p->kx;
4655 p->old_y = *p->ky;
4656 }
4657 return OK;
4658 }
4659
4660
fl_keyin_set(CSOUND * csound,FLKEYIN * p)4661 static int fl_keyin_set(CSOUND *csound,FLKEYIN *p)
4662 {
4663 FUNC* ftp;
4664 if (*p->ifn > 0) { // mapping values
4665 p->flag = 1;
4666
4667 if (LIKELY((ftp = csound->FTnp2Finde(csound,p->ifn)) != NULL))
4668 p->table = ftp->ftable;
4669 else {
4670 return csound->InitError(csound,
4671 "%s", Str("FLkeyIn: invalid table number"));
4672 }
4673 if (UNLIKELY(ftp->flen < 512)) {
4674 return csound->InitError(csound,
4675 "%s", Str("FLkeyIn: table too short!"));
4676 }
4677 }
4678 else p->flag = 0;
4679 return OK;
4680 }
4681
fl_keyin(CSOUND * csound,FLKEYIN * p)4682 static int fl_keyin(CSOUND *csound,FLKEYIN *p)
4683 {
4684 WIDGET_GLOBALS *widgetGlobals =
4685 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
4686 if (widgetGlobals->last_KEY) {
4687 int key;
4688
4689 if ( widgetGlobals->last_KEY > 0 && widgetGlobals->last_KEY < 256)
4690 key = widgetGlobals->last_KEY;
4691 else
4692 key = (widgetGlobals->last_KEY & 0xFF) + 256; // function keys
4693
4694 if(p->flag) {
4695 if(widgetGlobals->isKeyDown)
4696 p->table[key] = 1;
4697 else
4698 p->table[key] = 0;
4699 }
4700 if (widgetGlobals->isKeyDown) *p->kascii = key;
4701 else *p->kascii = -key;
4702 widgetGlobals->last_KEY = 0;
4703 }
4704 return OK;
4705 }
4706
fl_setSnapGroup(CSOUND * csound,FLSETSNAPGROUP * p)4707 static int fl_setSnapGroup(CSOUND *csound, FLSETSNAPGROUP *p)
4708 {
4709 IGN(csound);
4710 WIDGET_GLOBALS *widgetGlobals =
4711 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
4712 widgetGlobals->currentSnapGroup = (int) *p->group;
4713 return OK;
4714 }
4715
fl_mouse_set(CSOUND * csound,FLMOUSE * p)4716 static int fl_mouse_set(CSOUND *csound,FLMOUSE *p)
4717 {
4718 IGN(csound);
4719 p->width= Fl::w();
4720 p->height= Fl::h();
4721 return OK;
4722 }
4723
fl_mouse(CSOUND * csound,FLMOUSE * p)4724 static int fl_mouse(CSOUND *csound,FLMOUSE *p)
4725 {
4726 IGN(csound);
4727 if (*p->flagRaw == 0) {
4728 *p->x = (MYFLT) Fl::event_x_root()/p->width;
4729 *p->y = 1.0 - ((MYFLT) Fl::event_y_root()/p->height);
4730 }
4731 else if (*p->flagRaw == 1) {
4732 *p->x = (MYFLT) Fl::event_x_root();
4733 *p->y = (MYFLT) Fl::event_y_root();
4734 }
4735 else if (*p->flagRaw == 2) {
4736 *p->x = (MYFLT) Fl::event_x();
4737 *p->y = (MYFLT) Fl::event_y();
4738 }
4739 // *p->b1 = (MYFLT) (Fl::event_button1() >> 56);
4740 // *p->b2 = (MYFLT) (Fl::event_button2() >> 57);
4741 // *p->b3 = (MYFLT) (Fl::event_button3() >> 58);
4742 *p->b1 = (MYFLT) (Fl::event_button1() >> 24);
4743 *p->b2 = (MYFLT) (Fl::event_button2() >> 25);
4744 *p->b3 = (MYFLT) (Fl::event_button3() >> 26);
4745
4746 return OK;
4747 }
4748
4749
fl_vertical_slider_bank_(CSOUND * csound,FLSLIDERBANK * p,int istring)4750 static int fl_vertical_slider_bank_(CSOUND *csound, FLSLIDERBANK *p, int istring)
4751 {
4752 WIDGET_GLOBALS *widgetGlobals =
4753 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
4754 char s[MAXNAME];
4755 bool plastic = false;
4756 if (istring)
4757 strncpy(s, ((STRINGDAT *)p->names)->data, MAXNAME-1);
4758 else if ((long) *p->names <= csound->GetStrsmax(csound) &&
4759 csound->GetStrsets(csound,(long) *p->names)) {
4760 strncpy(s, csound->GetStrsets(csound,(long) *p->names), MAXNAME-1);
4761 }
4762 string tempname(s);
4763 stringstream sbuf;
4764 sbuf << tempname;
4765
4766 int height = (int) *p->iheight;
4767 if (height <=0) height = 100;
4768 Fl_Group* w = new Fl_Group((int)*p->ix, (int)*p->iy,
4769 (int)*p->inumsliders*10, height);
4770 FUNC *ftp;
4771 MYFLT *minmaxtable = NULL, *typetable = NULL, *outable, *exptable = NULL;
4772
4773 MYFLT *zkstart;
4774 int zklast = csound->GetZakBounds(csound, &zkstart);
4775 if (*p->ioutable < 1) {
4776 if (LIKELY(zkstart != NULL &&
4777 zklast > (long)(*p->inumsliders+*p->ioutablestart_ndx)))
4778 outable = zkstart + (long) *p->ioutablestart_ndx;
4779 else {
4780 return csound->InitError(csound,
4781 "%s", Str("invalid ZAK space allocation"));
4782 }
4783 }
4784 else {
4785 if (LIKELY((ftp = csound->FTnp2Finde(csound, p->ioutable)) != NULL))
4786 outable = ftp->ftable + (long) *p->ioutablestart_ndx;
4787 else
4788 return NOTOK;
4789 }
4790 if ((int) *p->iminmaxtable > 0) {
4791 if (LIKELY((ftp = csound->FTnp2Finde(csound, p->iminmaxtable)) != NULL))
4792 minmaxtable = ftp->ftable;
4793 else return NOTOK;
4794 }
4795 if ((int) *p->iexptable > 0) {
4796 if (LIKELY((ftp = csound->FTnp2Finde(csound, p->iexptable)) != NULL))
4797 exptable = ftp->ftable;
4798 else return NOTOK;
4799 }
4800 if ((int) *p->itypetable > 0) {
4801 if (LIKELY((ftp = csound->FTnp2Finde(csound, p->itypetable)) != NULL))
4802 typetable = ftp->ftable;
4803 else return NOTOK;
4804 }
4805 p->elements = (long) *p->inumsliders;
4806
4807 for (int j =0; j< p->elements; j++) {
4808 string stemp;
4809 if (tempname == " ") {
4810 char s[40];
4811 sprintf(s, "%d", j);
4812 stemp = s;
4813 }
4814 else
4815 getline(sbuf, stemp, '@');
4816 char *Name = new char[stemp.size()+2];
4817 strcpy(Name,stemp.c_str());
4818 widgetGlobals->allocatedStrings.push_back(Name);
4819
4820 int x = (int) *p->ix+j*10, y = (int) *p->iy /*+ j*10*/;
4821 Fl_Slider *o;
4822 int slider_type;
4823 if ((int) *p->itypetable <= 0) { // no slider type table
4824 if (*p->itypetable >= -7) // all sliders are of the same type
4825 slider_type = -((int) *p->itypetable);
4826 else if (*p->itypetable >= -27 && *p->itypetable < -20) {
4827 slider_type = -((int) *p->itypetable) - 20;
4828 plastic = true;
4829 }
4830 else { // random type
4831 slider_type = rand_31_i(csound, 7) | 1;
4832 switch(slider_type) {
4833 case 0: slider_type = 1; break;
4834 case 2: slider_type = 3; break;
4835 case 4: slider_type = 5; break;
4836 case 6: slider_type = 7; break;
4837 default: slider_type = 1;
4838 }
4839 }
4840 }
4841 else
4842 slider_type = (int) typetable[j];
4843 if (slider_type > 20) {
4844 plastic = true;
4845 slider_type -= 20;
4846 }
4847 if (slider_type < 10)
4848 o = new Fl_Slider(x, y, 10, height, Name);
4849 else {
4850 o = new Fl_Value_Slider_Input(csound, x, y, 10, height, Name);
4851 slider_type -=10;
4852 ((Fl_Value_Slider_Input*) o)->textboxsize(50);
4853 ((Fl_Value_Slider_Input*) o)->textsize(13);
4854 }
4855 switch((int) slider_type) { //type
4856 case 1: o->type(FL_VERT_FILL_SLIDER); break;
4857 case 3: o->type(FL_VERT_SLIDER); break;
4858 case 5: o->type(FL_VERT_NICE_SLIDER); o->box(FL_FLAT_BOX); break;
4859 case 7: o->type(FL_VERT_NICE_SLIDER); o->box(FL_DOWN_BOX); break;
4860 default: o->type(FL_VERT_NICE_SLIDER); o->box(FL_FLAT_BOX); break;
4861 }
4862 o->align(FL_ALIGN_BOTTOM);
4863 if (plastic) o->box(FL_PLASTIC_DOWN_BOX);
4864 widget_attributes(csound, o);
4865 MYFLT min, max, range;
4866 if ((int) *p->iminmaxtable > 0) {
4867 min = minmaxtable[j*2];
4868 max = minmaxtable[j*2+1];
4869 }
4870 else {
4871 min = MYFLT(0.0);
4872 max = MYFLT(1.0);
4873 }
4874 int iexp;
4875
4876 p->slider_data[j].min=min;
4877 p->slider_data[j].max=max;
4878 p->slider_data[j].out=&outable[j];
4879
4880 if ((int) *p->iexptable <=0)
4881 // no table, all sliders have the same behaviour
4882 iexp = (int) *p->iexptable;
4883 else
4884 iexp = (int) exptable[j];
4885 switch (iexp) {
4886 case -1: iexp = EXP_; break;
4887 case 0: iexp = LIN_; break;
4888 }
4889
4890 MYFLT val = 0;
4891 p->slider_data[j].exp = iexp;
4892 switch (iexp) {
4893 case LIN_: //linear
4894 o->range(min,max);
4895 o->callback((Fl_Callback*)fl_callbackLinearSliderBank,
4896 (void *) &(p->slider_data[j]));
4897 val = outable[j];
4898 if (val > max) val = max;
4899 else if (val < min) val = min;
4900 break;
4901 case EXP_ : //exponential
4902 if (UNLIKELY(min == 0 || max == 0))
4903 return
4904 csound->InitError(csound,
4905 "%s", Str("FLvslidBnk: zero is illegal "
4906 "in exponential operations"));
4907 range = max - min;
4908 o->range(range,0);
4909 #if defined(sun)
4910 p->slider_data[j].base = ::pow((max / (double)min), 1.0/(double)range);
4911 #else
4912 p->slider_data[j].base = ::pow((max / min), 1.0/(double)range);
4913 #endif
4914 o->callback((Fl_Callback*)fl_callbackExponentialSliderBank,
4915 (void *) &(p->slider_data[j]));
4916 {
4917 val = outable[j];
4918 MYFLT range = max-min;
4919 #if defined(sun)
4920 MYFLT base = ::pow(max / (double)min, 1.0/(double)range);
4921 #else
4922 MYFLT base = ::pow(max / min, 1.0/(double)range);
4923 #endif
4924 val = (log(val/min) / log(base)) ;
4925 }
4926 break;
4927 default:
4928 {
4929 FUNC *ftp;
4930 MYFLT fnum = abs(iexp);
4931 if (LIKELY((ftp = csound->FTnp2Finde(csound, &fnum)) != NULL))
4932 p->slider_data[j].table = ftp->ftable;
4933 else return NOTOK;
4934 p->slider_data[j].tablen = ftp->flen;
4935 o->range(.99999999,0);
4936 if (iexp > 0) //interpolated
4937 o->callback((Fl_Callback*)fl_callbackInterpTableSliderBank,
4938 (void *) &(p->slider_data[j]));
4939 else // non-interpolated
4940 o->callback((Fl_Callback*)fl_callbackTableSliderBank,
4941 (void *) &(p->slider_data[j]));
4942 }
4943 }
4944 o->value(val);
4945 p->slider_data[j].widget_addr= (void*) o;
4946 }
4947 w->resizable(w);
4948 if (*p->iwidth <=0 || *p->iheight <=0) {// default width and height
4949 int a,b;
4950 w->size( a= w->parent()->w(), b= w->parent()->h()-50);
4951 w->position(0, 0);
4952 }
4953 else {
4954 w->size( (int)*p->iwidth, (int)*p->iheight);
4955 w->position((int)*p->ix, (int)*p->iy);
4956 }
4957 w->end();
4958 widgetGlobals->AddrSetValue.push_back(ADDR_SET_VALUE(LIN_, 0, 0, (void *) w,
4959 (void *) p,
4960 widgetGlobals->currentSnapGroup));
4961 widgetGlobals->last_sldbnk = widgetGlobals->AddrSetValue.size()-1; //gab
4962
4963 return OK;
4964 }
4965
fl_vertical_slider_bank(CSOUND * csound,FLSLIDERBANK * p)4966 static int fl_vertical_slider_bank(CSOUND *csound, FLSLIDERBANK *p){
4967 return fl_vertical_slider_bank_(csound,p,0);
4968 }
4969
fl_vertical_slider_bank_S(CSOUND * csound,FLSLIDERBANK * p)4970 static int fl_vertical_slider_bank_S(CSOUND *csound, FLSLIDERBANK *p){
4971 return fl_vertical_slider_bank_(csound,p,1);
4972 }
4973
4974
fl_slider_bank2_(CSOUND * csound,FLSLIDERBANK2 * p,int istring)4975 static int fl_slider_bank2_(CSOUND *csound, FLSLIDERBANK2 *p, int istring)
4976 {
4977 WIDGET_GLOBALS *widgetGlobals =
4978 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
4979 char s[MAXNAME];
4980 bool plastic = false;
4981 if (istring)
4982 strncpy(s, ((STRINGDAT*) p->names)->data, MAXNAME-1);
4983 else if ((long) *p->names <= csound->GetStrsmax(csound) &&
4984 csound->GetStrsets(csound,(long) *p->names)) {
4985 strncpy(s, csound->GetStrsets(csound,(long) *p->names), MAXNAME-1);
4986 }
4987 string tempname(s);
4988 stringstream sbuf;
4989 sbuf << tempname;
4990
4991 int width = (int) *p->iwidth;
4992 if (width <=0) width = 100;
4993
4994 Fl_Group* w = new Fl_Group((int)*p->ix, (int)*p->iy,
4995 width, (int)*p->inumsliders*10);
4996 FUNC *ftp;
4997 MYFLT *configtable, *outable;
4998
4999 MYFLT *zkstart;
5000 int zklast = csound->GetZakBounds(csound, &zkstart);
5001 if (*p->ioutable < 1) {
5002 if (LIKELY(zkstart != NULL &&
5003 zklast>(long)(*p->inumsliders + *p->ioutablestart_ndx)))
5004 outable = zkstart + (long) *p->ioutablestart_ndx;
5005 else {
5006 return csound->InitError(csound,
5007 "%s", Str("invalid ZAK space allocation"));
5008 }
5009 }
5010 else {
5011 if ((ftp = csound->FTnp2Finde(csound, p->ioutable)) != NULL)
5012 outable = ftp->ftable + (long) *p->ioutablestart_ndx;
5013 else
5014 return NOTOK;
5015 }
5016 if((ftp = csound->FTnp2Finde(csound, p->iconfigtable)) != NULL)
5017 configtable = ftp->ftable;
5018 else return NOTOK;
5019
5020 p->elements = (long) *p->inumsliders;
5021 for (int j =0; j< p->elements; j++) {
5022 string stemp;
5023 if (tempname == " ") {
5024 char s[40];
5025 sprintf(s, "%d", j);
5026 stemp = s;
5027 }
5028 else
5029 getline(sbuf, stemp, '@');
5030 char *Name = new char[stemp.size()+2];
5031 strcpy(Name,stemp.c_str());
5032 widgetGlobals->allocatedStrings.push_back(Name);
5033
5034 int x = (int) *p->ix, y = (int) *p->iy + j*10;
5035 Fl_Slider *o;
5036 int slider_type = (int) configtable[j*4+3];
5037 int iexp = (int) configtable[j*4+2];
5038
5039 if (slider_type > 19) {
5040 plastic = true;
5041 slider_type = slider_type - 20;
5042 }
5043 if (UNLIKELY(slider_type > 10 && iexp == EXP_)) {
5044 csound->Warning(csound, "%s",
5045 Str("FLslider exponential, using non-labeled slider"));
5046 slider_type -= 10;
5047 }
5048 if (slider_type <= 10)
5049 o = new Fl_Slider(x, y, width, 10, Name);
5050 else {
5051 o = new Fl_Value_Slider_Input( csound, x, y, width, 10, Name);
5052 slider_type -=10;
5053 ((Fl_Value_Slider_Input*) o)->textboxsize(20);
5054 ((Fl_Value_Slider_Input*) o)->textsize(13);
5055 }
5056 switch((int) slider_type) { //type
5057 case 1: o->type(FL_HOR_FILL_SLIDER); break;
5058 case 3: o->type(FL_HOR_SLIDER); break;
5059 case 5: o->type(FL_HOR_NICE_SLIDER); o->box(FL_FLAT_BOX); break;
5060 case 7: o->type(FL_HOR_NICE_SLIDER); o->box(FL_DOWN_BOX); break;
5061 default: o->type(FL_HOR_NICE_SLIDER); o->box(FL_FLAT_BOX); break;
5062 }
5063 o->align(FL_ALIGN_LEFT);
5064 if (plastic) o->box(FL_PLASTIC_DOWN_BOX);
5065 o->step(0.0);
5066 widget_attributes(csound, o);
5067 MYFLT min, max, range;
5068 min = configtable[j*4];
5069 max = configtable[j*4+1];
5070
5071 p->slider_data[j].min=min;
5072 p->slider_data[j].max=max;
5073 p->slider_data[j].out=&outable[j];
5074
5075 switch (iexp) {
5076 case -1: iexp = EXP_; break;
5077 case 0: iexp = LIN_; break;
5078 }
5079
5080 MYFLT val = 0;
5081 p->slider_data[j].exp = iexp;
5082
5083 switch (iexp) {
5084 case LIN_: //linear
5085 o->range(min,max);
5086 o->callback((Fl_Callback*)fl_callbackLinearSliderBank,
5087 (void *) &(p->slider_data[j]));
5088 val = outable[j];
5089 if (val > max) val = max;
5090 else if (val < min) val = min;
5091 break;
5092 case EXP_ : //exponential
5093 if (UNLIKELY(min == 0 || max == 0))
5094 return
5095 csound->InitError(csound,
5096 "%s", Str("FLsliderBank: zero is illegal "
5097 "in exponential operations"));
5098 range = max - min;
5099 o->range(0,range);
5100 #if defined(sun)
5101 p->slider_data[j].base = ::pow((max / (double)min), 1.0/(double)range);
5102 #else
5103 p->slider_data[j].base = ::pow((max / min), 1.0/(double)range);
5104 #endif
5105 o->callback((Fl_Callback*)fl_callbackExponentialSliderBank,
5106 (void *) &(p->slider_data[j]));
5107 {
5108 val = outable[j];
5109 MYFLT range = max-min;
5110 #if defined(sun)
5111 MYFLT base = ::pow(max / (double)min, 1.0/(double)range);
5112 #else
5113 MYFLT base = ::pow(max / min, 1.0/(double)range);
5114 #endif
5115 val = (log(val/min) / log(base)) ;
5116 }
5117 break;
5118 default:
5119 {
5120 FUNC *ftp;
5121 MYFLT fnum = abs(iexp);
5122 if ((ftp = csound->FTnp2Finde(csound, &fnum)) != NULL)
5123 p->slider_data[j].table = ftp->ftable;
5124 else return NOTOK;
5125 p->slider_data[j].tablen = ftp->flen;
5126 o->range(0,0.99999999);
5127 if (iexp > 0) //interpolated
5128 o->callback((Fl_Callback*)fl_callbackInterpTableSliderBank,
5129 (void *) &(p->slider_data[j]));
5130 else // non-interpolated
5131 o->callback((Fl_Callback*)fl_callbackTableSliderBank,
5132 (void *) &(p->slider_data[j]));
5133 }
5134 }
5135 o->value(val);
5136 p->slider_data[j].widget_addr= (void*) o;
5137 }
5138 w->resizable(w);
5139 if (*p->iwidth <=0 || *p->iheight <=0) {// default width and height
5140 int a,b;
5141 w->size( a= w->parent()->w() -50, b= w->parent()->h());
5142 w->position(50, 0);
5143 }
5144 else {
5145 w->size( (int)*p->iwidth, (int)*p->iheight);
5146 w->position((int)*p->ix, (int)*p->iy);
5147 }
5148 w->end();
5149 widgetGlobals->AddrSetValue.push_back(ADDR_SET_VALUE(LIN_, 0, 0, (void *) w,
5150 (void *) p,
5151 widgetGlobals->currentSnapGroup));
5152 // *p->ihandle = widgetGlobals->AddrSetValue.size()-1;
5153 widgetGlobals->last_sldbnk = widgetGlobals->AddrSetValue.size()-1; //gab
5154
5155 return OK;
5156 }
5157
fl_slider_bank2(CSOUND * csound,FLSLIDERBANK2 * p)5158 static int fl_slider_bank2(CSOUND *csound, FLSLIDERBANK2 *p){
5159 return fl_slider_bank2_(csound, p,0);
5160 }
5161
fl_slider_bank2_S(CSOUND * csound,FLSLIDERBANK2 * p)5162 static int fl_slider_bank2_S(CSOUND *csound, FLSLIDERBANK2 *p){
5163 return fl_slider_bank2_(csound, p,1);
5164 }
5165
fl_vertical_slider_bank2_(CSOUND * csound,FLSLIDERBANK2 * p,int istring)5166 static int fl_vertical_slider_bank2_(CSOUND *csound,
5167 FLSLIDERBANK2 *p, int istring)
5168 {
5169 WIDGET_GLOBALS *widgetGlobals =
5170 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
5171 char s[MAXNAME];
5172 bool plastic = false;
5173 if (istring)
5174 strncpy(s, ((STRINGDAT*) p->names)->data, MAXNAME-1);
5175 else if ((long) *p->names <= csound->GetStrsmax(csound) &&
5176 csound->GetStrsets(csound,(long) *p->names)) {
5177 strncpy(s, csound->GetStrsets(csound,(long) *p->names), MAXNAME-1);
5178 }
5179 string tempname(s);
5180 stringstream sbuf;
5181 sbuf << tempname;
5182
5183 int height = (int) *p->iheight;
5184 if (height <=0) height = 100;
5185
5186 Fl_Group* w = new Fl_Group((int)*p->ix, (int)*p->iy,
5187 (int) *p->inumsliders*10, height);
5188 FUNC *ftp;
5189 MYFLT *configtable, *outable;
5190
5191 MYFLT *zkstart;
5192 int zklast = csound->GetZakBounds(csound, &zkstart);
5193 if (*p->ioutable < 1) {
5194 if (LIKELY(zkstart != NULL &&
5195 zklast>(long)(*p->inumsliders + *p->ioutablestart_ndx)))
5196 outable = zkstart + (long) *p->ioutablestart_ndx;
5197 else {
5198 return csound->InitError(csound,
5199 "%s", Str("invalid ZAK space allocation"));
5200 }
5201 }
5202 else {
5203 if ((ftp = csound->FTnp2Finde(csound, p->ioutable)) != NULL)
5204 outable = ftp->ftable + (long) *p->ioutablestart_ndx;
5205 else
5206 return NOTOK;
5207 }
5208 if((ftp = csound->FTnp2Finde(csound, p->iconfigtable)) != NULL)
5209 configtable = ftp->ftable;
5210 else
5211 return NOTOK;
5212
5213 p->elements = (long) *p->inumsliders;
5214 for (int j =0; j< p->elements; j++) {
5215 string stemp;
5216 if (tempname == " ") {
5217 char s[40];
5218 sprintf(s, "%d", j);
5219 stemp = s;
5220 }
5221 else
5222 getline(sbuf, stemp, '@');
5223 char *Name = new char[stemp.size()+2];
5224 strcpy(Name,stemp.c_str());
5225 widgetGlobals->allocatedStrings.push_back(Name);
5226
5227 int x = (int) *p->ix+j*10, y = (int) *p->iy /*+ j*10*/;
5228 Fl_Slider *o;
5229 int slider_type= (int) configtable[j*4+3];
5230 int iexp = (int) configtable[j*4+2];
5231
5232 if (slider_type > 19) {
5233 plastic = true;
5234 slider_type -= 20;
5235 }
5236 if (UNLIKELY(slider_type > 10 && iexp == EXP_)) {
5237 csound->Warning(csound,
5238 "%s", Str("FLslidBnk2: FLslider exponential, "
5239 "using non-labeled slider"));
5240 slider_type -= 10;
5241 }
5242 if (slider_type <= 10)
5243 o = new Fl_Slider(x, y, 10, height, Name);
5244 else {
5245 o = new Fl_Value_Slider_Input( csound, x, y, 10, height, Name);
5246 slider_type -=10;
5247 ((Fl_Value_Slider_Input*) o)->textboxsize(50);
5248 ((Fl_Value_Slider_Input*) o)->textsize(13);
5249 }
5250 switch((int) slider_type) { //type
5251 case 1: case 2: o->type(FL_VERT_FILL_SLIDER); break;
5252 case 3: case 4: o->type(FL_VERT_SLIDER); break;
5253 case 5: case 6: o->type(FL_VERT_NICE_SLIDER); o->box(FL_FLAT_BOX); break;
5254 case 7: case 8: o->type(FL_VERT_NICE_SLIDER); o->box(FL_DOWN_BOX); break;
5255 default: o->type(FL_VERT_NICE_SLIDER); o->box(FL_FLAT_BOX); break;
5256 }
5257 o->align(FL_ALIGN_BOTTOM);
5258 if (plastic) o->box(FL_PLASTIC_DOWN_BOX);
5259 widget_attributes(csound, o);
5260 MYFLT min, max, range;
5261 min = configtable[j*4];
5262 max = configtable[j*4+1];
5263
5264 p->slider_data[j].min=min;
5265 p->slider_data[j].max=max;
5266 p->slider_data[j].out=&outable[j];
5267
5268 switch (iexp) {
5269 case -1: iexp = EXP_; break;
5270 case 0: iexp = LIN_; break;
5271 }
5272
5273 MYFLT val = 0;
5274 p->slider_data[j].exp = iexp;
5275
5276 switch (iexp) {
5277 case LIN_: //linear
5278 o->range(min,max);
5279 o->callback((Fl_Callback*)fl_callbackLinearSliderBank,
5280 (void *) &(p->slider_data[j]));
5281 val = outable[j];
5282 if (val > max) val = max;
5283 else if (val < min) val = min;
5284 break;
5285 case EXP_ : //exponential
5286 if (UNLIKELY(min == 0 || max == 0))
5287 return
5288 csound->InitError(csound,
5289 "%s", Str("FLsliderBank: zero is illegal "
5290 "in exponential operations"));
5291 range = max - min;
5292 o->range(range,0);
5293 #if defined(sun)
5294 p->slider_data[j].base = ::pow((max / (double)min), 1.0/(double)range);
5295 #else
5296 p->slider_data[j].base = ::pow((max / min), 1.0/(double)range);
5297 #endif
5298 o->callback((Fl_Callback*)fl_callbackExponentialSliderBank,
5299 (void *) &(p->slider_data[j]));
5300 {
5301 val = outable[j];
5302 MYFLT range = max-min;
5303 #if defined(sun)
5304 MYFLT base = ::pow(max / (double)min, 1.0/(double)range);
5305 #else
5306 MYFLT base = ::pow(max / min, 1.0/(double)range);
5307 #endif
5308 val = (log(val/min) / log(base)) ;
5309 }
5310 break;
5311 default:
5312 {
5313 FUNC *ftp;
5314 MYFLT fnum = abs(iexp);
5315 if ((ftp = csound->FTnp2Finde(csound, &fnum)) != NULL)
5316 p->slider_data[j].table = ftp->ftable;
5317 else return NOTOK;
5318 p->slider_data[j].tablen = ftp->flen;
5319 o->range(.99999999,0);
5320 if (iexp > 0) //interpolated
5321 o->callback((Fl_Callback*)fl_callbackInterpTableSliderBank,
5322 (void *) &(p->slider_data[j]));
5323 else // non-interpolated
5324 o->callback((Fl_Callback*)fl_callbackTableSliderBank,
5325 (void *) &(p->slider_data[j]));
5326 }
5327 }
5328 o->value(val);
5329 p->slider_data[j].widget_addr= (void*) o;
5330
5331 }
5332 w->resizable(w);
5333 if (*p->iwidth <=0 || *p->iheight <=0) {// default width and height
5334 int a,b;
5335 w->size( a= w->parent()->w(), b= w->parent()->h()-50);
5336 w->position(0, 0);
5337 }
5338 else {
5339 w->size( (int)*p->iwidth, (int)*p->iheight);
5340 w->position((int)*p->ix, (int)*p->iy);
5341 }
5342 w->end();
5343 widgetGlobals->AddrSetValue.push_back(ADDR_SET_VALUE(LIN_, 0, 0,
5344 (void *) w, (void *) p,
5345 widgetGlobals->currentSnapGroup));
5346 // *p->ihandle = widgetGlobals->AddrSetValue.size()-1;
5347 widgetGlobals->last_sldbnk = widgetGlobals->AddrSetValue.size()-1; //gab
5348
5349 return OK;
5350 }
5351
fl_vertical_slider_bank2(CSOUND * csound,FLSLIDERBANK2 * p)5352 static int fl_vertical_slider_bank2(CSOUND *csound, FLSLIDERBANK2 *p){
5353 return fl_vertical_slider_bank2_(csound,p,0);
5354 }
5355
fl_vertical_slider_bank2_S(CSOUND * csound,FLSLIDERBANK2 * p)5356 static int fl_vertical_slider_bank2_S(CSOUND *csound, FLSLIDERBANK2 *p){
5357 return fl_vertical_slider_bank2_(csound,p,1);
5358 }
5359
5360
5361
fl_slider_bank_getHandle(CSOUND * csound,FLSLDBNK_GETHANDLE * p)5362 static int fl_slider_bank_getHandle(CSOUND *csound, FLSLDBNK_GETHANDLE *p)
5363 //valid only if called immediately after FLslidBnk
5364 {
5365 WIDGET_GLOBALS *widgetGlobals =
5366 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
5367 *p->ihandle = widgetGlobals->last_sldbnk;
5368 return OK;
5369 }
5370
fl_slider_bank_setVal(CSOUND * csound,FLSLDBNK_SET * p)5371 static int fl_slider_bank_setVal(CSOUND *csound, FLSLDBNK_SET *p)
5372 {
5373 FUNC* ftp;
5374 MYFLT *table, *outable;
5375 int numslid = (int)*p->numSlid;
5376 int startInd = (int)*p->startInd;
5377 int startSlid = (int)*p->startSlid;
5378 WIDGET_GLOBALS *widgetGlobals =
5379 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
5380
5381 if (LIKELY((ftp = csound->FTnp2Finde(csound, p->ifn)) != NULL))
5382 table = ftp->ftable;
5383 else {
5384 return csound->InitError(csound,
5385 "%s", Str("FLsldBnkSet: invalid table number"));
5386 }
5387 // *startInd, *startSlid, *numSlid
5388 if (UNLIKELY( (int) ftp->flen < startInd + numslid)) {
5389 return csound->InitError(csound,
5390 "%s", Str("FLslidBnkSet: table too short!"));
5391 }
5392 FLSLIDERBANK *q =
5393 (FLSLIDERBANK *)widgetGlobals->AddrSetValue[ (int) *p->ihandle].opcode;
5394
5395 if (LIKELY((ftp = csound->FTnp2Finde(csound, q->ioutable)) != NULL))
5396 outable = ftp->ftable;
5397 else {
5398 return csound->InitError(csound,
5399 "%s", Str("FLsldBnkSet: invalid outable number"));
5400 }
5401 if (numslid == 0) numslid = (int)(q->elements - *p->startSlid);
5402 if (UNLIKELY( q->elements > startSlid + numslid)) {
5403 return csound->InitError(csound, "%s",
5404 Str("FLslidBnkSet: too many sliders to reset!"));
5405 }
5406 for (int j = startSlid, k = startInd; j< numslid + startSlid; j++, k++) {
5407
5408 MYFLT val = 0;
5409 // MYFLT base = q->slider_data[j].base;
5410 int iexp = q->slider_data[j].exp;
5411 MYFLT min = q->slider_data[j].min;
5412 MYFLT max = q->slider_data[j].max;
5413 switch (iexp) {
5414 case LIN_: //linear
5415 val = table[k];
5416 if (val > max) val = max;
5417 else if (val < min) val = min;
5418 break;
5419 case EXP_ : //exponential
5420 {
5421 MYFLT range = max - min;
5422 MYFLT base2 = pow(max / min, 1/range);
5423 val = (log(table[k]/min) / log(base2)) ;
5424 }
5425 break;
5426 default:
5427 return csound->InitError(csound,
5428 "%s", Str("FLslidBnkSet: "
5429 "function mapping not available"));
5430 }
5431
5432 FLlock();
5433 ((Fl_Slider*) (q->slider_data[j].widget_addr))->value(val);
5434 FLunlock();
5435 outable[j] = table[k];
5436 }
5437 return OK;
5438 }
5439
fl_slider_bank2_setVal(CSOUND * csound,FLSLDBNK_SET * p)5440 static int fl_slider_bank2_setVal(CSOUND *csound, FLSLDBNK_SET *p)
5441 {
5442 FUNC* ftp;
5443 MYFLT *table, *outable;
5444 int numslid = (int)*p->numSlid;
5445 int startInd = (int)*p->startInd;
5446 int startSlid = (int)*p->startSlid;
5447 WIDGET_GLOBALS *widgetGlobals =
5448 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
5449
5450 if (LIKELY((ftp = csound->FTnp2Finde(csound, p->ifn)) != NULL))
5451 table = ftp->ftable;
5452 else {
5453 return csound->InitError(csound,
5454 "%s", Str("FLsldBnkSet: invalid table number"));
5455 }
5456 // *startInd, *startSlid, *numSlid
5457 if (UNLIKELY((int) ftp->flen < startInd + numslid)) {
5458 return csound->InitError(csound,
5459 "%s", Str("FLslidBnkSet: table too short!"));
5460 }
5461 FLSLIDERBANK2 *q =
5462 (FLSLIDERBANK2 *)widgetGlobals->AddrSetValue[ (int) *p->ihandle].opcode;
5463
5464 if (LIKELY((ftp = csound->FTnp2Finde(csound, q->ioutable)) != NULL))
5465 outable = ftp->ftable;
5466 else {
5467 return csound->InitError(csound,
5468 "%s", Str("FLsldBnkSet: invalid outable number"));
5469 }
5470
5471 if (numslid == 0) numslid = (int)(q->elements - *p->startSlid);
5472 if (UNLIKELY( q->elements > startSlid + numslid)) {
5473 return csound->InitError(csound, "%s",
5474 Str("FLslidBnkSet: too many sliders to reset!"));
5475 }
5476
5477 for (int j = startSlid, k = startInd; j< numslid + startSlid; j++, k++) {
5478
5479 MYFLT val = 0;
5480 // MYFLT base = q->slider_data[j].base;
5481 int iexp = q->slider_data[j].exp;
5482 MYFLT min = q->slider_data[j].min;
5483 MYFLT max = q->slider_data[j].max;
5484 switch (iexp) {
5485 case LIN_: //linear
5486 val = table[k];
5487 if (val > max) val = max;
5488 else if (val < min) val = min;
5489 break;
5490 case EXP_ : //exponential
5491 {
5492 MYFLT range = max - min;
5493 MYFLT base2 = pow(max / min, 1/range);
5494 val = (log(table[k]/min) / log(base2));
5495 }
5496 break;
5497 default: // table
5498 {
5499 // val = table[k];
5500 if (UNLIKELY(val < 0 || val > 1)) { // input range must be 0 to 1
5501 csound->PerfError(csound, &p->h,
5502 "%s", Str("FLslidBnk2Setk: value out of range: "
5503 "function mapping requires a 0 to 1 "
5504 "range for input"));
5505 }
5506 }
5507 //{
5508 // initerror("FLslidBnkSet: function mapping not available");
5509 // return;
5510 //}
5511 }
5512
5513 FLlock();
5514 ((Fl_Slider*) (q->slider_data[j].widget_addr))->value(val);
5515 FLunlock();
5516 outable[j] = table[k];
5517 }
5518 return OK;
5519 }
fl_slider_bank2_setVal_k_set(CSOUND * csound,FLSLDBNK2_SETK * p)5520 static int fl_slider_bank2_setVal_k_set(CSOUND *csound, FLSLDBNK2_SETK *p)
5521 {
5522 FUNC* ftp;
5523
5524 p->numslid = (int)*p->numSlid;
5525 p->startind = (int)*p->startInd;
5526 p->startslid = (int)*p->startSlid;
5527 WIDGET_GLOBALS *widgetGlobals =
5528 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
5529
5530 if (LIKELY((ftp = csound->FTnp2Finde(csound, p->ifn)) != NULL))
5531 p->table = ftp->ftable;
5532 else {
5533 return csound->InitError(csound,
5534 "%s", Str("FLsldBnkSetk: invalid table number"));
5535 }
5536 // *startInd, *startSlid, *numSlid
5537 if (UNLIKELY( (int) ftp->flen < p->startind + p->numslid)) {
5538 return csound->InitError(csound,
5539 "%s", Str("FLslidBnkSetk: table too short!"));
5540 }
5541 p->q = (FLSLIDERBANK2 *)
5542 widgetGlobals->AddrSetValue[ (int) *p->ihandle].opcode;
5543
5544 if (LIKELY((ftp = csound->FTnp2Finde(csound, p->q->ioutable)) != NULL))
5545 p->outable = ftp->ftable;
5546 else {
5547 return csound->InitError(csound, "%s",
5548 Str("FLsldBnkSetk: invalid outable number"));
5549 }
5550
5551 if (p->numslid == 0) p->numslid = p->q->elements - p->startslid;
5552 if (UNLIKELY( p->q->elements < p->startslid + p->numslid)) {
5553 return csound->InitError(csound, "%s",
5554 Str("FLslidBnkSetk: too many sliders to reset!"));
5555 }
5556 return OK;
5557 }
5558
5559
5560
fl_slider_bank2_setVal_k(CSOUND * csound,FLSLDBNK2_SETK * p)5561 static int fl_slider_bank2_setVal_k(CSOUND *csound, FLSLDBNK2_SETK *p)
5562 {
5563 //WIDGET_GLOBALS *widgetGlobals =
5564 // (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
5565
5566 if(*p->kflag) {
5567 FLSLIDERBANK2 *q = p->q;
5568 MYFLT *table=p->table;
5569 for (int j = p->startslid, k = p->startind;
5570 j< p->numslid + p->startslid;
5571 j++, k++) {
5572
5573 MYFLT val = 0;
5574 // MYFLT base= q->slider_data[j].base;
5575 int iexp = q->slider_data[j].exp;
5576 MYFLT min = q->slider_data[j].min;
5577 MYFLT max = q->slider_data[j].max;
5578 switch (iexp) {
5579 case LIN_: //linear
5580 val = table[k];
5581 if (val > max) val = max;
5582 else if (val < min) val = min;
5583 break;
5584 case EXP_ : //exponential
5585 {
5586 MYFLT range = max - min;
5587 MYFLT base2 = pow(max / min, 1/range);
5588 val = (log(table[k]/min) / log(base2));
5589 }
5590 break;
5591 default: // table
5592 {
5593 val = table[k];
5594 if (UNLIKELY(val < 0 || val > 1)) { // input range must be 0 to 1
5595 csound->PerfError(csound, &p->h,
5596 "%s", Str("FLslidBnk2Setk: value out of range:"
5597 " function mapping requires a 0 to 1"
5598 " range for input"));
5599 }
5600 }
5601 }
5602 if (val != p->oldValues[j]) {
5603 FLlock();
5604 ((Fl_Slider*) (q->slider_data[j].widget_addr))->value(val);
5605 ((Fl_Slider*) (q->slider_data[j].widget_addr))->do_callback();
5606 FLunlock();
5607 p->oldValues[j] = val;
5608 }
5609 }
5610 }
5611 return OK;
5612 }
5613
fl_slider_bank_setVal_k_set(CSOUND * csound,FLSLDBNK_SETK * p)5614 static int fl_slider_bank_setVal_k_set(CSOUND *csound, FLSLDBNK_SETK *p)
5615 {
5616 FUNC* ftp;
5617 WIDGET_GLOBALS *widgetGlobals =
5618 (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS");
5619 p->numslid = (int)*p->numSlid;
5620 p->startind = (int)*p->startInd;
5621 p->startslid = (int)*p->startSlid;
5622
5623 if (LIKELY((ftp = csound->FTnp2Finde(csound, p->ifn)) != NULL))
5624 p->table = ftp->ftable;
5625 else {
5626 return csound->InitError(csound,
5627 "%s", Str("FLslidBnkSetk: invalid table number"));
5628 }
5629 // *startInd, *startSlid, *numSlid
5630 if (UNLIKELY( (int) ftp->flen < p->startind + p->numslid)) {
5631 return csound->InitError(csound,
5632 "%s", Str("FLslidBnkSetk: table too short!"));
5633 }
5634 p->q =
5635 (FLSLIDERBANK *) widgetGlobals->AddrSetValue[ (int) *p->ihandle].opcode;
5636
5637 if (LIKELY((ftp = csound->FTnp2Finde(csound, p->q->ioutable)) != NULL))
5638 p->outable = ftp->ftable;
5639 else {
5640 return csound->InitError(csound, "%s",
5641 Str("FLslidBnkSetk: invalid outable number"));
5642 }
5643
5644 if (p->numslid == 0) p->numslid = p->q->elements - p->startslid;
5645 if (UNLIKELY( p->q->elements < p->startslid + p->numslid)) {
5646 return csound->InitError(csound, "%s",
5647 Str("FLslidBnkSetk: too many sliders to reset!"));
5648 }
5649 return OK;
5650 }
5651
5652
5653
fl_slider_bank_setVal_k(CSOUND * csound,FLSLDBNK_SETK * p)5654 static int fl_slider_bank_setVal_k(CSOUND *csound, FLSLDBNK_SETK *p)
5655 {
5656 if (*p->kflag) {
5657 FLSLIDERBANK *q = p->q;
5658 MYFLT *table=p->table;
5659 for (int j = p->startslid, k = p->startind;
5660 j< p->numslid + p->startslid;
5661 j++, k++) {
5662
5663 MYFLT val = 0;
5664 // MYFLT base= q->slider_data[j].base; //Not used
5665 int iexp = q->slider_data[j].exp;
5666 MYFLT min = q->slider_data[j].min;
5667 MYFLT max = q->slider_data[j].max;
5668 switch (iexp) {
5669 case LIN_: //linear
5670 val = table[k];
5671 if (val > max) val = max;
5672 else if (val < min) val = min;
5673 break;
5674 case EXP_ : //exponential
5675 {
5676 MYFLT range = max - min;
5677 MYFLT base2 = pow(max / min, 1/range);
5678 val = (log(table[k]/min) / log(base2));
5679 }
5680 break;
5681 default: // table
5682 {
5683 val = table[k];
5684 if (UNLIKELY(val < 0 || val > 1)) { // input range must be 0 to 1
5685 csound->PerfError(csound, &p->h,
5686 "%s", Str("FLslidBnk2Setk: value out of range: "
5687 "function mapping requires a 0 to 1 range "
5688 "for input"));
5689 }
5690 }
5691 }
5692 if (val != p->oldValues[j]) {
5693 FLlock();
5694 ((Fl_Slider*) (q->slider_data[j].widget_addr))->value(val);
5695 ((Fl_Slider*) (q->slider_data[j].widget_addr))->do_callback();
5696 FLunlock();
5697 p->oldValues[j] = val;
5698 }
5699 }
5700 }
5701 return OK;
5702 }
5703
FLxyin_set(CSOUND * csound,FLXYIN * p)5704 static int FLxyin_set(CSOUND *csound, FLXYIN *p)
5705 {
5706
5707 *p->koutx = *p->ioutx; //initial values
5708 *p->kouty = *p->iouty;
5709 p->rangex = *p->ioutx_max - *p->ioutx_min;
5710 p->rangey = *p->iouty_max - *p->iouty_min;
5711
5712 switch((int) *p->iexpx) {
5713 case 0: // LIN
5714 p->expx = LIN_; break;
5715 case -1: // EXP
5716 p->expx = EXP_;
5717 if (UNLIKELY(*p->ioutx_min == 0 || *p->ioutx_max==0))
5718 return csound->InitError(csound, "%s",
5719 Str("FLxyin: none of X limits can be zero in"
5720 " exponential mode!"));
5721 p->basex = pow((double) (*p->ioutx_max / *p->ioutx_min),
5722 (double) (1/p->rangex));
5723
5724 break;
5725 default: // TABLE
5726 p->expx = (int) *p->iexpx;
5727 {
5728 FUNC *ftp;
5729 MYFLT fnum = abs(p->expx);
5730 if ((ftp = csound->FTnp2Finde(csound, &fnum)) != NULL) {
5731 p->tablex = ftp->ftable;
5732 p->tablenx = ftp->flen;
5733 }
5734 else return NOTOK;
5735 }
5736
5737 }
5738
5739 switch((int) *p->iexpy) {
5740 case 0: // LIN
5741 p->expy = LIN_; break;
5742 case -1: // EXP
5743 p->expy = EXP_;
5744 if (UNLIKELY(*p->iouty_min == 0 || *p->iouty_max==0))
5745 return csound->InitError(csound,
5746 "%s", Str("FLxyin: none of Y limits can "
5747 "be zero in exponential mode!"));
5748 p->basey = pow((double) (*p->iouty_max / *p->iouty_min),
5749 (double) (1/p->rangey));
5750 break;
5751 default: // TABLE
5752 p->expy = (int) *p->iexpy;
5753 {
5754 FUNC *ftp;
5755 MYFLT fnum = abs(p->expy);
5756 if ((ftp = csound->FTnp2Finde(csound, &fnum)) != NULL) {
5757 p->tabley = ftp->ftable;
5758 p->tableny = ftp->flen;
5759 }
5760 else return NOTOK;
5761 }
5762
5763 }
5764 return OK;
5765 }
5766
FLxyin(CSOUND * csound,FLXYIN * p)5767 static int FLxyin(CSOUND *csound, FLXYIN *p)
5768 {
5769 IGN(csound);
5770 int windx_min = (int)*p->iwindx_min, windx_max = (int)*p->iwindx_max;
5771 int windy_min = (int)*p->iwindy_min, windy_max = (int)*p->iwindy_max;
5772 MYFLT outx_min = *p->ioutx_min, outy_min = *p->iouty_min;
5773
5774 MYFLT x=Fl::event_x();
5775 MYFLT y=Fl::event_y();
5776
5777 *p->kinside = 1;
5778
5779 if (x< windx_min) { x = windx_min; *p->kinside = 0; }
5780 else if (x > windx_max) { x = windx_max; *p->kinside = 0; }
5781
5782 if (y< windy_min) { y = windy_min; *p->kinside = 0; }
5783 else if (y > windy_max) { y = windy_max; *p->kinside = 0; }
5784
5785 MYFLT xx = x - windx_min;
5786 xx /= windx_max - windx_min;
5787
5788 MYFLT yy = windy_max - y;
5789 yy /= windy_max - windy_min;
5790
5791 switch (p->expx) {
5792 case LIN_:
5793 *p->koutx = outx_min + xx * p->rangex;
5794 break;
5795 case EXP_:
5796 *p->koutx = outx_min * pow (p->basex, xx * p->rangex);
5797 break;
5798 default: // TABLE
5799 if (p->expx > 0) { //interpolated
5800 MYFLT ndx = xx * (p->tablenx-1);
5801 int index = (int) ndx;
5802 MYFLT v1 = p->tablex[index];
5803 *p->koutx = outx_min + ( v1 + (p->tablex[index+1] - v1) *
5804 (ndx - index)) * p->rangex;
5805 }
5806 else // non-interpolated
5807 *p->koutx = outx_min + p->tablex[(int) (xx*p->tablenx)] * p->rangex;
5808 }
5809
5810 switch (p->expy) {
5811 case LIN_:
5812 *p->kouty = outy_min + yy * p->rangey;
5813 break;
5814 case EXP_:
5815 *p->kouty = outy_min * pow (p->basey, yy * p->rangey);
5816 break;
5817 default: // TABLE
5818 if (p->expy > 0) { //interpolated
5819 MYFLT ndx = yy * (p->tableny-1);
5820 int index = (int) ndx;
5821 MYFLT v1 = p->tabley[index];
5822 *p->kouty = outy_min + ( v1 + ( p->tabley[index+1] - v1) *
5823 (ndx - index)) * p->rangey;
5824 }
5825 else // non-interpolated
5826 *p->kouty = outy_min + p->tabley[(int) (yy*p->tableny)] * p->rangey;
5827 }
5828 return OK;
5829 }
5830
5831 // //FIXME: Should this be defined to 0dbfs?
5832 // #define MAXAMPVU 32767
5833 //
5834 // //TODO: Implement FLTK meter
5835 // void VuMeter(CSOUND *csound);
5836 //
5837 // static int VuMeter_set(CSOUND *csound, FLTKMETER *p) {
5838 // //isVumeterActive = 1;
5839 // csoundSetVuMeterCallback(csound, VuMeter);
5840 // //OPARMS *O = csound->oparms;
5841 // int nchnls = csound->nchnls;
5842 // Fl_Window *o;
5843 // int iw;
5844 // iw = (csound->oparms->sfread) ? 30 : 15;
5845 // o = new Fl_Window(0,0, 410,nchnls * iw+35, "Meter");
5846 // Fl_Box *box = new Fl_Box(10,3,260,10,"Outputs");
5847 // box->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
5848 // //else o = new Fl_Panel(x,y,width,height, panelName);
5849 // //o->box((Fl_Boxtype) borderType);
5850 // o->resizable(o);
5851 // o->callback(flpanel_cb);
5852 // //o->set_modal();
5853 // widget_attributes(csound,o);
5854 //
5855 // PANELS panel(o, (widgetGlobals->stack_count>0) ? 1 : 0);
5856 // widgetGlobals->fl_windows.push_back(panel);
5857 // int j;
5858 //
5859 // for ( j = 0; j < nchnls; j++) {
5860 // string stemp;
5861 // char s[10];
5862 // stemp = itoa(j+1,s,10);
5863 // char *Name = new char[stemp.size()+2];
5864 // strcpy(Name,stemp.c_str());
5865 // widgetGlobals->allocatedStrings.push_back(Name);
5866 //
5867 // Fl_Slider *w = new Fl_Slider(20, 18+15*j, 380, 10, Name);
5868 // w->align(FL_ALIGN_LEFT);
5869 // p->widg_address[j] = (unsigned long) w;
5870 // w->type(FL_HOR_FILL_SLIDER);
5871 // w->color(FL_BACKGROUND_COLOR,FL_GREEN);
5872 // w->box(FL_PLASTIC_DOWN_BOX);
5873 // w->range(0,MAXAMPVU);
5874 // }
5875 //
5876 // if (csound->oparms->sfread) {
5877 // box = new Fl_Box(10,18 + 15 * nchnls ,260,10,"Inputs");
5878 // box->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
5879 // for ( ; j < nchnls*2; j++) {
5880 // string stemp;
5881 // char s[10];
5882 // stemp = itoa(j+1- nchnls,s,10);
5883 // char *Name = new char[stemp.size()+2];
5884 // strcpy(Name,stemp.c_str());
5885 // widgetGlobals->allocatedStrings.push_back(Name);
5886 // Fl_Slider *w = new Fl_Slider(20, 30+15*j , 380, 10, Name);
5887 // w->align(FL_ALIGN_LEFT);
5888 // p->widg_address[j] = (unsigned long) w;
5889 // w->type(FL_HOR_FILL_SLIDER);
5890 // w->color(FL_BACKGROUND_COLOR,FL_YELLOW);
5891 // w->box(FL_PLASTIC_DOWN_BOX);
5892 // w->range(0,MAXAMPVU);
5893 // }
5894 // }
5895 // o->end();
5896 // widgetGlobals->p_vumeter = p;
5897 // p->dummycycles = csound->ekr / 16 ;
5898 // p->dummycyc = 0;
5899 // return OK;
5900 // }
5901 //
5902 // //extern "C" MYFLT *spout,*spin; //GAB
5903 //
5904 // void VuMeter(CSOUND *csound){
5905 // FLTKMETER *p = widgetGlobals->p_vumeter;
5906 // Fl_Slider *w;
5907 // int nchnls = csound->nchnls;
5908 // int n = (csound->oparms->sfread) ? nchnls * 2 : nchnls;
5909 // MYFLT temp[MAXCHNLS];
5910 // int smps = csound->GetKsmps(csound);
5911 // MYFLT max[MAXCHNLS];
5912 // MYFLT *spo = csound->spout;
5913 // MYFLT *spi = csound->spin;
5914 //
5915 // static int overfl[MAXCHNLS];
5916 // int i;
5917 // for (i=0;i<n;i++) {
5918 // max[i]=0;
5919 // temp[i] = 0;
5920 // }
5921 // do {
5922 // for ( i=0; i<nchnls; i++) {
5923 // if ((temp[i]=(MYFLT) fabs(*spo++)) > max[i] )
5924 // max[i]= temp[i];
5925 // }
5926 // if (csound->oparms->sfread) {
5927 // for ( ; i<n; i++) {
5928 //
5929 // if ((temp[i]=(MYFLT) fabs(*spi++)) > max[i] )
5930 // max[i]= temp[i];
5931 // }
5932 // }
5933 // //if ((temp= (MYFLT) fabs(*a++)) > max) max = temp;
5934 // } while (--smps);
5935 //
5936 // for (i=0; i<n; i++) {
5937 // if (max[i] > p->max[i])
5938 // p->max[i] = (overfl[i] = max[i]>MAXAMPVU) ? MAXAMPVU : max[i];
5939 // }
5940 // p->dummycyc++;
5941 // if (!(p->dummycyc % p->dummycycles)) {
5942 // for (int j=0; j<n; j++) {
5943 // w = (Fl_Slider *) p->widg_address[j];
5944 //
5945 // FLlock();
5946 // if (overfl[j]) {
5947 // w->selection_color(FL_RED);
5948 // overfl[j] = 0;
5949 // }
5950 // else {
5951 // if (j < nchnls) w->selection_color(FL_GREEN);
5952 // else w->selection_color(FL_YELLOW);
5953 // }
5954 // w->value( p->max[j]);
5955 // w->do_callback(w);
5956 // FLunlock();
5957 // }
5958 // #ifdef WIN32
5959 // // PostMessage(callback_target,0,0,0);
5960 // #endif
5961 // for (i=0; i<n; i++)
5962 // p->max[i] = 0;
5963 // }
5964 // }
5965 //
5966
5967 } // extern "C"
5968
5969 #define S(x) sizeof(x)
5970
5971 const OENTRY widgetOpcodes_[] = {
5972 { (char*)"FLslider", S(FLSLIDER), 0, 1, (char*)"ki", (char*)"Siijjjjjjj",
5973 (SUBR) fl_slider, (SUBR) NULL, (SUBR) NULL },
5974 { (char*)"FLslidBnk", S(FLSLIDERBANK), 0, 1, (char*)"", (char*)"Siooooooooo",
5975 (SUBR) fl_slider_bank_S, (SUBR) NULL, (SUBR) NULL },
5976 { (char*)"FLslidBnk.i", S(FLSLIDERBANK), 0, 1, (char*)"", (char*)"iiooooooooo",
5977 (SUBR) fl_slider_bank, (SUBR) NULL, (SUBR) NULL },
5978 { (char*)"FLknob", S(FLKNOB), 0, 1, (char*)"ki", (char*)"Siijjjjjjo",
5979 (SUBR) fl_knob, (SUBR) NULL, (SUBR) NULL },
5980 { (char*)"FLroller", S(FLROLLER), 0, 1, (char*)"ki", (char*)"Siijjjjjjjj",
5981 (SUBR) fl_roller, (SUBR) NULL, (SUBR) NULL },
5982 { (char*)"FLtext", S(FLTEXT), 0, 1, (char*)"ki", (char*)"Siijjjjjj",
5983 (SUBR) fl_text, (SUBR) NULL, (SUBR) NULL },
5984 { (char*)"FLjoy", S(FLJOYSTICK), 0, 1, (char*)"kkii", (char*)"Siiiijjjjjjjj",
5985 (SUBR) fl_joystick, (SUBR) NULL, (SUBR) NULL },
5986 { (char*)"FLcount", S(FLCOUNTER), 0, 1, (char*)"ki", (char*)"Siiiiiiiiiz",
5987 (SUBR) fl_counter, (SUBR) NULL, (SUBR) NULL },
5988 { (char*)"FLbutton", S(FLBUTTON), 0, 1, (char*)"ki", (char*)"Siiiiiiiz",
5989 (SUBR) fl_button, (SUBR) NULL, (SUBR) NULL },
5990 { (char*)"FLbutBank", S(FLBUTTONBANK), 0, 1, (char*)"ki", (char*)"iiiiiiiz",
5991 (SUBR) fl_button_bank, (SUBR) NULL, (SUBR) NULL },
5992 // { (char*)"FLkeyb", S(FLKEYB), 0, 1, (char*)"k", (char*)"z",
5993 // (SUBR) FLkeyb, (SUBR) NULL, (SUBR) NULL },
5994 { (char*)"FLcolor", S(FLWIDGCOL), 0, 1, (char*)"", (char*)"jjjjjj",
5995 (SUBR) fl_widget_color, (SUBR) NULL, (SUBR) NULL },
5996 { (char*)"FLcolor2", S(FLWIDGCOL2), 0, 1, (char*)"", (char*)"jjj",
5997 (SUBR) fl_widget_color2, (SUBR) NULL, (SUBR) NULL },
5998 { (char*)"FLlabel", S(FLWIDGLABEL), 0, 1, (char*)"", (char*)"ojojjj",
5999 (SUBR) fl_widget_label, (SUBR) NULL, (SUBR) NULL },
6000 { (char*)"FLsetVal_i", S(FL_SET_WIDGET_VALUE_I), 0, 1, (char*)"", (char*)"ii",
6001 (SUBR) fl_setWidgetValuei, (SUBR) NULL, (SUBR) NULL },
6002 { (char*)"FLsetVali", S(FL_SET_WIDGET_VALUE_I), 0, 1, (char*)"", (char*)"ii",
6003 (SUBR) fl_setWidgetValuei, (SUBR) NULL, (SUBR) NULL },
6004 { (char*)"FLsetVal", S(FL_SET_WIDGET_VALUE),0, 3, (char*)"", (char*)"kki",
6005 (SUBR) fl_setWidgetValue_set, (SUBR) fl_setWidgetValue, (SUBR) NULL },
6006 { (char*)"FLsetColor", S(FL_SET_COLOR), 0, 1, (char*)"", (char*)"iiii",
6007 (SUBR) fl_setColor1, (SUBR) NULL, (SUBR) NULL },
6008 { (char*)"FLsetColor2", S(FL_SET_COLOR), 0, 1, (char*)"", (char*)"iiii",
6009 (SUBR) fl_setColor2, (SUBR) NULL, (SUBR) NULL },
6010 { (char*)"FLsetTextSize", S(FL_SET_TEXTSIZE), 0, 1, (char*)"", (char*)"ii",
6011 (SUBR) fl_setTextSize, (SUBR) NULL, (SUBR) NULL },
6012 { (char*)"FLsetTextColor", S(FL_SET_COLOR), 0, 1, (char*)"", (char*)"iiii",
6013 (SUBR) fl_setTextColor, (SUBR) NULL, (SUBR) NULL },
6014 { (char*)"FLsetFont", S(FL_SET_FONT), 0, 1, (char*)"", (char*)"ii",
6015 (SUBR) fl_setFont, (SUBR) NULL, (SUBR) NULL },
6016 { (char*)"FLsetTextType", S(FL_SET_FONT), 0, 1, (char*)"", (char*)"ii",
6017 (SUBR) fl_setTextType, (SUBR) NULL, (SUBR) NULL },
6018 { (char*)"FLsetText", S(FL_SET_TEXT), 0, 1, (char*)"", (char*)"Si",
6019 (SUBR) fl_setText, (SUBR) NULL, (SUBR) NULL },
6020 { (char*)"FLsetText", S(FL_SET_TEXTi), 0, 1, (char*)"", (char*)"ii",
6021 (SUBR) fl_setTexti, (SUBR) NULL, (SUBR) NULL },
6022 { (char*)"FLsetSize", S(FL_SET_SIZE), 0, 1, (char*)"", (char*)"iii",
6023 (SUBR) fl_setSize, (SUBR) NULL, (SUBR) NULL },
6024 { (char*)"FLsetPosition", S(FL_SET_POSITION), 0, 1, (char*)"", (char*)"iii",
6025 (SUBR) fl_setPosition, (SUBR) NULL, (SUBR) NULL },
6026 { (char*)"FLhide", S(FL_WIDHIDE), 0, 1, (char*)"", (char*)"i",
6027 (SUBR) fl_hide, (SUBR) NULL, (SUBR) NULL },
6028 { (char*)"FLshow", S(FL_WIDSHOW), 0, 1, (char*)"", (char*)"i",
6029 (SUBR) fl_show, (SUBR) NULL, (SUBR) NULL },
6030 { (char*)"FLsetBox", S(FL_SETBOX), 0, 1, (char*)"", (char*)"ii",
6031 (SUBR) fl_setBox, (SUBR) NULL, (SUBR) NULL },
6032 { (char*)"FLsetAlign", S(FL_TALIGN), 0, 1, (char*)"", (char*)"ii",
6033 (SUBR) fl_align, (SUBR) NULL, (SUBR) NULL },
6034 { (char*)"FLbox", S(FL_BOX), 0, 1, (char*)"i", (char*)"Siiiiiii",
6035 (SUBR) fl_box_s, (SUBR) NULL, (SUBR) NULL },
6036 { (char*)"FLbox", S(FL_BOX), 0, 1, (char*)"i", (char*)"iiiiiiii",
6037 (SUBR) fl_box_i, (SUBR) NULL, (SUBR) NULL },
6038 { (char*)"FLvalue", S(FLVALUE), 0, 1, (char*)"i", (char*)"Sjjjj",
6039 (SUBR) fl_value, (SUBR) NULL, (SUBR) NULL },
6040 { (char*)"FLpanel", S(FLPANEL), 0, 1, (char*)"", (char*)"Sjjjoooo",
6041 (SUBR) StartPanel, (SUBR) NULL, (SUBR) NULL },
6042 { (char*)"FLpanelEnd", S(FLPANELEND), 0, 1, (char*)"", (char*)"",
6043 (SUBR) EndPanel, (SUBR) NULL, (SUBR) NULL },
6044 { (char*)"FLpanel_end", S(FLPANELEND), 0, 1, (char*)"", (char*)"",
6045 (SUBR) EndPanel, (SUBR) NULL, (SUBR) NULL },
6046 { (char*)"FLscroll", S(FLSCROLL), 0, 1, (char*)"", (char*)"iiii",
6047 (SUBR) StartScroll, (SUBR) NULL, (SUBR) NULL },
6048 { (char*)"FLscrollEnd", S(FLSCROLLEND), 0, 1, (char*)"", (char*)"",
6049 (SUBR) EndScroll, (SUBR) NULL, (SUBR) NULL },
6050 { (char*)"FLscroll_end",S(FLSCROLLEND), 0, 1, (char*)"", (char*)"",
6051 (SUBR) EndScroll, (SUBR) NULL, (SUBR) NULL },
6052 { (char*)"FLpack", S(FLPACK), 0, 1, (char*)"", (char*)"iiiiooo",
6053 (SUBR) StartPack, (SUBR) NULL, (SUBR) NULL },
6054 { (char*)"FLpackEnd", S(FLPACKEND), 0, 1, (char*)"", (char*)"",
6055 (SUBR) EndPack, (SUBR) NULL, (SUBR) NULL },
6056 { (char*)"FLpack_end", S(FLPACKEND), 0, 1, (char*)"", (char*)"",
6057 (SUBR) EndPack, (SUBR) NULL, (SUBR) NULL },
6058 { (char*)"FLtabs", S(FLTABS), 0, 1, (char*)"", (char*)"iiii",
6059 (SUBR) StartTabs, (SUBR) NULL, (SUBR) NULL },
6060 { (char*)"FLtabsEnd", S(FLTABSEND), 0, 1, (char*)"", (char*)"",
6061 (SUBR) EndTabs, (SUBR) NULL, (SUBR) NULL },
6062 { (char*)"FLtabs_end", S(FLTABSEND), 0, 1, (char*)"", (char*)"",
6063 (SUBR) EndTabs, (SUBR) NULL, (SUBR) NULL },
6064 { (char*)"FLgroup", S(FLGROUP), 0, 1, (char*)"", (char*)"Siiiij",
6065 (SUBR) StartGroup, (SUBR) NULL, (SUBR) NULL },
6066 { (char*)"FLgroupEnd", S(FLGROUPEND), 0, 1, (char*)"", (char*)"",
6067 (SUBR) EndGroup, (SUBR) NULL, (SUBR) NULL },
6068 { (char*)"FLgroup_end", S(FLGROUPEND), 0, 1, (char*)"", (char*)"",
6069 (SUBR) EndGroup, (SUBR) NULL, (SUBR) NULL },
6070 { (char*)"FLsetsnap", S(FLSETSNAP), 0, 1, (char*)"ii", (char*)"ioo",
6071 (SUBR) set_snap, (SUBR) NULL, (SUBR) NULL },
6072 { (char*)"FLsetSnapGroup", S(FLSETSNAPGROUP), 0, 1, (char*)"", (char*)"i",
6073 (SUBR)fl_setSnapGroup, (SUBR) NULL, (SUBR) NULL },
6074 { (char*)"FLgetsnap", S(FLGETSNAP), 0, 1, (char*)"i", (char*)"io",
6075 (SUBR) get_snap, (SUBR) NULL, (SUBR) NULL },
6076 { (char*)"FLsavesnap", S(FLSAVESNAPS), 0, 1, (char*)"", (char*)"So",
6077 (SUBR) save_snap, (SUBR) NULL, (SUBR) NULL },
6078 { (char*)"FLloadsnap", S(FLLOADSNAPS), 0, 1, (char*)"", (char*)"So",
6079 (SUBR) load_snap, (SUBR) NULL, (SUBR) NULL },
6080 { (char*)"FLrun", S(FLRUN), 0, 1, (char*)"", (char*)"",
6081 (SUBR) FL_run, (SUBR) NULL, (SUBR) NULL },
6082 { (char*)"FLupdate", S(FLRUN), 0, 1, (char*)"", (char*)"",
6083 (SUBR) fl_update, (SUBR) NULL, (SUBR) NULL },
6084 { (char*)"FLprintk", S(FLPRINTK), 0, 3, (char*)"", (char*)"iki",
6085 (SUBR) FLprintkset, (SUBR) FLprintk, (SUBR) NULL },
6086 { (char*)"FLprintk2", S(FLPRINTK2), 0, 3, (char*)"", (char*)"ki",
6087 (SUBR) FLprintk2set, (SUBR) FLprintk2, (SUBR) NULL },
6088 { (char*)"FLcloseButton", S(FLCLOSEBUTTON), 0, 1, (char*)"i", (char*)"Siiii",
6089 (SUBR) fl_close_button, (SUBR) NULL, (SUBR) NULL },
6090 { (char*)"FLexecButton", S(FLEXECBUTTON), 0, 1, (char*)"i", (char*)"Siiii",
6091 (SUBR) fl_exec_button, (SUBR) NULL, (SUBR) NULL },
6092 { (char*)"FLkeyIn", S(FLKEYIN), 0, 3, (char*)"k", (char*)"o",
6093 (SUBR)fl_keyin_set, (SUBR)fl_keyin, (SUBR) NULL },
6094 { (char*)"FLxyin", S(FLXYIN), 0, 3, (char*)"kkk",(char*)"iiiiiiiioooo",
6095 (SUBR)FLxyin_set, (SUBR)FLxyin, (SUBR) NULL },
6096 { (char*)"FLmouse", S(FLMOUSE), 0, 3, (char*)"kkkkk",(char*)"o",
6097 (SUBR)fl_mouse_set, (SUBR)fl_mouse, (SUBR) NULL },
6098 { (char*)"FLvslidBnk", S(FLSLIDERBANK), 0, 1, (char*)"", (char*)"Siooooooooo",
6099 (SUBR)fl_vertical_slider_bank_S, (SUBR) NULL, (SUBR) NULL },
6100 { (char*)"FLvslidBnk.i", S(FLSLIDERBANK), 0, 1, (char*)"", (char*)"iiooooooooo",
6101 (SUBR)fl_vertical_slider_bank, (SUBR) NULL, (SUBR) NULL },
6102 { (char*)"FLslidBnk2", S(FLSLIDERBANK2),0, 1, (char*)"", (char*)"Siiiooooo",
6103 (SUBR)fl_slider_bank2_S , (SUBR) NULL, (SUBR) NULL },
6104 { (char*)"FLslidBnk2.i", S(FLSLIDERBANK2),0, 1, (char*)"", (char*)"iiiiooooo",
6105 (SUBR)fl_slider_bank2 , (SUBR) NULL, (SUBR) NULL },
6106 { (char*)"FLvslidBnk2", S(FLSLIDERBANK2),0, 1, (char*)"", (char*)"Siiiooooo",
6107 (SUBR)fl_vertical_slider_bank2_S, (SUBR) NULL, (SUBR) NULL },
6108 { (char*)"FLvslidBnk2.i", S(FLSLIDERBANK2),0, 1, (char*)"", (char*)"iiiiooooo",
6109 (SUBR)fl_vertical_slider_bank2, (SUBR) NULL, (SUBR) NULL },
6110 { (char*)"FLslidBnkGetHandle",S(FLSLDBNK_GETHANDLE),0, 1, (char*)"i", (char*)"",
6111 (SUBR)fl_slider_bank_getHandle, (SUBR) NULL, (SUBR) NULL },
6112 { (char*)"FLslidBnkSet",S(FLSLDBNK_SET), 0, 1, (char*)"", (char*)"iiooo",
6113 (SUBR)fl_slider_bank_setVal, (SUBR) NULL, (SUBR) NULL },
6114 { (char*)"FLslidBnkSetk", S(FLSLDBNK2_SETK), 0, 3, (char*)"", (char*)"kiiooo",
6115 (SUBR)fl_slider_bank_setVal_k_set,(SUBR)fl_slider_bank_setVal_k,(SUBR) NULL },
6116 { (char*)"FLslidBnk2Set", S(FLSLDBNK_SET), 0, 1, (char*)"", (char*)"iiooo",
6117 (SUBR)fl_slider_bank2_setVal, (SUBR) NULL, (SUBR) NULL },
6118 { (char*)"FLslidBnk2Setk", S(FLSLDBNK2_SETK), 0, 3, (char*)"", (char*)"kiiooo",
6119 (SUBR)fl_slider_bank2_setVal_k_set, (SUBR)fl_slider_bank2_setVal_k,
6120 (SUBR) NULL },
6121 { (char*)"FLhvsBox", S(FL_HVSBOX), 0, 1, (char*)"i", (char*)"iiiiiio",
6122 (SUBR)fl_hvsbox, (SUBR) NULL, (SUBR) NULL },
6123 { (char*)"FLhvsBoxSetValue",S(FL_SET_HVS_VALUE), 0, 3, (char*)"", (char*)"kki",
6124 (SUBR)fl_setHvsValue_set, (SUBR)fl_setHvsValue, (SUBR) NULL },
6125 // { (char*)"FLmeter", S(FLTKMETER), 0, 1, (char*)"", (char*)"",
6126 // (SUBR)VuMeter_set, (SUBR) NULL, (SUBR) NULL },
6127 { NULL, 0, 0, 0, NULL, NULL,
6128 (SUBR) NULL, (SUBR) NULL, (SUBR) NULL }
6129 };
6130