1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-10-10 16:43:33 +02:00

Update Nyquist to v3.09.

This commit is contained in:
Leland Lucius
2015-04-07 22:10:17 -05:00
parent f88b27e6d8
commit 9fb0ce5b82
358 changed files with 26327 additions and 7043 deletions

View File

@@ -0,0 +1,2 @@
// button.h -- simple slider input

View File

@@ -0,0 +1,39 @@
#pragma warning( disable: 4237 ) // eub: temporary kludge
// RBD -- this will define true, false, bool
#include "yvals.h"
//these preprocessor checks seem to get rid of compiler
// error (redecl boolean)
// typedef int bool;
//#ifndef TRUE
#define TRUE 1
#define FALSE 0
//#endif
#define EOS '\000'
// now defined by yvals.h:
//#define true 1
//#define false 0
#define MALLOC ::malloc // note -- these macros are not consistently used
#define FREE ::free
void *MEMGET(long n);
void *MEMFREE(void *data, long n);
#define STREQ(a, b) (strcmp((a), (b)) == 0)
typedef unsigned long uint32;
typedef long int32;
typedef unsigned short uint16;
typedef short int16;
typedef unsigned char uint8;
//istvan 082197
// RBD commented out the following, instead, we're including yvals.h,
// a microsoft-dependent file
// #ifndef bool
// typedef unsigned char bool;
// #endif

View File

@@ -0,0 +1,34 @@
#include "stddef.h"
#include "cppext.h"
#include "longque.h"
#include "stdlib.h"
void longque::init(int size)
{
head = 0;
tail = 0;
count = 0;
max = size;
buff = (long *) malloc(sizeof(long) * size);
}
void longque::finish()
{
free(buff);
}
//1 producer-consumer safe
long longque::remove()
{
long l;
if (count <= 0) return 0;
count--;
l = buff[head++];
if (head == max) head = 0;
return l;
}

View File

@@ -0,0 +1,28 @@
class longque {
public:
void init(int size);
void finish();
//1 producer-consumer safe
void insert(long l) {
buff[tail] = l;
count++;
tail++;
if (tail == max) tail = 0;
}
long remove();
bool fullp() {
return count >= max;
}
bool emptyp() {
return count <= 0;
}
protected:
int max;
long *buff;
int head;
int tail;
int count;
};

View File

@@ -0,0 +1,21 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by winmain.rc
//
#define IDM_ABOUT 100
#define IDI_NYCON 101
#define ID_FILE_LOAD 101
#define ID_FILE_RELOAD 102
#define ID_FILE_EXIT 103
#define IDC_STATIC -1
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 103
#define _APS_NEXT_COMMAND_VALUE 104
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@@ -0,0 +1,6 @@
// slider.h -- simple slider input
#define NUMSLIDERS 9
extern HWND sliders[NUMSLIDERS];
void set_slider_pos(HWND hwnd, int ival);

View File

@@ -0,0 +1,248 @@
// textio.cpp -- handles text input and output to edit control
/*
Overview of character input:
ostgetc is called to get characters from stdin for XLisp
ostgetc gets characters using ggetchar() and performs line editing
ggetchar gets characters using wait_ascii()
wait_ascii() get characters from typein:queue; it calls
process_win_events if there are no characters, and it returns
ABORT_CHAR or BREAK_CHAR if abort_flag is set
characters get into typein::queue when the key handler is called
get_ascii is similar to wait_ascii, but it doesn't wait: it just
checks for input with process_win_events and returns a character
if there is one, otherwise, it returns false
*/
#include <stddef.h>
#include <stdarg.h>
#include <stdio.h>
#include <windows.h>
#include "cppext.h"
#include "longque.h"
#include "textio.h"
#include "typein.h"
#include "button.h"
#include "slider.h"
#include "winmain.h"
#include "assert.h"
extern "C" {
#include "xlisp.h"
}
#define GPRINTF_MESSAGE_LEN 500
//istvanmerge
//int abort_flag = 0;
longque typein::queue;
void typein::init()
{
queue.init(100);
}
void typein::finish()
{
queue.finish();
}
void typein::handler(char *inp)
{
if (!queue.fullp()) {
if (*inp == ABORT_CHAR) {
abort_flag = ABORT_LEVEL;
free(inp);
} else if (!abort_flag && *inp == BREAK_CHAR) {
abort_flag = BREAK_LEVEL;
free(inp);
} else if (!abort_flag && *inp == INFO_CHAR) {
xinfo();
free(inp);
} else queue.insert((long) inp);
}
}
extern char *next_ascii;
extern "C"
int get_ascii(char *c)
{
check_aborted(); /* input buffer check */
if (!next_ascii && typein::queue.emptyp()) return false;
*c = wait_ascii();
return true; // recurse with new string
}
/* check_aborted -- see if any characters are available, check for ctrl C */
extern "C"
int check_aborted()
{
process_win_events(USE_PEEK);
/* handle input messages, if ^C, handler will set abort flag */
return abort_flag;
}
/* define with va_alist and use vsprintf to get temp */
extern "C"
void gprintf(long where, char *format, ...)
{
char temp[GPRINTF_MESSAGE_LEN];
va_list pvar;
va_start(pvar, format);
_vsnprintf(temp, GPRINTF_MESSAGE_LEN, format, pvar);
va_end(pvar);
switch((long) where) {
case GTRANS:
break;
case GERROR:
break;
case GFATAL:
edit_append("FATAL: ");
edit_append(temp);
break;
case GDEBUG:
edit_append("DEBUG: ");
edit_append(temp);
break;
default:
edit_append("UNKNOWN: ");
edit_append(temp);
break;
}
edit_append(temp);
}
#if defined(nyquist_printf)
#error "nyquist_printf should not be defined yet"
#endif
extern "C"
void nyquist_printf(const char *format, ...)
{
char temp[GPRINTF_MESSAGE_LEN];
va_list pvar;
va_start(pvar, format);
_vsnprintf(temp, GPRINTF_MESSAGE_LEN, format, pvar);
va_end(pvar);
edit_append(temp);
}
/**************************************************************************
* gputchar
* General putchar
**************************************************************************/
extern "C"
void gputchar(int c)
{
char tmp[4];
tmp[0] = c;
tmp[1] = 0;
edit_append(tmp);
}
/**************************************************************************
* ggetchar
* General getchar
**************************************************************************/
extern "C"
int ggetchar()
{
return wait_ascii();
}
/**************************************************************************
* ggets
* General gets
**************************************************************************/
extern "C"
char *ggets(char *str)
{
char *s = str;
int c;
do {
c = ggetchar();
if (c == '\b' /* backspace */) {
if (s != str) {
gputchar('\b');
gputchar((int)' ');
gputchar('\b');
s--;
} else {
gputchar((int)0x07);
}
} else *s++ = (char) c;
} while (c != (int) '\n' && !abort_flag);
*(s-1) = EOS;
if (abort_flag) *str = EOS;
return str;
}
/****************************************************************************
* askbool
* Inputs:
* char *prompt: string to prompt for user input
* int deflt: true or false default
* Returns:
* boolean: true or false as entered by user
* Effect:
* prompts user for yes or no input, returns result
****************************************************************************/
extern "C"
int askbool(char *prompt, int deflt)
{
#define undefined -1
char defchar; /* the default answer */
char c; /* user input */
char in_string[100];
int result = -1; /* the result: -1 = undefined, 0 = false, 1 = true */
if (deflt) defchar = 'y';
else defchar = 'n';
while (result == undefined) {
gprintf(GTRANS, "%s? [%c]: ", prompt, defchar);
ggets(in_string);
c = in_string[0];
if (islower(c)) c = toupper(c);
if (c == 'Y') result = true;
else if (c == 'N') result = false;
else if (c == EOS) result = deflt;
else if (abort_flag) result = deflt;
/* space before Please to separate from user's type-in: */
else gprintf(GTRANS, " Please type Y or N.\n");
}
if (abort_flag == BREAK_LEVEL) {
abort_flag = 0;
result = deflt;
gprintf(GTRANS, "\n");
}
return result;
}
extern "C"
void io_init()
{
}

