1
2 /*
3 * Diverse Bristol midi 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 #define _GNU_SOURCE
23 #include <sys/socket.h>
24 #include <sys/select.h>
25 #include <sys/time.h>
26 #include <sys/stat.h>
27 #include <termios.h>
28 #include <stdlib.h>
29 #include <fcntl.h>
30 #include <ctype.h>
31 #include <stdio.h>
32
33 #include <string.h>
34
35 #include "brighton.h"
36 #include "brightoninternals.h"
37 #include "brightonMini.h"
38
39 extern char *getBristolCache(char *);
40 extern void brightonChangeParam(guiSynth *, int, int, float);
41 extern void brightonKeyInput(brightonWindow *, int, int);
42
43 static fd_set stdioset[32];
44 static struct timeval timeout;
45
46 static float lp = -1;
47
48 struct termios resetattr;
49
50 #define B_TTY_ACT_COUNT 80
51 #define B_TTY_LINE_LEN 256
52
53 #define B_TTY_RAW 0x00000001
54 #define B_TTY_RAW_P 0x00000002
55 #define B_TTY_RAW_P2 0x00000004
56 #define B_TTY_COOKED 0x00000008
57 #define B_TTY_RAW_ESC 0x00000010
58 #define B_TTY_RAW_ESC2 0x00000020
59 #define B_TTY_SEARCH 0x00000040
60 #define B_TTY_PLAY 0x00000080
61 #define B_TTY_MMASK 0x00000fff
62
63 #define B_TTY_INIT 0x00001000
64 #define B_TTY_DEBUG 0x00002000
65 #define B_TTY_AWV 0x00004000
66 #define B_TTY_AUV 0x00008000
67 #define B_TTY_ALIASING 0x00010000
68 #define B_TTY_SAVE_HIST 0x00020000
69 #define B_TTY_PLAY_LINE 0x00040000
70 #define B_TTY_CLEAR_KEY 0x00080000
71 #define B_TTY_SEQ 0x00100000
72
73 #define B_TTY_ARGC 32
74
75 static char hist[51][B_TTY_LINE_LEN];
76 static char pbuf[B_TTY_LINE_LEN];
77 static char cbuf[B_TTY_LINE_LEN];
78
79 #define B_SEQ_COUNT 16
80
81 static struct {
82 int count, rate, step[B_SEQ_COUNT];
83 } sequences[B_SEQ_COUNT] = {
84 {8, 30, {52 + 0, 52 + 7, 52 + 3, 52 + 7, 52 + 0, 52 + 5, 52 + 9, 52 + 5}},
85 {0, 0, {0}},
86 {0, 0, {0}},
87 {0, 0, {0}},
88 {0, 0, {0}},
89 {0, 0, {0}},
90 {0, 0, {0}},
91 {0, 0, {0}},
92 {0, 0, {0}},
93 {0, 0, {0}},
94 {0, 0, {0}},
95 {0, 0, {0}},
96 {0, 0, {0}},
97 {0, 0, {0}},
98 {0, 0, {0}},
99 {0, 0, {0}},
100 };
101
102 static char *unknown = "unnamed parameter";
103 static char *b_blank = " ";
104
105 #define B_TTY_A_LEFT 0
106 #define B_TTY_A_RIGHT 1
107 #define B_TTY_A_INCMIN 2
108 #define B_TTY_A_INC 3
109 #define B_TTY_A_INCMAX 4
110 #define B_TTY_A_DECMIN 5
111 #define B_TTY_A_DEC 6
112 #define B_TTY_A_DECMAX 7
113 #define B_TTY_A_M_UP 8
114 #define B_TTY_A_M_DOWN 9
115 #define B_TTY_A_M_READ 10
116 #define B_TTY_A_M_WRITE 11
117 #define B_TTY_A_M_TOG 12
118 #define B_TTY_A_INSERT 13
119 #define B_TTY_A_INC1 14
120 #define B_TTY_A_INC4 15
121 #define B_TTY_A_DEC1 16
122 #define B_TTY_A_DEC4 17
123 #define B_TTY_A_UPDATE 18
124 #define B_TTY_A_FIND 19
125 #define B_TTY_A_NULL -1
126
127 #define RESOURCES global->synths->resources
128 #define SYNTHS global->synths
129 #define paramname(x) RESOURCES->resources[btty.p].devlocn[x].name
130 //#define DEVICE(x) RESOURCES->resources[btty.p].devlocn[x]
131 #define DEVICE(x) global->synths->win->app->resources[btty.p].devlocn[x]
132 #define PDEV(x) ((brightonDevice *) global->synths->win->app->resources[btty.p].devlocn[x].dev)
133
134 #define unnamed(x) ((paramname(x)[0] == '\0') || (DEVICE(x).flags & BRIGHTON_WITHDRAWN))
135
136 // if (RESOURCES->resources[btty.p].devlocn[btty.i].to == 1.0f)
137 // if (DEVICE(btty.i).to == 1.0f)
138
139 brightonEvent event;
140 extern void printBrightonHelp(int);
141
142 typedef int (*clicom)();
143
144 static int bttyInterpret(guimain *, char *);
145 static int execHelp(guimain *, int, char **);
146 static int execMemory(guimain *, int, char **);
147 static int execLoad(guimain *, int, char **);
148 static int execDebug(guimain *, int, char **);
149 static int execImport(guimain *, int, char **);
150 static int execSet(guimain *, int, char **);
151 static int execBristol(guimain *, int, char **);
152 static int execBrighton(guimain *, int, char **);
153 static int execMidi(guimain *, int, char **);
154 static int execAlias(guimain *, int, char **);
155 static int execCLI(guimain *, int, char **);
156 static int execQuit(guimain *, int, char **);
157 static void bttyMemSave(guimain *);
158
159 /* Error codes */
160 #define B_ERR_EXIT -1
161 #define B_ERR_OK 0
162 #define B_ERR_NOT_FOUND 1
163 #define B_ERR_PARAM 2
164 #define B_ERR_VALUE 3
165 #define B_ERR_INV_ARG 4
166 #define B_ERR_EARLY 5
167
168 /* global command codes */
169 #define B_COM_LAST -1
170 #define B_COM_NOT_USED 0
171 #define B_COM_FREE 128
172
173 /* 'set memory' commands */
174 #define B_COM_FIND 1
175 #define B_COM_READ 2
176 #define B_COM_WRITE 3
177 #define B_COM_IMPORT 4
178 #define B_COM_EXPORT 5
179 #define B_COM_FORCE 6
180
181 typedef struct CommSet {
182 char name[12];
183 int map;
184 char help[B_TTY_LINE_LEN];
185 clicom exec;
186 struct CommSet *subcom;
187 } comSet;
188
189 comSet brightoncom[4] = {
190 {"", B_COM_NOT_USED, "", 0, 0},
191 {"panel", B_COM_FIND,
192 "<n> Set the active emulator parameter panel",
193 0, 0},
194 {"device", B_COM_FIND,
195 "<panel> <dev> <value> send parameter change message",
196 0, 0},
197 {"", B_COM_LAST, "", 0, 0},
198 };
199
200 comSet debugcomm[6] = {
201 {"", B_COM_NOT_USED, "", 0, 0},
202 {"cli", B_COM_FIND,
203 "Command Line Debuging on/off",
204 0, 0},
205 {"midi", B_COM_FIND,
206 "debug level midi interface libraries 0..3",
207 0, 0},
208 {"frontend", B_COM_FIND,
209 "debug engine interface libraries on/off",
210 0, 0},
211 {"engine", B_COM_FIND,
212 "engine debuging level 0..15 (0 = off, >9 = verbose)",
213 0, 0},
214 {"", B_COM_LAST, "", 0, 0},
215 };
216
217 comSet bristolcom[4] = {
218 {"", B_COM_NOT_USED, "", 0, 0},
219 {"register", B_COM_FIND,
220 "send MIDI surface controller registration request",
221 0, 0},
222 {"control", B_COM_FIND,
223 "<op> <cont> <value> send parameter change message to engine",
224 0, 0},
225 {"", B_COM_LAST, "", 0, 0},
226 };
227
228 comSet midicomm[24] = {
229 {"", B_COM_NOT_USED, "", 0, 0},
230 {"channel", B_COM_FIND,
231 "configure engine midi channel 1..16",
232 0, 0},
233 {"sid", B_COM_FIND,
234 "select internal messaging id",
235 0, 0},
236 {"debug", B_COM_FIND,
237 "engine debuging level 0..16",
238 0, 0},
239 {"lowkey", B_COM_FIND,
240 "lower midi keyboard split point 0..127",
241 0, 0},
242 {"highkey", B_COM_FIND,
243 "higher midi keyboard split point 0..127",
244 0, 0},
245 {"chanpress", B_COM_FIND,
246 "send a channel pressure event value p=0..127",
247 0, 0},
248 {"polypress", B_COM_FIND,
249 "send a key pressure event k=0..127 p=0..127",
250 0, 0},
251 {"filter", B_COM_FIND,
252 "engine filters: lwf/nwf/wwf/hwf",
253 0, 0},
254 {"notepref", B_COM_FIND,
255 "monophonic note preference logic: hnp/lnp/nnp",
256 0, 0},
257 {"velocity", B_COM_FIND,
258 "midi velocity curve 0..1000",
259 0, 0},
260 {"detune", B_COM_FIND,
261 "engine 'temperature sensitivity' detuning",
262 0, 0},
263 {"glide", B_COM_FIND,
264 "maximum glide rate (5s)",
265 0, 0},
266 {"legato", B_COM_FIND,
267 "monophonic legato velocity logic on/off",
268 0, 0},
269 {"trigger", B_COM_FIND,
270 "monophonic trig/retrig logic on/off",
271 0, 0},
272 {"gain", B_COM_FIND,
273 "emulator global gain control",
274 0, 0},
275 {"pwd", B_COM_FIND,
276 "midi pitch wheel depth semitones",
277 0, 0},
278 {"nrp", B_COM_FIND,
279 "enable user interface NRP response on/off",
280 0, 0},
281 {"enginenrp", B_COM_FIND,
282 "enable engine NRP response on/off",
283 0, 0},
284 {"forwarding", B_COM_FIND,
285 "enable engine midi message forwarding on/off",
286 0, 0},
287 {"tuning", B_COM_FIND,
288 "coarse/fine: global tuning 0..1.0",
289 0, 0},
290 {"controller", B_COM_FIND,
291 "send a value to a continuous controller value",
292 0, 0},
293 {"panic", B_COM_FIND,
294 "midi all-notes-off, etc",
295 0, 0},
296 {"", B_COM_LAST, "", 0, 0},
297 };
298
299 comSet cliComm[4] = {
300 {"", B_COM_NOT_USED, "", 0, 0},
301 {"cycle", B_COM_FIND,
302 "CLI cycle response time (ms)",
303 0, 0},
304 {"list", B_COM_FIND,
305 "list the CLI ESC command key templates",
306 0, 0},
307 {"", B_COM_LAST, "", 0, 0},
308 };
309
310 comSet memcomm[8] = {
311 /* Find/read/write/import/export should move to set memory */
312 {"", B_COM_NOT_USED, "", 0, 0},
313 {"find", B_COM_FIND,
314 "'find', 'find free', 'find load' synth memory search",
315 execLoad, 0},
316 {"read", B_COM_FIND,
317 "[<n>|undo] load synth memory at the configured index",
318 execLoad, 0},
319 {"write", B_COM_FIND,
320 "[<n>] save current synth settings to memory",
321 execLoad, 0},
322 {"import", B_COM_FIND,
323 "[path [mem]] read a file and save to memory",
324 execImport, 0},
325 {"export", B_COM_FIND,
326 "[path [mem]] save memory to external file",
327 execImport, 0},
328 {"force", B_COM_FIND,
329 "force the loading of an otherwise erroneous memory, on/off",
330 execLoad, 0},
331 {"", B_COM_LAST, "", 0, 0},
332 };
333
334 /*
335 * Need to build more structures to represent the parameters set of each
336 * command, this is needed for better help and command completion.
337 static struct {
338 char name[12];
339 int map;
340 char help[B_TTY_LINE_LEN];
341 clicom exec;
342 comSet *subcom;
343 } tmp;
344 */
345
346 /* 'set <comm> and top level interpretation */
347 #define B_COM_SET 1
348 #define B_COM_MEMORY 2
349 #define B_COM_MIDI 3
350 #define B_COM_DEBUG 4
351 #define B_COM_BRISTOL 5
352 #define B_COM_BRIGHTON 6
353 #define B_COM_CLI 7
354 #define B_COM_ALIAS 8
355 #define B_COM_SETALIAS 9
356 #define B_COM_HELP 10
357 #define B_COM_QUIT 11
358 #define B_COM_PLAY 12
359
360 comSet setcomm[B_TTY_ACT_COUNT + 1] = {
361 {"", B_COM_NOT_USED, "", 0, 0},
362 /* Find/read/write/import/export should move to set memory */
363 {"memory", B_COM_MEMORY,
364 "'set memory [find|read|write|import|export]",
365 execMemory, memcomm},
366 {"midi", B_COM_MIDI,
367 "[channel|debug|help] midi control commands",
368 execMidi, midicomm},
369 {"debug", B_COM_DEBUG,
370 "[on|off|engine [0..15]] debug settings",
371 execDebug, debugcomm},
372 {"bristol", B_COM_BRISTOL,
373 "[cont/op/value|register] - operator commands",
374 execBristol, bristolcom},
375 {"brighton",B_COM_BRIGHTON,
376 "[panel|p/d/v] - GUI management commands",
377 execBrighton, brightoncom},
378 {"cli", B_COM_CLI,
379 "[list|<key> action|cycle] navigation key management",
380 execCLI, cliComm},
381 {"alias", B_COM_SETALIAS,
382 "command aliases, %/$ signs will be remapped parameters",
383 execAlias, 0},
384 {"play", B_COM_PLAY,
385 "set play mode|stop, set play sequence <id>, to test synth patches",
386 execAlias, 0},
387 {"noalias", B_COM_SETALIAS,
388 "noalias <name>: remove an alias called 'name'",
389 execAlias, 0},
390 {"line", B_COM_NOT_USED,
391 "command line length",
392 0, 0},
393 {"history", B_COM_NOT_USED,
394 "history table size (max 50)",
395 0, 0},
396 {"savehistory", B_COM_NOT_USED,
397 "autosave history and parameters on exit",
398 0, 0},
399 {"prompt", B_COM_NOT_USED,
400 "CLI Prompt",
401 0, 0},
402 {"accelerator", B_COM_NOT_USED,
403 "Default ESC mode Up/Down parameter change value",
404 0, 0},
405 {"awv", B_COM_NOT_USED,
406 "access withdrawn variables",
407 0, 0},
408 {"", B_COM_LAST, "", 0, 0},
409 };
410
411 comSet commands[B_TTY_ACT_COUNT + 1] = {
412 {"", B_COM_NOT_USED, "", 0, 0},
413 /* Find/read/write/import/export should move to set memory */
414 {"set", B_COM_SET,
415 "[line|panel|awv|cli|noalias|hist|prompt]",
416 execSet, setcomm},
417 {"memory", B_COM_MEMORY,
418 "'set memory [find|read|write|import|export]",
419 execMemory, memcomm},
420 {"midi", B_COM_MIDI,
421 "[channel|debug|help] midi control commands",
422 execMidi, midicomm},
423 {"debug", B_COM_DEBUG,
424 "[on|off|engine [0..15]] debug settings",
425 execDebug, debugcomm},
426 {"bristol", B_COM_BRISTOL,
427 "[cont/op/value|register] - operator commands",
428 execBristol, bristolcom},
429 {"brighton",B_COM_BRIGHTON,
430 "[panel|p/d/v] - GUI management commands",
431 execBrighton, brightoncom},
432 {"cli", B_COM_CLI,
433 "[list|<key> action|cycle] navigation key management",
434 execCLI, cliComm},
435 {"alias", B_COM_SETALIAS,
436 "command aliases, %/$ signs will be remapped parameters",
437 execAlias, 0},
438 {"help", B_COM_HELP,
439 "'set <command> help', 'help <command>, this screen",
440 execHelp, 0},
441 {"quit", B_COM_QUIT,
442 "exit application, terminate the emulator",
443 execQuit, NULL},
444 {"", B_COM_LAST, "", 0, 0},
445 };
446
447 #define B_TTY_A_PREDEF 20
448
449 static struct {
450 char opname[12];
451 int imap;
452 } templates[B_TTY_ACT_COUNT + 1] = {
453 {"left", B_TTY_A_LEFT},
454 {"right", B_TTY_A_RIGHT},
455 {"incmin", B_TTY_A_INCMIN},
456 {"inc", B_TTY_A_INC},
457 {"incmax", B_TTY_A_INCMAX},
458 {"decmin", B_TTY_A_DECMIN},
459 {"dec", B_TTY_A_DEC},
460 {"decmax", B_TTY_A_DECMAX},
461 {"memUp", B_TTY_A_M_UP},
462 {"memDown", B_TTY_A_M_DOWN},
463 {"read", B_TTY_A_M_READ},
464 {"write", B_TTY_A_M_WRITE},
465 {"toggle", B_TTY_A_M_TOG},
466 {"insert", B_TTY_A_INSERT},
467 {"fineup", B_TTY_A_INC4},
468 {"up", B_TTY_A_INC1},
469 {"finedown",B_TTY_A_DEC4},
470 {"down", B_TTY_A_DEC1},
471 {"update", B_TTY_A_UPDATE},
472 {"search", B_TTY_A_FIND},
473 {"off", B_TTY_A_NULL},
474 {"", -1},
475 };
476
477 static struct {
478 char map;
479 int imap;
480 } action[B_TTY_ACT_COUNT + 1] = {
481 {'h', B_TTY_A_LEFT},
482 {'l', B_TTY_A_RIGHT},
483 {0x0b, B_TTY_A_INCMIN},
484 {'k', B_TTY_A_INC},
485 {'K', B_TTY_A_INCMAX},
486 {0x0a, B_TTY_A_DECMIN},
487 {'j', B_TTY_A_DEC},
488 {'J', B_TTY_A_DECMAX},
489 {'M', B_TTY_A_M_UP},
490 {'m', B_TTY_A_M_DOWN},
491 {'r', B_TTY_A_M_READ},
492 {'w', B_TTY_A_M_WRITE},
493 {'x', B_TTY_A_M_TOG},
494 {'u', B_TTY_A_INC1},
495 {'d', B_TTY_A_DEC1},
496 {'f', B_TTY_A_UPDATE},
497 {'U', B_TTY_A_INC4},
498 {'D', B_TTY_A_DEC4},
499 {':', B_TTY_A_INSERT},
500 {'/', B_TTY_A_FIND},
501 {'\0', -1},
502 };
503
504 static struct {
505 unsigned int flags;
506 guimain *global;
507 int cycle;
508 int i;
509 int p;
510 char promptText[64];
511 char prompt[64];
512 char *hist[51];
513 int hist_tmp;
514 int hist_c;
515 int edit_p;
516 char b;
517 char delim;
518 int len;
519 int fd[2];
520 int lastmem;
521 char ichan;
522 char mdbg;
523 char edbg;
524 char lowkey;
525 char highkey;
526 char preference;
527 float accel;
528 int fl;
529 int po;
530 unsigned int key;
531 int pcycle;
532 int acycle;
533 struct {
534 int id;
535 int step;
536 int count;
537 int transpose;
538 unsigned int flags;
539 } sequence;
540 } btty = {
541 B_TTY_INIT|B_TTY_COOKED|B_TTY_PLAY_LINE,
542 NULL,
543 500,
544 0,
545 0,
546 "%algo% (m %memory% ch %channel%): ",
547 "%algo%: ",
548 {hist[0], hist[1], hist[2], hist[3], hist[4],
549 hist[5], hist[6], hist[7], hist[8], hist[9],
550 hist[10], hist[11], hist[12], hist[13], hist[14],
551 hist[15], hist[16], hist[17], hist[18], hist[19],
552 hist[20], hist[21], hist[22], hist[23], hist[24],
553 hist[25], hist[26], hist[27], hist[28], hist[29],
554 hist[30], hist[31], hist[32], hist[33], hist[34],
555 hist[35], hist[36], hist[37], hist[38], hist[39],
556 hist[40], hist[41], hist[42], hist[43], hist[44],
557 hist[45], hist[46], hist[47], hist[48], hist[49], hist[50]},
558 0, 50, 0,
559 '\0',
560 ':',
561 80,
562 {0, 0},
563 0,
564 /* These all default to zero, the MIDI options */
565 0, 0, 0, 0, 127, 0,
566 /* Default Cursor key accelerator */
567 0.05f,
568 0,
569 0,
570 /* Keystroke management */
571 0, 500, 500
572 };
573
574 static void
print(char * str)575 print(char *str)
576 {
577 int i;
578 char tbuf[B_TTY_LINE_LEN];
579
580 if (btty.flags & B_TTY_DEBUG)
581 {
582 snprintf(tbuf, btty.len, "d: %s\r\n", str);
583 i = write(btty.fd[1], tbuf, strlen(tbuf));
584 }
585 }
586
587 static void
printChar(char ch)588 printChar(char ch)
589 {
590 int i;
591
592 if (btty.flags & B_TTY_DEBUG)
593 {
594 snprintf(pbuf, btty.len, "char 0x%x\r\n", ch);
595 i = write(btty.fd[1], pbuf, strlen(pbuf));
596 }
597 }
598
599 static void
seqStop(guimain * global)600 seqStop(guimain *global)
601 {
602 print("seqStop");
603
604 if (btty.flags & B_TTY_SEQ)
605 {
606 bristolMidiSendMsg(global->controlfd, SYNTHS->midichannel,
607 BRISTOL_EVENT_KEYOFF, 0,
608 sequences[btty.sequence.id].step[btty.sequence.step]
609 + btty.sequence.transpose);
610 bristolMidiSendMsg(global->controlfd, SYNTHS->sid, 127, 0,
611 BRISTOL_ALL_NOTES_OFF);
612 }
613
614 btty.flags &= ~B_TTY_SEQ;
615 btty.sequence.step = 0;
616 }
617
618 static void
bttyManageHistory(char * comm)619 bttyManageHistory(char *comm)
620 {
621 if (btty.flags & B_TTY_ALIASING)
622 return;
623 if ((strcmp(comm, btty.hist[1]) != 0) && (comm[0] != '\0'))
624 {
625 int i;
626 char *curr = btty.hist[50];
627
628 snprintf(btty.hist[0], btty.len, "%s", comm);
629 /* different history, cycle them and clean current */
630 for (i = 50; i > 0; i--)
631 btty.hist[i] = btty.hist[i - 1];
632 btty.hist[0] = curr;
633 memset(btty.hist[0], 0, B_TTY_LINE_LEN);
634 }
635 btty.hist_tmp = 0;
636 }
637
638 void
brightonCLIcleanup()639 brightonCLIcleanup()
640 {
641 if (btty.flags & B_TTY_SAVE_HIST)
642 {
643 btty.SYNTHS->location = 9999;
644 bttyMemSave(btty.global);
645 }
646 tcsetattr(btty.fd[0], TCSANOW, &resetattr);
647 }
648
649 void
brightonGetCLIcodes(int fd)650 brightonGetCLIcodes(int fd)
651 {
652 int i, n;
653
654 snprintf(pbuf, btty.len, "CLI: set history %i\n", btty.hist_c);
655 n = write(fd, pbuf, strlen(pbuf));
656
657 snprintf(pbuf, btty.len, "CLI: set line %i\n", btty.len);
658 n = write(fd, pbuf, strlen(pbuf));
659
660 snprintf(pbuf, btty.len, "CLI: set accel %f\n", btty.accel);
661 n = write(fd, pbuf, strlen(pbuf));
662
663 snprintf(pbuf, btty.len, "CLI: set prompttext \"%s\"\n", btty.promptText);
664 n = write(fd, pbuf, strlen(pbuf));
665
666 snprintf(pbuf, btty.len, "CLI: set cli cycle %i\n", btty.cycle);
667 n = write(fd, pbuf, strlen(pbuf));
668
669 if (btty.flags & B_TTY_DEBUG)
670 {
671 snprintf(pbuf, btty.len, "CLI: debug on\n");
672 n = write(fd, pbuf, strlen(pbuf));
673 }
674
675 snprintf(pbuf, btty.len, "CLI: set panel %i\n", btty.p);
676 n = write(fd, pbuf, strlen(pbuf));
677
678 for (i = 0; commands[i].map != -1; i++)
679 {
680 if (commands[i].map == B_COM_ALIAS)
681 {
682 snprintf(pbuf, btty.len, "CLI: set alias %s %s\n",
683 commands[i].name, commands[i].help);
684 n = write(fd, pbuf, strlen(pbuf));
685 }
686 }
687
688 for (i = 0; i < B_TTY_ACT_COUNT; i++)
689 {
690 if ((action[i].imap < 0) || (action[i].map == '\0'))
691 continue;
692
693 if (action[i].map < 26)
694 {
695 snprintf(pbuf, btty.len,
696 "CLI: set cli ^X %s\n", templates[action[i].imap].opname);
697 pbuf[14] = action[i].map + 96;
698 } else {
699 snprintf(pbuf, btty.len,
700 "CLI: set cli X %s\n", templates[action[i].imap].opname);
701 pbuf[13] = action[i].map;
702 }
703
704 n = write(fd, pbuf, strlen(pbuf));
705 }
706
707 if (btty.flags & B_TTY_SAVE_HIST)
708 {
709 snprintf(pbuf, btty.len, "CLI: set savehistory on\n");
710 n = write(fd, pbuf, strlen(pbuf));
711
712 for (i = 50; i >= 0; i--)
713 {
714 if (btty.hist[i][0] == '\0')
715 continue;
716 snprintf(pbuf, btty.len, "CLI: set history comm %s\n",
717 btty.hist[i]);
718 n = write(fd, pbuf, strlen(pbuf));
719 }
720 }
721
722 }
723
724 void
brightonSetCLIcode(char * input)725 brightonSetCLIcode(char *input)
726 {
727 int map, i, stuff = 0;
728 int act;
729 char c = input[0];
730 char *comm = &input[2];
731
732 if (btty.global == NULL)
733 return;
734
735 print("SetCLIcode");
736
737 if ((input[strlen(input) -1] == '\n')
738 || (input[strlen(input) -1] == '\r'))
739 input[strlen(input) -1] = '\0';
740
741 if (strncmp("set", input, 3) == 0)
742 {
743 snprintf(cbuf, btty.len, "%s", input);
744 bttyInterpret(btty.global, cbuf);
745 return;
746 }
747
748 if (c == '^')
749 {
750 c = input[1] - 96;
751 comm++;
752 }
753
754 print(comm);
755
756 for (act = 0; act < B_TTY_ACT_COUNT; act++)
757 {
758 /* return if we cannot find the action */
759 if (templates[act].imap == -1)
760 break;
761 if (templates[act].opname[0] == '\0')
762 break;
763 if (strcasecmp(comm, templates[act].opname) == 0)
764 {
765 stuff = act;
766 break;
767 }
768 }
769 if ((stuff) || (templates[act].imap == -1))
770 {
771 int i;
772
773 /*
774 * Search the ommmand table, add entry to templates
775 */
776 for (i = 0 ;
777 (commands[i].map != B_COM_LAST) && (i < B_TTY_ACT_COUNT);
778 i++)
779 {
780 if (strcasecmp(comm, commands[i].name) == 0)
781 {
782 /*
783 * Found a command.
784 */
785 if (templates[act].imap == -1)
786 {
787 templates[act + 1].imap = -1;
788 templates[act + 1].opname[0] = '\0';
789 }
790 templates[act].imap = act;
791 snprintf(templates[act].opname, 12, "%s", comm);
792 break;
793 }
794 }
795 }
796
797 print(templates[act].opname);
798
799 if (act >= B_TTY_ACT_COUNT)
800 return;
801
802 act = templates[act].imap;
803
804 for (map = 0; map < B_TTY_ACT_COUNT; map++)
805 {
806 if (action[map].map == '\0')
807 break;
808 if (action[map].map == c)
809 break;
810 }
811 if (map == B_TTY_ACT_COUNT)
812 return;
813
814 if (action[map].map == '\0')
815 {
816 action[map + 1].map = '\0';
817 action[map + 1].imap = B_COM_LAST;
818 }
819
820 action[map].map = c;
821 action[map].imap = act;
822
823 if (btty.flags & B_TTY_DEBUG)
824 {
825 if (input[0] == '^')
826 {
827 snprintf(pbuf, btty.len, "^X is %s\n\r", templates[act].opname);
828 pbuf[1] = c + 96;
829 } else {
830 snprintf(pbuf, btty.len, "X is %s %i %i\n\r", templates[act].opname,
831 map, action[map].imap);
832 pbuf[0] = action[map].map;
833 }
834 i = write(btty.fd[1], pbuf, strlen(pbuf));
835 }
836 }
837
838 static int
execHelpCheck(int c,char ** v)839 execHelpCheck(int c, char **v)
840 {
841 int i, j, n;
842
843 if ((c == 2) && (strncmp("help", v[1], strlen(v[1])) == 0))
844 {
845 for (i = 0; commands[i].map != B_COM_LAST; i++)
846 {
847 if (strncmp(commands[i].name, v[0], strlen(v[0])) == 0)
848 {
849 if (commands[i].subcom == 0)
850 {
851 snprintf(pbuf, B_TTY_LINE_LEN, "%12s: %s\n\r",
852 commands[i].name, commands[i].help);
853 n = write(btty.fd[1], pbuf, strlen(pbuf));
854 return(1);
855 } else {
856 for (j = 0; commands[i].subcom[j].map != B_COM_LAST; j++)
857 {
858 if ((commands[i].subcom[j].name[0] == '\0')
859 || (commands[i].subcom[j].help[0] == '\0'))
860 continue;
861 snprintf(pbuf, B_TTY_LINE_LEN, "%13s: %s\n\r",
862 commands[i].subcom[j].name,
863 commands[i].subcom[j].help);
864 n = write(btty.fd[1], pbuf, strlen(pbuf));
865 }
866 return(1);
867 }
868 }
869 }
870 }
871
872 return(0);
873 }
874
875 static int
isparam(int set,int comm,char * name)876 isparam(int set, int comm, char *name)
877 {
878 if (strncmp(commands[set].subcom[comm].name, name, strlen(name)) == 0)
879 return(1);
880 return(0);
881 }
882
883 static void
bttyMemSave(guimain * global)884 bttyMemSave(guimain *global)
885 {
886 int i;
887
888 SYNTHS->cmem = SYNTHS->lmem;
889 if (SYNTHS->saveMemory != NULL)
890 SYNTHS->saveMemory(SYNTHS,
891 RESOURCES->name, 0,
892 SYNTHS->location, 0);
893 else
894 saveMemory(SYNTHS, RESOURCES->name,
895 0, SYNTHS->location, 0);
896 if (btty.flags & B_TTY_DEBUG)
897 {
898 snprintf(pbuf, btty.len, "write: %i\n\r", SYNTHS->location);
899 i = write(btty.fd[1], pbuf, strlen(pbuf));
900 }
901 }
902
903 static void
bttyMemLoad(guimain * global)904 bttyMemLoad(guimain *global)
905 {
906 int i;
907
908 SYNTHS->lmem = SYNTHS->cmem;
909 if (SYNTHS->loadMemory != NULL)
910 SYNTHS->loadMemory(SYNTHS,
911 RESOURCES->name,
912 0, SYNTHS->location, SYNTHS->mem.active,
913 0, btty.fl);
914 else
915 loadMemory(SYNTHS, RESOURCES->name,
916 0, SYNTHS->location, SYNTHS->mem.active,
917 0, btty.fl);
918 SYNTHS->cmem = SYNTHS->location;
919
920 if (SYNTHS->location != 9999)
921 {
922 snprintf(pbuf, btty.len, "read: %i\r\n", SYNTHS->location);
923 i = write(btty.fd[1], pbuf, strlen(pbuf));
924 } else {
925 snprintf(pbuf, btty.len, "read: unread\r\n");
926 i = write(btty.fd[1], pbuf, strlen(pbuf));
927 }
928 }
929
930 static int
execMemory(guimain * global,int c,char ** argv)931 execMemory(guimain *global, int c, char **argv)
932 {
933 int n;
934
935 if (c == 1)
936 return(B_ERR_PARAM);
937
938 if (execHelpCheck(c, argv)) return(0);
939
940 if (c == 2)
941 {
942 /* <n> find, read, write */
943 if (isparam(B_COM_MEMORY, B_COM_FIND, argv[1]))
944 {
945 int location = SYNTHS->location + 1;
946 /* find mem */
947 while (loadMemory(SYNTHS, RESOURCES->name, 0,
948 location, SYNTHS->mem.active, 0, BRISTOL_STAT) != 0)
949 {
950 if (++location >= 1024)
951 location = 0;
952 if (location == SYNTHS->location)
953 break;
954 }
955 if (location != SYNTHS->location)
956 {
957 SYNTHS->location = location;
958 snprintf(pbuf, btty.len, "mem: %i\r\n", SYNTHS->location);
959 n = write(btty.fd[1], pbuf, strlen(pbuf));
960 } else {
961 snprintf(pbuf, btty.len, "no memories\r\n");
962 n = write(btty.fd[1], pbuf, strlen(pbuf));
963 }
964 return(B_ERR_OK);
965 }
966 if (isparam(B_COM_MEMORY, B_COM_READ, argv[1]))
967 {
968 bttyMemLoad(global);
969 return(B_ERR_OK);
970 }
971 if (isparam(B_COM_MEMORY, B_COM_WRITE, argv[1]))
972 {
973 bttyMemSave(global);
974 return(B_ERR_OK);
975 }
976 if (isdigit(argv[1][0]))
977 {
978 if ((n = atoi(argv[1])) < 0)
979 return(B_ERR_VALUE);
980 if (n > 1023)
981 return(B_ERR_VALUE);
982
983 SYNTHS->location = n;
984 return(B_ERR_OK);
985 }
986 return(B_ERR_PARAM);
987 }
988
989 if (c == 3)
990 {
991 /* find free, find read, read undo, read n, write n */
992 if (isparam(B_COM_MEMORY, B_COM_FIND, argv[1]))
993 {
994 if (strncmp("free", argv[2], strlen(argv[2])) == 0)
995 {
996 int location = SYNTHS->location + 1;
997 /* find mem */
998 while (loadMemory(SYNTHS, RESOURCES->name, 0,
999 location, SYNTHS->mem.active, 0, BRISTOL_STAT) == 0)
1000 {
1001 if (++location >= 1024)
1002 location = 0;
1003 if (location == SYNTHS->location)
1004 break;
1005 }
1006 if (location != SYNTHS->location)
1007 {
1008 SYNTHS->location = location;
1009 snprintf(pbuf, btty.len, "mem: %i\r\n", SYNTHS->location);
1010 n = write(btty.fd[1], pbuf, strlen(pbuf));
1011 } else {
1012 snprintf(pbuf, btty.len, "no memories\r\n");
1013 n = write(btty.fd[1], pbuf, strlen(pbuf));
1014 return(B_ERR_VALUE);
1015 }
1016 return(B_ERR_OK);
1017 }
1018 if ((strncmp("load", argv[2], strlen(argv[2])) == 0)
1019 ||(strncmp("read", argv[2], strlen(argv[2])) == 0))
1020 {
1021 int location = SYNTHS->location + 1;
1022 /* find mem */
1023 while (loadMemory(SYNTHS, RESOURCES->name, 0,
1024 location, SYNTHS->mem.active, 0, BRISTOL_STAT) != 0)
1025 {
1026 if (++location >= 1024)
1027 location = 0;
1028 if (location == SYNTHS->location)
1029 break;
1030 }
1031 if (location != SYNTHS->location)
1032 {
1033 SYNTHS->location = location;
1034 bttyMemLoad(global);
1035 return(B_ERR_OK);
1036 } else {
1037 snprintf(pbuf, btty.len, "no memories\r\n");
1038 n = write(btty.fd[1], pbuf, strlen(pbuf));
1039 return(B_ERR_VALUE);
1040 }
1041 }
1042 } else if (isparam(B_COM_MEMORY, B_COM_READ, argv[1])) {
1043 if (strncmp("undo", argv[2], strlen(argv[2])) == 0)
1044 {
1045 n = SYNTHS->location;
1046 SYNTHS->location = 9999;
1047 bttyMemLoad(global);
1048 SYNTHS->location = n;
1049 return(B_ERR_OK);
1050 }
1051
1052 if ((n = atoi(argv[2])) < 0)
1053 return(B_ERR_VALUE);
1054 if (n > 1023)
1055 return(B_ERR_VALUE);
1056
1057 SYNTHS->location = n;
1058 bttyMemLoad(global);
1059 return(B_ERR_OK);
1060 } else if (isparam(B_COM_MEMORY, B_COM_FORCE, argv[1])) {
1061 if (strcmp(argv[2], "on") == 0)
1062 {
1063 btty.fl = BRISTOL_FORCE;
1064 return(B_ERR_OK);
1065 } else if (strcmp(argv[2], "off") == 0) {
1066 btty.fl = 0;
1067 return(B_ERR_OK);
1068 }
1069 return(B_ERR_PARAM);
1070 } else if (isparam(B_COM_MEMORY, B_COM_WRITE, argv[1])) {
1071 if ((n = atoi(argv[2])) < 0)
1072 return(B_ERR_VALUE);
1073 if (n > 1023)
1074 return(B_ERR_VALUE);
1075
1076 SYNTHS->location = n;
1077 bttyMemSave(global);
1078 return(B_ERR_OK);
1079 }
1080 return(B_ERR_PARAM);
1081 }
1082
1083 if (c == 4)
1084 {
1085 int loc;
1086
1087 /* import, export */
1088 if (isparam(B_COM_MEMORY, B_COM_IMPORT, argv[1]))
1089 {
1090 loc = atoi(argv[3]);
1091 bristolMemoryImport(loc, argv[2], RESOURCES->name);
1092 return(B_ERR_OK);
1093 } else if (isparam(B_COM_MEMORY, B_COM_EXPORT, argv[1])) {
1094 loc = atoi(argv[2]);
1095 bristolMemoryExport(loc, argv[1], RESOURCES->name);
1096 return(B_ERR_OK);
1097 }
1098 return(B_ERR_PARAM);
1099 }
1100
1101 return(B_ERR_PARAM);
1102 }
1103
1104 static int
execCLI(guimain * global,int c,char ** argv)1105 execCLI(guimain *global, int c, char **argv)
1106 {
1107 int n;
1108
1109 if (c == 1)
1110 {
1111 int i;
1112
1113 snprintf(pbuf, btty.len, "cycle: %i\r\n", btty.cycle);
1114 n = write(btty.fd[1], pbuf, strlen(pbuf));
1115
1116 snprintf(pbuf, btty.len, "CLI <ESC> mode navigation keys:\n\r");
1117 n = write(btty.fd[1], pbuf, strlen(pbuf));
1118
1119 for (i = 0; action[i].imap != -1; i++)
1120 {
1121 snprintf(pbuf, btty.len, "%2i : %s\n\r",
1122 i,
1123 templates[action[i].imap].opname);
1124 if (action[i].map <= 27)
1125 {
1126 pbuf[3] = '^';
1127 pbuf[4] = action[i].map + 96;
1128 } else
1129 pbuf[4] = action[i].map;
1130 n = write(btty.fd[1], pbuf, strlen(pbuf));
1131 }
1132 return(0);
1133 }
1134
1135 if (c == 2)
1136 {
1137 if (strncmp("cycle", argv[1], strlen(argv[1])) == 0) {
1138 snprintf(pbuf, btty.len, "cycle: %i\r\n",
1139 btty.cycle);
1140 n = write(btty.fd[1], pbuf, strlen(pbuf));
1141 return(0);
1142 } else if (strncmp("listcommands", argv[1], strlen(argv[1])) == 0) {
1143 int i;
1144
1145 for (i = 0; templates[i].imap != -1; i++)
1146 {
1147 snprintf(pbuf, btty.len, " %s\n\r", templates[i].opname);
1148 n = write(btty.fd[1], pbuf, strlen(pbuf));
1149 }
1150 return(0);
1151 }
1152 }
1153
1154 if (c == 3)
1155 {
1156 if (strncmp("cycle", argv[1], strlen(argv[1])) == 0) {
1157 if ((btty.cycle = atoi(argv[2])) < 50)
1158 btty.cycle = 50;
1159 else if (btty.cycle > 1000)
1160 btty.cycle = 1000;
1161 snprintf(pbuf, btty.len, "cycle: %i\r\n",
1162 btty.cycle);
1163 n = write(btty.fd[1], pbuf, strlen(pbuf));
1164 } else {
1165 char comm[B_TTY_LINE_LEN];
1166 snprintf(comm, B_TTY_LINE_LEN, "%s %s\n", argv[1], argv[2]);
1167 print(comm);
1168 brightonSetCLIcode(comm);
1169 }
1170 return(0);
1171 }
1172 return(2);
1173 }
1174
1175 static int
execAlias(guimain * global,int c,char ** argv)1176 execAlias(guimain *global, int c, char **argv)
1177 {
1178 char *comm, alias[B_TTY_LINE_LEN];
1179 int i;
1180
1181 print("execAlias");
1182
1183 if ((c == 1) && (strncmp(argv[0], "alias", strlen(argv[0])) == 0))
1184 {
1185 int n;
1186 for (i = 0; commands[i].map != B_COM_LAST; i++)
1187 {
1188 if (commands[i].map == B_COM_ALIAS)
1189 {
1190 snprintf(pbuf, B_TTY_LINE_LEN, "%12s: %s\n\r",
1191 commands[i].name, commands[i].help);
1192 n = write(btty.fd[1], pbuf, strlen(pbuf));
1193 }
1194 }
1195 return(0);
1196 }
1197
1198 /*
1199 * Two calls, one with the actual 'alias' token, if not we should search
1200 * the alias list.
1201 */
1202 if (strncmp("alias", argv[0], strlen(argv[0])) == 0)
1203 {
1204 if (c < 3)
1205 return(2);
1206 /*
1207 * the alias is in our cbuf, we just have to find it.
1208 */
1209 if (cbuf[0] == 's')
1210 {
1211 if ((comm = index(cbuf, ' ')) == NULL)
1212 return(3);
1213 comm++;
1214 if ((comm = index(comm, ' ')) == NULL)
1215 return(3);
1216 comm++;
1217 if ((comm = index(comm, ' ')) == NULL)
1218 return(3);
1219 comm++;
1220 if (comm[0] == '\0')
1221 return(3);
1222 snprintf(alias, btty.len, "%s", comm);
1223 } else if (cbuf[0] == 'a') {
1224 if ((comm = index(cbuf, ' ')) == NULL)
1225 return(3);
1226 comm++;
1227 if ((comm = index(comm, ' ')) == NULL)
1228 return(3);
1229 comm++;
1230 if (comm[0] == '\0')
1231 return(3);
1232 snprintf(alias, btty.len, "%s", comm);
1233 } else
1234 return(2);
1235
1236 comm = argv[1];
1237 if (strncmp(comm, alias, strlen(comm)) == 0)
1238 {
1239 print("cannot apply alias: recursive");
1240 return(2);
1241 }
1242
1243 /* Find free command */
1244 for (i = 0; commands[i].map != -1; i++)
1245 {
1246 if (i == (B_TTY_ACT_COUNT - 1))
1247 {
1248 snprintf(pbuf, btty.len, "command table full\r\n");
1249 i = write(btty.fd[1], pbuf, strlen(pbuf));
1250 return(4);
1251 }
1252
1253 if (strcmp(commands[i].name, comm) == 0)
1254 {
1255 if (commands[i].map != B_COM_ALIAS)
1256 {
1257 print("cannot apply alias: name in use");
1258 return(2);
1259 }
1260 print("remapping alias");
1261 snprintf(commands[i].name, 11, "%s", comm);
1262 snprintf(commands[i].help, B_TTY_LINE_LEN, "%s", alias);
1263 commands[i].exec = execAlias;
1264 return(0);
1265 }
1266 if (commands[i].map == B_COM_FREE)
1267 break;
1268 }
1269
1270 print(comm);
1271 print(alias);
1272
1273 /* Flag next entry as last */
1274 if (commands[i].map != B_COM_FREE)
1275 {
1276 commands[i + 1].name[0] = '\0';
1277 commands[i + 1].map = B_COM_LAST;
1278 }
1279
1280 snprintf(commands[i].name, 11, "%s", comm);
1281 snprintf(commands[i].help, B_TTY_LINE_LEN, "%s", alias);
1282 commands[i].map = B_COM_ALIAS;
1283 commands[i].exec = execAlias;
1284 return(0);
1285 } else {
1286 int j = 1, k = 0;
1287
1288 print("searchAlias");
1289
1290 /*
1291 * Build a new command line and exec it. Find the alias, take it's
1292 * help line, copy over byte by byte to cbuf, replace each % with
1293 * increasing argv (if we have enough)
1294 */
1295 for (i = 0; commands[i].map != -1; i++)
1296 {
1297 if (strncmp(argv[0], commands[i].name, strlen(argv[0])) == 0)
1298 break;
1299 }
1300 if (commands[i].map != B_COM_ALIAS)
1301 return(B_ERR_PARAM);
1302 comm = commands[i].help;
1303
1304 print(comm);
1305
1306 btty.flags |= B_TTY_ALIASING;
1307 for (i = 0; comm[i] != '\0'; i++)
1308 {
1309 if (comm[i] == '$')
1310 {
1311 int l, m;
1312
1313 i++;
1314
1315 if (((m = atoi(&comm[i])) < 1) || (m >= c))
1316 {
1317 print("alias failed: too few arguments");
1318 btty.flags &= ~B_TTY_ALIASING;
1319 return(B_ERR_INV_ARG);
1320 }
1321 for (l = 0; argv[m][l] != '\0'; l++)
1322 alias[k++] = argv[m][l];
1323 }
1324 if (comm[i] == '%')
1325 {
1326 int l;
1327
1328 if (j == c)
1329 {
1330 print("alias failed: too few arguments");
1331 btty.flags &= ~B_TTY_ALIASING;
1332 return(B_ERR_INV_ARG);
1333 }
1334 for (l = 0; argv[j][l] != '\0'; l++)
1335 alias[k++] = argv[j][l];
1336 if (comm[i] == '%')
1337 j++;
1338 i++;
1339 }
1340 if (comm[i] == ';')
1341 {
1342 alias[k] = '\0';
1343 print(alias);
1344 bttyInterpret(global, alias);
1345 memset(alias, 0, B_TTY_LINE_LEN);
1346 k = 0;
1347 } else
1348 alias[k++] = comm[i];
1349 }
1350 alias[k++] = '\0';
1351 print(alias);
1352 bttyInterpret(global, alias);
1353 btty.flags &= ~B_TTY_ALIASING;
1354 return(0);
1355 }
1356 return(2);
1357 }
1358
1359 /*
1360 * controller c o v - very expert usage.
1361 */
1362 static int
execBristol(guimain * global,int c,char ** argv)1363 execBristol(guimain *global, int c, char **argv)
1364 {
1365 int o, p;
1366 float v;
1367
1368 print("execBristol");
1369
1370 if (execHelpCheck(c, argv)) return(0);
1371
1372 if (c == 2)
1373 {
1374 if (strncmp(bristolcom[1].name, argv[1], strlen(argv[1])) == 0)
1375 {
1376 snprintf(pbuf, btty.len, "register request %i %p\n\r",
1377 btty.i, DEVICE(btty.i).dev);
1378 o = write(btty.fd[1], pbuf, strlen(pbuf));
1379 brightonRegisterController((brightonDevice *)
1380 DEVICE(btty.i).dev);
1381 return(0);
1382 }
1383 }
1384
1385 if (c == 5)
1386 {
1387 if (strncmp(bristolcom[2].name, argv[1], strlen(argv[1])) == 0)
1388 {
1389 int sid;
1390
1391 if ((o = atoi(argv[2])) < 0) return(3); if (o > 127) return(3);
1392 if ((p = atoi(argv[3])) < 0) return(3); if (p > 127) return(3);
1393 if ((v = atof(argv[4])) < 0.0f) return(3); if (v > 1.0f) return(3);
1394
1395 if (btty.ichan == 0)
1396 sid = SYNTHS->sid;
1397 else
1398 sid = SYNTHS->sid2;
1399 bristolMidiSendMsg(global->controlfd, btty.ichan,
1400 o, p, (int) (v * C_RANGE_MIN_1));
1401 return(0);
1402 }
1403 }
1404
1405 return(B_ERR_PARAM);
1406 }
1407
1408 extern int bristolPressureEvent(int, int, int, int);
1409 extern int bristolPolyPressureEvent(int, int, int, int, int);
1410
1411 /*
1412 * This is probably going to become a large part of the interface, it can give
1413 * access to loads of stuff that many of the GUI may not use because there was
1414 * no other way to control them.
1415 *
1416 * midi channel 1..16
1417 * midi debug 0..3
1418 * midi lowkey|highkey 0..127
1419 * midi filters lwf|nwf|wwf|hwf
1420 * midi notepref hnp|lnp|nnp
1421 * midi velocity 1..1000
1422 * midi chanpressure 0..127
1423 * midi polypressure 0..127 0..127
1424 * midi detune 0..500
1425 * midi glide 0..30
1426 * midi legato on/off
1427 * midi trig on/off
1428 * midi gain 1..
1429 * midi pwd 0..
1430 * midi nrp on/off
1431 * midi forwarding on/off
1432 * midi tuning fine 0..1.0
1433 * midi tuning coarse 0..1.0
1434 * midi panic
1435 */
1436 static int
execMidi(guimain * global,int c,char ** v)1437 execMidi(guimain *global, int c, char **v)
1438 {
1439 int i, n, k;
1440
1441 if (execHelpCheck(c, v)) return(0);
1442 //if (midiHelpCheck(c, v)) return(0);
1443
1444 for (i = 0; i < c; i++)
1445 print(v[i]);
1446
1447 if (c == 1)
1448 {
1449 snprintf(pbuf, btty.len, "MIDI channel: %i\r\n",
1450 SYNTHS->midichannel+1);
1451 i = write(btty.fd[1], pbuf, strlen(pbuf));
1452 snprintf(pbuf, btty.len, "SID channel: %i\r\n",
1453 btty.ichan);
1454 i = write(btty.fd[1], pbuf, strlen(pbuf));
1455 snprintf(pbuf, btty.len, "MIDI debug: %i\r\n",
1456 btty.mdbg);
1457 i = write(btty.fd[1], pbuf, strlen(pbuf));
1458 snprintf(pbuf, btty.len, "MIDI lowkey %i\r\n",
1459 btty.lowkey);
1460 i = write(btty.fd[1], pbuf, strlen(pbuf));
1461 snprintf(pbuf, btty.len, "MIDI highkey: %i\r\n",
1462 btty.highkey);
1463 i = write(btty.fd[1], pbuf, strlen(pbuf));
1464 return(B_ERR_OK);
1465 }
1466
1467 if (c == 4)
1468 {
1469 if (strncmp("tuning", v[1], strlen(v[1])) == 0)
1470 {
1471 float tune = 0.5;
1472 if (strncmp("fine", v[2], strlen(v[2])) == 0)
1473 {
1474 i = MIDI_RP_FINETUNE;
1475
1476 if ((tune = atof(v[3])) < 0.0f) return(3);
1477 if (tune > 1.0f) return(3);
1478 } else if (strncmp("coarse", v[2], strlen(v[3])) == 0) {
1479 i = MIDI_RP_COARSETUNE;
1480
1481 if ((tune = atof(v[3])) < 0.0f) return(3);
1482 if (tune > 1.0f) return(3);
1483 }
1484 tune *= C_RANGE_MIN_1;
1485 bristolMidiSendNRP(global->controlfd, SYNTHS->midichannel, i, tune);
1486 return(B_ERR_OK);
1487 }
1488 if (strncmp("polypressure", v[1], strlen(v[1])) == 0)
1489 {
1490 int k, p;
1491
1492 if ((k = atoi(v[2])) < 0) return(3); if (k > 127) return(3);
1493 if ((p = atoi(v[3])) < 0) return(3); if (p > 127) return(3);
1494
1495 bristolPolyPressureEvent(global->controlfd, 0, SYNTHS->midichannel,
1496 k, p);
1497
1498 return(B_ERR_OK);
1499 }
1500 if (strncmp("controller", v[1], strlen(v[1])) == 0)
1501 {
1502 int id, value;
1503
1504 if ((id = atoi(v[2])) < 0) return(B_ERR_VALUE);
1505 if (id > 127) return(B_ERR_VALUE);
1506 if ((value = atoi(v[3])) < 0) return(B_ERR_VALUE);
1507 if (value > 127) return(B_ERR_VALUE);
1508 bristolMidiSendControlMsg(global->controlfd,
1509 SYNTHS->midichannel, id, value);
1510 return(B_ERR_OK);
1511 }
1512 return(B_ERR_PARAM);
1513 }
1514
1515 if (c == 2)
1516 {
1517 if (strncmp(v[1], "panic", strlen(v[1])) == 0) {
1518 bristolMidiSendMsg(global->controlfd, SYNTHS->sid2, 127, 0,
1519 BRISTOL_ALL_NOTES_OFF);
1520 bristolMidiSendMsg(global->controlfd, SYNTHS->sid, 127, 0,
1521 BRISTOL_ALL_NOTES_OFF);
1522 return(B_ERR_OK);
1523 } else if (strncmp(v[1], "sid", strlen(v[1])) == 0) {
1524 snprintf(pbuf, btty.len, "SID channel : %i\r\n",
1525 btty.ichan);
1526 i = write(btty.fd[1], pbuf, strlen(pbuf));
1527 return(B_ERR_OK);
1528 } else if (strncmp(v[1], "channel", strlen(v[1])) == 0) {
1529 snprintf(pbuf, btty.len, "MIDI channel: %i\r\n",
1530 SYNTHS->midichannel+1);
1531 i = write(btty.fd[1], pbuf, strlen(pbuf));
1532 return(B_ERR_OK);
1533 } else if (strncmp(v[1], "debug", strlen(v[1])) == 0) {
1534 snprintf(pbuf, btty.len, "MIDI debug: %i\r\n",
1535 btty.mdbg);
1536 i = write(btty.fd[1], pbuf, strlen(pbuf));
1537 return(B_ERR_OK);
1538 }
1539 return(B_ERR_PARAM);
1540 }
1541
1542 if (c == 3)
1543 {
1544 if (strncmp(v[1], "sid", strlen(v[1])) == 0) {
1545 if ((n = atoi(v[2])) < 1)
1546 n = 0;
1547 else
1548 n = 1;
1549 btty.ichan = n;
1550 snprintf(pbuf, btty.len, "SID channel: %i\r\n", btty.ichan);
1551 i = write(btty.fd[1], pbuf, strlen(pbuf));
1552 return(B_ERR_OK);
1553 } else if (strncmp(v[1], "charpressure", strlen(v[1])) == 0) {
1554 if ((n = atoi(v[2])) < 0) return(B_ERR_VALUE);
1555 if (n > 127) return(B_ERR_VALUE);
1556
1557 bristolPressureEvent(global->controlfd, 0, SYNTHS->midichannel, n);
1558 return(B_ERR_OK);
1559 } else if (strncmp(v[1], "channel", strlen(v[1])) == 0) {
1560 if ((n = atoi(v[2])) < 1)
1561 return(3);
1562 else if (n > 16)
1563 return(3);
1564 SYNTHS->midichannel = n - 1;
1565 snprintf(pbuf, btty.len, "MIDI channel: %i\r\n",
1566 SYNTHS->midichannel+1);
1567 i = write(btty.fd[1], pbuf, strlen(pbuf));
1568
1569 SYNTHS->midichannel = SYNTHS->midichannel;
1570 if (global->libtest == 0)
1571 bristolMidiSendMsg(global->controlfd, SYNTHS->sid,
1572 127, 0, BRISTOL_MIDICHANNEL|SYNTHS->midichannel);
1573 if ((k = atoi(v[2])) < 0) return(3); if (k > 127) return(3);
1574
1575 SYNTHS->highkey = btty.highkey = k;
1576
1577 bristolMidiSendMsg(global->controlfd, SYNTHS->sid, 127, 0,
1578 BRISTOL_HIGHKEY|SYNTHS->highkey);
1579 return(B_ERR_OK);
1580 } else if (strncmp(v[1], "lowkey", strlen(v[1])) == 0) {
1581 if ((k = atoi(v[2])) < 0) return(3); if (k > 127) return(3);
1582
1583 SYNTHS->lowkey = btty.lowkey = k;
1584
1585 bristolMidiSendMsg(global->controlfd, SYNTHS->sid, 127, 0,
1586 BRISTOL_LOWKEY|SYNTHS->lowkey);
1587 return(B_ERR_OK);
1588 } else if (strncmp(v[1], "filter", strlen(v[1])) == 0) {
1589 k = 0;
1590 if (strcmp(v[2], "lwf") == 0) k = 1;
1591 else if (strcmp(v[2], "nwf") == 0) k = 0;
1592 else if (strcmp(v[2], "wwf") == 0) k = 2;
1593 else if (strcmp(v[2], "hwf") == 0) k = 3;
1594 else return(B_ERR_INV_ARG);
1595 bristolMidiSendNRP(global->controlfd, SYNTHS->midichannel,
1596 BRISTOL_NRP_LWF, k);
1597 return(B_ERR_OK);
1598 } else if (strncmp(v[1], "detune", strlen(v[1])) == 0) {
1599 if ((k = atoi(v[2])) < 0) return(3); if (k > 16383) return(3);
1600 bristolMidiSendNRP(global->controlfd, SYNTHS->midichannel,
1601 BRISTOL_NRP_DETUNE, k);
1602 return(B_ERR_OK);
1603 } else if (strncmp(v[1], "velocity", strlen(v[1])) == 0) {
1604 if ((k = atoi(v[2])) < 0) return(3); if (k > 16383) return(3);
1605 bristolMidiSendNRP(global->controlfd, SYNTHS->midichannel,
1606 BRISTOL_NRP_VELOCITY, k);
1607 return(B_ERR_OK);
1608 } else if (strncmp(v[1], "glide", strlen(v[1])) == 0) {
1609 if ((k = atoi(v[2])) < 0) return(3); if (k > 16383) return(3);
1610 bristolMidiSendNRP(global->controlfd, SYNTHS->midichannel,
1611 BRISTOL_NRP_GLIDE, k);
1612 return(B_ERR_OK);
1613 } else if (strncmp(v[1], "pwd", strlen(v[1])) == 0) {
1614 if ((k = atoi(v[2])) < 0) return(3); if (k > 16383) return(3);
1615 bristolMidiSendNRP(global->controlfd, SYNTHS->midichannel,
1616 MIDI_RP_PW, k);
1617 return(B_ERR_OK);
1618 } else if (strncmp(v[1], "gain", strlen(v[1])) == 0) {
1619 if ((k = atoi(v[2])) < 0) return(3); if (k > 16383) return(3);
1620 bristolMidiSendNRP(global->controlfd, SYNTHS->midichannel,
1621 BRISTOL_NRP_GAIN, k);
1622 return(B_ERR_OK);
1623 } else if (strncmp(v[1], "forwarding", strlen(v[1])) == 0) {
1624 k = 1;
1625 if (strcmp(v[2], "on") == 0) k = 1;
1626 if (strcmp(v[2], "off") == 0) k = 0;
1627 bristolMidiSendNRP(global->controlfd, SYNTHS->midichannel,
1628 BRISTOL_NRP_FORWARD, k);
1629 return(B_ERR_OK);
1630 } else if (strncmp(v[1], "nrp", strlen(v[1])) == 0) {
1631 if (strcmp(v[2], "on") == 0)
1632 SYNTHS->flags |= GUI_NRP;
1633 else if (strcmp(v[2], "off") == 0)
1634 SYNTHS->flags &= ~GUI_NRP;
1635 return(B_ERR_OK);
1636 } else if (strncmp(v[1], "enginenrp", strlen(v[1])) == 0) {
1637 k = 0;
1638 if (strcmp(v[2], "on") == 0) k = 1;
1639 if (strcmp(v[2], "off") == 0) k = 0;
1640 bristolMidiSendNRP(global->controlfd, SYNTHS->midichannel,
1641 BRISTOL_NRP_ENABLE_NRP, k);
1642 return(B_ERR_OK);
1643 } else if (strncmp(v[1], "legato", strlen(v[1])) == 0) {
1644 k = 1;
1645 if (strcmp(v[2], "on") == 0) k = 1;
1646 if (strcmp(v[2], "off") == 0) k = 0;
1647 bristolMidiSendNRP(global->controlfd, SYNTHS->midichannel,
1648 BRISTOL_NRP_MNL_VELOC, k);
1649 return(B_ERR_OK);
1650 } else if (strncmp(v[1], "trigger", strlen(v[1])) == 0) {
1651 k = 1;
1652 if (strcmp(v[2], "on") == 0) k = 1;
1653 if (strcmp(v[2], "off") == 0) k = 0;
1654 bristolMidiSendNRP(global->controlfd, SYNTHS->midichannel,
1655 BRISTOL_NRP_MNL_TRIG, k);
1656 return(B_ERR_OK);
1657 } else if (strncmp(v[1], "precedence", strlen(v[1])) == 0) {
1658 k = BRIGHTON_LNP;
1659 if (strcmp(v[2], "hnp") == 0) k = BRIGHTON_HNP;
1660 if (strcmp(v[2], "lnp") == 0) k = BRIGHTON_LNP;
1661 if (strcmp(v[2], "nnp") == 0) k = BRIGHTON_POLYPHONIC;
1662 bristolMidiSendNRP(global->controlfd, SYNTHS->midichannel,
1663 BRISTOL_NRP_MNL_PREF, k);
1664 return(B_ERR_OK);
1665 } else if (strncmp(v[1], "debug", strlen(v[1])) == 0) {
1666 n = atoi(v[2]);
1667
1668 switch (n) {
1669 default:
1670 case 0:
1671 n = 0;
1672 break;
1673 case 1:
1674 break;
1675 case 2:
1676 break;
1677 case 3:
1678 break;
1679 }
1680 btty.mdbg = n;
1681 if (global->libtest == 0)
1682 bristolMidiSendNRP(global->controlfd, SYNTHS->midichannel,
1683 BRISTOL_NRP_DEBUG, n);
1684 snprintf(pbuf, btty.len, "MIDI debug: %i\r\n",
1685 btty.mdbg);
1686 i = write(btty.fd[1], pbuf, strlen(pbuf));
1687 return(B_ERR_OK);
1688 }
1689 return(B_ERR_PARAM);
1690 }
1691
1692 return(B_ERR_PARAM);
1693 }
1694
1695 /*
1696 * Set line width. Set debug on/off.
1697 */
1698 static int
execSet(guimain * global,int c,char ** v)1699 execSet(guimain *global, int c, char **v)
1700 {
1701 int i, n;
1702
1703 if (execHelpCheck(c, v)) return(0);
1704
1705 for (i = 0; i < c; i++)
1706 print(v[i]);
1707
1708 if (c > 1)
1709 {
1710 if (strncmp("memory", v[1], strlen(v[1])) == 0)
1711 return(execMemory(global, c - 1, v += 1));
1712 if (strncmp("midi", v[1], strlen(v[1])) == 0)
1713 return(execMidi(global, c - 1, v += 1));
1714 if (strncmp("debug", v[1], strlen(v[1])) == 0)
1715 return(execDebug(global, c - 1, v += 1));
1716 if (strncmp("bristol", v[1], strlen(v[1])) == 0)
1717 return(execBristol(global, c - 1, v += 1));
1718 if (strncmp("control", v[1], strlen(v[1])) == 0)
1719 return(execBristol(global, c - 1, v += 1));
1720 if (strncmp("brighton", v[1], strlen(v[1])) == 0)
1721 return(execBrighton(global, c - 1, v += 1));
1722 if (strncmp("alias", v[1], strlen(v[1])) == 0)
1723 return(execAlias(global, c - 1, v += 1));
1724 if (strncmp("cli", v[1], strlen(v[1])) == 0)
1725 return(execCLI(global, c - 1, v += 1));
1726 }
1727
1728
1729 if (c == 1)
1730 {
1731 snprintf(pbuf, btty.len, "line width: %i\r\n",
1732 btty.len);
1733 i = write(btty.fd[1], pbuf, strlen(pbuf));
1734 snprintf(pbuf, btty.len, "history: %i\r\n",
1735 btty.hist_c);
1736 i = write(btty.fd[1], pbuf, strlen(pbuf));
1737 if (btty.flags & B_TTY_SAVE_HIST)
1738 snprintf(pbuf, btty.len, "savehistory: on\r\n");
1739 else
1740 snprintf(pbuf, btty.len, "savehistory: off\r\n");
1741 i = write(btty.fd[1], pbuf, strlen(pbuf));
1742
1743 snprintf(pbuf, btty.len, "prompt: %s\r\n",
1744 btty.prompt);
1745 i = write(btty.fd[1], pbuf, strlen(pbuf));
1746
1747 snprintf(pbuf, btty.len, "prompttext: %s\r\n",
1748 btty.promptText);
1749 i = write(btty.fd[1], pbuf, strlen(pbuf));
1750
1751 snprintf(pbuf, btty.len, "accelerator: %0.3f\r\n",
1752 btty.accel);
1753 i = write(btty.fd[1], pbuf, strlen(pbuf));
1754
1755 snprintf(pbuf, btty.len, "active panel: %i\r\n",
1756 btty.p);
1757 i = write(btty.fd[1], pbuf, strlen(pbuf));
1758
1759 if (btty.flags & B_TTY_DEBUG)
1760 snprintf(pbuf, btty.len, "debug (cli): on\r\n");
1761 else
1762 snprintf(pbuf, btty.len, "debug (cli): off\r\n");
1763 i = write(btty.fd[1], pbuf, strlen(pbuf));
1764 if (btty.flags & B_TTY_AWV)
1765 snprintf(pbuf, btty.len, "access withdrawn var on\r\n");
1766 else
1767 snprintf(pbuf, btty.len, "access withdrawn var off\r\n");
1768 i = write(btty.fd[1], pbuf, strlen(pbuf));
1769 if (btty.flags & B_TTY_AUV)
1770 snprintf(pbuf, btty.len, "access unnamed var on\r\n");
1771 else
1772 snprintf(pbuf, btty.len, "access unnamed var off\r\n");
1773 i = write(btty.fd[1], pbuf, strlen(pbuf));
1774 return(B_ERR_OK);
1775 }
1776
1777 if (c == 2)
1778 {
1779 if (strncmp(v[1], "line", strlen(v[1])) == 0)
1780 {
1781 snprintf(pbuf, btty.len, "line width: %i\r\n",
1782 btty.len);
1783 i = write(btty.fd[1], pbuf, strlen(pbuf));
1784 return(B_ERR_OK);
1785 } else if (strncmp(v[1], "prompt", strlen(v[1])) == 0) {
1786 snprintf(pbuf, btty.len, "prompt: %s\r\n",
1787 btty.prompt);
1788 i = write(btty.fd[1], pbuf, strlen(pbuf));
1789 return(B_ERR_OK);
1790 } else if (strncmp(v[1], "prompttext", strlen(v[1])) == 0) {
1791 snprintf(pbuf, btty.len, "prompttext: %s\r\n",
1792 btty.promptText);
1793 i = write(btty.fd[1], pbuf, strlen(pbuf));
1794 return(B_ERR_OK);
1795 } else if (strncmp(v[1], "panel", strlen(v[1])) == 0) {
1796 snprintf(pbuf, btty.len, "active panel: %i\r\n",
1797 btty.p);
1798 i = write(btty.fd[1], pbuf, strlen(pbuf));
1799 return(B_ERR_OK);
1800 } else if (strncmp(v[1], "accelerator", strlen(v[1])) == 0) {
1801 snprintf(pbuf, btty.len, "accelerator: %0.3f\r\n",
1802 btty.accel);
1803 i = write(btty.fd[1], pbuf, strlen(pbuf));
1804 return(B_ERR_OK);
1805 } else if (strncmp(v[1], "awv", strlen(v[1])) == 0) {
1806 if (btty.flags & B_TTY_AWV)
1807 snprintf(pbuf, btty.len, "access withdrawn var on\r\n");
1808 else
1809 snprintf(pbuf, btty.len, "access withdrawn var off\r\n");
1810 return(B_ERR_OK);
1811 } else if (strncmp(v[1], "prompt", strlen(v[1])) == 0) {
1812 snprintf(pbuf, btty.len, "prompt: %s\r\n",
1813 btty.prompt);
1814 i = write(btty.fd[1], pbuf, strlen(pbuf));
1815 return(B_ERR_OK);
1816 } else if (strncmp(v[1], "prompttext", strlen(v[1])) == 0) {
1817 snprintf(pbuf, btty.len, "prompttext: %s\r\n",
1818 btty.promptText);
1819 i = write(btty.fd[1], pbuf, strlen(pbuf));
1820 return(B_ERR_OK);
1821 } else if (strncmp(v[1], "panel", strlen(v[1])) == 0) {
1822 snprintf(pbuf, btty.len, "active panel: %i\r\n",
1823 btty.p);
1824 i = write(btty.fd[1], pbuf, strlen(pbuf));
1825 return(B_ERR_OK);
1826 } else if (strncmp(v[1], "accelerator", strlen(v[1])) == 0) {
1827 snprintf(pbuf, btty.len, "accelerator: %0.3f\r\n",
1828 btty.accel);
1829 i = write(btty.fd[1], pbuf, strlen(pbuf));
1830 return(B_ERR_OK);
1831 } else if (strncmp(v[1], "awv", strlen(v[1])) == 0) {
1832 if (btty.flags & B_TTY_AWV)
1833 snprintf(pbuf, btty.len, "access withdrawn var on\r\n");
1834 else
1835 snprintf(pbuf, btty.len, "access withdrawn var off\r\n");
1836 i = write(btty.fd[1], pbuf, strlen(pbuf));
1837 return(B_ERR_OK);
1838 } else if (strncmp(v[1], "debug", strlen(v[1])) == 0) {
1839 if (btty.flags & B_TTY_DEBUG)
1840 snprintf(pbuf, btty.len, "debug (cli): on\r\n");
1841 else
1842 snprintf(pbuf, btty.len, "debug (cli): off\r\n");
1843 i = write(btty.fd[1], pbuf, strlen(pbuf));
1844 return(B_ERR_OK);
1845 } else if (strncmp(v[1], "save", strlen(v[1])) == 0) {
1846 snprintf(pbuf, btty.len, "save set not implemented\r\n");
1847 i = write(btty.fd[1], pbuf, strlen(pbuf));
1848 return(B_ERR_OK);
1849 } else if (strncmp(v[1], "savehistory", strlen(v[1])) == 0) {
1850 if (btty.flags & B_TTY_SAVE_HIST)
1851 snprintf(pbuf, btty.len, "savehistory: on\r\n");
1852 else
1853 snprintf(pbuf, btty.len, "savehistory: off\r\n");
1854 i = write(btty.fd[1], pbuf, strlen(pbuf));
1855 return(B_ERR_OK);
1856 } else if (strncmp(v[1], "history", strlen(v[1])) == 0) {
1857 for (i = btty.hist_c; i > 0; i--)
1858 {
1859 if (btty.hist[i][0] != '\0')
1860 {
1861 snprintf(pbuf, btty.len, "%i %s\r\n", i, btty.hist[i]);
1862 n = write(btty.fd[1], pbuf, strlen(pbuf));
1863 }
1864 }
1865 return(B_ERR_OK);
1866 }
1867 return(2);
1868 }
1869
1870 if (c == 3)
1871 {
1872 if (strncmp(v[1], "line", strlen(v[1])) == 0)
1873 {
1874 if ((n = atoi(v[2])) < 0)
1875 return(3);
1876 else if (n > B_TTY_LINE_LEN)
1877 return(3);
1878 else
1879 btty.len = n;
1880 snprintf(pbuf, btty.len, "line width: %i\r\n",
1881 btty.len);
1882 i = write(btty.fd[1], pbuf, strlen(pbuf));
1883 return(B_ERR_OK);
1884 } else if (strncmp(v[1], "prompttext", strlen(v[1])) == 0) {
1885 snprintf(btty.promptText, 64, "%s", v[2]);
1886 snprintf(pbuf, btty.len, "prompttext: %s\r\n",
1887 btty.promptText);
1888 i = write(btty.fd[1], pbuf, strlen(pbuf));
1889 return(B_ERR_OK);
1890 } else if (strncmp(v[1], "play", strlen(v[1])) == 0) {
1891 if (strncmp(v[2], "mode", strlen(v[2])) == 0) {
1892 btty.flags &= ~B_TTY_MMASK;
1893 btty.flags |= B_TTY_PLAY;
1894 snprintf(pbuf, btty.len,
1895 "Play mode: type ':' or <ESC> to exit\n\r");
1896 i = write(btty.fd[1], pbuf, strlen(pbuf));
1897 return(B_ERR_EARLY);
1898 }
1899 } else if (strncmp(v[1], "accelerator", strlen(v[1])) == 0) {
1900 btty.accel = atof(v[2]);
1901 snprintf(pbuf, btty.len, "accelerator: %0.3f\r\n",
1902 btty.accel);
1903 i = write(btty.fd[1], pbuf, strlen(pbuf));
1904 return(B_ERR_OK);
1905 } else if (strncmp(v[1], "panel", strlen(v[1])) == 0) {
1906 int x = -1;
1907 if ((x = atoi(v[2])) < 0)
1908 x = -1;
1909 if (x >= SYNTHS->win->app->nresources)
1910 x = -1;
1911 if (SYNTHS->win->app->resources[x].ndevices == 0)
1912 x = -1;
1913 if (SYNTHS->win->app->resources[x].devlocn == NULL)
1914 x = -1;
1915 if (x >= 0)
1916 {
1917 btty.p = x;
1918 if (btty.i >= SYNTHS->win->app->resources[x].ndevices)
1919 btty.i = SYNTHS->win->app->resources[x].ndevices - 1;
1920 }
1921 else
1922 return(3);
1923 snprintf(pbuf, btty.len, "active panel: %i\r\n",
1924 btty.p);
1925 i = write(btty.fd[1], pbuf, strlen(pbuf));
1926 return(B_ERR_OK);
1927 } else if (strncmp(v[1], "auv", strlen(v[1])) == 0) {
1928 btty.flags &= ~B_TTY_AUV;
1929 if (strcmp("on", v[2]) == 0)
1930 btty.flags |= B_TTY_AWV;
1931 if (btty.flags & B_TTY_AWV)
1932 snprintf(pbuf, btty.len, "access unnamed var on\r\n");
1933 else
1934 snprintf(pbuf, btty.len, "access unnamed var off\r\n");
1935 i = write(btty.fd[1], pbuf, strlen(pbuf));
1936 return(B_ERR_OK);
1937 } else if (strncmp(v[1], "awv", strlen(v[1])) == 0) {
1938 btty.flags &= ~B_TTY_AWV;
1939 if (strcmp("on", v[2]) == 0)
1940 btty.flags |= B_TTY_AWV;
1941 if (btty.flags & B_TTY_AWV)
1942 snprintf(pbuf, btty.len, "access withdrawn var on\r\n");
1943 else
1944 snprintf(pbuf, btty.len, "access withdrawn var off\r\n");
1945 i = write(btty.fd[1], pbuf, strlen(pbuf));
1946 return(B_ERR_OK);
1947 } else if (strncmp(v[1], "savehistory", strlen(v[1])) == 0) {
1948 if (strcmp(v[2], "on") == 0)
1949 btty.flags |= B_TTY_SAVE_HIST;
1950 else if (strcmp(v[2], "off") == 0)
1951 btty.flags &= ~B_TTY_SAVE_HIST;
1952 if (btty.flags & B_TTY_SAVE_HIST)
1953 snprintf(pbuf, btty.len, "savehistory: on\r\n");
1954 else
1955 snprintf(pbuf, btty.len, "savehistory: off\r\n");
1956 i = write(btty.fd[1], pbuf, strlen(pbuf));
1957 return(B_ERR_OK);
1958 } else if (strncmp(v[1], "history", strlen(v[1])) == 0) {
1959 if ((btty.hist_c = atoi(v[2])) <= 0)
1960 btty.hist_c = 50;
1961 else if (btty.hist_c > 50)
1962 btty.hist_c = 50;
1963 return(B_ERR_OK);
1964 } else if (strncmp(v[1], "noalias", strlen(v[1])) == 0) {
1965 for (i = 0; commands[i].map != -1; i++)
1966 {
1967 if (commands[i].map != B_COM_ALIAS)
1968 continue;
1969 if (strcmp(commands[i].name, v[2]) == 0)
1970 {
1971 commands[i].name[0] = '\0';
1972 commands[i].help[0] = '\0';
1973 commands[i].map = B_COM_FREE;
1974 commands[i].exec = NULL;
1975 break;
1976 }
1977 }
1978 return(B_ERR_OK);
1979 } else if (strncmp(v[1], "debug", strlen(v[1])) == 0) {
1980 btty.flags &= ~B_TTY_DEBUG;
1981 if (strcmp(v[2], "on") == 0)
1982 btty.flags |= B_TTY_DEBUG;
1983 if (btty.flags & B_TTY_DEBUG)
1984 snprintf(pbuf, btty.len, "debug (cli): on\r\n");
1985 else
1986 snprintf(pbuf, btty.len, "debug (cli): off\r\n");
1987 i = write(btty.fd[1], pbuf, strlen(pbuf));
1988 return(B_ERR_OK);
1989 }
1990 }
1991
1992 if (c > 3)
1993 {
1994 if (strncmp(v[1], "play", strlen(v[1])) == 0) {
1995 print("set play");
1996 if (c != 4)
1997 return(B_ERR_PARAM);
1998 if (strncmp(v[2], "rate", strlen(v[2])) == 0)
1999 {
2000 int rate;
2001
2002 if ((rate = atoi(v[3])) < 0) return(B_ERR_VALUE);
2003 sequences[btty.sequence.id].rate = rate;
2004 return(B_ERR_OK);
2005 }
2006 if (strncmp(v[2], "transpose", strlen(v[2])) == 0)
2007 {
2008 int transpose;
2009
2010 transpose = atoi(v[3]);
2011 btty.sequence.transpose = transpose;
2012 return(B_ERR_OK);
2013 }
2014 if (strncmp(v[2], "sequence", strlen(v[2])) == 0)
2015 {
2016 int seq;
2017
2018 print("sequence");
2019 if ((seq = atoi(v[3])) < 0) return(B_ERR_VALUE);
2020 if (seq >= B_SEQ_COUNT) return(B_ERR_VALUE);
2021 if (sequences[seq].count <= 0) return(B_ERR_VALUE);
2022
2023 btty.sequence.step = -1;
2024 btty.sequence.count =
2025 250 * 60 / sequences[btty.sequence.id].rate;
2026
2027 btty.flags &= ~B_TTY_MMASK;
2028 btty.flags |= B_TTY_SEQ|B_TTY_RAW;
2029
2030 return(B_ERR_EARLY);
2031 }
2032 } else if ((strncmp(v[1], "history", strlen(v[1])) == 0)
2033 && (strncmp(v[2], "comm", strlen(v[2])) == 0))
2034 {
2035 char *comm;
2036
2037 /* rotate history, add this one */
2038 if ((comm = strstr(cbuf, "comm")) == NULL)
2039 return(2);
2040 comm += 5;
2041 snprintf(btty.hist[1], B_TTY_LINE_LEN, "%s", comm);
2042 return(B_ERR_OK);
2043 }
2044 }
2045
2046 return(2);
2047 }
2048
2049 static int
execImport(guimain * global,int c,char ** v)2050 execImport(guimain *global, int c, char **v)
2051 {
2052 int loc;
2053
2054 if (execHelpCheck(c, v)) return(0);
2055
2056 loc = SYNTHS->location;
2057
2058 if (c == 1)
2059 return(2);
2060
2061 if (c == 2) {
2062 loc = SYNTHS->location;
2063 if ((v[1] == NULL) || (v[1][0] == '\0'))
2064 return(3);
2065 }
2066
2067 print(v[1]);
2068
2069 if (strncmp("import", v[0], strlen(v[0])) == 0)
2070 {
2071 if (c == 3)
2072 loc = atoi(v[2]);
2073 bristolMemoryImport(loc, v[1], RESOURCES->name);
2074 return(0);
2075 } else if (strncmp("export", v[0], strlen(v[0])) == 0) {
2076 if (c == 3)
2077 loc = atoi(v[2]);
2078 bristolMemoryExport(loc, v[1], RESOURCES->name);
2079 return(0);
2080 }
2081
2082 return(0);
2083 }
2084
2085 static void
execParamChange(guimain * global,float v)2086 execParamChange(guimain *global, float v)
2087 {
2088 int i;
2089 char *name;
2090
2091 if ((paramname(btty.i) == NULL) || (paramname(btty.i)[0] == '\0'))
2092 name = unknown;
2093 else
2094 name = paramname(btty.i);
2095
2096 /*
2097 if ((SYNTHS->win->app->resources[btty.p].devlocn[btty.i].type == 1)
2098 || (SYNTHS->win->app->resources[btty.p].devlocn[btty.i].type == 7))
2099 brightonChangeParam(SYNTHS, btty.p, btty.i, v);
2100 else
2101 brightonChangeParam(SYNTHS, btty.p, btty.i,
2102 v * RESOURCES->resources[btty.p].devlocn[btty.i].to);
2103 */
2104 brightonChangeParam(SYNTHS, btty.p, btty.i, v * DEVICE(btty.i).to);
2105
2106 if (DEVICE(btty.i).to == 1.0f)
2107 {
2108 if (DEVICE(btty.i).type == 1)
2109 snprintf(pbuf, btty.len, "%02i %-25s: %4.0f\r\n", btty.i,
2110 name, (1.0 - PDEV(btty.i)->value) * 1000.0f);
2111 else if (DEVICE(btty.i).type == 2)
2112 snprintf(pbuf, btty.len, "%02i %-25s: %1.0f\r\n", btty.i,
2113 name, PDEV(btty.i)->value);
2114 else
2115 snprintf(pbuf, btty.len, "%02i %-25s: %4.0f\r\n", btty.i,
2116 name, PDEV(btty.i)->value * 1000.0f);
2117 } else {
2118 if (DEVICE(btty.i).type == 1)
2119 {
2120 if (DEVICE(btty.i).flags & BRIGHTON_REVERSE)
2121 snprintf(pbuf, btty.len, "%02i %-25s: %4.0f\r\n", btty.i,
2122 name, PDEV(btty.i)->value * DEVICE(btty.i).to);
2123 else
2124 snprintf(pbuf, btty.len, "%02i %-25s: %4.0f\r\n", btty.i,
2125 name, (1.0 - PDEV(btty.i)->value)
2126 * DEVICE(btty.i).to);
2127 } else if (DEVICE(btty.i).type == 2) {
2128 snprintf(pbuf, btty.len, "%02i %-25s: %4.0f\r\n", btty.i,
2129 name, PDEV(btty.i)->value);
2130 } else
2131 snprintf(pbuf, btty.len, "%02i %-25s: %4.0f\r\n", btty.i,
2132 name, PDEV(btty.i)->value * DEVICE(btty.i).to);
2133 // snprintf(pbuf, btty.len, "%02i %-25s: %3.0f\n\r", btty.i,
2134 // name, ((brightonDevice *) DEVICE(btty.i).dev)->value);
2135 }
2136
2137 i = write(btty.fd[1], pbuf, strlen(pbuf));
2138 }
2139
2140 static int
execBrighton(guimain * global,int c,char ** argv)2141 execBrighton(guimain *global, int c, char **argv)
2142 {
2143 int p, d, tp, ti;
2144 float v;
2145
2146 print("execBrighton");
2147
2148 if (execHelpCheck(c, argv)) return(0);
2149
2150 if (c == 2)
2151 {
2152 if (strncmp(brightoncom[1].name, argv[1], strlen(argv[1])) == 0)
2153 {
2154 snprintf(pbuf, btty.len, "active panel: %i\r\n", btty.p);
2155 p = write(btty.fd[1], pbuf, strlen(pbuf));
2156 return(0);
2157 }
2158 return(1);
2159 }
2160
2161 if (c == 3)
2162 {
2163 if (strncmp(brightoncom[1].name, argv[1], strlen(argv[1])) == 0)
2164 {
2165 int x;
2166
2167 if ((x = atoi(argv[2])) < 0)
2168 return(3);
2169 if (btty.p > SYNTHS->win->app->nresources)
2170 return(3);
2171 if (SYNTHS->win->app->resources[x].ndevices == 0)
2172 return(3);
2173 btty.p = x;
2174 snprintf(pbuf, btty.len, "active panel: %i\r\n", btty.p);
2175 p = write(btty.fd[1], pbuf, strlen(pbuf));
2176 return(0);
2177 }
2178 return(2);
2179 }
2180
2181 if (c == 5)
2182 {
2183 if (strncmp(brightoncom[2].name, argv[1], strlen(argv[1])) == 0)
2184 {
2185 /* Device settings */
2186 if ((p = atoi(argv[2])) < 0)
2187 return(B_ERR_PARAM);
2188 if (p >= SYNTHS->win->app->nresources)
2189 return(B_ERR_PARAM);
2190 if (SYNTHS->win->app->resources[p].ndevices <= 0)
2191 return(B_ERR_PARAM);
2192 if ((d = atoi(argv[3])) < 0)
2193 return(B_ERR_PARAM);
2194 if (d >= SYNTHS->win->app->resources[p].ndevices)
2195 return(B_ERR_PARAM);
2196
2197 tp = btty.p;
2198 ti = btty.i;
2199
2200 btty.p = p;
2201 btty.i = d;
2202
2203 if (argv[4][1] == '=')
2204 {
2205 if (argv[4][0] == '+')
2206 v = atof(&argv[4][2]) + PDEV(d)->value;
2207 else if (argv[4][0] == '-')
2208 v = PDEV(d)->value - atof(&argv[4][2]);
2209 else
2210 return(B_ERR_VALUE);
2211 } else if ((v = atof(argv[4])) < 0.0f)
2212 return(B_ERR_VALUE);
2213
2214 if (v < 0) v = 0.0f;
2215
2216 execParamChange(global, v);
2217
2218 btty.p = tp;
2219 btty.i = ti;
2220
2221 return(B_ERR_OK);
2222 }
2223 }
2224 return(B_ERR_PARAM);
2225 }
2226
2227 static void
cliParamChange(guimain * global,float v)2228 cliParamChange(guimain *global, float v)
2229 {
2230 int i;
2231 char *name, crlf[4] = "\r\n", *c1 = crlf, *c2 = "";
2232
2233 if ((paramname(btty.i) == NULL) || (paramname(btty.i)[0] == '\0'))
2234 name = unknown;
2235 else
2236 name = paramname(btty.i);
2237
2238 if (v != 0)
2239 {
2240 //if (RESOURCES->resources[btty.p].devlocn[btty.i].to != 1.0f)
2241 if (DEVICE(btty.i).to != 1.0f)
2242 {
2243 if (DEVICE(btty.i).type == 1)
2244 {
2245 if (DEVICE(btty.i).flags & BRIGHTON_VERTICAL) {
2246 if (v > 0)
2247 brightonChangeParam(SYNTHS, btty.p, btty.i,
2248 PDEV(btty.i)->value * DEVICE(btty.i).to + 1);
2249 else
2250 brightonChangeParam(SYNTHS, btty.p, btty.i,
2251 PDEV(btty.i)->value * DEVICE(btty.i).to - 1);
2252 } else if (DEVICE(btty.i).flags & BRIGHTON_REVERSE) {
2253 if (v > 0)
2254 brightonChangeParam(SYNTHS, btty.p, btty.i,
2255 PDEV(btty.i)->value * DEVICE(btty.i).to - 1);
2256 else
2257 brightonChangeParam(SYNTHS, btty.p, btty.i,
2258 PDEV(btty.i)->value * DEVICE(btty.i).to + 1);
2259 } else {
2260 if (v > 0)
2261 brightonChangeParam(SYNTHS, btty.p, btty.i,
2262 (1.0 - PDEV(btty.i)->value)
2263 * DEVICE(btty.i).to + 1);
2264 else
2265 brightonChangeParam(SYNTHS, btty.p, btty.i,
2266 (1.0 - PDEV(btty.i)->value)
2267 * DEVICE(btty.i).to - 1);
2268 }
2269 } else if (DEVICE(btty.i).type == 7) {
2270 if (v > 0)
2271 brightonChangeParam(SYNTHS, btty.p, btty.i,
2272 PDEV(btty.i)->value
2273 * DEVICE(btty.i).to + 1);
2274 else
2275 brightonChangeParam(SYNTHS, btty.p, btty.i,
2276 PDEV(btty.i)->value
2277 * DEVICE(btty.i).to - 1);
2278 } else if (DEVICE(btty.i).type == 2) {
2279 if (v > 0)
2280 brightonChangeParam(SYNTHS, btty.p, btty.i,
2281 PDEV(btty.i)->value + 1);
2282 else
2283 brightonChangeParam(SYNTHS, btty.p, btty.i,
2284 PDEV(btty.i)->value - 1);
2285 } else {
2286 if (v > 0)
2287 brightonChangeParam(SYNTHS, btty.p, btty.i,
2288 PDEV(btty.i)->value * DEVICE(btty.i).to + 1);
2289 else
2290 brightonChangeParam(SYNTHS, btty.p, btty.i,
2291 PDEV(btty.i)->value * DEVICE(btty.i).to - 1);
2292 }
2293 } else {
2294 if (DEVICE(btty.i).type == 1)
2295 {
2296 if (DEVICE(btty.i).flags & BRIGHTON_VERTICAL)
2297 brightonChangeParam(SYNTHS, btty.p, btty.i,
2298 PDEV(btty.i)->value + v);
2299 else if (DEVICE(btty.i).flags & BRIGHTON_REVERSE)
2300 brightonChangeParam(SYNTHS, btty.p, btty.i,
2301 PDEV(btty.i)->value - v);
2302 else
2303 brightonChangeParam(SYNTHS, btty.p, btty.i,
2304 (1.0 - PDEV(btty.i)->value) + v);
2305 } else
2306 brightonChangeParam(SYNTHS, btty.p, btty.i,
2307 PDEV(btty.i)->value + v);
2308 }
2309 }
2310
2311 if (btty.flags & B_TTY_COOKED)
2312 {
2313 print("post return");
2314 c1 = c2; c2 = crlf;
2315 } else
2316 print("pre return");
2317
2318 if (DEVICE(btty.i).to == 1.0f)
2319 {
2320 if (DEVICE(btty.i).type == 1)
2321 {
2322 if (DEVICE(btty.i).flags & BRIGHTON_VERTICAL)
2323 snprintf(pbuf, btty.len, "%s%02i %-25s: %4.0f%s", c1, btty.i,
2324 name, PDEV(btty.i)->value * 1000.0f, c2);
2325 else
2326 snprintf(pbuf, btty.len, "%s%02i %-25s: %4.0f%s", c1, btty.i,
2327 name, (1.0 - PDEV(btty.i)->value) * 1000.0f, c2);
2328 } else if (DEVICE(btty.i).type == 2)
2329 snprintf(pbuf, btty.len, "%s%02i %-25s: %4.0f%s", c1, btty.i,
2330 name, PDEV(btty.i)->value, c2);
2331 else
2332 snprintf(pbuf, btty.len, "%s%02i %-25s: %4.0f%s", c1, btty.i,
2333 name, PDEV(btty.i)->value * 1000.0f, c2);
2334 } else {
2335 if (DEVICE(btty.i).type == 1)
2336 {
2337 if (DEVICE(btty.i).flags & BRIGHTON_REVERSE)
2338 snprintf(pbuf, btty.len, "%s%02i %-25s: %4.0f%s", c1, btty.i,
2339 name, PDEV(btty.i)->value * DEVICE(btty.i).to, c2);
2340 else
2341 snprintf(pbuf, btty.len, "%s%02i %-25s: %4.0f%s", c1, btty.i,
2342 name, (1.0 - PDEV(btty.i)->value)
2343 * DEVICE(btty.i).to, c2);
2344 } else if (DEVICE(btty.i).type == 2) {
2345 snprintf(pbuf, btty.len, "%s%02i %-25s: %4.0f%s", c1, btty.i,
2346 name, PDEV(btty.i)->value, c2);
2347 } else
2348 snprintf(pbuf, btty.len, "%s%02i %-25s: %4.0f%s", c1, btty.i,
2349 name, PDEV(btty.i)->value * DEVICE(btty.i).to, c2);
2350 // snprintf(pbuf, btty.len, "%02i %-25s: %3.0f\n\r", btty.i,
2351 // name, ((brightonDevice *) DEVICE(btty.i).dev)->value);
2352 }
2353
2354 lp = PDEV(btty.i)->value;
2355
2356 i = write(btty.fd[1], pbuf, strlen(pbuf));
2357 }
2358
2359 void
brightonCLIinit(guimain * global,int fd[])2360 brightonCLIinit(guimain *global, int fd[])
2361 {
2362 btty.fd[0] = fd[0];
2363 btty.fd[1] = fd[1];
2364 btty.cycle = 500;
2365
2366 snprintf(btty.prompt, 64, "nicky");
2367
2368 btty.global = global;
2369 btty.flags |= B_TTY_COOKED|B_TTY_INIT;
2370 }
2371
2372 #define B_MATCHES 64
2373
2374 /*
2375 * Take input line, extract word up to first space and attempt completion.
2376 * If we get a completion see if there are more words and complete them with
2377 * the new comset
2378 */
2379 int
bttyCookedCompletion(char * line,comSet * coms)2380 bttyCookedCompletion(char *line, comSet *coms)
2381 {
2382 int i, v, count = 0, t, c, first = -1;
2383 char src[B_TTY_LINE_LEN], dst[B_TTY_LINE_LEN];
2384 char *matches[B_MATCHES];
2385
2386 print("Complete");
2387
2388 if (coms == NULL)
2389 return(0);
2390
2391 print(line);
2392
2393 memset(matches, 0, sizeof(matches));
2394 memset(src, 0, B_TTY_LINE_LEN);
2395 memset(dst, 0, B_TTY_LINE_LEN);
2396
2397 for (i = 0; 1 ; i++)
2398 {
2399 if (((src[i] = line[i]) == ' ') || (src[i] == '\0'))
2400 {
2401 src[i] = '\0';
2402 break;
2403 }
2404 }
2405
2406 for (v = 0; coms[v].map != B_COM_LAST; v++)
2407 {
2408 if (strncasecmp(coms[v].name, src, strlen(src)) == 0)
2409 {
2410 print(coms[v].name);
2411
2412 matches[count] = brightonmalloc(64);
2413 snprintf(matches[count], 64, "%s", coms[v].name);
2414
2415 if (first < 0) first = v;
2416 if (++count >= B_MATCHES)
2417 break;
2418 }
2419 }
2420
2421 if (count == 1) {
2422 /*
2423 * We now have one word filled out, see if we can continue
2424 */
2425 snprintf(src, B_TTY_LINE_LEN, "%s", coms[first].name);
2426
2427 if (line[i] != '\0')
2428 {
2429 snprintf(dst, B_TTY_LINE_LEN, "%s", &line[i + 1]);
2430 print("subsearch");
2431 print(dst);
2432 if (bttyCookedCompletion(dst, coms[first].subcom) >= 1)
2433 snprintf(line, B_TTY_LINE_LEN, "%s %s", src, dst);
2434 else
2435 snprintf(line, B_TTY_LINE_LEN, "%s %s", src, &line[i + 1]);
2436 } else
2437 snprintf(line, B_TTY_LINE_LEN, "%s ", src);
2438 //btty.edit_p = strlen(src);
2439 } else if (count != 0) {
2440 int y, x, ch, cont = 1;
2441
2442 /* Many hits - see how we can match them, display the result */
2443 for (x = 0; cont; x++)
2444 {
2445 ch = matches[0][x];
2446 for (y = 1; y < count; y++)
2447 {
2448 if (matches[y][x] == '\0')
2449 cont = 0;
2450 if (matches[y][x] != ch)
2451 cont = 0;
2452 }
2453 }
2454 if (x > 0)
2455 {
2456 c = 0;
2457 ch = ' ';
2458 /* Show the list of commands we have matched */
2459 for (y = 0; y < count; y++)
2460 {
2461 t = write(btty.fd[1], matches[y], strlen(matches[y]));
2462 t = write(btty.fd[1], &ch, 1);
2463 if ((c += strlen(matches[y]) + 1) > btty.len - 16)
2464 {
2465 snprintf(pbuf, 4, "\n\r");
2466 t = write(btty.fd[1], pbuf, 2);
2467 c = 0;
2468 }
2469 }
2470 /* And an extra return if we need it */
2471 if (c != 0)
2472 {
2473 snprintf(pbuf, 4, "\n\r");
2474 t = write(btty.fd[1], pbuf, 2);
2475 }
2476 /* Then see if we can move the display forward */
2477 if (x > strlen(line))
2478 {
2479 snprintf(line, x, "%s", matches[0]);
2480 btty.edit_p = strlen(line);
2481 }
2482 // snprintf(pbuf, B_TTY_LINE_LEN, "%i %s\r\n", x, line);
2483 // t = write(btty.fd[1], pbuf, strlen(pbuf));
2484 }
2485 }
2486
2487 btty.edit_p = strlen(line);
2488
2489 for (i = 0; matches[i] != NULL; i++)
2490 brightonfree(matches[i]);
2491
2492 return(count);
2493 }
2494
2495 /*
2496 * Search only through the CLI command set
2497 */
2498 static int
bttyComplete(guimain * global)2499 bttyComplete(guimain *global)
2500 {
2501 int v, first = -1, count = 0, c, t;//, mi = 0;
2502 char *matches[B_MATCHES];
2503
2504 memset(matches, 0, sizeof(matches));
2505
2506 if (btty.flags & B_TTY_DEBUG)
2507 {
2508 snprintf(pbuf, btty.len, "\n\rcomplete %s\r", cbuf);
2509 t = write(btty.fd[1], pbuf, strlen(pbuf));
2510 }
2511
2512 if (btty.flags & B_TTY_COOKED) {
2513 /* Complete then edit */
2514 if (isdigit(cbuf[0]))
2515 {
2516 switch (strlen(cbuf)) {
2517 case 1:
2518 case 2:
2519 v = atoi(cbuf);
2520 if (btty.hist[v][0] == '\0')
2521 break;
2522 snprintf(cbuf, btty.len, "%s", btty.hist[v]);
2523 btty.edit_p = strlen(cbuf);
2524 return(1);
2525 default:
2526 break;
2527 }
2528 }
2529
2530 /* Complete then edit */
2531 if ((cbuf[0] == '!') && (isdigit(cbuf[1])))
2532 {
2533 switch (strlen(&cbuf[1])) {
2534 case 1:
2535 case 2:
2536 v = atoi(&cbuf[1]);
2537 if (btty.hist[v][0] == '\0')
2538 break;
2539 snprintf(cbuf, btty.len, "%s", btty.hist[v]);
2540 btty.edit_p = strlen(cbuf);
2541 return(1);
2542 default:
2543 break;
2544 }
2545 }
2546
2547 count = bttyCookedCompletion(cbuf, commands);
2548 btty.edit_p = strlen(cbuf);
2549 }
2550
2551 for (v = 0; ((matches[v] != NULL) && (v < B_MATCHES)); v++)
2552 brightonfree(matches[v]);
2553 memset(matches, 0, sizeof(matches));
2554
2555 if (count != 0)
2556 return(0);
2557
2558 c = SYNTHS->win->app->resources[btty.p].ndevices;
2559
2560 for (v = 0; v != c; v++)
2561 {
2562 if (cbuf[0] == '^') {
2563 if (strncasecmp(paramname(v), &cbuf[1], strlen(cbuf) - 1) == 0)
2564 {
2565 if (first < 0) first = v;
2566 matches[count] = brightonmalloc(64);
2567 snprintf(matches[count], 64, "%s", paramname(v));
2568 if (++count >= B_MATCHES)
2569 break;
2570 }
2571 } else if (strcasestr(paramname(v), cbuf) != NULL) {
2572 if (first < 0) first = v;
2573 matches[count] = brightonmalloc(64);
2574 snprintf(matches[count], 64, "%s", paramname(v));
2575 if (++count >= B_MATCHES)
2576 break;
2577 }
2578 }
2579 if (count == 1) {
2580 snprintf(cbuf, btty.len, "%s", paramname(first));
2581 btty.i = first;
2582 btty.edit_p = strlen(cbuf);
2583 } else if (count != 0) {
2584 int y, x, ch, cont = 1;
2585
2586 /* Many hits - see how far we can match them, display the result */
2587 for (x = 0; cont; x++)
2588 {
2589 ch = matches[0][x];
2590 for (y = 1; y < count; y++)
2591 {
2592 if (matches[y][x] == '\0')
2593 cont = 0;
2594 if (matches[y][x] != ch)
2595 cont = 0;
2596 }
2597 }
2598 if (x > 0)
2599 {
2600 c = 0;
2601 ch = ' ';
2602 for (y = 0; y < count; y++)
2603 {
2604 t = write(btty.fd[1], matches[y], strlen(matches[y]));
2605 t = write(btty.fd[1], &ch, 1);
2606 if ((c += strlen(matches[y]) + 1) > btty.len - 16)
2607 {
2608 snprintf(pbuf, 4, "\n\r");
2609 t = write(btty.fd[1], pbuf, 2);
2610 c = 0;
2611 }
2612 }
2613 if (c != 0)
2614 {
2615 snprintf(pbuf, 4, "\n\r");
2616 t = write(btty.fd[1], pbuf, 2);
2617 }
2618 if (x > strlen(cbuf))
2619 {
2620 snprintf(cbuf, x, "%s", matches[0]);
2621 btty.edit_p = strlen(cbuf);
2622 }
2623 }
2624 }
2625
2626 for (v = 0; ((matches[v] != NULL) && (v < B_MATCHES)); v++)
2627 brightonfree(matches[v]);
2628
2629 return(count);
2630 }
2631
2632 /*
2633 * Search only through the synth parameters.
2634 */
2635 static int
bttySearch(guimain * global)2636 bttySearch(guimain *global)
2637 {
2638 int v, first = -1, count = 0;
2639
2640 // snprintf(pbuf, btty.len, "bttySearch\n\r");
2641 // t = write(btty.fd[1], pbuf, strlen(pbuf));
2642
2643 if (cbuf[0] == '\0')
2644 return(1);
2645
2646 if (btty.flags & B_TTY_DEBUG)
2647 {
2648 snprintf(pbuf, btty.len, "\n\rsearch %s\r", cbuf);
2649 v = write(btty.fd[1], pbuf, strlen(pbuf));
2650 }
2651
2652 /*
2653 * Search through the internal commands and the synth parameters. If only
2654 * one match then commplete it, otherwise list them.
2655 */
2656 if (btty.i >= SYNTHS->win->app->resources[btty.p].ndevices)
2657 {
2658 btty.i = SYNTHS->win->app->resources[btty.p].ndevices - 1;
2659 v = 0;
2660 } else
2661 v = btty.i + 1;
2662
2663 for (; v != btty.i; v++)
2664 {
2665 if (v >= SYNTHS->win->app->resources[btty.p].ndevices)
2666 v = -1;
2667 //snprintf(pbuf, btty.len, "%s %s %i %i\n\r", paramname(v), cbuf, btty.i, v);
2668 //t = write(btty.fd[1], pbuf, strlen(pbuf));
2669 if (paramname(v) == NULL)
2670 continue;
2671 if (unnamed(v))
2672 continue;
2673 if (cbuf[0] == '^') {
2674 if (strncasecmp(paramname(v), &cbuf[1], strlen(cbuf) - 1) == 0)
2675 {
2676 if (first == -1)
2677 first = v;
2678 count++;
2679 break;
2680 }
2681 } else if (strcasestr(paramname(v), cbuf) != NULL) {
2682 if (first == -1)
2683 first = v;
2684 count++;
2685 break;
2686 }
2687 }
2688
2689 if (first >= 0)
2690 btty.i = first;
2691
2692 cliParamChange(global, 0.0f);
2693
2694 btty.flags &= ~B_TTY_MMASK;
2695 btty.flags |= B_TTY_RAW;
2696
2697 btty.edit_p = 0;
2698 btty.hist_tmp = 0;
2699 memset(cbuf, 0, B_TTY_LINE_LEN);
2700
2701 return(count);
2702 }
2703
2704 static int
execDebug(guimain * global,int c,char ** v)2705 execDebug(guimain *global, int c, char **v)
2706 {
2707 int i;
2708
2709 if (execHelpCheck(c, v)) return(0);
2710
2711 if (c == 2) {
2712 if (strncmp("off", v[1], strlen(v[1])) == 0)
2713 btty.flags &= ~B_TTY_DEBUG;
2714 else if (strncmp("on", v[1], strlen(v[1])) == 0)
2715 btty.flags |= B_TTY_DEBUG;
2716 else
2717 btty.flags &= ~B_TTY_DEBUG;
2718 return(0);
2719 }
2720
2721 if (c == 3)
2722 {
2723 if (strncmp("cli", v[1], strlen(v[1])) == 0)
2724 {
2725 if (strncmp("off", v[2], strlen(v[2])) == 0)
2726 btty.flags &= ~B_TTY_DEBUG;
2727 else if (strncmp("on", v[2], strlen(v[2])) == 0)
2728 btty.flags |= B_TTY_DEBUG;
2729 else
2730 btty.flags &= ~B_TTY_DEBUG;
2731 return(0);
2732 }
2733 if (strncmp(debugcomm[2].name, v[1], strlen(v[1])) == 0)
2734 {
2735 if (strncmp("off", v[2], strlen(v[2])) == 0)
2736 {
2737 SYNTHS->flags &= ~REQ_DEBUG_MASK;
2738 SYNTHS->win->flags &= ~BRIGHTON_DEBUG;
2739 } else if (strncmp("on", v[2], strlen(v[2])) == 0) {
2740 SYNTHS->flags |= REQ_DEBUG_MASK;
2741 SYNTHS->win->flags |= BRIGHTON_DEBUG;
2742 }
2743 }
2744 if (strncmp("engine", v[1], strlen(v[1])) == 0)
2745 {
2746 if ((btty.edbg = atoi(v[2])) <= 0)
2747 btty.edbg = 0;
2748 if (btty.edbg > 15)
2749 btty.edbg = 15;
2750
2751 bristolMidiSendMsg(global->controlfd, SYNTHS->sid,
2752 BRISTOL_SYSTEM, 0, BRISTOL_REQ_DEBUG|btty.edbg);
2753
2754 snprintf(pbuf, btty.len, "debug (engine): %i\r\n",
2755 btty.edbg);
2756 i = write(btty.fd[1], pbuf, strlen(pbuf));
2757
2758 return(0);
2759 } if (strncmp("midi", v[1], strlen(v[1])) == 0) {
2760 int n = atoi(v[2]);
2761 switch (n) {
2762 default:
2763 case 0:
2764 n = 0;
2765 break;
2766 case 1:
2767 break;
2768 case 2:
2769 break;
2770 case 3:
2771 break;
2772 }
2773 btty.mdbg = n;
2774 if (global->libtest == 0)
2775 bristolMidiSendNRP(global->controlfd, SYNTHS->midichannel,
2776 BRISTOL_NRP_DEBUG, n);
2777 snprintf(pbuf, btty.len, "MIDI debug: %i\r\n",
2778 btty.mdbg);
2779 i = write(btty.fd[1], pbuf, strlen(pbuf));
2780 return(B_ERR_OK);
2781 }
2782 }
2783
2784 if (c == 1)
2785 {
2786 if (btty.flags & B_TTY_DEBUG)
2787 snprintf(pbuf, btty.len, "debug (cli): on\r\n");
2788 else
2789 snprintf(pbuf, btty.len, "debug (cli): off\r\n");
2790 i = write(btty.fd[1], pbuf, strlen(pbuf));
2791
2792 snprintf(pbuf, btty.len, "debug (engine): %i\r\n", btty.edbg);
2793 i = write(btty.fd[1], pbuf, strlen(pbuf));
2794
2795 return(0);
2796 }
2797
2798 return(0);
2799 }
2800
2801 static int
execLoad(guimain * global,int c,char ** v)2802 execLoad(guimain *global, int c, char **v)
2803 {
2804 int n = 0, undo = 0;
2805
2806 if (execHelpCheck(c, v)) return(0);
2807
2808 print(v[0]);
2809
2810 if (c >= 2)
2811 {
2812 if (strncmp("undo", v[1], strlen(v[1])) == 0)
2813 undo = 1;
2814 else if ((n = atoi(v[1])) < 0)
2815 return(0);
2816 }
2817
2818 if ((strncmp(v[0], "load", strlen(v[0])) == 0)
2819 || (strncmp(v[0], "read", strlen(v[0])) == 0))
2820 {
2821 if (undo) {
2822 SYNTHS->location = 9999;
2823 bttyMemLoad(global);
2824 SYNTHS->location = btty.lastmem;
2825 } else if (c == 1) {
2826 /* load current mem */
2827 btty.lastmem = SYNTHS->location;
2828 bttyMemLoad(global);
2829 SYNTHS->location = btty.lastmem;
2830 return(0);
2831 } else {
2832 /* load named memory */
2833 btty.lastmem = SYNTHS->location;
2834 SYNTHS->location = n;
2835 bttyMemLoad(global);
2836 }
2837 }
2838
2839 if ((strncmp(v[0], "save", strlen(v[0])) == 0)
2840 || (strncmp(v[0], "write", strlen(v[0])) == 0))
2841 {
2842 if (c == 1)
2843 {
2844 /* save current mem */
2845 bttyMemSave(global);
2846 return(0);
2847 } else {
2848 SYNTHS->location = n;
2849 bttyMemSave(global);
2850 }
2851 }
2852
2853 if (strncmp(v[0], "find", strlen(v[0])) == 0)
2854 {
2855 int location = SYNTHS->location + 1;
2856
2857 if (location > 1023)
2858 location = 0;
2859
2860 if ((c == 2) && (strncmp(v[1], "free", strlen(v[1])) == 0))
2861 {
2862 /* find free mem */
2863 while (loadMemory(SYNTHS, RESOURCES->name, 0,
2864 location, SYNTHS->mem.active, 0, BRISTOL_STAT) == 0)
2865 {
2866 if (++location > 1024)
2867 location = 0;
2868 if (location == SYNTHS->location)
2869 break;
2870 }
2871 if (location != SYNTHS->location)
2872 {
2873 SYNTHS->location = location;
2874 snprintf(pbuf, btty.len, "free: %i\r\n", SYNTHS->location);
2875 n = write(btty.fd[1], pbuf, strlen(pbuf));
2876 } else {
2877 snprintf(pbuf, btty.len, "no free memories\r\n");
2878 n = write(btty.fd[1], pbuf, strlen(pbuf));
2879 }
2880 }
2881
2882 if ((c == 2) && ((strncmp(v[1], "load", strlen(v[1])) == 0)
2883 || (strncmp(v[1], "read", strlen(v[1])) == 0)))
2884 {
2885 /* find mem */
2886 while (loadMemory(SYNTHS, RESOURCES->name, 0,
2887 location, SYNTHS->mem.active, 0, BRISTOL_STAT) != 0)
2888 {
2889 if (++location > 1024)
2890 location = 0;
2891 if (location == SYNTHS->location)
2892 break;
2893 }
2894
2895 SYNTHS->location = location;
2896 bttyMemLoad(global);
2897 }
2898
2899 if (c == 1)
2900 {
2901 /* find mem */
2902 while (loadMemory(SYNTHS, RESOURCES->name, 0,
2903 location, SYNTHS->mem.active, 0, BRISTOL_STAT) != 0)
2904 {
2905 if (++location > 1024)
2906 location = 0;
2907 if (location == SYNTHS->location)
2908 break;
2909 }
2910 if (location != SYNTHS->location)
2911 {
2912 SYNTHS->location = location;
2913 snprintf(pbuf, btty.len, "mem: %i\r\n", SYNTHS->location);
2914 n = write(btty.fd[1], pbuf, strlen(pbuf));
2915 } else {
2916 snprintf(pbuf, btty.len, "no memories\r\n");
2917 n = write(btty.fd[1], pbuf, strlen(pbuf));
2918 }
2919
2920 return(0);
2921 }
2922 }
2923
2924 return(0);
2925 }
2926
2927 static int
execHelp(guimain * global,int c,char ** v)2928 execHelp(guimain *global, int c, char **v)
2929 {
2930 int i, n;
2931
2932 if (execHelpCheck(c, v)) return(0);
2933
2934 print(v[0]);
2935
2936 if (c == 1)
2937 {
2938 snprintf(pbuf, B_TTY_LINE_LEN, "CLI ':insert' mode command list:\r\n");
2939 n = write(btty.fd[1], pbuf, strlen(pbuf));
2940
2941 for (i = 0; commands[i].map != -1; i++)
2942 {
2943 if (commands[i].map == B_COM_NOT_USED)
2944 continue;
2945 snprintf(pbuf, B_TTY_LINE_LEN, "%12s (:) %s\n\r",
2946 commands[i].name, commands[i].help);
2947 if (commands[i].map == B_COM_ALIAS)
2948 pbuf[14] = 'a';
2949 else
2950 pbuf[14] = 'c';
2951 n = write(btty.fd[1], pbuf, strlen(pbuf));
2952 }
2953 return(0);
2954 }
2955
2956 for (i = 0; commands[i].map != B_COM_LAST; i++)
2957 {
2958 if (commands[i].map == B_COM_NOT_USED)
2959 continue;
2960 if (strncmp(commands[i].name, v[1], strlen(v[1])) == 0)
2961 {
2962 snprintf(pbuf, B_TTY_LINE_LEN, "%12s: %s\n\r",
2963 commands[i].name, commands[i].help);
2964 n = write(btty.fd[1], pbuf, strlen(pbuf));
2965 break;
2966 }
2967 }
2968
2969 if (commands[i].map == B_COM_LAST)
2970 {
2971 snprintf(pbuf, btty.len, "help '%s' not found\n\r", v[1]);
2972 n = write(btty.fd[1], pbuf, strlen(pbuf));
2973 }
2974
2975 return(0);
2976 }
2977 static int
execQuit(guimain * global,int c,char ** v)2978 execQuit(guimain *global, int c, char **v)
2979 {
2980 if ((c == 1) && (strlen(v[0]) == 4) && (strcmp(v[0], "quit") == 0))
2981 return(B_ERR_EXIT);
2982 return(B_ERR_PARAM);
2983 }
2984
2985 static int
bttyExecute(guimain * global,int c,char ** v)2986 bttyExecute(guimain *global, int c, char **v)
2987 {
2988 int i, j, k, n;
2989 char var[B_TTY_LINE_LEN];
2990 float value = 0.0f;
2991
2992 if (btty.flags & B_TTY_DEBUG)
2993 {
2994 for (i = 0; i < c; i++)
2995 {
2996 snprintf(pbuf, btty.len, "%i: %i: %s\n\r", i, (int) strlen(v[i]), v[i]);
2997 n = write(btty.fd[1], pbuf, strlen(pbuf));
2998 }
2999 }
3000
3001 for (i = 0; commands[i].map != B_COM_LAST; i++)
3002 {
3003 if (commands[i].map == B_COM_NOT_USED)
3004 continue;
3005 if (commands[i].map == B_COM_FREE)
3006 continue;
3007 if ((strncmp(v[0], commands[i].name, strlen(v[0])) == 0)
3008 && (commands[i].exec != NULL))
3009 {
3010 n = commands[i].exec(global, c, v);
3011 if (btty.flags & B_TTY_ALIASING)
3012 return(n);
3013 memset(pbuf, 0, B_TTY_LINE_LEN);
3014 return(n);
3015 }
3016 }
3017
3018 /*
3019 * Search for the command in the synth parameters.
3020 */
3021 for (i = 0, j = 0, k = 0, n = -1; j < c; i++)
3022 {
3023 switch (v[j][i]) {
3024 case '\0':
3025 i = -1;
3026 if (++j < c)
3027 var[k++] = ' ';
3028 else
3029 var[k++] = '\0';
3030 break;
3031 case '=':
3032 var[k] = '\0';
3033 print(var);
3034 value = atof(&v[j][++i]);
3035 n = 1;
3036 break;
3037 case '+':
3038 if (v[j][i+1] == '+') {
3039 n = 3;
3040 } else if (v[j][i+1] == '=') {
3041 n = 4;
3042 ++i;
3043 value = atof(&v[j][++i]);
3044 } else {
3045 n = 2;
3046 }
3047 var[k] = '\0';
3048 print("found");
3049 break;
3050 case '-':
3051 if (v[j][i+1] == '-') {
3052 n = 6;
3053 } else if (v[j][i+1] == '=') {
3054 n = 7;
3055 ++i;
3056 value = atof(&v[j][++i]);
3057 } else {
3058 n = 5;
3059 }
3060 var[k] = '\0';
3061 print("found");
3062 break;
3063 default:
3064 var[k++] = v[j][i];
3065 break;
3066 }
3067 if (n != -1) break;
3068 }
3069
3070 for (i = 0; i < SYNTHS->win->app->resources[btty.p].ndevices; i++)
3071 {
3072 if ((paramname(i) == NULL) || (paramname(i)[0] == '\0'))
3073 continue;
3074 if (strcmp(var, paramname(i)) == 0)
3075 {
3076 print(paramname(i));
3077 btty.i = i;
3078
3079 switch (n) {
3080 case 1: /* Value was set explicity */
3081 break;
3082 case 2: /* + */
3083 value = PDEV(btty.i)->value + 0.01;
3084 break;
3085 case 3: /* ++ */
3086 value = PDEV(btty.i)->value + btty.accel;
3087 break;
3088 case 4: /* += */
3089 value += PDEV(btty.i)->value;
3090 break;
3091 case 5: /* - */
3092 if ((value = PDEV(btty.i)->value - 0.01) < 0.0f)
3093 value = 0.0f;
3094 break;
3095 case 6: /* -- */
3096 if ((value = PDEV(btty.i)->value - btty.accel) < 0.0f)
3097 value = 0.0f;
3098 break;
3099 case 7: /* -= */
3100 if ((value = PDEV(btty.i)->value - value) < 0.0f)
3101 value = 0.0f;
3102 break;
3103 }
3104
3105 if (n > 0)
3106 execParamChange(global, value);
3107 else
3108 cliParamChange(global, 0.0f);
3109 n = 0;
3110 return(0);
3111 }
3112 }
3113
3114 memset(pbuf, 0, B_TTY_LINE_LEN);
3115
3116 return(1);
3117 }
3118
3119 static char resvar[64];
3120
3121 char *
getprintvar(guimain * global,char * var)3122 getprintvar(guimain *global, char *var)
3123 {
3124 int i;
3125
3126 if (strcmp(var, "panelid") == 0)
3127 {
3128 snprintf(resvar, 64, "%s", RESOURCES->resources[btty.p].name);
3129 return(resvar);
3130 }
3131 if (strcmp(var, "algo") == 0)
3132 {
3133 snprintf(resvar, 64, "%s", RESOURCES->name);
3134 return(resvar);
3135 }
3136 if (strcmp(var, "channel") == 0)
3137 {
3138 snprintf(resvar, 64, "%i", SYNTHS->midichannel + 1);
3139 return(resvar);
3140 }
3141 if (strcmp(var, "memory") == 0)
3142 {
3143 snprintf(resvar, 64, "%i", SYNTHS->location);
3144 return(resvar);
3145 }
3146
3147 for (i = 0 ; i < SYNTHS->win->app->resources[btty.p].ndevices; i++)
3148 {
3149 if (strcasecmp(paramname(i), var) == 0)
3150 break;
3151 }
3152
3153 if (i >= SYNTHS->win->app->resources[btty.p].ndevices)
3154 {
3155 snprintf(resvar, 64, "%s", var);
3156 return(resvar);
3157 }
3158
3159 /*
3160 * Found var, take value.
3161 */
3162 if (DEVICE(i).to == 1.0f)
3163 {
3164 if (DEVICE(i).type == 2)
3165 snprintf(resvar, 64, "%1.0f", PDEV(i)->value);
3166 else
3167 snprintf(resvar, 64, "%-3.0f", PDEV(i)->value*1000.0f);
3168 } else
3169 snprintf(resvar, 64, "%1.0f", PDEV(btty.i)->value);
3170
3171 return(resvar);
3172 }
3173
3174 /*
3175 * So how much work to accept a single string:
3176 * promt='mem %memory% chan %channel%'
3177 */
3178 char *
printprompt(guimain * global)3179 printprompt(guimain *global)
3180 {
3181 int i = 0, j = 0, aliasing = 0;;
3182 char var[64], *s = btty.promptText, *d = btty.prompt, *alias;
3183
3184 /*
3185 * Format is "text", or "text <variable>" where var is searched in the
3186 * synth table.
3187 *
3188 * We are looking for 'mem %something% chan %something%: '
3189 */
3190 for (i = 0; i < 64; i++)
3191 {
3192 if (*s == '\0')
3193 {
3194 *d = '\0';
3195 break;
3196 }
3197 if (*s == '%')
3198 {
3199 if (aliasing)
3200 {
3201 var[j] = '\0';
3202 alias = getprintvar(global, var);
3203 for (; *alias != 0;)
3204 *d++ = *alias++;
3205 aliasing = 0;
3206 } else {
3207 aliasing = 1;
3208 memset(var, 0, 64);
3209 j = 0;
3210 }
3211 s++;
3212 } else if (aliasing)
3213 var[j++] = *s++;
3214 else
3215 *d++ = *s++;
3216 }
3217
3218 if (btty.prompt[0] == '\0')
3219 {
3220 btty.prompt[0] = ':';
3221 btty.prompt[1] = '\0';
3222 }
3223
3224 return(btty.prompt);
3225 }
3226
3227 static int
bttyInterpret(guimain * global,char * tbuf)3228 bttyInterpret(guimain *global, char *tbuf)
3229 {
3230 int v, i = 0, j = 0, k, quoted = 0;
3231 char *comm = tbuf, **vargs, zbuf[B_TTY_LINE_LEN];
3232
3233 while (isspace(*comm))
3234 comm++;
3235
3236 /*
3237 * This is to 'overlook' cooked commands that start with a colon, they
3238 * typicaly come from retyping ':' due to a damaged output stream from
3239 * debuging output.
3240 */
3241 if ((*comm == ':') && (btty.flags & B_TTY_COOKED))
3242 comm++;
3243
3244 if (comm[0] == '!')
3245 {
3246 if (((i = atoi(&comm[1])) < 0) || (i >= 49))
3247 {
3248 btty.hist_tmp = 0;
3249 btty.edit_p = 0;
3250 memset(tbuf, 0, B_TTY_LINE_LEN);
3251 return(0);
3252 }
3253 memset(zbuf, 0, B_TTY_LINE_LEN);
3254 snprintf(zbuf, B_TTY_LINE_LEN, "%s", btty.hist[i]);
3255 comm = zbuf;
3256 }
3257
3258 if ((comm[0] == '\0') || (isalpha(comm[0]) == 0))
3259 {
3260 v = write(btty.fd[1], btty.hist[0], strlen(btty.hist[0]));
3261 snprintf(pbuf, btty.len, "\r:");
3262 v = write(btty.fd[1], pbuf, strlen(pbuf));
3263
3264 btty.edit_p = 0;
3265 memset(cbuf, 0, B_TTY_LINE_LEN);
3266 memset(btty.hist[0], 0, B_TTY_LINE_LEN);
3267 return(1);
3268 }
3269
3270 if (strncmp("history", comm, strlen(comm)) == 0)
3271 {
3272 for (i = btty.hist_c; i > 0; i--)
3273 {
3274 if (btty.hist[i][0] == '\0')
3275 continue;
3276 snprintf(pbuf, B_TTY_LINE_LEN, "%i %s\n\r", i, btty.hist[i]);
3277 v = write(btty.fd[1], pbuf, strlen(pbuf));
3278 }
3279 snprintf(pbuf, B_TTY_LINE_LEN, ":");
3280 v = write(btty.fd[1], pbuf, strlen(pbuf));
3281 btty.edit_p = 0;
3282 memset(cbuf, 0, B_TTY_LINE_LEN);
3283 return(0);
3284 }
3285
3286 if (((strncmp("quit", comm, 4) == 0) || (strncmp("exit", comm, 4) == 0))
3287 && (strlen(comm) == 4))
3288 {
3289 memset(pbuf, 0, B_TTY_LINE_LEN);
3290 snprintf(pbuf, btty.len, "quiting\n\r");
3291 v = write(btty.fd[1], pbuf, strlen(pbuf));
3292 brightonCLIcleanup();
3293 return(-1);
3294 }
3295
3296 if (strlen(comm) == 0)
3297 {
3298 snprintf(pbuf, B_TTY_LINE_LEN, "\r%s", btty.prompt);
3299 v = write(btty.fd[1], pbuf, strlen(pbuf));
3300 btty.edit_p = 0;
3301 memset(cbuf, 0, B_TTY_LINE_LEN);
3302 return(1);
3303 }
3304
3305 if (~btty.flags & B_TTY_RAW)
3306 bttyManageHistory(comm);
3307
3308 vargs = brightonmalloc(sizeof(size_t) * B_TTY_ARGC);
3309 memset(vargs, 0, sizeof(size_t) * B_TTY_ARGC);
3310
3311 for (k = 0, i = 0, j = 0; k < btty.len; k++)
3312 {
3313 /* Get an arg pointer */
3314 if (vargs[i] == NULL)
3315 {
3316 vargs[i] = brightonmalloc(B_TTY_LINE_LEN);
3317 memset(vargs[i], 0, B_TTY_LINE_LEN);
3318 }
3319 /* See if it is the end of the line */
3320 if (comm[k] == '\0')
3321 {
3322 if ((quoted) & (j != 0))
3323 vargs[i][j - 1] = '"';
3324 vargs[i][j] = '\0';
3325 if (j != 0)
3326 i++;
3327 break;
3328 }
3329 if ((comm[k] == '\'') || (comm[k] == '"'))
3330 {
3331 //vargs[i][j++] = comm[k];
3332 if (quoted)
3333 {
3334 quoted = 0;
3335 vargs[i][j] = '\0';
3336 if (j == 0)
3337 break;
3338 if (++i >= B_TTY_ARGC)
3339 break;
3340 j = 0;
3341 } else
3342 quoted = 1;
3343 } else if ((comm[k] == ' ') & (quoted == 0)) {
3344 vargs[i][j] = '\0';
3345 if (j == 0)
3346 break;
3347 if (++i >= B_TTY_ARGC)
3348 break;
3349 j = 0;
3350 } else
3351 vargs[i][j++] = comm[k];
3352 }
3353
3354 k = bttyExecute(global, i, vargs);
3355
3356 switch (k) {
3357 case 0:
3358 if (btty.flags & B_TTY_DEBUG)
3359 {
3360 snprintf(pbuf, btty.len, "success: command executed\n\r");
3361 v = write(btty.fd[1], pbuf, strlen(pbuf));
3362 }
3363 break;
3364 case B_ERR_NOT_FOUND:
3365 snprintf(pbuf, btty.len, "failed: command not found\n\r");
3366 v = write(btty.fd[1], pbuf, strlen(pbuf));
3367 break;
3368 case B_ERR_PARAM:
3369 snprintf(pbuf, btty.len, "failed: parameter error\n\r");
3370 v = write(btty.fd[1], pbuf, strlen(pbuf));
3371 break;
3372 case B_ERR_VALUE:
3373 snprintf(pbuf, btty.len, "failed: parameter out of range\n\r");
3374 v = write(btty.fd[1], pbuf, strlen(pbuf));
3375 break;
3376 case B_ERR_INV_ARG:
3377 snprintf(pbuf, btty.len, "failed: invalid argument\n\r");
3378 v = write(btty.fd[1], pbuf, strlen(pbuf));
3379 break;
3380 case B_ERR_EXIT:
3381 snprintf(pbuf, btty.len, "requested to exit\n\r");
3382 v = write(btty.fd[1], pbuf, strlen(pbuf));
3383 break;
3384 case B_ERR_EARLY:
3385 break;
3386 default:
3387 snprintf(pbuf, btty.len, "failed: unknown error\n\r");
3388 v = write(btty.fd[1], pbuf, strlen(pbuf));
3389 break;
3390 }
3391
3392 for (i = 0; vargs[i] != NULL; i++)
3393 brightonfree(vargs[i]);
3394 brightonfree(vargs);
3395
3396 snprintf(btty.hist[0], btty.len, "%s", b_blank);
3397 if (~btty.flags & B_TTY_RAW)
3398 {
3399 snprintf(pbuf, btty.len, "\r%s\r", b_blank);
3400 //snprintf(pbuf, btty.len, "\r:");
3401 v = write(btty.fd[1], pbuf, strlen(pbuf));
3402 }
3403
3404 btty.edit_p = 0;
3405 memset(cbuf, 0, B_TTY_LINE_LEN);
3406 memset(btty.hist[0], 0, B_TTY_LINE_LEN);
3407
3408 return(k);
3409 }
3410
3411 static int
bttyPlayMode(guimain * global,char ch)3412 bttyPlayMode(guimain *global, char ch)
3413 {
3414 int v;
3415
3416 if (btty.flags & B_TTY_DEBUG)
3417 {
3418 snprintf(pbuf, btty.len, "%x\r\n", ch);
3419 v = write(btty.fd[1], pbuf, strlen(pbuf));
3420 }
3421
3422 btty.acycle = btty.pcycle;
3423
3424 if (ch == 0x1b)
3425 {
3426 btty.flags &= ~B_TTY_MMASK;
3427 btty.flags |= B_TTY_RAW;
3428 brightonKeyInput(SYNTHS->win, btty.key, 0);
3429 cliParamChange(global, 0.0f);
3430 btty.acycle = btty.cycle;
3431 return(B_ERR_OK);
3432 } else if (ch == ':') {
3433 btty.flags &= ~B_TTY_MMASK;
3434 btty.flags |= B_TTY_COOKED;
3435 brightonKeyInput(SYNTHS->win, btty.key, 0);
3436 snprintf(pbuf, btty.len, "%s", btty.prompt);
3437 v = write(btty.fd[1], pbuf, strlen(pbuf));
3438 btty.acycle = btty.cycle;
3439 return(B_ERR_OK);
3440 }
3441
3442 /* They were the two escape codes, now we have to play keys */
3443 if (ch != btty.key)
3444 {
3445 brightonKeyInput(SYNTHS->win, btty.key, 0);
3446 brightonKeyInput(SYNTHS->win, ch, 1);
3447 btty.key = ch;
3448 btty.flags &= ~B_TTY_CLEAR_KEY;
3449 }
3450
3451 return(B_ERR_OK);
3452 }
3453
3454 static int
bttyCookedMode(guimain * global,char ch)3455 bttyCookedMode(guimain *global, char ch)
3456 {
3457 int v, i;
3458
3459 snprintf(pbuf, btty.len, "\r%s", b_blank);
3460 v = write(btty.fd[1], pbuf, strlen(pbuf));
3461 snprintf(pbuf, btty.len, "\r");
3462 v = write(btty.fd[1], pbuf, strlen(pbuf));
3463
3464 btty.acycle = btty.cycle;
3465
3466 /*
3467 * Start with escape, this will later become interpretted as it could
3468 * also by arrows for history functions.
3469 */
3470 if (btty.flags & B_TTY_RAW_P2) {
3471 btty.flags &= ~B_TTY_MMASK;
3472 btty.flags |= B_TTY_COOKED;
3473 /*
3474 * If we get back here with P2 then we have an arrow escape. Start with
3475 * up and down arrow for history, then command line editing later.
3476 */
3477 switch (ch) {
3478 case 0x43: /* Right */
3479 {
3480 if (cbuf[btty.edit_p] != '\0')
3481 btty.edit_p++;
3482 break;
3483 }
3484 case 0x44: /* Left */
3485 {
3486 if (--btty.edit_p < 0)
3487 btty.edit_p = 0;
3488 //snprintf(tbuf, btty.edit_p, "\r%s", btty.hist[btty.hist_tmp]);
3489 //v = write(btty.fd[1], tbuf, strlen(tbuf));
3490 break;
3491 }
3492 case 0x41: /* Up */
3493 if ((btty.hist_tmp < 50)
3494 && (btty.hist[btty.hist_tmp + 1] != NULL)
3495 && (btty.hist[btty.hist_tmp + 1][0] != '\0'))
3496 {
3497 btty.hist_tmp++;
3498 //memset(cbuf, 0, B_TTY_LINE_LEN);
3499 //memset(btty.hist[btty.hist_tmp], 0, B_TTY_LINE_LEN);
3500 snprintf(cbuf, btty.len, "%s", btty.hist[btty.hist_tmp]);
3501 snprintf(pbuf, btty.len, "%s%s", btty.prompt, cbuf);
3502 v = write(btty.fd[1], pbuf, strlen(pbuf));
3503 } else
3504 snprintf(cbuf, btty.len, "%s", btty.hist[btty.hist_tmp]);
3505 btty.edit_p = strlen(cbuf);;
3506 break;
3507 case 0x42: /* Down */
3508 if (btty.hist_tmp > 0)
3509 btty.hist_tmp--;
3510 snprintf(cbuf, btty.len, "%s", btty.hist[btty.hist_tmp]);
3511 snprintf(pbuf, btty.len, "\r%s%s", btty.prompt, cbuf);
3512 btty.edit_p = strlen(cbuf);;
3513 v = write(btty.fd[1], pbuf, strlen(pbuf));
3514 break;
3515 }
3516 } else if (ch == 0x03) {
3517 /* ^C kill line
3518 btty.edit_p = 0;
3519 btty.hist_tmp = 0;
3520 btty.flags &= ~B_TTY_MMASK;
3521 btty.flags |= B_TTY_RAW_P;
3522 snprintf(pbuf, btty.len, "\r%s%s", btty.prompt, cbuf);
3523 memset(cbuf, 0, B_TTY_LINE_LEN);
3524 btty.edit_p = 0;
3525 v = write(btty.fd[1], pbuf, strlen(pbuf));
3526 cliParamChange(global, 0.0f);
3527 return(0);
3528 */
3529 snprintf(pbuf, btty.len, "\r%s%s\n\r", btty.prompt, cbuf);
3530 v = write(btty.fd[1], pbuf, strlen(pbuf));
3531 memset(cbuf, 0, B_TTY_LINE_LEN);
3532 btty.edit_p = 0;
3533 snprintf(pbuf, btty.len, "\r%s%s", printprompt(global), cbuf);
3534 v = write(btty.fd[1], pbuf, strlen(pbuf));
3535 } else if ((ch == 0x08) || (ch == 0x7f)) {
3536 int c;
3537 /* BS/DEL */
3538 if (btty.edit_p == 0)
3539 {
3540 if (btty.flags & B_TTY_SEARCH)
3541 {
3542 btty.flags &= ~B_TTY_MMASK;
3543 btty.flags |= B_TTY_RAW;
3544 snprintf(pbuf, btty.len, "\r/");
3545 v = write(btty.fd[1], pbuf, strlen(pbuf));
3546 cliParamChange(global, 0.0f);
3547 return(1);
3548 }
3549 //snprintf(pbuf, btty.len, "\r:");
3550 snprintf(pbuf, btty.len, "\r%s%s", btty.prompt, cbuf);
3551 //pbuf[1] = btty.delim;
3552 v = write(btty.fd[1], pbuf, strlen(pbuf));
3553 return(0);
3554 }
3555
3556 btty.edit_p--;
3557
3558 for (c = btty.edit_p; c < strlen(cbuf); c++)
3559 cbuf[c] = cbuf[c + 1];
3560
3561 if (btty.flags & B_TTY_COOKED)
3562 snprintf(pbuf, btty.len, "\r%s%s", btty.prompt, cbuf);
3563 else if (btty.flags & B_TTY_SEARCH)
3564 snprintf(pbuf, btty.len, "\r/%s", cbuf);
3565 v = write(btty.fd[1], pbuf, strlen(pbuf));
3566 if (strlen(cbuf) == btty.len)
3567 {
3568 cbuf[strlen(cbuf) - 1] = '\0';
3569 btty.edit_p = strlen(cbuf);;
3570 }
3571 } else if ((ch == 0x0c) || (ch == 0x12)) {
3572 /* ^L ^R - redraw */
3573 snprintf(pbuf, btty.len, "\r%s%s", btty.prompt, cbuf);
3574 pbuf[1] = btty.delim;
3575 } else if (ch == 0x09) {
3576 /* tab */
3577 bttyComplete(global);
3578 } else if (ch == 0x01) {
3579 /* ^A start of line */
3580 snprintf(pbuf, btty.len, "\r%s%s", btty.prompt, cbuf);
3581 btty.edit_p = 0;
3582 v = write(btty.fd[1], pbuf, strlen(pbuf));
3583 } else if (ch == 0x05) {
3584 /* ^E end of line */
3585 snprintf(pbuf, btty.len, "\r%s%s", btty.prompt, cbuf);
3586 btty.edit_p = strlen(cbuf);
3587 v = write(btty.fd[1], pbuf, strlen(pbuf));
3588 } else if (ch == 0x0e) {
3589 /* Down hist ^n */
3590 if (btty.hist_tmp > 0)
3591 btty.hist_tmp--;
3592 snprintf(cbuf, btty.len, "%s", btty.hist[btty.hist_tmp]);
3593 snprintf(pbuf, btty.len, "\r%s%s", btty.prompt, cbuf);
3594 btty.edit_p = strlen(cbuf);;
3595 v = write(btty.fd[1], pbuf, strlen(pbuf));
3596 } else if (ch == 0x10) {
3597 /* Up hist ^p */
3598 if ((btty.hist_tmp < 50)
3599 && (btty.hist[btty.hist_tmp + 1] != NULL)
3600 && (btty.hist[btty.hist_tmp + 1][0] != '\0'))
3601 {
3602 btty.hist_tmp++;
3603 //memset(cbuf, 0, B_TTY_LINE_LEN);
3604 //memset(btty.hist[btty.hist_tmp], 0, B_TTY_LINE_LEN);
3605 snprintf(cbuf, btty.len, "%s", btty.hist[btty.hist_tmp]);
3606 snprintf(pbuf, btty.len, "\r%s%s", btty.prompt, cbuf);
3607 v = write(btty.fd[1], pbuf, strlen(pbuf));
3608 } else
3609 snprintf(cbuf, btty.len, "%s", btty.hist[btty.hist_tmp]);
3610 btty.edit_p = strlen(cbuf);;
3611 } else if (ch == 0x15) {
3612 /* ^U kill line */
3613 memset(cbuf, 0, B_TTY_LINE_LEN);
3614 memset(btty.hist[0], 0, B_TTY_LINE_LEN);
3615 btty.edit_p = 0;
3616 btty.hist_tmp = 0;
3617 } else if (ch == 0x17) {
3618 int t = btty.edit_p - 1;
3619 int o = btty.edit_p;
3620 /* ^W kill word - current edit point to start of previous word */
3621 snprintf(btty.hist[0], btty.len, "%s", cbuf);
3622 while (cbuf[t] == ' ')
3623 {
3624 if (--t == 0)
3625 break;
3626 }
3627 if (strlen(cbuf) != '\0')
3628 {
3629 while (t != 0)
3630 {
3631 if (cbuf[t] == ' ')
3632 break;
3633 t--;
3634 }
3635 if (t != 0)
3636 btty.edit_p = ++t;
3637 else
3638 btty.edit_p = 0;
3639 while ((cbuf[t++] = cbuf[o++]) != '\0')
3640 ;
3641
3642 if (btty.flags & B_TTY_COOKED)
3643 snprintf(pbuf, btty.len, "\r%s%s", btty.prompt, cbuf);
3644 else
3645 snprintf(pbuf, btty.len, "\r/%s", cbuf);
3646 v = write(btty.fd[1], pbuf, strlen(pbuf));
3647 }
3648 } else if (ch == 0x1b) {
3649 /* Esc - we should not actually get this */
3650 btty.flags &= ~B_TTY_MMASK;
3651 btty.flags |= B_TTY_RAW_P;
3652 cliParamChange(global, 0.0f);
3653 return(1);
3654 } else if ((ch == 0x0a) || (ch == 0x0d)) {
3655 /*
3656 * Enter
3657 if (cbuf[0] == '\0')
3658 {
3659 snprintf(pbuf, btty.len, ":\r");
3660 pbuf[0] = btty.delim;
3661 v = write(btty.fd[1], pbuf, strlen(pbuf));
3662 btty.flags &= ~B_TTY_MMASK;
3663 btty.flags |= B_TTY_RAW_P;
3664 cliParamChange(global, 0.0f);
3665 return(1);
3666 }
3667 */
3668 if (btty.flags & B_TTY_COOKED)
3669 {
3670 int i;
3671 snprintf(pbuf, btty.len, "\r%s%s\n\r", btty.prompt, cbuf);
3672 v = write(btty.fd[1], pbuf, strlen(pbuf));
3673 if ((i = bttyInterpret(global, cbuf)) < 0)
3674 {
3675 brightonCLIcleanup();
3676 return(i);
3677 }
3678 if (i != B_ERR_EARLY)
3679 {
3680 snprintf(pbuf, btty.len, "\r%s%s", printprompt(global), cbuf);
3681 v = write(btty.fd[1], pbuf, strlen(pbuf));
3682 }
3683 return(i);
3684 }
3685 if (btty.flags & B_TTY_SEARCH)
3686 {
3687 if (cbuf[0] == '\0')
3688 {
3689 btty.flags &= ~B_TTY_MMASK;
3690 btty.flags |= B_TTY_RAW;
3691 snprintf(pbuf, btty.len, "\r/");
3692 v = write(btty.fd[1], pbuf, strlen(pbuf));
3693 cliParamChange(global, 0.0f);
3694 return(1);
3695 }
3696 snprintf(pbuf, btty.len, "/%s", cbuf);
3697 v = write(btty.fd[1], pbuf, strlen(pbuf));
3698 return(bttySearch(global));
3699 }
3700 } else {
3701 /* Insert char at edit point */
3702 for (i = strlen(cbuf) + 1; i >= btty.edit_p; i--)
3703 cbuf[i] = cbuf[i - 1];
3704 cbuf[btty.edit_p++] = ch;
3705 }
3706
3707 if (btty.flags & B_TTY_SEARCH)
3708 {
3709 snprintf(pbuf, btty.len, "\r/%s", cbuf);
3710 v = write(btty.fd[1], pbuf, strlen(pbuf));
3711 } else if (btty.flags & B_TTY_COOKED) {
3712 if (strlen(cbuf) >= 79)
3713 return(bttyInterpret(global, cbuf));
3714 snprintf(pbuf, btty.len, "\r%s%s", btty.prompt, cbuf);
3715 v = write(btty.fd[1], pbuf, strlen(pbuf));
3716 }
3717
3718 /* Cursor positioning for command line editing */
3719 *pbuf = 0x08;
3720 for (i = strlen(cbuf); i > btty.edit_p; i--)
3721 v = write(btty.fd[1], pbuf, 1);
3722
3723 return(1);
3724 }
3725
3726 int
brightonCLIcheck(guimain * global)3727 brightonCLIcheck(guimain *global)
3728 {
3729 char ch = 0, chmap = B_TTY_A_NULL;
3730 int i = 0, v = 0, r = 0, s;
3731
3732 if (btty.flags & B_TTY_INIT)
3733 {
3734 struct termios attr;
3735
3736 sleep(1);
3737
3738 memset(&attr, 0, sizeof(struct termios));
3739
3740 tcgetattr(btty.fd[0], &resetattr);
3741 tcgetattr(btty.fd[0], &attr);
3742 cfmakeraw(&attr);
3743 tcsetattr(btty.fd[0], TCSANOW, &attr);
3744
3745 btty.flags &= ~B_TTY_MMASK;
3746
3747 if (SYNTHS->flags & REQ_DEBUG_1)
3748 {
3749 btty.p = RESOURCES->emulate.panel;
3750 snprintf(pbuf, btty.len, "panel: %i\r\n", btty.p);
3751 v = write(btty.fd[1], pbuf, strlen(pbuf));
3752 }
3753
3754 btty.flags &= ~B_TTY_INIT;
3755 btty.flags |= B_TTY_RAW;
3756 snprintf(pbuf, btty.len, "\n\rHi %s!\n\r", getenv("USER"));
3757 v = write(btty.fd[1], pbuf, strlen(pbuf));
3758 snprintf(pbuf, btty.len, "Bristol Command Line Interface.\r\n");
3759 v = write(btty.fd[1], pbuf, strlen(pbuf));
3760 snprintf(pbuf, btty.len, "Cursor motion keys will access parameters.\r\n");
3761 v = write(btty.fd[1], pbuf, strlen(pbuf));
3762 snprintf(pbuf, btty.len, "Try ':help' and ':set cli' for information");
3763 v = write(btty.fd[1], pbuf, strlen(pbuf));
3764 btty.i = 0;
3765 }
3766
3767 FD_ZERO(stdioset);
3768 FD_SET(btty.fd[0], stdioset);
3769 timeout.tv_sec = 0;
3770
3771 if ((timeout.tv_usec = btty.acycle * 1000 - 1) < 0)
3772 timeout.tv_usec = 100000;
3773
3774 /*
3775 * We have three modes here:
3776 * raw: default vi type control
3777 * insert mode: readline style entry
3778 * raw_p pending: seen escape but might be arrow keys, needs second state
3779 */
3780 while ((s = select(2, stdioset, NULL, NULL, &timeout)) != 0)
3781 {
3782 r = read(btty.fd[0], &ch, 1);
3783
3784 // pbuf[0] = ch + 96;
3785 // pbuf[1] = '\0';
3786 // print(pbuf);
3787 printChar(ch);
3788
3789 if (ch == 0x04)
3790 {
3791 brightonCLIcleanup();
3792 return(-1);
3793 }
3794
3795 switch (btty.flags & B_TTY_MMASK) {
3796 default:
3797 case B_TTY_RAW:
3798 if (ch == 0x1b)
3799 {
3800 /* Esc */
3801 btty.flags &= ~B_TTY_MMASK;
3802 btty.flags |= B_TTY_RAW_ESC;
3803 return(1);
3804 }
3805 if (ch == 0x0c)
3806 {
3807 if ((unnamed(btty.i)) && (~btty.flags & B_TTY_AWV))
3808 break;
3809
3810 cliParamChange(global, 0.0f);
3811 return(0);
3812 }
3813 break;
3814 if (ch == 0x0d)
3815 {
3816 if (btty.i >= SYNTHS->win->app->resources[btty.p].ndevices)
3817 btty.i = SYNTHS->win->app->resources[btty.p].ndevices-1;
3818
3819 if ((unnamed(btty.i)) && (~btty.flags & B_TTY_AWV))
3820 break;
3821
3822 cliParamChange(global, 0.0f);
3823 return(0);
3824 }
3825 break;
3826 case B_TTY_RAW_ESC:
3827 if (ch == '[')
3828 {
3829 btty.flags &= ~B_TTY_MMASK;
3830 btty.flags |= B_TTY_RAW_ESC2;
3831 return(1);
3832 }
3833 break;
3834 case B_TTY_RAW_P:
3835 /* If we get 'O' go to P2 else RAW */
3836 btty.flags &= ~B_TTY_MMASK;
3837 if (ch == '[') {
3838 btty.flags |= B_TTY_RAW_P2;
3839 return(1);
3840 }
3841 btty.flags |= B_TTY_RAW;
3842 break;
3843 case B_TTY_RAW_P2:
3844 if ((ch == 0x41) || (ch == 0x42)
3845 || (ch == 0x43) || (ch == 0x44))
3846 return(bttyCookedMode(global, ch));
3847 btty.flags &= ~B_TTY_MMASK;
3848 btty.flags |= B_TTY_RAW;
3849 break;
3850 case B_TTY_COOKED:
3851 if (ch == 0x1b)
3852 {
3853 btty.flags &= ~B_TTY_MMASK;
3854 btty.flags |= B_TTY_RAW_P;
3855 return(1);
3856 }
3857 case B_TTY_SEARCH:
3858 return(bttyCookedMode(global, ch));
3859 case B_TTY_PLAY:
3860 return(bttyPlayMode(global, ch));
3861 }
3862
3863 if (btty.flags & B_TTY_RAW_ESC2)
3864 {
3865 btty.flags &= ~B_TTY_MMASK;
3866 btty.flags |= B_TTY_RAW;
3867 switch (ch) {
3868 case 0x41:
3869 ch = 'k';
3870 break;
3871 case 0x42:
3872 ch = 'j';
3873 break;
3874 case 0x43:
3875 ch = 'l';
3876 break;
3877 case 0x44:
3878 ch = 'h';
3879 break;
3880 case 0x0d:
3881 case 0x0a:
3882 ch = 'l';
3883 break;
3884 }
3885 }
3886 if (btty.flags & B_TTY_RAW_ESC2)
3887 {
3888 switch (ch) {
3889 case 0x5b:
3890 case 0x1b:
3891 btty.flags &= ~B_TTY_MMASK;
3892 btty.flags |= B_TTY_RAW_P;
3893 return(i);
3894 }
3895 }
3896 /*
3897 switch (ch) {
3898 case 0x0d:
3899 if (++btty.i >= SYNTHS->mem.active)
3900 btty.i = SYNTHS->mem.active -1;
3901
3902 if (DEVICE(bbty.i).flags & BRIGHTON_WITHDRAWN)
3903 break;
3904
3905 cliParamChange(global, 0.0f);
3906 return(0);
3907 };
3908 */
3909
3910 for (i = 0; i < B_TTY_ACT_COUNT; i++)
3911 {
3912 if (action[i].map == '\0')
3913 break;
3914 if (action[i].map == ch)
3915 {
3916 chmap = action[i].imap;
3917 /*
3918 * We need to exec the template here, it is not predefined so
3919 * is probably an aliased command for accelerated access
3920 */
3921 if (chmap >= B_TTY_A_PREDEF)
3922 {
3923 i = chmap;
3924 print(templates[i].opname);
3925 snprintf(cbuf, B_TTY_LINE_LEN, "%s", templates[i].opname);
3926 return(bttyInterpret(global, cbuf));
3927 }
3928 break;
3929 }
3930 }
3931
3932 if ((chmap == B_TTY_A_NULL) || (i == B_TTY_ACT_COUNT))
3933 return(1);
3934
3935 switch (chmap) {
3936 case B_TTY_A_M_TOG:
3937 {
3938 int cmem;
3939
3940 if ((SYNTHS->flags & REQ_DEBUG_MASK) > REQ_DEBUG_2)
3941 snprintf(pbuf, btty.len,
3942 "excepted Control switch memory: %s\r\n",
3943 RESOURCES->name);
3944 v = write(btty.fd[1], pbuf, strlen(pbuf));
3945
3946 cmem = SYNTHS->cmem;
3947
3948 if (SYNTHS->loadMemory != NULL)
3949 SYNTHS->loadMemory(SYNTHS,
3950 RESOURCES->name, 0,
3951 SYNTHS->lmem, SYNTHS->mem.active, 0, btty.fl);
3952 else
3953 loadMemory(SYNTHS, RESOURCES->name,
3954 0, SYNTHS->lmem, SYNTHS->mem.active,
3955 0, btty.fl);
3956 SYNTHS->lmem = cmem;
3957 break;
3958 }
3959 case B_TTY_A_M_WRITE:
3960 /* Save */
3961 SYNTHS->cmem = SYNTHS->lmem;
3962 if (SYNTHS->saveMemory != NULL)
3963 SYNTHS->saveMemory(SYNTHS,
3964 RESOURCES->name, 0,
3965 SYNTHS->location, 0);
3966 else
3967 saveMemory(SYNTHS, RESOURCES->name,
3968 0, SYNTHS->location, 0);
3969 snprintf(pbuf, btty.len, "\r\nwrite: %i", SYNTHS->location);
3970 v = write(btty.fd[1], pbuf, strlen(pbuf));
3971 break;
3972 case B_TTY_A_M_READ:
3973 /* Open */
3974 SYNTHS->lmem = SYNTHS->cmem;
3975 if (SYNTHS->loadMemory != NULL)
3976 SYNTHS->loadMemory(SYNTHS,
3977 RESOURCES->name,
3978 0, SYNTHS->location, SYNTHS->mem.active,
3979 0, btty.fl);
3980 else
3981 loadMemory(SYNTHS, RESOURCES->name,
3982 0, SYNTHS->location, SYNTHS->mem.active,
3983 0, btty.fl);
3984 SYNTHS->cmem = SYNTHS->location;
3985 snprintf(pbuf, btty.len, "read: %i\r\n", SYNTHS->location);
3986 v = write(btty.fd[1], pbuf, strlen(pbuf));
3987 break;
3988 case B_TTY_A_M_DOWN:
3989 /* Mem down */
3990 if (--SYNTHS->location < 0)
3991 SYNTHS->location = 99;
3992 if (loadMemory(SYNTHS, RESOURCES->name,
3993 0, SYNTHS->location, SYNTHS->mem.active,
3994 0, BRISTOL_STAT) < 0)
3995 snprintf(pbuf, btty.len, "free mem: %i\r\n",
3996 SYNTHS->location);
3997 else
3998 snprintf(pbuf, btty.len, "mem: %i\r\n", SYNTHS->location);
3999 v = write(btty.fd[1], pbuf, strlen(pbuf));
4000 break;
4001 case B_TTY_A_M_UP:
4002 /* Mem up */
4003 if (++SYNTHS->location > 99)
4004 SYNTHS->location = 0;
4005 if (loadMemory(SYNTHS, RESOURCES->name,
4006 0, SYNTHS->location, SYNTHS->mem.active,
4007 0, BRISTOL_STAT) < 0)
4008 snprintf(pbuf, btty.len, "free mem: %i\r\n",
4009 SYNTHS->location);
4010 else
4011 snprintf(pbuf, btty.len, "mem: %i\r\n", SYNTHS->location);
4012 v = write(btty.fd[1], pbuf, strlen(pbuf));
4013 break;
4014 case B_TTY_A_LEFT:
4015 if (--btty.i < 0)
4016 {
4017 btty.i = 0;
4018 break;
4019 }
4020
4021 if ((paramname(btty.i)[0] == '\0') && (~btty.flags & B_TTY_AWV))
4022 {
4023 while (paramname(btty.i)[0] == '\0')
4024 {
4025 btty.i--;
4026 if (btty.i < 0)
4027 {
4028 btty.i = 0;
4029 return(1);
4030 }
4031 }
4032 }
4033
4034 cliParamChange(global, 0.0f);
4035 break;
4036 case B_TTY_A_RIGHT:
4037 btty.i++;
4038
4039 if (btty.i >= SYNTHS->win->app->resources[btty.p].ndevices)
4040 {
4041 btty.i = SYNTHS->win->app->resources[btty.p].ndevices - 1;
4042 break;
4043 }
4044
4045 //if ((DEVICE(btty.i).flags & BRIGHTON_WITHDRAWN)
4046 if ((unnamed(btty.i)) && (~btty.flags & B_TTY_AWV))
4047 {
4048 int h = btty.i - 1;
4049 //while (DEVICE(btty.i).flags & BRIGHTON_WITHDRAWN)
4050 while (paramname(btty.i)[0] == '\0')
4051 {
4052 if (++btty.i
4053 >= SYNTHS->win->app->resources[btty.p].ndevices)
4054 {
4055 if ((btty.i = h) < 0)
4056 btty.i = 0;
4057 return(1);
4058 }
4059 }
4060 }
4061
4062 cliParamChange(global, 0.0f);
4063 break;
4064 case B_TTY_A_UPDATE:
4065 /* refresh */
4066 cliParamChange(global, 0.0f);
4067 break;
4068 case B_TTY_A_DECMAX:
4069 /* Param down */
4070 cliParamChange(global, -0.1f);
4071 break;
4072 case B_TTY_A_DEC:
4073 /* Param down */
4074 cliParamChange(global, -btty.accel);
4075 break;
4076 /*
4077 * Param down
4078 */
4079 case B_TTY_A_DEC1:
4080 cliParamChange(global, -1.0f/16383);
4081 break;
4082 case B_TTY_A_DEC4:
4083 cliParamChange(global, -4.0f/16383);
4084 break;
4085 case B_TTY_A_DECMIN:
4086 cliParamChange(global, -0.001f);
4087 break;
4088 case B_TTY_A_INCMAX:
4089 /* Param up */
4090 cliParamChange(global, 0.1f);
4091 break;
4092 case B_TTY_A_INC:
4093 /* Param up */
4094 cliParamChange(global, btty.accel);
4095 break;
4096 /*
4097 * Param up
4098 */
4099 case B_TTY_A_INCMIN:
4100 cliParamChange(global, 0.001f);
4101 break;
4102 case B_TTY_A_INC1:
4103 cliParamChange(global, 1.0f/16383.001f);
4104 break;
4105 case B_TTY_A_INC4:
4106 cliParamChange(global, 4.0f/16383.001f);
4107 break;
4108 case B_TTY_A_INSERT:
4109 seqStop(global);
4110 btty.flags &= ~(B_TTY_MMASK|B_TTY_SEQ);
4111 btty.flags |= B_TTY_COOKED;
4112 btty.edit_p = 0;
4113 memset(cbuf, 0, B_TTY_LINE_LEN);
4114 snprintf(pbuf, btty.len, "\n\r%s", printprompt(global));
4115 btty.delim = ':';
4116 v = write(btty.fd[1], pbuf, strlen(pbuf));
4117 break;
4118 case B_TTY_A_FIND:
4119 btty.flags &= ~B_TTY_MMASK;
4120 btty.flags |= B_TTY_SEARCH;
4121 btty.edit_p = 0;
4122 memset(cbuf, 0, B_TTY_LINE_LEN);
4123 snprintf(pbuf, btty.len, "\n\r/");
4124 btty.delim = '/';
4125 v = write(btty.fd[1], pbuf, strlen(pbuf));
4126 break;
4127 default:
4128 case B_TTY_A_NULL:
4129 snprintf(pbuf, btty.len, "unimplemented char 0x%x\r\n", ch);
4130 if (SYNTHS->flags & REQ_DEBUG_1)
4131 v = write(btty.fd[1], pbuf, strlen(pbuf));
4132 break;
4133 }
4134 lp = PDEV(btty.i)->value;
4135 }
4136
4137 /* if the GUI has changed the value we show here, CLI to match */
4138 if ((btty.flags & B_TTY_PLAY) && (btty.flags & B_TTY_PLAY_LINE))
4139 {
4140 if (btty.flags & B_TTY_CLEAR_KEY)
4141 {
4142 brightonKeyInput(SYNTHS->win, btty.key, 0);
4143 btty.key = 255;
4144 }
4145
4146 btty.flags |= B_TTY_CLEAR_KEY;
4147 }
4148
4149 if (btty.flags & B_TTY_SEQ)
4150 {
4151 if (sequences[btty.sequence.id].count > 0)
4152 {
4153 if ((btty.sequence.count -= btty.acycle) <= 0)
4154 {
4155 /* Send note off/on */
4156 print("note off");
4157 if (btty.sequence.step < 0)
4158 btty.sequence.step = sequences[btty.sequence.id].count;
4159 else if (sequences[btty.sequence.id].step[btty.sequence.step]
4160 > 0)
4161 bristolMidiSendMsg(global->controlfd, SYNTHS->midichannel,
4162 BRISTOL_EVENT_KEYOFF, 0,
4163 sequences[btty.sequence.id].step[btty.sequence.step]
4164 + btty.sequence.transpose);
4165
4166 if (++btty.sequence.step
4167 >= sequences[btty.sequence.id].count)
4168 btty.sequence.step = 0;
4169
4170 print("note on");
4171 if (sequences[btty.sequence.id].step[btty.sequence.step] > 0)
4172 bristolMidiSendMsg(global->controlfd, SYNTHS->midichannel,
4173 BRISTOL_EVENT_KEYON, 0,
4174 sequences[btty.sequence.id].step[btty.sequence.step]
4175 + btty.sequence.transpose);
4176
4177 btty.sequence.count =
4178 250 * 60 / sequences[btty.sequence.id].rate;
4179
4180 snprintf(pbuf, btty.len, "rate %i, count %i(%i), step %i\n\r",
4181 sequences[0].rate, btty.sequence.count, btty.acycle,
4182 btty.sequence.step);
4183 v = write(btty.fd[1], pbuf, strlen(pbuf));
4184 }
4185 } else {
4186 btty.flags &= ~B_TTY_SEQ;
4187 seqStop(global);
4188 }
4189 }
4190
4191 if ((btty.flags & B_TTY_RAW)
4192 && (s == 0) && (r == 0)
4193 && (lp != PDEV(btty.i)->value))
4194 {
4195 lp = PDEV(btty.i)->value;
4196 cliParamChange(global, 0.0f);
4197 }
4198
4199 if ((r == 0) && (btty.flags & B_TTY_RAW_P))
4200 {
4201 btty.flags &= ~B_TTY_MMASK;
4202 btty.flags |= B_TTY_RAW;
4203 cliParamChange(global, 0.0f);
4204 }
4205
4206 return(r);
4207 }
4208
4209