1 /* winstuff.c - windows interface routines for xlisp */
2 /* Written by Chris Tchou. */
3 /* This file contains the stuff that the other xlisp files call directly. */
4
5 #include "windows.h"
6 #include <stdio.h>
7 //#include <QuickDraw.h> /* for Random */
8 #include <memory.h> /* for DisposPtr */
9 #include <string.h>
10 //#include <SegLoad.h> /* for ExitToShell */
11 #include "xlisp.h"
12 #include "textio.h"
13
14 #if OSC
15 #include "sliders.h" /* define sliders */
16 #include "sound.h" /* define nosc_enabled */
17 #endif
18 #include "falloc.h" /* define table_memory */
19
20 const char os_pathchar = '\\';
21 const char os_sepchar = ',';
22
23
24 /* externals */
25 extern FILE *tfp; /* transcript file pointer */
26 extern int cursorPos;
27 extern char *macgets (void);
28
29 #define LBSIZE 200
30
31 /* local variables */
32 static char lbuf[LBSIZE];
33 static int lpos[LBSIZE];
34 static int lindex;
35 static int lcount = 0;
36 static int lposition;
37 static int line_edit = TRUE;
38
39 //int isascii (char c) { return 1; } /* every char is an ascii char, isn't it? */
40
osinit(const char * banner)41 void osinit(const char *banner) {
42 // int i;
43 char version[] = "\nWindows console interface by Roger Dannenberg.\n";
44 // InitMac (); /* initialize the mac interface routines */
45 // lposition = 0; /* initialize the line editor */
46 // for (i = 0; banner[i] != '\0'; i++) macputc (banner[i]);
47 // for (i = 0; version[i] != '\0'; i++) macputc (version[i]);
48 nyquist_printf(banner);
49 nyquist_printf(version);
50 }
51
52
osaopen(const char * name,const char * mode)53 FILE *osaopen (const char *name, const char *mode) {
54 FILE *fp = NULL;
55 if (ok_to_open(name, mode))
56 fp = fopen (name, mode);
57 return fp;
58 }
59
osbopen(const char * name,const char * mode)60 FILE *osbopen (const char *name, const char *mode) {
61 FILE *fp = NULL;
62 char nmode[4];
63 strcpy (nmode, mode); strcat (nmode, "b");
64 if (ok_to_open(name, mode))
65 fp = fopen (name, mode);
66 return fp;
67 }
68
osclose(FILE * fp)69 int osclose (FILE *fp) { return (fclose (fp)); }
osaputc(int ch,FILE * fp)70 int osaputc (int ch, FILE *fp) { return (putc (ch, fp)); }
osbputc(int ch,FILE * fp)71 int osbputc (int ch, FILE *fp) { return (putc (ch, fp)); }
osoutflush(FILE * fp)72 void osoutflush(FILE *fp) { fflush(fp); }
73
74 /* osagetc - get a character from an ascii file */
osagetc(fp)75 int osagetc(fp)
76 FILE *fp;
77 {
78 return (getc(fp));
79 }
80
81
82 extern int abort_flag;
83
84
85 #define OLDGETC
86 #ifdef OLDGETC
87
ostgetc(void)88 int ostgetc (void) {
89 /* int i;
90
91 if (numChars <= 0) { /* get some more */
92 /* if (linebuf) DisposPtr (linebuf);
93 linebuf = macgets ();
94 i = 0;
95 while (linebuf[i] != '\0') i++;
96 numChars = i;
97 if (tfp) for (i = 0; i < numChars; i++) osaputc (linebuf[i], tfp);
98 lineptr = linebuf;
99 }
100 numChars--;
101 if (*lineptr == '\r') {
102 lineptr++;
103 return '\n';
104 } else return (*lineptr++);*/
105
106 int ch = ggetchar();
107 oscheck(); /* in case user typed ^C */
108 if (ch == BREAK_CHAR && abort_flag == BREAK_LEVEL) {
109 abort_flag = 0;
110 }
111 return ch;
112 }
113
114 #else
115
end_of_line_edit()116 void end_of_line_edit()
117 {
118 line_edit = FALSE;
119 if (tfp) {
120 for (lindex = 0; lindex < lcount; ++lindex)
121 osaputc(lbuf[lindex], tfp);
122 }
123 lindex = 0;
124 }
125
126
127
ostgetc()128 int ostgetc()
129 {
130 /*
131 * NOTE: lbuf[] accumulates characters as they are typed
132 * lpos[] is the column position of the characters
133 * lcount is the number of characters in lbuf
134 * lposition is current position
135 * lindex is index of next char to output
136 * line_edit is true iff we're inputing characters
137 *
138 */
139 int ch;
140
141 while (line_edit) {
142 ch = ggetchar();
143 oscheck(); /* in case user typed ^C */
144 if (ch == BREAK_CHAR && abort_flag == BREAK_LEVEL) {
145 abort_flag = 0;
146 }
147 /* assume for now we should add the character */
148 lbuf[lcount] = ch;
149 lpos[lcount] = lposition;
150 lcount++;
151 lposition++;
152
153 /* now do all the special character processing */
154 switch (ch) {
155 case '\n':
156 lposition = 0;
157 end_of_line_edit();
158 gputchar('\r');
159 gputchar(ch);
160 break;
161 /* delete key generates: 1b, 5b, 33, 7E
162 which is: ESC, [, 3, ~ */
163 case '\010': /* backspace */
164 case '\177': /* delete */
165 lcount--; /* take out backspace or delete char */
166 lposition--;
167 if (lcount) {
168 lcount--;
169 while (lposition > lpos[lcount]) {
170 gputchar('\010');
171 gputchar(' ');
172 gputchar('\010');
173 lposition--;
174 }
175 }
176 break;
177 case '\025': /* control-u */
178 lcount--;
179 lposition--;
180 if (lcount) {
181 while (lposition > lpos[0]) {
182 gputchar('\010');
183 gputchar(' ');
184 gputchar('\010');
185 lposition--;
186 }
187 lcount = 0;
188 }
189 break;
190
191 /* note that control-z never reaches here */
192 case '\003': /* control-c */
193 xltoplevel();
194 lcount = 0;
195 break;
196 case '\007': /* control-g */
197 xlcleanup();
198 lcount = 0;
199 break;
200 case '\020': /* control-p */
201 xlcontinue();
202 lcount = 0;
203 break;
204 case '\002':
205 ostputc('\n'); /* control-b */
206 xlbreak("BREAK",s_unbound);
207 break;
208 case '\024': /* control-t */
209 xinfo();
210 lcount = 0;
211 break;
212 case '\t': /* TAB */
213 lposition--; /* undo the increment above */
214 do {
215 lposition++;
216 gputchar(' ');
217 } while (lposition & 7);
218 break;
219 default:
220 gputchar(ch);
221 break;
222 }
223 }
224 if (lindex + 1 >= lcount) {
225 lcount = 0;
226 line_edit = TRUE;
227 }
228 ch = lbuf[lindex++];
229 /* printf("[%c]", ch); */
230 fflush(stdout);
231 return ch;
232 }
233 #endif
234
235
ostputc(int ch)236 void ostputc (int ch) {
237 // macputc (ch);
238 gputchar(ch); // console
239
240 if (tfp) osaputc (ch, tfp);
241 }
242
ostoutflush()243 void ostoutflush()
244 {
245 if (tfp) fflush(tfp);
246 /* since ostputc calls gputchar which just calls putchar,
247 I'm going to flush stdout rather than extending the
248 "g" abstraction with a gflush() call. -RBD
249 */
250 fflush(stdout);
251 }
252
osflush(void)253 void osflush (void) {
254 lindex = lcount = lposition = 0;
255 line_edit = TRUE;
256 }
257
258 extern int abort_flag;
259
oscheck(void)260 void oscheck (void)
261 {
262
263 #if OSC
264 if (nosc_enabled) nosc_poll();
265 #endif
266
267 check_aborted();
268 if (abort_flag == ABORT_LEVEL) {
269 abort_flag = 0;
270 osflush();
271 xltoplevel();
272 } else if (abort_flag == BREAK_LEVEL) {
273 abort_flag = 0;
274 osflush();
275 xlbreak("BREAK",s_unbound);
276 }
277 run_time++;
278 if (run_time % 30 == 0) {
279 // maybe we should call fflush here like in Unix; I'm not sure if this is
280 // a bug or it is not necessary for Windows - RBD
281 if (run_time_limit > 0 && run_time > run_time_limit) {
282 xlfatal("Run time limit exceeded");
283 }
284 if (memory_limit > 0 &&
285 npools * MAXPOOLSIZE + table_memory + total >
286 memory_limit * 1000000) {
287 xlfatal("Memory limit exceeded");
288 }
289 }
290 }
291
oserror(const char * msg)292 void oserror(const char *msg) {
293 char line[100], *p;
294 sprintf (line,"error: %s\n",msg);
295 for (p = line; *p != '\0'; ++p) ostputc (*p);
296 }
297
osfinish(void)298 void osfinish(void) {
299 portaudio_exit();
300 /* dispose of everything... */
301 // if (linebuf) DisposPtr (linebuf);
302 // MacWrapUp ();
303 // ExitToShell ();
304 }
305
renamebackup(char * filename)306 int renamebackup (char *filename) { return 0; }
307
308
309
310 static WIN32_FIND_DATA FindFileData;
311 static HANDLE hFind = INVALID_HANDLE_VALUE;
312 #define OSDIR_LIST_READY 0
313 #define OSDIR_LIST_STARTED 1
314 #define OSDIR_LIST_DONE 2
315 static osdir_list_status = OSDIR_LIST_READY;
316 #define OSDIR_MAX_PATH 256
317 static char osdir_path[OSDIR_MAX_PATH];
318
319 // osdir_list_start -- prepare to list a directory
osdir_list_start(const char * path)320 int osdir_list_start(const char *path)
321 {
322 if (strlen(path) >= OSDIR_MAX_PATH - 2) {
323 xlcerror("LISTDIR path too big", "return nil", NULL);
324 return FALSE;
325 }
326 if (!ok_to_open(path, "r")) return FALSE;
327 strcpy(osdir_path, path);
328 strcat(osdir_path, "/*"); // make a pattern to match all files
329 if (osdir_list_status != OSDIR_LIST_READY) {
330 osdir_list_finish(); // close previously interrupted listing
331 }
332 hFind = FindFirstFile(osdir_path, &FindFileData); // get the "."
333 if (hFind == INVALID_HANDLE_VALUE) return FALSE;
334 if (FindNextFile(hFind, &FindFileData) == 0) return FALSE; // get the ".."
335 osdir_list_status = OSDIR_LIST_STARTED;
336 return TRUE;
337 }
338
339
osdir_list_next()340 const char *osdir_list_next()
341 {
342 if (FindNextFile(hFind, &FindFileData) == 0) {
343 osdir_list_status = OSDIR_LIST_DONE;
344 return NULL;
345 }
346 return FindFileData.cFileName;
347 }
348
osdir_list_finish()349 void osdir_list_finish()
350 {
351 if (osdir_list_status != OSDIR_LIST_READY) {
352 FindClose(hFind);
353 }
354 osdir_list_status = OSDIR_LIST_READY;
355 }
356
357
358 /* xechoenabled -- set/clear echo_enabled flag (unix only) */
xechoenabled()359 LVAL xechoenabled()
360 {
361 int flag = (xlgetarg() != NULL);
362 xllastarg();
363 // echo_enabled = flag; -- do nothing in Windows
364 return NULL;
365 }
366
367