View File

@@ -0,0 +1,36 @@
#define CR '\n'
#define ABORT_CHAR 0x03
#define BREAK_CHAR 0x02
#define CLEANUP_CHAR 0x07
#define INFO_CHAR '\024'
#define BREAK_LEVEL 1
#define ABORT_LEVEL 2
#ifdef __cplusplus
extern "C" {
#endif
int ggetchar(void);
void gprintf(long where, char *format, ...);
void gputchar(int c);
int get_ascii(char *c);
char *ggets(char *str);
int check_aborted();
int askbool(char *prompt, int deflt);
char wait_ascii();
void io_init();
/* this is not entirely kosher: nyquist_printf is also declared in sound.h
so that all C programs will see it. Perhaps it should go into cext.h, but
I'm not sure I want to drag all that into here.
*/
void nyquist_printf(const char *format, ...);
#ifdef __cplusplus
}
#endif
#define GTRANS 0
#define GERROR 1
#define GFATAL 2
#define GDEBUG 3

View File

@@ -0,0 +1,8 @@
class typein {
public:
static longque queue;
static void init(void);
static void finish(void);
static void handler(char *inp);
};

View File

@@ -0,0 +1,366 @@
/* winstuff.c - windows interface routines for xlisp */
/* Written by Chris Tchou. */
/* This file contains the stuff that the other xlisp files call directly. */
#include "windows.h"
#include <stdio.h>
//#include <QuickDraw.h> /* for Random */
#include <memory.h> /* for DisposPtr */
#include <string.h>
//#include <SegLoad.h> /* for ExitToShell */
#include "xlisp.h"
#include "textio.h"
#if OSC
#include "sliders.h" /* define sliders */
#include "sound.h" /* define nosc_enabled */
#endif
#include "falloc.h" /* define table_memory */
const char os_pathchar = '\\';
const char os_sepchar = ',';
/* externals */
extern FILE *tfp; /* transcript file pointer */
extern int cursorPos;
extern char *macgets (void);
#define LBSIZE 200
/* local variables */
static char lbuf[LBSIZE];
static int lpos[LBSIZE];
static int lindex;
static int lcount = 0;
static int lposition;
static int line_edit = TRUE;
//int isascii (char c) { return 1; } /* every char is an ascii char, isn't it? */
void osinit(const char *banner) {
// int i;
char version[] = "\nWindows console interface by Roger Dannenberg.\n";
// InitMac (); /* initialize the mac interface routines */
// lposition = 0; /* initialize the line editor */
// for (i = 0; banner[i] != '\0'; i++) macputc (banner[i]);
// for (i = 0; version[i] != '\0'; i++) macputc (version[i]);
nyquist_printf(banner);
nyquist_printf(version);
}
FILE *osaopen (const char *name, const char *mode) {
FILE *fp = NULL;
if (ok_to_open(name, mode))
fp = fopen (name, mode);
return fp;
}
FILE *osbopen (const char *name, const char *mode) {
FILE *fp = NULL;
char nmode[4];
strcpy (nmode, mode); strcat (nmode, "b");
if (ok_to_open(name, mode))
fp = fopen (name, mode);
return fp;
}
int osclose (FILE *fp) { return (fclose (fp)); }
int osaputc (int ch, FILE *fp) { return (putc (ch, fp)); }
int osbputc (int ch, FILE *fp) { return (putc (ch, fp)); }
void osoutflush(FILE *fp) { fflush(fp); }
/* osagetc - get a character from an ascii file */
int osagetc(fp)
FILE *fp;
{
return (getc(fp));
}
extern int abort_flag;
#define OLDGETC
#ifdef OLDGETC
int ostgetc (void) {
/* int i;
if (numChars <= 0) { /* get some more */
/* if (linebuf) DisposPtr (linebuf);
linebuf = macgets ();
i = 0;
while (linebuf[i] != '\0') i++;
numChars = i;
if (tfp) for (i = 0; i < numChars; i++) osaputc (linebuf[i], tfp);
lineptr = linebuf;
}
numChars--;
if (*lineptr == '\r') {
lineptr++;
return '\n';
} else return (*lineptr++);*/
int ch = ggetchar();
oscheck(); /* in case user typed ^C */
if (ch == BREAK_CHAR && abort_flag == BREAK_LEVEL) {
abort_flag = 0;
}
return ch;
}
#else
void end_of_line_edit()
{
line_edit = FALSE;
if (tfp) {
for (lindex = 0; lindex < lcount; ++lindex)
osaputc(lbuf[lindex], tfp);
}
lindex = 0;
}
int ostgetc()
{
/*
* NOTE: lbuf[] accumulates characters as they are typed
* lpos[] is the column position of the characters
* lcount is the number of characters in lbuf
* lposition is current position
* lindex is index of next char to output
* line_edit is true iff we're inputing characters
*
*/
int ch;
while (line_edit) {
ch = ggetchar();
oscheck(); /* in case user typed ^C */
if (ch == BREAK_CHAR && abort_flag == BREAK_LEVEL) {
abort_flag = 0;
}
/* assume for now we should add the character */
lbuf[lcount] = ch;
lpos[lcount] = lposition;
lcount++;
lposition++;
/* now do all the special character processing */
switch (ch) {
case '\n':
lposition = 0;
end_of_line_edit();
gputchar('\r');
gputchar(ch);
break;
/* delete key generates: 1b, 5b, 33, 7E
which is: ESC, [, 3, ~ */
case '\010': /* backspace */
case '\177': /* delete */
lcount--; /* take out backspace or delete char */
lposition--;
if (lcount) {
lcount--;
while (lposition > lpos[lcount]) {
gputchar('\010');
gputchar(' ');
gputchar('\010');
lposition--;
}
}
break;
case '\025': /* control-u */
lcount--;
lposition--;
if (lcount) {
while (lposition > lpos[0]) {
gputchar('\010');
gputchar(' ');
gputchar('\010');
lposition--;
}
lcount = 0;
}
break;
/* note that control-z never reaches here */
case '\003': /* control-c */
xltoplevel();
lcount = 0;
break;
case '\007': /* control-g */
xlcleanup();
lcount = 0;
break;
case '\020': /* control-p */
xlcontinue();
lcount = 0;
break;
case '\002':
ostputc('\n'); /* control-b */
xlbreak("BREAK",s_unbound);
break;
case '\024': /* control-t */
xinfo();
lcount = 0;
break;
case '\t': /* TAB */
lposition--; /* undo the increment above */
do {
lposition++;
gputchar(' ');
} while (lposition & 7);
break;
default:
gputchar(ch);
break;
}
}
if (lindex + 1 >= lcount) {
lcount = 0;
line_edit = TRUE;
}
ch = lbuf[lindex++];
/* printf("[%c]", ch); */
fflush(stdout);
return ch;
}
#endif
void ostputc (int ch) {
// macputc (ch);
gputchar(ch); // console
if (tfp) osaputc (ch, tfp);
}
void ostoutflush()
{
if (tfp) fflush(tfp);
/* since ostputc calls gputchar which just calls putchar,
I'm going to flush stdout rather than extending the
"g" abstraction with a gflush() call. -RBD
*/
fflush(stdout);
}
void osflush (void) {
lindex = lcount = lposition = 0;
line_edit = TRUE;
}
extern int abort_flag;
void oscheck (void)
{
#if OSC
if (nosc_enabled) nosc_poll();
#endif
check_aborted();
if (abort_flag == ABORT_LEVEL) {
abort_flag = 0;
osflush();
xltoplevel();
} else if (abort_flag == BREAK_LEVEL) {
abort_flag = 0;
osflush();
xlbreak("BREAK",s_unbound);
}
run_time++;
if (run_time % 30 == 0) {
// maybe we should call fflush here like in Unix; I'm not sure if this is
// a bug or it is not necessary for Windows - RBD
if (run_time_limit > 0 && run_time > run_time_limit) {
xlfatal("Run time limit exceeded");
}
if (memory_limit > 0 &&
npools * MAXPOOLSIZE + table_memory + total >
memory_limit * 1000000) {
xlfatal("Memory limit exceeded");
}
}
}
void oserror(const char *msg) {
char line[100], *p;
sprintf (line,"error: %s\n",msg);
for (p = line; *p != '\0'; ++p) ostputc (*p);
}
void osfinish(void) {
portaudio_exit();
/* dispose of everything... */
// if (linebuf) DisposPtr (linebuf);
// MacWrapUp ();
// ExitToShell ();
}
int renamebackup (char *filename) { return 0; }
static WIN32_FIND_DATA FindFileData;
static HANDLE hFind = INVALID_HANDLE_VALUE;
#define OSDIR_LIST_READY 0
#define OSDIR_LIST_STARTED 1
#define OSDIR_LIST_DONE 2
static osdir_list_status = OSDIR_LIST_READY;
#define OSDIR_MAX_PATH 256
static char osdir_path[OSDIR_MAX_PATH];
// osdir_list_start -- prepare to list a directory
int osdir_list_start(const char *path)
{
if (strlen(path) >= OSDIR_MAX_PATH - 2) {
xlcerror("LISTDIR path too big", "return nil", NULL);
return FALSE;
}
if (!ok_to_open(path, "r")) return FALSE;
strcpy(osdir_path, path);
strcat(osdir_path, "/*"); // make a pattern to match all files
if (osdir_list_status != OSDIR_LIST_READY) {
osdir_list_finish(); // close previously interrupted listing
}
hFind = FindFirstFile(osdir_path, &FindFileData); // get the "."
if (hFind == INVALID_HANDLE_VALUE) return FALSE;
if (FindNextFile(hFind, &FindFileData) == 0) return FALSE; // get the ".."
osdir_list_status = OSDIR_LIST_STARTED;
return TRUE;
}
const char *osdir_list_next()
{
if (FindNextFile(hFind, &FindFileData) == 0) {
osdir_list_status = OSDIR_LIST_DONE;
return NULL;
}
return FindFileData.cFileName;
}
void osdir_list_finish()
{
if (osdir_list_status != OSDIR_LIST_READY) {
FindClose(hFind);
}
osdir_list_status = OSDIR_LIST_READY;
}
/* xechoenabled -- set/clear echo_enabled flag (unix only) */
LVAL xechoenabled()
{
int flag = (xlgetarg() != NULL);
xllastarg();
// echo_enabled = flag; -- do nothing in Windows
return NULL;
}

