home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
-
- mac_io.c: Copyright (c) Kevin Hammond 1993. All rights reserved.
-
- This module implements character-based IO, such as printf to the
- worksheet, and keyboard input. It handles i/o during evaluation
- as well as input to the edit windows.
-
- IMPORTANT: DON'T INCLUDE the GOFER prelude.h.
- This file uses the REAL fprintf etc.!!
-
- *****************************************************************************/
-
-
- #include "mac.h"
- #include <stdarg.h>
- #include <string.h>
- #include <AppleEvents.h>
-
- #pragma segment IO
-
- extern Bool USER_ABORT; /* Abort Gofer */
- extern Bool terminalEchoReqd; /* Whether to echo input */
-
- extern Boolean quit; /* Set on application exit */
- extern Boolean MemoryInstalledOK; /* Whether initialisation's OK */
- extern jmp_buf catch_error; /* Standard Error Location */
-
- Boolean running_interpreter = FALSE; /* Set if the interpreter's running */
- Boolean HandlingEvents = FALSE; /* Set if a graphics program's running */
- Boolean EOFread = FALSE; /* Set when EOF's been read */
- static short inputafter = 0; /* Start of user input */
-
- Boolean cursorkey(); /* Test for a cursor key */
- void CheckKeys(); /* Check whether a key's been pressed */
- void DoKeyEvent(); /* Handle a key event */
-
- static short IntInterval = 0;
- #define IntThreshold 300
-
-
- /* Standard event masks for window events, and key events */
-
- #define WinEventMask (updateMask|activMask|highLevelEventMask|osMask|mDownMask)
- #define KeyEventMask (keyDownMask|autoKeyMask|osMask|highLevelEventMask)
- #define HiPriEvt (~(KeyEventMask|updateMask))
- #define KEY_BUFFER_SIZE 256
- static EventRecord KeyEvents[KEY_BUFFER_SIZE];
- static short firstkeyevent = 0, lastkeyevent = 0;
-
- /***************************************************************************
-
- Interrupt Handing.
-
- ***************************************************************************/
-
-
- /*
- Check for an interrupt (CMD-DOT) without losing keyboard events.
- */
-
-
- CheckInterrupt()
- {
- /* No interrupts at first */
- if(!MemoryInstalledOK)
- return;
-
- do {
- EventRecord myEvent, dummyEvent, *myEventP;
-
- int nextkeyevent = (lastkeyevent + 1) % KEY_BUFFER_SIZE;
-
- if(nextkeyevent == firstkeyevent)
- myEventP = &myEvent;
- else
- myEventP = &(KeyEvents[lastkeyevent]);
-
- IntInterval = 0;
-
- (void) EventAvail(KeyEventMask,myEventP);
-
- /* Check for interrupt */
- if(myEventP->what != nullEvent)
- {
- char ch = (char) (myEventP->message & charCodeMask);
-
- GetNextEvent(KeyEventMask,&dummyEvent);
-
- if(myEventP->what == osEvt)
- DoOSEvent();
-
- else if(myEventP->what == kHighLevelEvent)
- DoHighLevelEvent();
-
- else
- {
- if ((myEventP->modifiers & cmdKey) != 0 && ch == '.')
- {
- FlushEvents (everyEvent,0 ); /* Clear all outstanding events */
- lastkeyevent = firstkeyevent; /* Including buffered characters */
- breakHandler();
- }
-
- if ( nextkeyevent != firstkeyevent )
- lastkeyevent = nextkeyevent;
- }
- }
- else
- break;
-
- } while (1);
- }
-
-
- /*
- Handle any saved keyboard events.
- Called after execution, or on initialisation.
- */
-
-
- FlushKeyEvents()
- {
- while( firstkeyevent != lastkeyevent )
- {
- int savekeyevent = firstkeyevent;
- firstkeyevent = (firstkeyevent + 1) % KEY_BUFFER_SIZE;
- DoKeyEvent(&(KeyEvents[savekeyevent]),worksheet,FALSE);
- }
- }
-
-
- GetNextKbdEvent(evtmask,checkonly)
- int evtmask, checkonly;
- {
- /* First check for interrupts */
- CheckInterrupt();
-
- if(firstkeyevent != lastkeyevent && (evtmask & KeyEventMask) != 0)
- {
- myEvent.what = nullEvent;
-
- if((evtmask & HiPriEvt) != 0 && EventAvail(evtmask & HiPriEvt,&myEvent) && !checkonly)
- getnextevent(evtmask & HiPriEvt);
-
- if(myEvent.what == nullEvent)
- {
- myEvent.what = KeyEvents[firstkeyevent].what;
- myEvent.message = KeyEvents[firstkeyevent].message;
- myEvent.when = KeyEvents[firstkeyevent].when;
- myEvent.where = KeyEvents[firstkeyevent].where;
- myEvent.modifiers = KeyEvents[firstkeyevent].modifiers;
-
- if(!checkonly)
- firstkeyevent = (firstkeyevent + 1) % KEY_BUFFER_SIZE;
- }
-
- }
- else
- if(checkonly)
- (void) EventAvail(evtmask,&myEvent);
- else
- getnextevent(evtmask);
- }
-
- /***************************************************************************
-
- Output Handing.
-
- ***************************************************************************/
-
-
- /*
- Append a buffer of characters to the worksheet window.
- */
-
- showbuff(buffer,buflen)
- char *buffer;
- long buflen;
- {
- if (buflen > 0)
- {
- TEHandle teh = TEHANDLE(worksheet);
-
- if((*teh)->teLength + buflen > TE_REC_SIZE)
- ClearSpace(teh,buflen);
-
- /* We add one to indicate the *right* of the last character */
- TESetSelect((*teh)->teLength+1,(*teh)->teLength+1,teh);
- TEInsert((Ptr)buffer,buflen,teh);
- inputafter = (*teh)->selStart;
- }
- }
-
-
-
- /*
- Append a single character to the worksheet window.
- */
-
- showchar(c)
- char c;
- {
- TEHandle teh = TEHANDLE(worksheet);
- short caretState = (*teh)->caretState;
-
- if((*teh)->teLength == TE_REC_SIZE)
- ClearLines(teh,100);
-
- // (*teh)->caretState = 0;
- /* We add one to indicate the *right* of the last character */
- TESetSelect((*teh)->teLength+1,(*teh)->teLength+1,teh);
- TEInsert((Ptr)&c,1,teh);
- inputafter = (*teh)->selStart;
- // (*teh)->caretState = caretState;
- }
-
-
- /*
- Make sure the worksheet scrolls to the right position during IO.
- */
-
- updateWorksheet()
- {
- AdjustScrollBars(worksheet);
- ScrollToSelection(worksheet);
- }
-
-
-
- /***************************************************************************
-
- Macintosh printf code.
-
- This code reimplements printf, so that characters can be
- written correctly to the worksheet. It has to be done this
- way rather than using a single sprintf, because there is no version
- of sprintf which takes an array of arguments in a form which
- we can extract from the printf call.
-
- We also want to update the worksheet window whenever we see a
- newline.
-
- ***************************************************************************/
-
-
-
- static char buffer[256]; /* Temporary buffer */
- static char minifmt[20]; /* Holds a short format string */
-
- domprintf(fmt,argl)
- char *fmt;
- va_list *argl;
- {
- va_list args = (va_list) argl;
- char *buffp = buffer;
-
- int minisize; /* -- used in a call to sprintf */
- Boolean found; /* Set when a format has been found */
- char ch;
-
- minifmt[0]='%';
-
- while((ch = *fmt) != '\0')
- {
- if(ch == '%')
- {
- ++fmt;
- for(found=FALSE, minisize = 1;
- !found && (ch = *fmt) != '\0';
- ++fmt)
-
- switch (ch)
- {
- case '%':
- *buffp++ = '%';
- found = TRUE;
- break;
-
- /* All printfs of %c are ints rather than chars!
-
- case 'c':
- strcpy(minifmt+minisize,"c");
- sprintf(buffp,minifmt,va_arg(args,char));
- buffp += strlen(buffp);
- found = TRUE;
- break;
- */
-
- case 'l':
- case '.':
- case '-': case '+':
- case '1': case '2': case '3': case '4': case'5':
- case '6': case '7': case '8': case '9': case'0':
- minifmt[minisize++] = ch;
- break;
-
- case 's':
- minifmt[minisize++]= ch;
- minifmt[minisize] = '\0';
- sprintf(buffp,minifmt,va_arg(args,char *));
- buffp += strlen(buffp);
- found = TRUE;
- break;
-
- case 'f': case 'g':
- minifmt[minisize++]= ch;
- minifmt[minisize] = '\0';
- sprintf(buffp,minifmt,va_arg(args,double));
- buffp += strlen(buffp);
- found = TRUE;
- break;
-
- case 'c': /* All Gofer chars are ints! KH */
- case 'd': case 'x': case 'o':
- case 'u': case 'i':
- case 'X':
- minifmt[minisize++]= ch;
- minifmt[minisize] = '\0';
- sprintf(buffp,minifmt,va_arg(args,int));
- buffp += strlen(buffp);
- found = TRUE;
- break;
-
- default:
- AbortErrorN("Unrecognised Control Char in printf: %%%c",(int)ch);
- *buffp++ = ch;
- }
- }
-
- /* Flush the current buffer on newline */
- else if (ch == '\n' || ch == '\r' )
- {
- showbuff(buffer,(long)(buffp-buffer));
- updateWorksheet();
- showchar('\n');
-
- buffp=buffer;
- fmt++;
- }
-
- else /* Neither % nor newline */
- *buffp++ = *fmt++;
- }
- va_end(args);
- showbuff(buffer,(long)(buffp-buffer));
- updateWorksheet();
- changed(worksheet);
- }
-
-
- /*
- printf is aliased to this in the standard Gofer code.
- */
-
- mprintf(fmt,argl)
- char *fmt;
- va_list argl;
- {
- CheckInterrupt();
- domprintf(fmt,&argl);
- }
-
-
- /*
- fprintf is aliased to this in the standard Gofer code.
- Send output to the worksheet for stdout/stderr, or to
- a file for any other file pointer.
- */
-
-
- mfprintf(f,fmt,argl)
- FILE *f;
- char *fmt;
- va_list argl;
- {
- CheckInterrupt();
-
- if(f == stdout || f == stderr)
- domprintf(fmt,&argl);
- else
- fprintf(f,fmt,argl);
- }
-
- /*
- Output a character to either the worksheet or a file.
- Implements the standard putc(char,file);
- */
-
- mputc(c,f)
- FILE *f;
- int c;
- {
- if(f == stdout || f == stderr)
- {
- TEHandle teh = TEHANDLE(worksheet);
-
- showchar(c);
- changed(worksheet);
-
- /* Moved out of loop to allow for auto-wrap on output */
- if((*teh)->selStart == (*teh)->lineStarts[(*teh)->nLines])
- {
- AdjustScrollBars(worksheet);
- ScrollToSelection(worksheet);
- }
-
- if(c == '\r' || c == '\n')
- CheckInterrupt();
- }
- else
- {
- fputc(c,f);
- if(++IntInterval == IntThreshold)
- CheckInterrupt();
- }
- }
-
-
- /* Write a newline to the worksheet if not already at the start of a line */
-
- writeNewLine()
- {
- TEHandle teh = TEHANDLE(worksheet);
- char *text;
- char ch;
- TESetSelect((*teh)->selEnd,(*teh)->selEnd,teh);
- text = *(char **)((*teh)->hText);
-
- if( (ch=*(text+(*teh)->selStart-1)) != '\n' && ch != '\r' )
- mputc('\n',stdout);
- }
-
-
-
- /***************************************************************************
-
- Input Handing.
-
- ***************************************************************************/
-
-
- #define KEY_SIZE 1024
- static char keybuff[KEY_SIZE]; /* The key input buffer */
- static int keystart = 0; /* Head of queue */
- static int keyend = 0; /* Tail of queue */
-
-
- /*
- Handle key presses as Toolbox Events.
- */
-
-
- static char tabs[] = " ";
-
- void DoKeyEvent(event,thewindow,domenus)
- EventRecord *event;
- int thewindow;
- Boolean domenus;
- {
- char ch = (char) (event->message & charCodeMask); /* Convert to ASCII */
- int nextkey;
-
- /* Handle command keys */
-
- if ((event->modifiers & cmdKey) != 0)
- {
- if (ch == '.')
- USER_ABORT = TRUE;
-
- else if (ch == ENTERkey)
- EOFread = TRUE;
-
- /* The general-purpose code doesn't seem to trap CMD-? */
- else if (ch == '?' || ch == '/')
- {
- DoMenuWindow(MItem_Help);
- drawcursor(myEvent, FALSE);
- }
-
- else if (domenus)
- {
- long result = MenuKey(ch);
- DoMenu(result,event->modifiers);
- }
- }
-
- /* Abort if Escape/Clear pressed */
- else if (ch == ESC)
- USER_ABORT = TRUE;
-
- /* Otherwise it's a normal character */
- else if (isEditWindow(thewindow))
- {
- ObscureCursor();
-
- /* If echo is off, don't echo to the worksheet */
- if(!terminalEchoReqd && thewindow == worksheet)
- {
- if((nextkey=(keyend+1)%KEY_SIZE)!= keystart)
- {
- keybuff[keystart]=ch;
- keyend = nextkey;
- }
- else
- StopAlert(Res_Kbd_Buffer_Full_Alert,NIL);
- }
- else
- {
- TEHandle teh = TEHANDLE(thewindow);
-
- /* teLength removed to try to avoid crashing */
- short selStart = (*teh)->selStart, selEnd = (*teh)->selEnd;
-
-
- /* Set the changed flag, unless this was a cursor key */
- if (!cursorkey(ch))
- {
- keyundo(thewindow);
- changed(thewindow);
- }
- else
- cantundo();
-
- /* Return, newline and enter are treated uniformly */
- if(ch=='\r' || ch == ENTERkey)
- ch = '\n';
-
- if(ch=='\n' && thewindow == worksheet)
- {
- if(selEnd == (*teh)->teLength)
- {
- if((*teh)->teLength >= TE_REC_SIZE)
- ClearSpace(teh,1000);
-
- AdjustPromptCount(TRUE);
- TEKey(ch,teh);
- }
- AdjustScrollBars(worksheet);
- ScrollToSelection(worksheet);
- ReadWorksheetLine();
- }
-
- else if (ch != DELETEkey || thewindow != worksheet ||
- selStart != inputafter || selStart != selEnd )
- {
- WindowKey(ch,thewindow);
- }
- }
- }
- AdjustMenus(FALSE);
- }
-
-
- /*
- Handle a normal character key for a window.
- */
-
- #define TAB_SPACING 8
-
- WindowKey(ch,thewindow)
- char ch;
- int thewindow;
- {
- int charwidth;
- TEHandle teh = TEHANDLE(thewindow);
- short selStart = (*teh)->selStart,
- selEnd = (*teh)->selEnd;
-
- thefrontwindow = thewindow;
-
- /* Abort if the key can't be added to the window */
- if(ch == TABkey && (*teh)->teLength >= TE_REC_SIZE-TAB_SPACING ||
- (*teh)->teLength >= TE_REC_SIZE)
- {
- if(thewindow == worksheet)
- ClearLines(teh,100);
- else
- AbortError("","Can't add any more text to this window");
- }
-
- if(thewindow == worksheet && (selStart < inputafter || selEnd < inputafter) &&
- !cursorkey(ch))
- {
- AdjustPromptCount(TRUE);
- }
-
- /* Tabs are converted to an appropriate number of spaces on input */
- if(ch == TABkey)
- {
- int nl;
- char ch1;
-
- for(nl=(*teh)->selStart-1; (ch1=*(*((*teh)->hText)+nl)) != '\n'&& ch1 != '\r' && nl >= 0; --nl)
- /* SKIP */;
-
- charwidth = TAB_SPACING-((*teh)->selStart-1-nl)%TAB_SPACING;
- TEInsert((Ptr)tabs,(long)charwidth,teh);
- }
-
- /* Other characters are just added to the window */
- else
- {
- TEKey(ch,teh);
- charwidth = ch == DELETEkey?-(selStart==selEnd):1;
- }
-
- /* Update the characters after the prompt */
- if(thewindow == worksheet && (selStart < inputafter || selEnd < inputafter) &&
- !cursorkey(ch))
- {
- inputafter += charwidth;
- }
-
- /* Fix up the scroll bars and adjust the window */
- AdjustScrollBars(thewindow);
- ScrollToSelection(thewindow);
- }
-
-
- /* Remove the first nlines lines from the Text Edit record teh */
-
- ClearLines(teh,nlines)
- TEHandle teh;
- int nlines;
- {
- TESetSelect(0,(*teh)->lineStarts[nlines],teh);
- TEDelete(teh);
- TESetSelect((*teh)->teLength+1,(*teh)->teLength+1,teh);
- }
-
- /* Clear some space at the start of the text edit record */
-
- ClearSpace(teh,nchars)
- TEHandle teh;
- int nchars;
- {
- TESetSelect(0,nchars,teh);
- TEDelete(teh);
- TESetSelect((*teh)->teLength+1,(*teh)->teLength+1,teh);
- }
-
- /*
- Works out where the prompt is on the current line, so that
- this isn't counted when <CR> is pressed.
- */
-
- static short selStart, selEnd;
-
- AdjustPromptCount(delete)
- Boolean delete;
- {
- TEHandle teh = TEHANDLE(worksheet);
-
- selEnd = (*teh)->selEnd;
-
- if(delete)
- {
- selStart = (*teh)->selStart;
- if(selStart < inputafter)
- {
- int i;
-
- /* find line start corresponding to selStart */
- for(i=1;(*teh)->lineStarts[i]<selStart;++i)
- ;
-
- /* Allow for character at start of line */
- if(i < (*teh)->nLines && (*teh)->lineStarts[i]==selStart)
- ++i;
-
- inputafter = (*teh)->lineStarts[i-1];
- }
- }
- else if(selStart < inputafter)
- {
- if(selEnd < inputafter)
- inputafter += selEnd - selStart;
- else
- inputafter = selEnd;
- }
- }
-
-
- /*
- Determines whether the TextEdit buffer contains a newline in
- the specified selection region.
- */
-
- Boolean findnl(teStart,teEnd,teh)
- short teStart,teEnd;
- TEHandle teh;
- {
- char **hText = (char **) (*teh)->hText;
- char ch;
- for(;teStart<teEnd;teStart++)
- if((ch=*((*hText)+teStart)) == '\n' || ch == '\r')
- return(TRUE);
- return(FALSE);
- }
-
-
- /*
- Called when a selection is copied into the worksheet window,
- it calls newinput, which will execute the interpreter if it's
- not already running, whenever the input contains a newline.
- */
-
-
- PasteInput()
- {
- if(selStart >= inputafter && findnl(selStart,selEnd,TEHANDLE(worksheet)))
- newinput(selStart,selEnd,FALSE);
- }
-
-
- /*
- Read a line from the worksheet.
- */
-
- ReadWorksheetLine()
- {
- short i;
- short posn, teStart, teEnd;
- TEHandle teh = TEHANDLE(worksheet);
-
- retry:
- posn = (*teh)->selStart;
-
- /* find line start corresponding to posn */
- for(i=1;(*teh)->lineStarts[i]<posn;++i)
- ;
-
- /* Allow for character at start of line */
- if(i < (*teh)->nLines && (*teh)->lineStarts[i]==posn)
- ++i;
-
- /* Calculate start and end points. Allow for prompts */
- teStart = (*teh)->lineStarts[i-1];
- if(i == (*teh)->nLines && inputafter > teStart)
- teStart = inputafter;
- teEnd = i==(*teh)->nLines?(*teh)->teLength-1:(*teh)->lineStarts[i]-1;
-
- if((long)(*teh)->teLength + teEnd - teStart + 1 > TE_REC_SIZE)
- {
- ClearLines(teh,100);
- goto retry;
- }
-
- /*
- Add the line to the end of the worksheet.
- Include a NL except when we're at the end of the buffer.
- */
-
- TESetSelect((**teh).teLength+1,(**teh).teLength+1,teh);
-
- if(i==(*teh)->nLines)
- {
- char ch = *(*(*teh)->hText + teEnd);
- if (ch != '\n' && ch != '\r')
- {
- TEKey('\n',teh);
- ++teEnd;
- }
- }
- else
- TEInsert((Ptr)((*(*teh)->hText)+teStart),teEnd-teStart+1,teh);
-
- updateWorksheet();
-
- newinput(teStart,teEnd,TRUE);
- }
-
-
- /*
- Is ch a cursor key.
- */
-
-
- Boolean cursorkey(ch)
- char ch;
- {
- return(ch == LARROWkey || ch == RARROWkey || ch == UARROWkey || ch == DARROWkey);
- }
-
-
- /*
- Non-Multitasking input routine.
-
- Handle all outstanding key and window events during evaluation.
- If we are handling our own events, then only intercept the
- keyboard events.
-
- */
-
-
-
- void CheckKeys()
- {
- EventRecord event;
-
- int evtmask = HandlingEvents? KeyEventMask: (KeyEventMask|WinEventMask);
-
- FlushKeyEvents();
-
- while(EventAvail(evtmask,&event))
- {
- if(EventAvail(KeyEventMask,&event))
- {
- GetNextEvent(KeyEventMask,&event);
- DoKeyEvent(&event,worksheet,FALSE);
- }
- else
- {
- /* Temporarily ignore project resources */
- if(HandlingEvents)
- useprojectresfile(FALSE,FALSE);
-
- eventloop(WinEventMask);
-
- /* Use project resources once more if handling events ourselves */
- if(HandlingEvents)
- useprojectresfile(TRUE,FALSE);
- }
- }
- }
-
-
- /*
- Reset the input buffer.
- Should be called on initialisation or error.
- */
-
- resetinput()
- {
- keyend = keystart;
- EOFread = FALSE;
- terminalEchoReqd = TRUE;
- inputafter = (*TEHANDLE(worksheet))->selStart;
- }
-
-
- /*
- Get a character from the key buffer, or from a
- file.
- */
-
- int mgetc(stream)
- FILE *stream;
- {
- int ch;
-
- if(stream == stdin)
- {
- while(keystart == keyend && !EOFread)
- {
- if(MultiTasking)
- eventloop(everyEvent);
- else
- CheckKeys();
- if(USER_ABORT)
- {
- USER_ABORT = FALSE;
- breakHandler();
- }
- if(quit)
- longjmp(catch_error,1);
- }
-
- if(keystart==keyend && EOFread)
- {
- ch = EOF;
- EOFread = FALSE;
- }
-
- else
- {
- ch = keybuff[keystart];
- keystart = (keystart + 1) % KEY_SIZE;
- }
- }
- else
- {
- /* Check for CTRL-. even when reading files */
- if(++IntInterval == IntThreshold)
- CheckInterrupt();
- ch = getc(stream);
- }
-
- return(ch);
- }
-
-
- /*
- "Steal" input from a textedit buffer.
- */
-
- extern Boolean MemoryInstalledOK;
-
- newinput(teStart,teEnd,appendNL)
- long teStart, teEnd;
- Boolean appendNL;
- {
- char *text, lastch = ' ';
- int nextkey;
-
- text = *(char **)(*TEHANDLE(worksheet))->hText;
-
- /* Try to protect the user from themselves */
- if(!MemoryInstalledOK)
- {
- SysBeep(3);
- return;
- }
-
- while(teStart <= teEnd && (nextkey=(keyend+1)%KEY_SIZE) != keystart)
- {
- /* Convert CR to NL */
- if(text[teStart] == '\r')
- text[teStart] = '\n';
-
- /* Convert intermediate newlines to spaces */
- if(teStart < teEnd && text[teStart] == '\n')
- lastch = keybuff[keyend] = ' ';
- else
- lastch = keybuff[keyend] = text[teStart];
-
- ++teStart;
- keyend = nextkey;
- }
-
- if(appendNL && (nextkey=(keyend+1)%KEY_SIZE) != keystart && lastch != '\n')
- {
- keybuff[keyend] = '\n';
- keyend = nextkey;
- }
-
- /* Evaluate if we're not already doing so */
- if(!running_interpreter)
- {
- running_interpreter = TRUE;
- USER_ABORT = EOFread = FALSE;
- HandlingEvents = FALSE;
-
- SpinCursor(0);
- ShowCursor();
- if(!MultiTasking)
- disablemenus(TRUE);
-
- /* do
- {
- */
- EOFread = FALSE;
- interpreter(0);
- /*
- }
- while(keystart != keyend);
- */
-
- /* Unload the project resources, if necessary */
- useprojectresfile(FALSE,TRUE);
-
- DoneInterpreter();
- }
- }
-
-
-
- /*
- Tidy up after running the interpreter.
- */
-
- DoneInterpreter()
- {
- thefrontwindow = findMyWindow(FrontWindow());
-
- running_interpreter = FALSE;
-
- disablemenus(FALSE);
-
- AdjustMenus(TRUE);
-
- resetinput();
-
- FlushKeyEvents();
-
- ResetCursor(); /* Reset the cursor from a watch cursor */
- }
-
-
- /*
- Flush a file. Don't do anything for the worksheet,
- it's always "unbuffered".
- */
-
- mflush(f)
- FILE *f;
- {
- if(f == stdout || f == stderr)
- /* SKIP */;
- else
- fflush(f);
- }
-