1
2 /*
3 * Diverse Bristol audio routines.
4 * Copyright (c) by Nick Copeland <nickycopeland@hotmail.com> 1996,2012
5 *
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22
23 #include <fcntl.h>
24
25 #include "brighton.h"
26 #include "brightonMini.h"
27 #include "brightoninternals.h"
28
29 static int rhodesInit();
30 static int rhodesConfigure();
31 static int rhodesCallback(brightonWindow *, int, int, float);
32 static int rhodesMidiCallback(brightonWindow *, int, int, float);
33
34 extern guimain global;
35
36 #include "brightonKeys.h"
37
38 #define OPTS_PANEL 0
39 #define MOD_PANEL 1
40 #define MEM_PANEL 2
41 #define KEY_PANEL 3
42
43 #define FIRST_DEV 0
44
45 #define MOD_COUNT 4
46 #define OPTS_COUNT 12
47 #define MEM_COUNT 17
48
49 #define OPTS_START 0
50 #define MOD_START OPTS_COUNT
51 #define MEM_START (MOD_COUNT + MOD_START)
52
53 #define ACTIVE_DEVS (OPTS_COUNT + MOD_COUNT - 1)
54 #define DEVICE_COUNT (MOD_COUNT + OPTS_COUNT + MEM_COUNT)
55 #define DISPLAY_DEV (MEM_COUNT - 1)
56 #define MEM_MGT ACTIVE_DEVS
57
58 #define MIDI_MGT (MEM_MGT + 12)
59
60 extern int memCallback(brightonWindow * , int, int, float);
61 extern brightonLocations mem[];
62
63 /*
64 * This structure is for device definition. The structure is defined in
65 * include/brighton.h, further definitions in brighton/brightonDevtable.h and
66 * include/brightoninternals.h
67 *
68 * typedef int (*brightonCallback)(int, float);
69 * typedef struct BrightonLocations {
70 * int device; 0=rotary, 1=scale, etc.
71 * float relx, rely; relative position with regards to 1000 by 1000 window
72 * float relw, relh; relative height.
73 * int from, to;
74 * brightonCallback callback; specific to this dev
75 * char *image; bitmap. If zero take a device default.
76 * int flags;
77 * } brightonLocations;
78 *
79 * This example is for a rhodesBristol type synth interface.
80 */
81
82 #define R1 0
83
84 #define W1 100
85 #define L1 600
86
87 #define C1 40
88 #define C2 190
89 #define C3 340
90 #define C4 490
91 #define C5 700
92 #define C6 850
93
94 static brightonLocations locations[MOD_COUNT] = {
95 {"Bass", 0, 90, 100, 300, 600, 0, 1, 0, 0, 0, 0},
96 {"Volume", 0, 123, 100, 300, 600, 0, 1, 0, 0, 0, 0},
97 {"", 2, 50, 200, 30, 400, 0, 1, 0,
98 "bitmaps/buttons/rockerwhite.xpm", 0, 0},
99 {"Chorus", 0, 156, 100, 300, 600, 0, 1, 0, 0, 0, 0},
100 };
101
102 #define S1 200
103
104 /* Options should only be a few piano selectors, no programmers. */
105 static brightonLocations options[OPTS_COUNT] = {
106 {"", 2, 100, 500, 50, 200, 0, 1, 0,
107 "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
108 {"", 2, 200, 500, 50, 200, 0, 1, 0,
109 "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
110 {"", 2, 300, 500, 50, 200, 0, 1, 0,
111 "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
112 {"", 2, 400, 500, 50, 200, 0, 1, 0,
113 "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
114 {"", 2, 500, 500, 50, 200, 0, 1, 0,
115 "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
116 {"", 2, 600, 500, 50, 200, 0, 1, 0,
117 "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
118 {"", 2, 700, 500, 50, 200, 0, 1, 0,
119 "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
120 {"", 2, 800, 500, 50, 200, 0, 1, 0,
121 "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
122 {"", 0, 100, 200, 60, 300, 0, 1, 0, "bitmaps/knobs/knobrednew.xpm",
123 "bitmaps/knobs/alpharotary.xpm", 0},
124 {"", 0, 200, 200, 60, 300, 0, 1, 0, "bitmaps/knobs/knobyellownew.xpm",
125 "bitmaps/knobs/alpharotary.xpm", 0},
126 {"", 0, 300, 200, 60, 300, 0, 1, 0, "bitmaps/knobs/knobgreennew.xpm",
127 "bitmaps/knobs/alpharotary.xpm", 0},
128 {"", 0, 400, 200, 60, 300, 0, 1, 0, "bitmaps/knobs/knobbluenew.xpm",
129 "bitmaps/knobs/alpharotary.xpm", 0},
130 };
131
132 /*
133 * This is a set of globals for the main window rendering. Again taken from
134 * include/brighton.h
135 */
136 brightonApp rhodesApp = {
137 "rhodes",
138 0, /* no blueprint on wood background. */
139 "bitmaps/textures/leather.xpm",
140 0,
141 rhodesInit,
142 rhodesConfigure, /* 3 callbacks */
143 rhodesMidiCallback,
144 0,
145 {16, 0, 2, 2, 5, 520, 0, 1},
146 750, 250, 0, 0,
147 7, /* panel count */
148 {
149 {
150 "Opts",
151 "bitmaps/blueprints/rhodesopts.xpm",
152 "bitmaps/textures/metal5.xpm", /* flags */
153 0x020,
154 0,
155 0,
156 rhodesCallback,
157 19, 40, 600, 510,
158 OPTS_COUNT,
159 options
160 },
161 {
162 "Mods",
163 "bitmaps/blueprints/rhodes.xpm",
164 "bitmaps/images/rhodesplate.xpm",
165 BRIGHTON_STRETCH,
166 0,
167 0,
168 rhodesCallback,
169 12, 559, 976, 100,
170 MOD_COUNT,
171 locations
172 },
173 {
174 "Mem",
175 "bitmaps/blueprints/genmem.xpm",
176 "bitmaps/textures/metal5.xpm", /* flags */
177 0x020,
178 0,
179 0,
180 memCallback,
181 619, 40, 362, 510,
182 MEM_COUNT,
183 mem
184 },
185 {
186 "Keyboard",
187 0,
188 "bitmaps/newkeys/dkbg.xpm", /* flags */
189 0x020|BRIGHTON_STRETCH,
190 0,
191 0,
192 keyCallback,
193 52, 662, 900, 305,
194 KEY_COUNT_6_OCTAVE,
195 keys6octave
196 },
197 {
198 "Rhodes",
199 0,
200 "bitmaps/images/rhodes.xpm",
201 BRIGHTON_STRETCH, /* flags */
202 0,
203 0,
204 0,
205 12, 30, 976, 530,
206 0,
207 0
208 },
209 {
210 "backing",
211 0,
212 "bitmaps/textures/metal6.xpm", /* flags */
213 BRIGHTON_STRETCH,
214 0,
215 0,
216 0,
217 953, 662, 35, 310,
218 0,
219 0
220 },
221 {
222 "backing",
223 0,
224 "bitmaps/textures/metal6.xpm", /* flags */
225 BRIGHTON_STRETCH,
226 0,
227 0,
228 0,
229 12, 662, 40, 310,
230 0,
231 0
232 },
233 }
234 };
235
236 /*static dispatcher dispatch[DEVICE_COUNT]; */
237
238 static int
rhodesMidiSendMsg(void * synth,int fd,int chan,int c,int o,int v)239 rhodesMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v)
240 {
241 /*printf("rhodesMidiSendMsg(%i, %i, %i)\n", c, o, v); */
242 bristolMidiSendMsg(fd, chan, c, o, v);
243 return(0);
244 }
245
246 /*
247 * For the sake of ease of use, links have been placed here to be called
248 * by any of the devices created. They would be better in some other file,
249 * perhaps with this as a dispatch.
250 *
251 * Param refers to the device index in the locations table given below.
252 */
253 static int
rhodesCallback(brightonWindow * win,int panel,int index,float value)254 rhodesCallback(brightonWindow * win, int panel, int index, float value)
255 {
256 guiSynth *synth = findSynth(global.synths, win);
257 int sendvalue;
258
259 /* printf("rhodesCallback(%i, %i, %f): %x\n", panel, index, value, synth); */
260
261 if (synth == 0)
262 return(0);
263
264 if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0))
265 return(0);
266
267 if (rhodesApp.resources[panel].devlocn[index].to == 1)
268 sendvalue = value * C_RANGE_MIN_1;
269 else
270 sendvalue = value;
271
272 switch (panel) {
273 case OPTS_PANEL:
274 index += OPTS_START;
275 break;
276 case MOD_PANEL:
277 index += MOD_START;
278 break;
279 case MEM_PANEL:
280 index += MEM_START;
281 break;
282 }
283
284 synth->mem.param[index] = value;
285
286 if ((!global.libtest) || (index >= ACTIVE_DEVS))
287 synth->dispatch[index].routine(synth,
288 global.controlfd, synth->sid,
289 synth->dispatch[index].controller,
290 synth->dispatch[index].operator,
291 sendvalue);
292 #ifdef DEBUG
293 else
294 printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index,
295 global.controlfd, synth->sid,
296 synth->dispatch[index].controller,
297 synth->dispatch[index].operator,
298 sendvalue);
299 #endif
300
301 return(0);
302 }
303
304 static void
rhodesProgramme(guiSynth * synth,int fd,int chan,int cont,int op,int value)305 rhodesProgramme(guiSynth *synth, int fd, int chan, int cont, int op, int value)
306 {
307 brightonEvent event;
308
309 if (synth->dispatch[OPTS_START].other2)
310 {
311 synth->dispatch[OPTS_START].other2 = 0;
312 synth->mem.param[synth->dispatch[OPTS_START].other1] = 0;
313 return;
314 }
315
316 if ((synth->flags & MEM_LOADING) == 0)
317 {
318 if (synth->dispatch[OPTS_START].other1 != -1)
319 {
320 synth->dispatch[OPTS_START].other2 = 1;
321
322 if (synth->dispatch[OPTS_START].other1 != op)
323 event.value = 0;
324 else
325 event.value = 1;
326
327 brightonParamChange(synth->win, OPTS_PANEL,
328 synth->dispatch[OPTS_START].other1, &event);
329 }
330 synth->dispatch[OPTS_START].other1 = op;
331 synth->mem.param[op] = 1;
332 } else
333 return;
334
335 if (synth->flags & SUPPRESS)
336 return;
337
338 if (value != 0)
339 {
340 float *memhold;
341 float mem[256];
342 int optr, ind;
343
344 /* printf("rhodesProgramme(%x, %i, %i, %i, %i, %i)\n", */
345 /* synth, fd, chan, cont, op, value); */
346
347 /*
348 * Each of the 8 voices has an associated set of DX parameters. We
349 * need to get hold of these, and send them directly over our config
350 * interface tap - we cannot forward via the normal GUi interface since
351 * we do not have these parameters mapped.
352 *
353 * The memories are mapped as 6 operators, each with 20 parameters,
354 * of which 13 are active, and then we have 4 additional parameters for
355 * algo, pitch, glide and volume.
356 */
357 memhold = &synth->mem.param[0];
358
359 synth->mem.param = &mem[0];
360
361 ind = 1000 + op;
362
363 /*
364 * Load the memory parameters with no callbacks. We have to force the
365 * loading since we are using 'rhodes' as our type, but the memories
366 * are actually typed as DX.
367 */
368 if (loadMemory(synth, "rhodes", 0, ind, 148, 0,
369 BRISTOL_NOCALLS|BRISTOL_FORCE) < 0)
370 {
371 printf("Memory not found, returning\n");
372 synth->mem.param = memhold;
373 synth->dispatch[OPTS_START].other1 = op;
374 return;
375 }
376
377 for (optr = 0; optr < 6; optr++)
378 {
379 rhodesMidiSendMsg(synth, global.controlfd, synth->sid,
380 126, optr * 10, mem[optr * 20] * C_RANGE_MIN_1);
381 rhodesMidiSendMsg(synth, global.controlfd, synth->sid,
382 optr, 1, mem[optr * 20 + 1] * C_RANGE_MIN_1);
383 rhodesMidiSendMsg(synth, global.controlfd, synth->sid,
384 optr, 0, mem[optr * 20 + 2]);
385 rhodesMidiSendMsg(synth, global.controlfd, synth->sid,
386 optr, 6, mem[optr * 20 + 3] * C_RANGE_MIN_1);
387 rhodesMidiSendMsg(synth, global.controlfd, synth->sid,
388 126, optr * 10 + 1, mem[optr * 20 + 4] * C_RANGE_MIN_1);
389 rhodesMidiSendMsg(synth, global.controlfd, synth->sid,
390 optr, 2, mem[optr * 20 + 5] * C_RANGE_MIN_1);
391 rhodesMidiSendMsg(synth, global.controlfd, synth->sid,
392 optr, 3, mem[optr * 20 + 6] * C_RANGE_MIN_1);
393 rhodesMidiSendMsg(synth, global.controlfd, synth->sid,
394 optr, 4, mem[optr * 20 + 7] * C_RANGE_MIN_1);
395 rhodesMidiSendMsg(synth, global.controlfd, synth->sid,
396 optr, 5, mem[optr * 20 + 8] * C_RANGE_MIN_1);
397 rhodesMidiSendMsg(synth, global.controlfd, synth->sid,
398 optr, 7, mem[optr * 20 + 9] * C_RANGE_MIN_1);
399 rhodesMidiSendMsg(synth, global.controlfd, synth->sid,
400 126, optr * 10 + 2, mem[optr * 20 + 10] * C_RANGE_MIN_1);
401 rhodesMidiSendMsg(synth, global.controlfd, synth->sid,
402 126, optr * 10 + 3, mem[optr * 20 + 11] * C_RANGE_MIN_1);
403 rhodesMidiSendMsg(synth, global.controlfd, synth->sid,
404 optr, 9, mem[optr * 20 + 12] * C_RANGE_MIN_1);
405 rhodesMidiSendMsg(synth, global.controlfd, synth->sid,
406 optr, 10, mem[optr * 20 + 13] * C_RANGE_MIN_1);
407 rhodesMidiSendMsg(synth, global.controlfd, synth->sid,
408 optr, 11, mem[optr * 20 + 14] * C_RANGE_MIN_1);
409 rhodesMidiSendMsg(synth, global.controlfd, synth->sid,
410 optr, 12, mem[optr * 20 + 15] * C_RANGE_MIN_1);
411 }
412
413 /*
414 * These go through all the algorithms, looking for a single nonzero
415 */
416 for (ind = 0; ind < 24; ind++)
417 {
418 if (mem[120 + ind] != 0)
419 {
420 bristolMidiSendMsg(global.controlfd, synth->sid, 126, 101, ind);
421 break;
422 }
423 }
424
425 rhodesMidiSendMsg(synth, global.controlfd, synth->sid,
426 126, 99, 0);
427 rhodesMidiSendMsg(synth, global.controlfd, synth->sid,
428 126, 100, 0);
429 rhodesMidiSendMsg(synth, global.controlfd, synth->sid,
430 126, 102, C_RANGE_MIN_1);
431
432 synth->mem.param = memhold;
433 synth->dispatch[OPTS_START].other1 = op;
434 }
435 }
436
437 static int
rhodesMidiCallback(brightonWindow * win,int command,int value,float v)438 rhodesMidiCallback(brightonWindow *win, int command, int value, float v)
439 {
440 guiSynth *synth = findSynth(global.synths, win);
441
442 printf("midi callback: %x, %i\n", command, value);
443
444 switch(command)
445 {
446 case MIDI_PROGRAM:
447 printf("midi program: %x, %i\n", command, value);
448 synth->location = value;
449
450 rhodesProgramme(synth, global.controlfd, synth->sid,
451 synth->dispatch[OPTS_START].controller,
452 synth->dispatch[OPTS_START].operator, 1.0f);
453
454 break;
455 case MIDI_BANK_SELECT:
456 printf("midi banksel: %x, %i\n", command, value);
457 synth->bank = value;
458 break;
459 }
460 return(0);
461 }
462
463 static void
rhodesPanelSwitch(guiSynth * id,int fd,int chan,int cont,int op,int value)464 rhodesPanelSwitch(guiSynth *id, int fd, int chan, int cont, int op, int value)
465 {
466 brightonEvent event;
467
468 id->flags |= SUPPRESS;
469 /*printf("rhodesPanelSwitch()\n"); */
470 /*
471 * If the sendvalue is zero, then withdraw the opts window, draw the
472 * slider window, and vice versa.
473 */
474 if (value == 0)
475 {
476 event.type = BRIGHTON_EXPOSE;
477 event.intvalue = 0;
478 brightonParamChange(id->win, 0, -1, &event);
479 event.intvalue = 0;
480 brightonParamChange(id->win, 2, -1, &event);
481 event.intvalue = 1;
482 brightonParamChange(id->win, 4, -1, &event);
483 } else {
484 event.type = BRIGHTON_EXPOSE;
485 event.intvalue = 0;
486 brightonParamChange(id->win, 4, -1, &event);
487 event.intvalue = 1;
488 brightonParamChange(id->win, 0, -1, &event);
489 event.intvalue = 1;
490 brightonParamChange(id->win, 2, -1, &event);
491 }
492 id->flags &= ~SUPPRESS;
493 }
494
495 static void
rhodesVolume(guiSynth * id,int fd,int chan,int cont,int op,int value)496 rhodesVolume(guiSynth *id, int fd, int chan, int cont, int op, int value)
497 {
498 /*printf("rhodesVolume(%i)\n", value); */
499 bristolMidiSendMsg(global.controlfd, chan, 126, 102, value);
500 }
501
502 static void
rhodesBoost(guiSynth * synth,int fd,int chan,int cont,int op,int value)503 rhodesBoost(guiSynth *synth, int fd, int chan, int cont, int op, int value)
504 {
505 /*printf("rhodesBoost(%i)\n", value); */
506 bristolMidiControl(global.controlfd, synth->sid, 0, 1, value >> 7);
507 }
508
509 static void
rhodesChorus(guiSynth * synth,int fd,int chan,int cont,int op,int value)510 rhodesChorus(guiSynth *synth, int fd, int chan, int cont, int op, int value)
511 {
512 /*printf("Rhodes chorus: %i\n", value); */
513 bristolMidiSendMsg(global.controlfd, synth->sid, 123, 0, value);
514 bristolMidiSendMsg(global.controlfd, synth->sid, 123, 3, value);
515 }
516
517 /*
518 * Any location initialisation required to run the callbacks. For bristol, this
519 * will connect to the engine, and give it some base parameters.
520 * May need to generate some application specific menus.
521 * Will also then make specific requests to some of the devices to alter their
522 * rendering.
523 */
524 static int
rhodesInit(brightonWindow * win)525 rhodesInit(brightonWindow *win)
526 {
527 guiSynth *synth = findSynth(global.synths, win);
528 dispatcher *dispatch;
529 int i;
530
531 if (synth == 0)
532 {
533 synth = findSynth(global.synths, 0);
534 if (synth == 0)
535 {
536 printf("cannot init\n");
537 return(0);
538 }
539 }
540
541 synth->win = win;
542
543 printf("Initialise the rhodes link to bristol: %p\n", synth->win);
544
545 synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float));
546 synth->mem.count = DEVICE_COUNT;
547 synth->mem.active = ACTIVE_DEVS;
548 synth->dispatch = (dispatcher *)
549 brightonmalloc(DEVICE_COUNT * sizeof(dispatcher));
550 dispatch = synth->dispatch;
551
552 /*
553 * The rhodes is actually a DX algorithm but it may eventually use a
554 * wrapper in the engine such that the FM coding is fed into a chorus.
555 synth->synthtype = BRISTOL_DX;
556 */
557
558 /*
559 * We really want to have three connection mechanisms. These should be
560 * 1. Unix named sockets.
561 * 2. UDP sockets.
562 * 3. MIDI pipe.
563 */
564 if (!global.libtest)
565 if ((synth->sid = initConnection(&global, synth)) < 0)
566 return(-1);
567
568 for (i = 0; i < DEVICE_COUNT; i++)
569 synth->dispatch[i].routine = rhodesMidiSendMsg;
570
571 synth->dispatch[MOD_START + 0].routine = (synthRoutine) rhodesBoost;
572 synth->dispatch[MOD_START + 1].routine = (synthRoutine) rhodesVolume;
573 synth->dispatch[MOD_START + 2].routine = (synthRoutine) rhodesPanelSwitch;
574 synth->dispatch[MOD_START + 3].controller = 123;
575 synth->dispatch[MOD_START + 3].operator = 0;
576 synth->dispatch[MOD_START + 3].routine = (synthRoutine) rhodesChorus;
577
578 synth->dispatch[OPTS_START + 0].routine
579 = synth->dispatch[OPTS_START + 1].routine
580 = synth->dispatch[OPTS_START + 2].routine
581 = synth->dispatch[OPTS_START + 3].routine
582 = synth->dispatch[OPTS_START + 4].routine
583 = synth->dispatch[OPTS_START + 5].routine
584 = synth->dispatch[OPTS_START + 6].routine
585 = synth->dispatch[OPTS_START + 7].routine
586 = (synthRoutine) rhodesProgramme;
587 synth->dispatch[OPTS_START + 0].operator = 0;
588 synth->dispatch[OPTS_START + 1].operator = 1;
589 synth->dispatch[OPTS_START + 2].operator = 2;
590 synth->dispatch[OPTS_START + 3].operator = 3;
591 synth->dispatch[OPTS_START + 4].operator = 4;
592 synth->dispatch[OPTS_START + 5].operator = 5;
593 synth->dispatch[OPTS_START + 6].operator = 6;
594 synth->dispatch[OPTS_START + 7].operator = 7;
595
596 synth->dispatch[OPTS_START + 8].controller
597 = synth->dispatch[OPTS_START + 9].controller
598 = synth->dispatch[OPTS_START + 10].controller
599 = synth->dispatch[OPTS_START + 11].controller = 123;
600 synth->dispatch[OPTS_START + 8].operator = 0;
601 synth->dispatch[OPTS_START + 9].operator = 1;
602 synth->dispatch[OPTS_START + 10].operator = 2;
603 synth->dispatch[OPTS_START + 11].operator = 3;
604
605 return(0);
606 }
607
608 /*
609 * This will be called to make any routine specific parameters available.
610 */
611 static int
rhodesConfigure(brightonWindow * win)612 rhodesConfigure(brightonWindow *win)
613 {
614 guiSynth *synth = findSynth(global.synths, win);
615 brightonEvent event;
616
617 if (synth == 0)
618 {
619 printf("problems going operational\n");
620 return(-1);
621 }
622
623 if (synth->flags & OPERATIONAL)
624 return(0);
625
626 printf("going operational\n");
627
628 synth->flags |= OPERATIONAL;
629 synth->keypanel = 3;
630 synth->keypanel2 = -1;
631 synth->transpose = 36;
632 /* loadMemory(synth, "rhodes", 0, synth->location, synth->mem.active, */
633 /* FIRST_DEV, BRISTOL_NOCALLS|BRISTOL_FORCE); */
634
635 rhodesProgramme(synth, global.controlfd, synth->sid,
636 synth->dispatch[OPTS_START].controller,
637 synth->dispatch[OPTS_START].operator, 1.0f);
638
639 displayPanelText(synth, "PRG", synth->location, MEM_PANEL, MEM_COUNT - 1);
640
641 /*
642 * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only
643 * occurs on first paint, so we suppress the first paint, and then request
644 * an expose here.
645 */
646 event.type = BRIGHTON_EXPOSE;
647 event.intvalue = 1;
648 brightonParamChange(synth->win, KEY_PANEL, -1, &event);
649 event.type = BRIGHTON_FLOAT;
650 event.value = 1;
651 brightonParamChange(synth->win, 0, 0, &event);
652 configureGlobals(synth);
653
654 event.type = BRIGHTON_FLOAT;
655 event.value = 0.1;
656 brightonParamChange(synth->win, OPTS_PANEL, 8, &event);
657 brightonParamChange(synth->win, OPTS_PANEL, 9, &event);
658 brightonParamChange(synth->win, OPTS_PANEL, 10, &event);
659 event.value = 0.5;
660 brightonParamChange(synth->win, OPTS_PANEL, 11, &event);
661
662 brightonPut(synth->win, "bitmaps/blueprints/rhodesshade.xpm",
663 0, 0, synth->win->width, synth->win->height);
664
665 return(0);
666 }
667
668