View File

@@ -0,0 +1,657 @@
#include "windows.h" /* required for all Windows applications */
#include "cppext.h"
#include "longque.h"
#include "button.h"
#include "slider.h"
#include "winmain.h" /* specific to this program */
#include "stdlib.h"
#include "string.h"
#include "stdio.h"
#include "textio.h"
#include "mmsystem.h"
#include <crtdbg.h>
#include <mapiwin.h> // for Sleep()
#include "stdio.h"
#include "resource.h"
#include "typein.h"
#include "xlispfns.h"
#include "winfun.h"
//#define THUMBTRACK // tries to get continuous scrollbars with SB_THUMBTRACK messages.
// doesn't work -- zone 1 doesn't seem to wake up until the button-up.
//#include "saudio.h"
//#define D if(0)
HWND buttons[NUMBUTTONS];
HWND sliders[NUMSLIDERS];
HWND textinput;
HWND textoutput;
HFONT hfont;
HWND alt_win;
WNDPROC alt_proc;
extern "C" {
HINSTANCE hInst; /* current instance */
HWND hMainWindow; /* main window handle */
}
/* HINSTANCE hInst; /* current instance */
/* HWND hMainWindow; /* main window handle */
int quit_value; // return value from WinMain
int abort_flag = 0;
// there's some state here:
// when we get a message from the input queue, it is an entire
// string. We save the string and a pointer to the next char
//
char *get_ascii_string = NULL;
char *next_ascii = NULL;
//asciiwait -- wait for ascii input
char wait_ascii()
{
if (next_ascii && *next_ascii) {
char c = *next_ascii++;
if (c == '\r') c = '\n';
_RPT1(_CRT_WARN, "|%c|", c);
return c;
}
if (get_ascii_string) {
_RPT2(_CRT_WARN, "free get_ascii_string %x %s\n",
get_ascii_string, get_ascii_string);
free(get_ascii_string);
get_ascii_string = NULL;
next_ascii = NULL;
}
// no input, so look for Windows messages
while (typein::queue.emptyp() && !abort_flag) {
process_win_events(USE_GET);
}
if (abort_flag == ABORT_LEVEL) return ABORT_CHAR;
if (abort_flag == BREAK_LEVEL) return BREAK_CHAR;
get_ascii_string = (char *) typein::queue.remove();
_RPT2(_CRT_WARN, "removed %x: %s\n", get_ascii_string, get_ascii_string);
edit_append(get_ascii_string);
next_ascii = get_ascii_string;
return wait_ascii();
}
//process_win_events -- receive and handle windows by either:
// USE_PEEK: non-blocking
// USE_GET: blocks
void process_win_events(int method)
{
MSG msg;
edit_append(""); // flush the output
if (method == USE_GET) {
//blocks until at least a message arrives
if (GetMessage(&msg, //msg stored here
NULL, //receive ALL application messages
NULL,NULL)) //no msg filtering
{
//standard windows loop
TranslateMessage(&msg); //posts another msg if there is a virtual to WM_CHAR mapping
DispatchMessage(&msg); //calls object's receive function
} else {
//is this ever entered???
quit_value = msg.wParam;
abort_flag = ABORT_CHAR;
exit(0);
}
} else {
//default: process all messges that already exist (non-blocking)
while (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE | PM_NOYIELD))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
//STUFF TO PROVIDE CONSOLE-------------------------------------------------
//terminate strings and strip out LF
int lf2crlf(char *dest, char *src)
{
char *d = dest;
while (*src) {
if (*src == '\n') {
*dest++ = '\r';
}
*dest++ = *src++;
}
*dest = EOS;
return dest - d; /* string length */
}
#define EDIT_HIGH_WATER 10000
#define EDIT_LOW_WATER 9000
#define EABUFFMAX 110
static char eabuff[EABUFFMAX]; /* edit_append buffer */
static char eabuffx = 0;
static void edit_append2(char *txt2);
/* edit_append -- optimizes output by buffering
*
* call with empty string to flush buffer
*/
void edit_append(char *txt)
{
/* new algorithm to deal with long strings on input:
* if input is longer than 50, insert a zero and
* call recursively; then undo the zero and continue.
*/
char txt2[100];
while (strlen(txt) > 50) {
char temp = txt[50];
txt[50] = 0;
edit_append(txt); /* strlen(txt) == 50 */
txt = txt + 50;
txt[0] = temp;
}
int len = lf2crlf(txt2, txt);
if ((eabuffx + len + 1 > EABUFFMAX) || ((len == 0) && eabuffx)) {
edit_append2(eabuff);
eabuffx = 0;
}
strcpy(eabuff + eabuffx, txt2);
eabuffx += len;
}
static void edit_append2(char *txt2)
{
int len;
int lines;
if (*txt2 == '\b') { // special case: erase last character
long len = SendMessage(textoutput, WM_GETTEXTLENGTH, (WPARAM) 0, (LPARAM) 0);
if (len > 0) {
// select the last character:
SendMessage(textoutput, EM_SETSEL, (WPARAM) len - 1, (LPARAM) -1);
// delete the last character:
SendMessage(textoutput, EM_REPLACESEL, (WPARAM) 0, (LPARAM) ((LPSTR) ""));
}
return;
}
// to put insertion point at the end, first select
// everything ...
//wparam is UINT ; lparam is LONG
SendMessage(textoutput, EM_SETSEL, (WPARAM) 0, (LPARAM) -1);
// then remove selection, leaving cursor at the end:
SendMessage(textoutput, EM_SETSEL, (WPARAM) -1, (LPARAM) -1);
// now, replacement actually appends to the buffer:
SendMessage(textoutput, EM_REPLACESEL, (WPARAM) 0, (LPARAM) ((LPSTR) txt2));
// if the number of characters exceeds EDIT_HIGH_WATER, then
// trim the number of characters to EDIT_LOW_WATER by deleting
// all lines up to the one containing total-EDIT_LOW_WATER
lines = (int) SendMessage(textoutput, EM_GETLINECOUNT, (WPARAM) 0, (LPARAM) 0);
len = (int) SendMessage(textoutput, EM_LINEINDEX, (WPARAM)(lines - 1), (LPARAM) 0);
len += (int) SendMessage(textoutput, EM_LINELENGTH, (WPARAM)(lines - 1), (LPARAM) 0);
if (len > EDIT_HIGH_WATER) {
//these SendMessages operate to completion
lines = (int) SendMessage(textoutput, EM_LINEFROMCHAR,
(WPARAM)(len - EDIT_LOW_WATER), (LPARAM) 0);
len = (int) SendMessage(textoutput, EM_LINEINDEX, (WPARAM)(lines), (LPARAM) 0);
SendMessage(textoutput, EM_SETSEL, (WPARAM) 0, (LPARAM)(len));
SendMessage(textoutput, EM_REPLACESEL, (WPARAM) 0, (LPARAM) ((LPSTR) ""));
}
}
//THE STUFF REQUIRED BY WINDOWS APPLICATIONS----------------------------------
// we will subclass the textinput window with a window procedure that detects
// the Enter key (hex 0x0d) and sets a flag. Then in the main window proc,
// when an EN_CHANGE message is received, we will know the user typed Enter,
// so we can transfer the text to XLISP.
//
// This would be a good place also to add editing characters to scroll through
// previous entries.
//
WNDPROC DefaultEditWndProc = NULL;
#define ENTER_KEY 0x0d
bool enter_flag = false;
long CALLBACK EditWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if (message == WM_CHAR) {
if (wParam == ENTER_KEY) enter_flag = true;
_RPT1(_CRT_WARN, "wm_char is %x\n", wParam);
}
return CallWindowProc(DefaultEditWndProc, hWnd, message, wParam, lParam);
}
//All applications need to register
BOOL InitApplication(HINSTANCE hInstance /* current instance */)
{
WNDCLASS wc;
/* Fill in window class structure with parameters that describe the */
/* main window. */
wc.style = NULL; /* Class style(s). */
wc.lpfnWndProc = MainWndProc; /* Function to retrieve messages for */
/* windows of this class. */
wc.cbClsExtra = 0; /* No per-class extra data. */
wc.cbWndExtra = 0; /* No per-window extra data. */
wc.hInstance = hInstance; /* Application that owns the class. */
wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_NYCON));
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = "MAINMENU"; /* Name of menu resource in .RC file. */
wc.lpszClassName = "CMTWClass"; /* Name used in call to CreateWindow. */
/* Register the window class and return success/failure code. */
return (RegisterClass(&wc));
}
static char *button_names[NUMBUTTONS] = { "Load File", "Reload File",
"Replay Sound", "Break", "Top", "Up", "Info", "F1", "F2", "F3", "F4" };
//each time this application is run, the following program must be run
BOOL InitInstance(
HINSTANCE hInstance, /* Current instance identifier. */
int nCmdShow) /* Param for first ShowWindow() call. */
{
int i;
RECT rect;
LRESULT rslt;
/* Save the instance handle in static variable, which will be used in */
/* many subsequent calls from this application to Windows. */
hInst = hInstance;
/* Create a main window for this application instance. */
hMainWindow = CreateWindow(
"CMTWClass", /* See RegisterClass() call. */
"Nyquist", /* Text for window title bar. */
WS_OVERLAPPEDWINDOW, /* Window style. */
CW_USEDEFAULT, /* Default horizontal position. */
CW_USEDEFAULT, /* Default vertical position. */
CW_USEDEFAULT, /* Default width. */
CW_USEDEFAULT, /* Default height. */
NULL, /* Overlapped windows have no parent. */
NULL, /* Use the window class menu. */
hInstance, /* This instance owns this window. */
NULL /* Pointer not needed. */
);
/* If window could not be created, return "failure" */
if (!hMainWindow)
return (FALSE);
GetClientRect(hMainWindow, (LPRECT) &rect);
/* Make the window visible; update its client area; and return "success" */
const int button_y = 25; // size in pixels
const int slider_x = 20;
const int slider_gap = 1;
const int input_height = 48; // how high is input type-in edit control
int slider_xsum = slider_x * NUMSLIDERS;
int button_ysum = button_y * NUMBUTTONS_VERT;
ShowWindow(hMainWindow, nCmdShow); /* Show the window */
UpdateWindow(hMainWindow); /* Sends WM_PAINT message */
for (i = 0; i < NUMBUTTONS; i++) {
int x = 0;
int y = i * button_y;
int width = slider_xsum;
if (i > 2) {
y = (3 + (i - 3) / 2) * button_y;
width = width / 2;
if ((i & 1) == 0) x = width;
}
buttons[i] = CreateWindow("Button", //lpszClassName
button_names[i],//windowName
BS_PUSHBUTTON | //Style: 1) PB
WS_CHILD | // 2) must reside w/in parent
WS_VISIBLE, // 3) initially visible
x, y, width, button_y,
hMainWindow, //owner window
(HMENU)(IDC_BUTTON+i),
//&buttonsH[i], //child window Id
hInstance, //application instance
NULL); //WM_CREATE argument
//activate current window & display w/current size and position
ShowWindow(buttons[i], SW_SHOW);
//update (nonempty) client area via WM_PAINT
UpdateWindow(buttons[i]);
}
for (i=0; i<NUMSLIDERS; ++i) {
char name[5];
sprintf(name, "%d", i);
sliders[i] = CreateWindow("Scrollbar", name, WS_CHILD | WS_VISIBLE | SBS_VERT /*| WS_BORDER */,
slider_x * i + slider_gap, button_ysum, slider_x - slider_gap, (rect.bottom - rect.top) - button_ysum,
hMainWindow, (HMENU)(IDC_SLIDER+i), hInstance, NULL); // (was IDC_BUTTON)
SetScrollRange(sliders[i], SB_CTL, 0, 127, 1);
ShowWindow(sliders[i], SW_SHOW);
UpdateWindow(sliders[i]);
}
textinput = CreateWindow("Edit", NULL,
WS_CHILD | WS_VISIBLE | ES_MULTILINE |
WS_VSCROLL | ES_AUTOVSCROLL | WS_BORDER,
slider_xsum, 0,
(rect.right - rect.left) - slider_xsum,
input_height,
hMainWindow, (HMENU)(IDC_EDIT_INPUT), hInstance, NULL);
// subclass the input window so we can catch the Enter key
DefaultEditWndProc = (WNDPROC) SetWindowLong(textinput, GWL_WNDPROC, (long) EditWndProc);
textoutput = CreateWindow("Edit", NULL,
WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_READONLY |
WS_VSCROLL | ES_AUTOVSCROLL | WS_BORDER,
slider_xsum, input_height - 1,
(rect.right - rect.left) - slider_xsum,
(rect.bottom - rect.top) - input_height,
hMainWindow, (HMENU)(IDC_EDIT), hInstance, NULL);
hfont = CreateFont(0, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE,
ANSI_CHARSET, OUT_RASTER_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, FIXED_PITCH | FF_DONTCARE,
"Courier");
rslt = SendMessage(textoutput, WM_SETFONT, (WPARAM) hfont,
MAKELPARAM(TRUE, 0));
ShowWindow(textoutput, SW_SHOW);
UpdateWindow(textoutput);
rslt = SendMessage(textinput, WM_SETFONT, (WPARAM) hfont,
MAKELPARAM(TRUE, 0));
ShowWindow(textinput, SW_SHOW);
UpdateWindow(textinput);
return (TRUE); /* Returns the value from PostQuitMessage */
}
//this is the hook called where any windows application starts up
extern "C" int WINAPI WinMain(
HINSTANCE hInstance, /* current instance */
HINSTANCE hPrevInstance, /* previous instance */
LPSTR lpCmdLine, /* command line */
int nCmdShow) /* show-window type (open/icon) */
{
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG);
_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_WNDW); // EUB
#if defined(_DEBUG) && 0
int flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
flags |= _CRTDBG_CHECK_ALWAYS_DF; // do expensive memory checking -eub
flags |= _CRTDBG_LEAK_CHECK_DF; // check for leaks at termination
_CrtSetDbgFlag(flags);
_CrtCheckMemory();
#endif
typein::init();
if (!hPrevInstance) /* Other instances of app running? */
if (!InitApplication(hInstance)) /* Initialize shared things */
return (FALSE); /* Exits if unable to initialize */
/* Perform initializations that apply to a specific instance */
if (!InitInstance(hInstance, nCmdShow)) return (FALSE);
run_xlisp();
return quit_value;
}
char *button_msgs[] = {
"(ny:load-file)\n",
"(ny:reload-file)\n",
"(r)\n",
"\002",
"\003",
"\007",
"\024",
"(F1)\n",
"(F2)\n",
"(F3)\n",
"(F4)\n" };
static void type_this(char *ptr)
{
char *s = (char *) malloc(strlen(ptr) + 1);
_RPT1(_CRT_WARN, "type_this mallocs %x\n", s);
strcpy(s, ptr);
typein::handler(s);
}
//This is the Main Window Receive Function
long CALLBACK MainWndProc(
HWND hWnd, /* window handle */
UINT message, /* type of message */
WPARAM wParam, /* additional information */
LPARAM lParam) /* additional information */
{
switch (message) {
case WM_CHAR: {
//message: character code is posted via Translate Message
TCHAR c = (TCHAR) wParam;
//lKeyData = lParam; extended, ctrl, etc keys are ignored!!!
// typein::handler(c);
break;
}
case WM_COMMAND: {
//message: command from application menu
short int code = HIWORD(wParam);
int wid = LOWORD(wParam);
HWND hwndCtrl = (HWND) lParam;
if (code == 0 && wid == IDM_ABOUT) {
DialogBox(hInst, /*current inst*/ "ABOUTBOX", /*resource to use*/
hWnd, /* parent*/ (DLGPROC) About /*About() instance address*/);
} else if (code == 0 && wid == ID_FILE_LOAD) {
type_this(button_msgs[0]);
} else if (code == 0 && wid == ID_FILE_RELOAD) {
type_this(button_msgs[1]);
} else if (code == 0 && wid == ID_FILE_EXIT) {
type_this("(exit)\n");
} else if (wid >= IDC_BUTTON && wid < IDC_BUTTON + NUMBUTTONS) {
SetFocus(textinput); /* get focus back */
type_this(button_msgs[wid - IDC_BUTTON]);
} else if (wid == IDC_EDIT_INPUT) {
if (code == EN_CHANGE) {
if (enter_flag) {
enter_flag = false;
long len = SendMessage(hwndCtrl, WM_GETTEXTLENGTH, 0, 0);
len++; // allow for terminating null character
char *buffer = (char *) malloc(len);
SendMessage(hwndCtrl, WM_GETTEXT, (WPARAM) len, (LPARAM) buffer);
_RPT2(_CRT_WARN, "inserting %x: %s\n", buffer, buffer);
typein::handler(buffer);
SendMessage(hwndCtrl, WM_SETTEXT, (WPARAM) 0, (LPARAM) "");
}
}
} else if (wid == IDC_EDIT) {
if (code == EN_CHANGE) {
} else {
}
} else {
/*Let Windows process it*/
printf("unhandled: message %d\n", message);
return (DefWindowProc(hWnd, message, wParam, lParam));
}
break;
}
case WM_DESTROY:
//message: window being destroyed
PostQuitMessage(0);
break;
#ifdef MOUSEBUTTON_INPUT
case WM_LBUTTONDOWN: {
//message: left mouse button pressed while cursor in client area
//never used, need SetCaputure???
int /*???*/ xPos LOWORD(lParam);
int /*???*/ yPos HIWORD(lParam);
//int /*???*/ fwKeys; virtual keys not used!!!
buffer[0] = '<';
_itoa(xPos,buffer+1,10/*radix*/);
i = strlen(buffer);
buffer[i++] = ',';
_itoa(yPos,buffer+i,10/*radix*/);
i = strlen(buffer);
buffer[i++] = '>';
buffer[i] = 0;
edit_append(buffer);
break;
#endif
#ifdef DEBUGINPUT
//WM_USER msg codes are from the callbacks-------------------------
case WM_USER_TIMEOUT: {
//dummy message just unblocks GetMessage
break;
}
//remaining wMsg codes generated elsewhere------------------------------------
case WM_KILLFOCUS: {
//message: this window's loosing focus, focus must be set to new window
HWND newFocus = (HWND) wParam;
if (newFocus == textoutput) {
//why not also set buttons, sliders...???
SetFocus(hWnd);
}
break;
}
case WM_VSCROLL: {
//message: control bar scroll I/O
//where is window scroll bar handled???
//why is this not also a WM_COMMAND???
HWND hwndCtrl = (HWND) lParam;
short int nPos = HIWORD(wParam);
int code = LOWORD(wParam);
int i;
for (i = 0; i < NUMSLIDERS; i++) {
if (sliders[i] == hwndCtrl) {
int pos = GetScrollPos(hwndCtrl /*parent*/, SB_CTL /*control*/);
switch (code) {
case SB_LINEUP: pos--; break;
case SB_LINEDOWN: pos++; break;
case SB_PAGEUP: pos -= 10; break;
case SB_PAGEDOWN: pos += 10; break;
case SB_ENDSCROLL:
break; //why not continue???
case SB_THUMBTRACK:
#ifdef THUMBTRACK
pos = nPos;
break;
#else
continue; // no silly multiple messages
#endif
//break;
case SB_THUMBPOSITION:
#ifndef THUMBTRACK
pos = nPos;
#endif
break;
case SB_TOP: pos = 0; break;
case SB_BOTTOM: pos = 127; break;
default: continue; //avoid SetScrollPos
}
// SetScrollRange() set the range to 0-127, but clip just to make sure:
if (pos < 0) pos = 0;
if (pos > 127) pos = 127;
if (code != SB_ENDSCROLL
#ifdef THUMBTRACK
&& code != SB_THUMBTRACK
#endif
) {
//ctrlevents.insert(CTRLEVENT(IDC_SLIDER + i, 127 - pos));
}
SetScrollPos(hwndCtrl /*parent*/, SB_CTL /*control sb*/, pos /*new position*/, TRUE /*redraw*/);
break;
}
}
break;
}
#endif
default:
//Pass on all unproccessed messages
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return (NULL); //all messages currently return this...
}
/****************************************************************************
FUNCTION: About(HWND, unsigned, WORD, LONG)
PURPOSE: Processes messages for "About" dialog box
MESSAGES:
WM_INITDIALOG - initialize dialog box
WM_COMMAND - Input received
COMMENTS:
No initialization is needed for this particular dialog box, but TRUE
must be returned to Windows.
Wait for user to click on "Ok" button, then close the dialog box.
****************************************************************************/
extern "C" BOOL CALLBACK About(
HWND hDlg, /* window handle of the dialog box */
unsigned message, /* type of message */
WORD wParam, /* message-specific information */
LONG lParam)
{
switch (message)
{
case WM_INITDIALOG: /* message: initialize dialog box */
return (TRUE);
case WM_COMMAND: /* message: received a command */
if (wParam == IDOK /* "OK" box selected? */
|| wParam == IDCANCEL) /* System menu close command? */
{
EndDialog(hDlg, TRUE); /* Exits the dialog box */
return TRUE;
}
break;
}
return FALSE; /* Didn't process a message */
}
/* Load File support */
extern "C"
void RegisterWindow(HWND w, WNDPROC p) {
alt_win = w;
alt_proc = p;
}

View File

@@ -0,0 +1,28 @@
#include "resource.h"
#ifdef __cplusplus
extern "C" {
#endif
BOOL InitApplication(HANDLE);
BOOL InitInstance(HANDLE, int);
long CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK About(HWND, unsigned, WORD, LONG);
void RegisterWindow(HWND, WNDPROC);
#define IDC_EDIT 300
#define IDC_EDIT_INPUT 301
#define IDC_BUTTON 400
#define IDC_SLIDER 500
#define NUMBUTTONS 11
// 7 buttons high:
#define NUMBUTTONS_VERT 7
extern int abort_flag;
#ifdef __cplusplus
}
#endif
#include "winmain2.h"

View File

@@ -0,0 +1,120 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#define APSTUDIO_HIDDEN_SYMBOLS
#include "windows.h"
#undef APSTUDIO_HIDDEN_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
MAINMENU MENU DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
MENUITEM "&Load...", ID_FILE_LOAD
MENUITEM "&Reload", ID_FILE_RELOAD
MENUITEM SEPARATOR
MENUITEM "E&xit", ID_FILE_EXIT
END
POPUP "&Help"
BEGIN
MENUITEM "&About Nyquist...", IDM_ABOUT
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
ABOUTBOX DIALOG DISCARDABLE 22, 17, 177, 98
STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
CAPTION "About Nyquist"
FONT 8, "MS Sans Serif"
BEGIN
CTEXT "Nyquist, a language for music composition",IDC_STATIC,0,
5,177,8
CTEXT " and sound synthesis.",IDC_STATIC,0,14,177,8
CTEXT "Version 2.16",IDC_STATIC,0,76,177,8
DEFPUSHBUTTON "OK",IDOK,145,84,32,14,WS_GROUP
CTEXT "Copyright (c) 2001, by Roger B. Dannenberg",IDC_STATIC,
0,66,177,8
CTEXT "http://www.cs.cmu.edu/~rbd/nyquist",IDC_STATIC,0,26,177,
8
ICON IDI_NYCON,IDC_STATIC,79,38,21,20
END
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
"#include ""windows.h""\r\n"
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_NYCON ICON DISCARDABLE "nycon.ico"
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@@ -0,0 +1,41 @@
extern int quit_flag;
extern int waiting_flag;
extern long start_time; // initial system time in ms
extern long the_time; // current time - updated by periodic interrupt
extern HWND hMainWindow; /* main window handle */
void edit_append(char *txt);
void debugeventwait();
bool get_mouse(int &x, int &y);
void wait_mouse(int &x, int &y);
void pause(long ms);
// parameters to process_win_events()
#define USE_GET 0
#define USE_PEEK 1
void process_win_events(int method);
#define CTRLEVENT(a, b) (((long) (a))<<16 | (b))
#define WM_USER_TIMEOUT (WM_USER + 0)
#define WM_USER_TIMESHOW (WM_USER + 1)
#define WM_USER_TIMESHOW1 (WM_USER + 2)
#define WM_USER_MIDI_INPUT (WM_USER + 10)
#define WM_USER_MIDISHOW (WM_USER + 11)
#define WM_USER_MIDISHOW1 (WM_USER + 12)
#define WM_USER_MIDI_IN_ERROR (WM_USER + 20)
#define WM_USER_MIDI_OUT_ERROR (WM_USER + 21)
#define TIMERCB 1
#define MIDIINCB 2
#define FROMTIMERCB(x) ((x) == TIMERCB)
#define FROMMIDIINCB(x) ((x) == MIDIINCB)
#define TEXT_WIN_HT 200

View File

@@ -0,0 +1 @@
/* nothing to do */

View File

@@ -0,0 +1,11 @@
#include "xlisp.h"
#include "xlispfns.h"
void run_xlisp()
{
xlisp_main_init(0,NULL);
xlisp_main();
/* clean up */
xlisp_wrapup();
}

View File

@@ -0,0 +1,9 @@
#ifdef __cplusplus
extern "C" {
#endif
void run_xlisp();
#ifdef __cplusplus
}
#endif