home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * console.c
- *
- * Copyright (c) 1989 Symantec Corporation. All rights reserved.
- *
-
- This file has some additions by G. Speranza, clearly identified by comments
- It is fully compatible with the original version, nothing was lost, but there
- are a few new entry points and a few "hooks" by which you may exploit some
- potentialities which existed but where not intended to be exploited by user
- programs
- */
-
- #include <MacHeaders>
- #include <PrintMgr.h>
- extern Boolean WWExist : 0x8F2;
-
- /* remove this line to work on ALL systems */
- #include <PrintTraps.h> /* requires System 4.1 */
-
- #include "stdio.h"
- #include "stddef.h"
- #include "stdlib.h"
- #include "string.h"
- #include "signal.h"
- #include "errno.h"
- #include "console.h"
- #include "ansi_private.h"
-
-
- /********* aggiunta di G. Speranza **********/
-
- int isConsoleWindow(WindowPeek);
-
- void (*my_add_about)(MenuHandle) =NULL; /* aggiunta entry al men¥ mela */
- /* you may assign to it a function which adds items
- to the apple menu */
- void (*my_add_commands)(MenuHandle) =NULL; /* aggiunta al men¥ file */
- /* add items to the File menu */
- void (*my_add_menus)() =NULL; /* aggiunta altri men¥ dopo il men¥ edit */
- /* add menus after the Edit menu */
- void (*my_handle_menus)(long)=NULL; /* gestione nuove entry in qualunque men¥ */
- /* handle selection of any item introduced by previous
- routines */
- void (*my_event_filter)(EventRecord*)=NULL; /* permette di "filtrare" un evento, dopo che
- ProcessEvent ha chiamato GetNextEvent e prima che lo
- gestisca, basta settare il campo what a nullEvent per
- sopprimere la gestione standard*/
- /* filter events, that is handle (and possibly modify)
- them before the standard actions take place */
-
- long my_current_size=0; /* permette di settare le dimensioni iniziali
- di una finestra a un valore diverso dalle dimensioni
- massime (quelle oltre cui poi si rifiuta di crescere),
- meglio usarlo attraverso le funzioni in my_window */
- long my_current_A5; /* da usare attraverso le funzioni in my_window */
- static short quit_selection;
- static short n_about_entries;
-
- /********* isConsoleWindow: returns true if the window belongs to the ANSI library
- (FindWindow returns inSysWindow, as if they belonged to desk accessories! ) */
-
- int isConsoleWindow(wp)
- WindowPeek wp;
- {
- register FILE *fp;
- int n;
- for (fp = &__file[0], n = FOPEN_MAX ; n--; fp++)
- if (fp->refnum && (fp->window==wp) ) return 1;
- return 0;
- }
-
- /********* fine aggiunta ***************/
-
-
-
- struct __copt console_options = { 50, 10, "\pconsole", 8, 4, 9, 0, 25, 80, 1 };
- char __log_stdout;
-
- /*commentato
- static
- *****/
- void InitConsole(void);
- /****** commentato
- static
- *****/
- void ProcessEvent(void);
- static WindowPeek new_console(void);
- static void kill_console(void);
- static void closeecho(void);
- static WindowPeek cflush(FILE *);
-
- static void console_exit(void);
- static int consoleio(FILE *, int);
- static pascal void myStdText(int, char *, Point, Point);
-
- static void cleos(int);
- static void cleol(void);
- static void output(unsigned char *, int);
- static void overwrite(unsigned char *, long);
- static void delete(int, int);
- static void insert(char, int);
- static void pad(char, long, long);
- static void paste(int, int);
- static int setcursor(int);
- static TEPtr deactivate(void);
- static void strip(void);
- static char *copy(void);
- static void endcopy(void);
- static void newline(void);
- static void resize(void);
- static void setup(WindowPeek, struct save *);
- static void restore(struct save *);
- static void use(WindowPeek);
-
- static int open_console_driver(void);
- static int doClose(void);
- static int doControl(void);
- static void doCursor(void);
- static void doClick(EventRecord *);
- static void doZoom(Point, int);
- static void doGrow(Point);
- static void doSelect(EventRecord *);
- static int doCmdKey(int);
- static void doKey(int);
- static void doCut(void);
- static void doCopy(void);
- static void doPaste(void);
-
- static void print_console(void);
- static void print(void);
-
- static pascal Handle NewHandle(long);
- static pascal void DisposHandle(void *);
-
- static struct console {
- WindowPeek wp;
- short height;
- short width;
- short nrows;
- short ncols;
- Point cursor;
- short tabs;
- TEHandle hTE;
- Point limit;
- Handle pasteH;
- long pasteOfs;
- long pasteLen;
- FILE *echo2fp;
- unsigned raw : 1;
- unsigned cbreak : 1;
- unsigned edit : 1;
- unsigned reading : 1;
- unsigned inverse : 1;
- unsigned spool : 1;
- } c;
-
- static char console_environment, noPrint, interrupted;
- static short console_refnum;
- static MenuHandle appleMenu;
- static WindowPeek theConsole;
-
- struct save {
- WindowPeek console;
- GrafPtr port;
- };
-
- static struct {
- unsigned char *buf;
- unsigned char *ptr;
- size_t cnt;
- int min;
- int max;
- } in;
-
- struct vector {
- short vJMP;
- int (*vCode)();
- };
-
- #define OFS(x) offsetof(struct drvr, x)
-
- static struct drvr {
- short drvrFlags, drvrDelay, drvrEMask, drvrMenu;
- short drvrOpen, drvrPrime, drvrCtl, drvrStatus, drvrClose;
- char drvrName[10];
- short drvrRTS;
- struct vector vCtl, vClose;
- } drvr = {
- 0x0760, 0, 0x016A, 0,
- OFS(drvrRTS), OFS(drvrRTS), OFS(vCtl), OFS(drvrRTS), OFS(vClose),
- "\p.console",
- 0x4E75,
- { 0x4EF9 }, { 0x4EF9 }
- }, **drvrH;
-
- #define hiword(x) (((short *) &(x))[0])
- #define loword(x) (((short *) &(x))[1])
-
- /* ---------- public entry points ---------- */
-
-
- /*
- * fopenc - open a stream on a new console
- *
- */
-
- FILE *
- fopenc()
- {
- return(freopenc(NULL, __getfile()));
- }
-
-
- /*
- * freopenc - reopen a stream on a new or existing console
- *
- * "fp" is closed, if necessary, then opened as a console. If "fp2"
- * is NULL, a new console is created; otherwise "fp2" must refer to
- * a console, and "fp" is made to refer to the same console.
- *
- */
-
- FILE *
- freopenc(fp2, fp)
- register FILE *fp2, *fp;
- {
- if (fp == NULL)
- return(NULL);
- if (WWExist)
- InitConsole();
- fclose(fp);
- fp->refnum = -1;
- fp->window = fp2 ? fp2->window : new_console();
- setvbuf(fp, NULL, _IOLBF, BUFSIZ);
- fp->proc = consoleio;
- __atexit_console(console_exit);
- return(fp);
- }
-
-
- /*
- * cgotoxy - position cursor at <x,y>
- *
- * The position of the upper left corner is <1,1>.
- *
- * This routine does NOT check its arguments. Don't place the
- * cursor off-screen!
- *
- */
-
- void
- cgotoxy(x, y, fp)
- int x, y;
- FILE *fp;
- {
- struct save save;
-
- setup(cflush(fp), &save);
- c.cursor.h = x - 1;
- c.cursor.v = y - 1;
- restore(&save);
- }
-
-
- /*
- * cgetxy - report the current cursor position
- *
- * The position of the upper left corner is <1,1>.
- *
- */
-
- void
- cgetxy(x, y, fp)
- int *x, *y;
- FILE *fp;
- {
- struct save save;
-
- setup(cflush(fp), &save);
- *x = c.cursor.h + 1;
- *y = c.cursor.v + 1;
- restore(&save);
- }
-
-
- /*
- * ccleos - clear from cursor to end of screen
- *
- * The line containing the cursor, and all following lines, are erased.
- * The cursor is left at the start of the first line erased.
- *
- */
-
- void
- ccleos(fp)
- FILE *fp;
- {
- struct save save;
-
- setup(cflush(fp), &save);
- cleos(c.cursor.v);
- restore(&save);
- }
-
-
- /*
- * ccleol - clear from cursor to end of line
- *
- */
-
- void
- ccleol(fp)
- FILE *fp;
- {
- struct save save;
-
- setup(cflush(fp), &save);
- cleol();
- restore(&save);
- }
-
-
- /*
- * csettabs - set tab stops
- *
- */
-
- void
- csettabs(tabs, fp)
- int tabs;
- FILE *fp;
- {
- struct save save;
-
- setup(cflush(fp), &save);
- if (tabs < 1 || tabs > c.ncols)
- tabs = 1;
- c.tabs = tabs;
- restore(&save);
- }
-
-
- /*
- * csetmode - set console mode
- *
- */
-
- void
- csetmode(mode, fp)
- int mode;
- FILE *fp;
- {
- struct save save;
-
- setup(cflush(fp), &save);
- c.raw = c.cbreak = c.edit = 0;
- switch (mode) {
- case C_RAW:
- c.raw = 1;
- break;
- case C_CBREAK:
- c.cbreak = 1;
- break;
- case C_NOECHO:
- break;
- case C_ECHO:
- c.edit = 1;
- break;
- }
- restore(&save);
- }
-
-
- /*
- * cinverse - set inverse video mode
- *
- * As a side effect, the entire screen is erased. The cursor is moved
- * to the start of its line.
- *
- */
-
- void
- cinverse(on, fp)
- int on;
- FILE *fp;
- {
- register WindowPeek wp = cflush(fp);
- struct save save;
-
- setup(wp, &save);
- if (on) {
- if (!wp->port.grafProcs) {
- wp->port.grafProcs = malloc(sizeof(QDProcs));
- SetStdProcs(wp->port.grafProcs);
- wp->port.grafProcs->textProc = (Ptr) myStdText;
- }
- }
- else {
- if (wp->port.grafProcs) {
- free(wp->port.grafProcs);
- wp->port.grafProcs = 0;
- }
- }
- cleos(0);
- restore(&save);
- }
-
-
- /*
- * cshow - show a console window
- *
- * All pending output to the window is forced to appear.
- *
- */
-
- void
- cshow(fp)
- register FILE *fp;
- {
- WindowPeek wp = cflush(fp);
-
- SelectWindow(wp);
- ShowWindow(wp);
- }
-
-
- /*
- * chide - hide a console window
- *
- */
-
- void
- chide(fp)
- FILE *fp;
- {
- HideWindow(cflush(fp));
- }
-
-
- /*
- * cecho2file - echo console display to file
- *
- */
-
- void
- cecho2file(s, append, fp)
- char *s;
- int append;
- FILE *fp;
- {
- struct save save;
-
- setup(cflush(fp), &save);
- closeecho();
- c.echo2fp = fopen(s, append ? "a" : "w");
- c.spool = 0;
- restore(&save);
- }
-
-
- /*
- * cecho2printer - echo console display to printer
- *
- */
-
- void
- cecho2printer(fp)
- FILE *fp;
- {
- struct save save;
-
- setup(cflush(fp), &save);
- closeecho();
- c.echo2fp = tmpfile();
- c.spool = 1;
- restore(&save);
- }
-
-
- /* ---------- console management ---------- */
-
-
- /*
- * __open_std - open the std streams
- *
- * This is called automatically (by "__checkfile") whenever an
- * unopened std stream is referenced.
- *
- */
-
- void
- __open_std()
- {
- FILE *fp = NULL;
- char buf[40];
-
- if (stdin->std)
- fp = freopenc(fp, stdin);
- if (stdout->std)
- fp = freopenc(fp, stdout);
- if (stderr->std)
- fp = freopenc(fp, stderr);
- if (__log_stdout) {
- sprintf(buf, "%#s.log", CurApName);
- cecho2file(buf, 1, stdout);
- console_options.pause_atexit = 0;
- }
- }
-
-
- /*
- * InitConsole - initialize the console environment
- *
- */
-
- /******* commentato
- static
- *****/
- void
- InitConsole()
- {
- MenuHandle menu;
-
- /***** aggiunta *****/
- static _inited=0;
-
- if(_inited)return;
- _inited=1;
- /******** fine aggiunta *******/
-
- /* initialize the Memory Manager */
-
- asm {
- moveq #9,d1
- tst.w ROM85
- bmi.s @1
- _MaxApplZone
- @1 _MoreMasters
- dbra d1,@1
- }
-
- /* initialize Quickdraw */
-
- asm {
- move.l #206,d0
- _NewPtr
- pea 202(a0)
- /************** aggiunta ***********/
- move.l (SP),my_current_A5
- /********* fine *********/
- _InitGraf
- }
-
- /* initialize the Toolbox */
-
- InitFonts();
- InitWindows();
- TEInit();
- InitDialogs(0);
- InitMenus();
-
- /* create menus */
-
- InsertMenu(appleMenu = NewMenu(1, "\p\024"), 0);
-
- /******** aggiunta di G. Speranza ****/
- n_about_entries=0;
- if(my_add_about!=NULL){
- (*my_add_about)(appleMenu);
- n_about_entries=CountMItems(appleMenu);
- AppendMenu(appleMenu, "\p(-");
- }
- /** fine aggiunta **********/
-
- AddResMenu(appleMenu, 'DRVR');
- InsertMenu(menu = NewMenu(2, "\pFile"), 0);
-
- /****** altra aggiunta *********/
- if(my_add_commands!=NULL){
- (*my_add_commands)(menu);
- AppendMenu(menu, "\p(-");
- }
- quit_selection=CountMItems(menu)+1;
- /****** fine aggiunta ********/
-
- AppendMenu(menu, "\pQuit/Q");
-
- InsertMenu(menu = NewMenu(3, "\pEdit"), 0);
- AppendMenu(menu, "\pUndo/Z;(-;Cut/X;Copy/C;Paste/V;Clear");
-
- /******* altra aggiunta ******/
- if(my_add_menus!=NULL)
- (*my_add_menus)();
- /****** fine aggiunta ********/
-
- DrawMenuBar();
-
- /* ready to receive events */
-
- asm {
- moveq #0,d0
- subq.w #1,d0
- _FlushEvents
- }
- InitCursor();
- console_environment = 1;
- }
-
-
- /*
- * ProcessEvent - handle one event
- *
- */
-
- /************* commentato
- static
- */
- void
- ProcessEvent()
- {
- int key;
- EventRecord event;
- WindowPeek wp;
- long choice;
- Str255 buf;
-
- /* process key from paste buffer */
-
- if (c.pasteH) {
- key = (unsigned char) (*c.pasteH)[c.pasteOfs++];
- if (c.pasteOfs == c.pasteLen) {
- DisposHandle(c.pasteH);
- c.pasteH = 0;
- }
- if (c.inverse)
- key &= 0x7F;
- if (key == '\t')
- key = ' ';
- doKey(key);
- return;
- }
-
- /* check for an event */
-
- SystemTask();
- SEvtEnb = false;
- if (GetNextEvent(everyEvent, &event)) {
- /*********** aggiunta ************/
- if(my_event_filter!=NULL) (*my_event_filter)(&event);
- /********* fine aggiunta *********/
- if (!SystemEvent(&event))
- goto doEvent;
- }
- else if (event.what == nullEvent) {
- if (FrontWindow() == 0)
- InitCursor();
- }
- return;
-
- /* handle event */
-
- doEvent:
- if (event.what == mouseDown) {
- switch (FindWindow(event.where, &wp)) {
- case inMenuBar:
- InitCursor();
- choice = MenuSelect(event.where);
- goto doMenu;
- case inSysWindow:
- SystemClick(&event, wp);
- break;
- }
- }
- return;
-
- /* handle menu choice */
-
- doMenu:
- switch (hiword(choice)) {
- case 1: /* Apple */
-
- /****** aggiunta ******/
- if(loword(choice)<=n_about_entries){
- (*my_handle_menus)(choice);
- break;
- }
- /**** fine aggiunta **/
-
- GetItem(appleMenu, loword(choice), buf);
- OpenDeskAcc(buf);
- break;
- case 2: /* File */
-
- /****** aggiunta *********/
- if(loword(choice)!=quit_selection){
- (*my_handle_menus)(choice);
- break;
- }
- /**** fine aggiunta **/
-
- console_options.pause_atexit = 0;
- exit(0);
- /* no return */
- case 3: /* Edit */
- SystemEdit(loword(choice) - 1);
- break;
-
- /**** aggiunta *****/
- case 0: /* no selection */
- break;
- default:
- (*my_handle_menus)(choice);
- /*** fine aggiunta ****/
-
- }
- HiliteMenu(0);
- }
-
-
- /*
- * new_console - create a new console window
- *
- */
-
- static WindowPeek
- new_console()
- {
- GrafPtr savePort;
- struct console **cH;
- static Rect wbox = { 100, 100, 200, 300 };
- register WindowPeek wp;
- Rect bounds;
- FontInfo fontInfo;
- register WStateData *p;
-
- GetPort(&savePort);
- use(0);
-
- /* create the window */
-
- wp = (WindowPeek) NewWindow(0, &wbox, console_options.title, 0, console_options.procID, -1, 0, 0);
- MoveWindow(wp, console_options.left, console_options.top, 0);
- SetPort(c.wp = wp);
-
- /* set up the font characteristics */
-
- TextFont(console_options.txFont);
- TextSize(console_options.txSize);
- TextFace(console_options.txFace);
- GetFontInfo(&fontInfo);
- c.height = fontInfo.ascent + fontInfo.descent + fontInfo.leading;
- c.width = fontInfo.widMax;
-
- /* set console defaults */
-
- c.tabs = 8;
- c.raw = c.cbreak = c.reading = c.inverse = 0;
- c.edit = 1;
- c.pasteH = 0;
- c.echo2fp = 0;
-
- /* set initial window size */
-
- bounds.top = bounds.left = 0;
- bounds.bottom = (c.nrows = console_options.nrows) * c.height + 8;
- bounds.right = (c.ncols = console_options.ncols) * c.width + 8;
-
- /************** aggiunta ***********/
- if(my_current_size!=0){
- SizeWindow(wp, hiword(my_current_size) * c.width + 8,
- loword(my_current_size) * c.height + 8, 0);
- my_current_size=0;
- }
- else
- /*************** fine aggiunta ********/
- SizeWindow(wp, bounds.right, bounds.bottom, 0);
-
- /* create TE record */
-
- c.hTE = TENew(&bounds, &bounds);
- (**c.hTE).crOnly = -1;
- c.cursor.v = c.nrows - 1;
- cleos(0);
-
- /* set up grow/zoom parameters */
-
- c.limit = botRight(bounds);
- ++c.limit.v, ++c.limit.h;
- LocalToGlobal(&topLeft(bounds));
- LocalToGlobal(&botRight(bounds));
- p = * (WStateData **) wp->dataHandle;
- p->userState = p->stdState = bounds;
-
- /* associate window with console */
-
- asm {
- lea c,a0
- move.l #sizeof(c),d0
- _PtrToHand
- move.l a0,offsetof(WindowRecord,refCon)(wp)
- }
- if (!console_refnum)
- console_refnum = open_console_driver();
- wp->windowKind = console_refnum;
-
- /* done */
-
- resize();
- ShowWindow(wp);
- SetPort(savePort);
- return(wp);
- }
-
-
- /*
- * kill_console - close a console window
- *
- * The console is not closed if more than one stream shares it.
- *
- */
-
- static void
- kill_console()
- {
- register FILE *fp;
- int i = 0, n;
-
- /* see if more than one stream shares this console */
-
- for (fp = &__file[0], n = FOPEN_MAX; n--; fp++) {
- if (fp->window == c.wp && i++)
- return;
- }
-
- /* close echo file (if any) */
-
- closeecho();
-
- /* discard console data structures */
-
- if (c.pasteH)
- DisposHandle(c.pasteH);
- DisposHandle((Handle) c.wp->refCon);
- TEDispose(c.hTE);
- DisposeWindow(c.wp);
- c.wp = 0;
- }
-
-
- /*
- * closeecho - close echo file (if any)
- *
- */
-
- static void
- closeecho()
- {
- if (c.echo2fp) {
- if (c.spool)
- print_console();
- fclose(c.echo2fp);
- }
- }
-
-
- /*
- * cflush - flush all pending output to a console
- *
- */
-
- static WindowPeek
- cflush(fp)
- register FILE *fp;
- {
- WindowPeek wp = __checkfile(fp)->window;
- int n;
-
- for (fp = &__file[0], n = FOPEN_MAX; n--; fp++) {
- if (fp->dirty && fp->window == wp)
- fflush(fp);
- }
- return(wp);
- }
-
-
- /* ---------- vectored entry points ---------- */
-
-
- /*
- * console_exit - console shutdown routine
- *
- */
-
- static void
- console_exit()
- {
- register FILE *fp;
- int n;
-
- /* complete pending output */
-
- for (fp = &__file[0], n = FOPEN_MAX; n--; fp++) {
- if (fp->dirty && fp->window)
- fflush(fp);
- }
-
- /* pause for user acknowledgement */
-
- if (console_environment && console_options.pause_atexit) {
- for (fp = &__file[0], n = FOPEN_MAX; n--; fp++) {
- if (fp->window) {
- SetWTitle(fp->window, "\ppress ╟return╚ to exit");
- c.raw = c.cbreak = c.edit = 0;
- setbuf(fp, NULL);
- fgetc(fp);
- break;
- }
- }
- }
-
- /* close consoles */
-
- for (fp = &__file[0], n = FOPEN_MAX; n--; fp++) {
- if (fp->window)
- fclose(fp);
- }
- }
-
-
- /*
- * consoleio - I/O handler proc for console windows
- *
- */
-
- static int
- consoleio(fp, i)
- register FILE *fp;
- int i;
- {
- struct save save;
- int result = 0;
-
- if (_abnormal_exit)
- return(0);
- setup(fp->window, &save);
- switch (i) {
-
- /* read */
-
- case 0:
- in.buf = in.ptr = fp->ptr;
- if (console_environment) {
- cshow(fp);
- c.reading = 1;
- in.cnt = fp->cnt;
- if (c.edit && c.cursor.h + in.cnt > c.ncols)
- in.cnt = c.ncols - c.cursor.h + 1;
- in.min = in.max = c.raw ? 0 : setcursor(0);
- fp->eof = 0;
- do {
- ProcessEvent();
- } while (in.cnt && !c.raw);
- c.reading = 0;
- }
- if ((fp->cnt = in.ptr - in.buf) == 0) {
- fp->eof = 1;
- result = EOF;
- }
- break;
-
- /* write */
-
- case 1:
- output(fp->ptr, fp->cnt);
- break;
-
- /* close */
-
- case 2:
- kill_console();
- if (fp->window == save.console)
- save.console = 0;
- break;
- }
-
- /* check for interrupt */
-
- if (interrupted) {
- interrupted = 0;
- asm {
- moveq #keyDownMask,d0
- _FlushEvents
- }
- fp->cnt = 0;
- raise(SIGINT);
- errno = EINTR;
- result = EOF;
- }
-
- /* done */
-
- restore(&save);
- return(result);
- }
-
-
- /*
- * myStdText - inverse video handler
- *
- */
-
- static pascal void
- myStdText(n, s, numer, denom)
- register int n;
- register char *s;
- Point numer, denom;
- {
- register char *t;
- char buf;
-
- while (n--) {
- t = s;
- asm {
- @1 tst.b (s)+
- @2 dbmi n,@1
- bpl.s @3
- subq.l #1,s
- @3 }
- if (s > t)
- StdText(s - t, t, numer, denom);
- if (n < 0)
- break;
- buf = *s++ & 0x7F;
- TextMode(notSrcCopy);
- StdText(1, &buf, numer, denom);
- TextMode(srcCopy);
- }
- }
-
-
- /* ---------- I/O primitives ---------- */
-
-
- /*
- * cleos - clear to end of screen
- *
- * The given line, and all following lines, are erased. The cursor is
- * moved to the start of its line.
- *
- */
-
- static void
- cleos(i)
- int i;
- {
- pad('\r', 0, c.nrows - i);
- paste((**c.hTE).lineStarts[i], (**c.hTE).teLength);
- c.cursor.h = 0;
- }
-
-
- /*
- * cleol - clear to end of line
- *
- */
-
- static void
- cleol()
- {
- register TEPtr pTE = deactivate();
- register int *line = &pTE->lineStarts[c.cursor.v];
- register int selStart = line[0] + c.cursor.h;
- register int selEnd = line[1] - 1;
-
- if (selStart < selEnd) {
- pTE->selStart = selStart;
- pTE->selEnd = selEnd;
- TEDelete(c.hTE);
- }
- }
-
-
- /*
- * output - write characters to the current console
- *
- */
-
- static void
- output(s, n)
- register unsigned char *s;
- register int n;
- {
- unsigned char *t;
- register EvQElPtr q;
-
- while (n--) {
- t = s;
- asm {
- moveq #' ',d0
- @1 cmp.b (s)+,d0
- @2 dbhi n,@1
- bls.s @3
- subq.l #1,s
- @3 }
- if (s > t)
- overwrite(t, s - t);
- if (n < 0)
- break;
- if (!c.raw) {
- for (q = (EvQElPtr) EventQueue.qHead; q; q = (EvQElPtr) q->qLink) {
- if (q->evtQWhat == keyDown && (char) q->evtQMessage == '.') {
- if (q->evtQModifiers & cmdKey) {
- interrupted = 1;
- return;
- }
- }
- }
- }
- switch (*s++) {
- case '\a':
- SysBeep(4);
- break;
- case '\b':
- deactivate();
- if (c.cursor.h)
- --c.cursor.h;
- break;
- case '\f':
- c.cursor.v = 0;
- cleos(0);
- break;
- case '\n':
- newline();
- break;
- case '\v':
- if (++c.cursor.v == c.nrows)
- --c.cursor.v;
- break;
- case '\r':
- c.cursor.h = 0;
- break;
- case '\t':
- do {
- ++c.cursor.h;
- } while (c.cursor.h % c.tabs);
- if (c.cursor.h > c.ncols)
- c.cursor.h = c.ncols;
- break;
- }
- }
- }
-
-
- /*
- * overwrite - place new text on a line
- *
- * The text must not contain any control characters. Text is drawn
- * starting at the current cursor, overwriting any existing characters.
- * The cursor is left at the end of the new text.
- *
- */
-
- static void
- overwrite(s, n)
- unsigned char *s;
- register long n;
- {
- register long m;
- register int *line, selStart, selEnd;
-
- /* wrap output at "ncols" */
-
- more:
- if (c.cursor.h + (m = n) > c.ncols)
- m = c.ncols - c.cursor.h;
-
- /* set replacement range */
-
- line = &(**c.hTE).lineStarts[c.cursor.v];
- selStart = line[0] + c.cursor.h;
- selEnd = line[1] - 1;
- if (selStart > selEnd) { /* pad line with blanks */
- pad(' ', 0, selStart - selEnd);
- paste(selEnd, selEnd);
- selEnd = selStart;
- }
- else if (selEnd > selStart + m)
- selEnd = selStart + m;
-
- /* paste in new text */
-
- asm {
- movea.l s,a0
- move.l m,d0
- move.w d0,TEScrpLength
- movea.l TEScrpHandle,a1
- _PtrToXHand
- }
- paste(selStart, selEnd);
-
- /* wrap to next line if necessary */
-
- if (m < n) {
- newline();
- s += m;
- n -= m;
- goto more;
- }
- c.cursor.h += m;
- }
-
-
- /*
- * delete - erase the indicated portion of the input field
- *
- */
-
- static void
- delete(selStart, selEnd)
- int selStart, selEnd;
- {
- register TEPtr pTE = deactivate();
-
- if (in.max + 1 == pTE->lineStarts[c.cursor.v + 1]) {
- pTE->selStart = selStart;
- pTE->selEnd = selEnd;
- TEDelete(c.hTE);
- }
- else {
- pTE->selStart = selEnd;
- pTE->selEnd = in.max;
- TECopy(c.hTE);
- pad(' ', in.max - selEnd, in.max - selStart);
- paste(selStart, in.max);
- }
- in.max -= selEnd - selStart;
- }
-
-
- /*
- * insert - insert a character at the indicated point
- *
- */
-
- static void
- insert(ch, selStart)
- char ch;
- int selStart;
- {
- register TEPtr pTE = deactivate();
-
- pTE->selStart = selStart;
- if (in.max + 1 == pTE->lineStarts[c.cursor.v + 1]) {
- pTE->selEnd = selStart;
- TEKey(ch, c.hTE);
- }
- else {
- pTE->selEnd = in.max;
- TECopy(c.hTE);
- Munger(TEScrpHandle, 0, 0, 0, &ch, 1);
- ++TEScrpLength;
- paste(selStart, in.max + 1);
- }
- in.max++;
- }
-
-
- /*
- * pad - pad the TE scrap to a desired size
- *
- */
-
- static void
- pad(ch, ofs, len)
- register char ch;
- register long ofs, len;
- {
- /* set scrap size */
-
- asm {
- movea.l TEScrpHandle,a0
- move.l len,d0
- move.w d0,TEScrpLength
- _SetHandleSize
- }
-
- /* fill scrap */
-
- asm {
- movea.l (a0),a0
- adda.l ofs,a0
- sub.l ofs,len
- bra.s @2
- @1 move.b ch,(a0)+
- @2 dbra len,@1
- }
- }
-
-
- /*
- * paste - replace range with contents of TEScrap
- *
- */
-
- static void
- paste(selStart, selEnd)
- int selStart, selEnd;
- {
- register TEPtr pTE = deactivate();
-
- pTE->selStart = selStart;
- pTE->selEnd = selEnd;
- TEPaste(c.hTE);
- }
-
-
- /*
- * setcursor - activate flashing caret at cursor
- *
- */
-
- static int
- setcursor(sel)
- register int sel;
- {
- register TEPtr pTE = deactivate();
- register int *line = &pTE->lineStarts[c.cursor.v];
- register int end = line[1] - 1;
-
- sel += line[0] + c.cursor.h;
- if (sel > end) { /* pad line with blanks */
- pad(' ', 0, sel - end);
- paste(end, end);
- pTE = *c.hTE;
- }
- pTE->selStart = pTE->selEnd = sel;
- pTE->clikStuff = 255; /* per TN127 */
- TEActivate(c.hTE);
- return(sel);
- }
-
-
- /*
- * deactivate - make sure TE record is inactive
- *
- * The dereferenced pointer to the TE record is returned.
- *
- */
-
- static TEPtr
- deactivate()
- {
- if ((**c.hTE).active)
- TEDeactivate(c.hTE);
- return(*c.hTE);
- }
-
-
- /*
- * strip - strip trailing blanks from all lines
- *
- * Note that we don't strip blanks that are part of the current
- * input field.
- *
- */
-
- static void
- strip()
- {
- register int i = c.nrows, j, k;
- register TEPtr pTE = *c.hTE;
- register char *p;
-
- while (i) {
- j = k = pTE->lineStarts[i--] - 1;
- for (p = *pTE->hText + j; j && *--p == ' '; j--)
- ;
- if (c.reading && !c.raw && i == c.cursor.v && j < in.max)
- j = in.max;
- if (k -= j) {
- Munger(pTE->hText, j, 0, k, "", 0);
- pTE = *c.hTE;
- if (c.reading) {
- if (in.min > j)
- in.min -= k;
- if (in.max > j)
- in.max -= k;
- }
- if (pTE->selStart > j)
- pTE->selStart -= k;
- if (pTE->selEnd > j)
- pTE->selEnd -= k;
- }
- }
- TECalText(c.hTE);
- }
-
-
- /*
- * resize - respond to new window size
- *
- * If the window is too small to display the entire console, the lower
- * left portion of the console is displayed.
- *
- */
-
- static void
- resize()
- {
- Rect bounds;
-
- bounds = c.wp->port.portRect;
- InvalRect(&bounds);
- InsetRect(&bounds, 4, 4);
- (**c.hTE).viewRect = bounds;
- bounds.top = bounds.bottom - c.height * c.nrows;
- (**c.hTE).destRect = bounds;
- }
-
-
- /*
- * setup - focus on the appropriate console
- *
- * The current console and the current grafport are set appropriately,
- * and the previous values are saved. Any pending update is performed.
- *
- */
-
- static void
- setup(wp, save)
- register WindowPeek wp;
- struct save *save;
- {
- Rect bounds;
-
- GetPort(&save->port);
- save->console = theConsole;
- if (wp && wp->windowKind == console_refnum) {
- use(wp);
- SetPort(wp);
- if (!EmptyRgn(wp->updateRgn)) {
- bounds = wp->port.portRect;
- BeginUpdate(wp);
- EraseRect(&bounds);
- TEUpdate(&bounds, c.hTE);
- EndUpdate(wp);
- }
- theConsole = wp;
- }
- }
-
-
- /*
- * restore - done with the current console
- *
- * The console and grafport saved by a previous "setup" call are restored.
- *
- */
-
- static void
- restore(save)
- register struct save *save;
- {
- if (theConsole = save->console)
- use(save->console);
- SetPort(save->port);
- }
-
-
- /*
- * use - load global "c" from window's refCon
- *
- */
-
- static void
- use(wp)
- WindowPeek wp;
- {
- if (wp != c.wp) {
- if (c.wp)
- ** (struct console **) c.wp->refCon = c;
- if (wp)
- c = ** (struct console **) wp->refCon;
- }
- }
-
-
- /*
- * copy - get a pointer to the text in the TE scrap
- *
- * If inverse video is in use, the high bit is stripped from each byte.
- * This call must be balanced by a call to "endcopy".
- *
- */
-
- static char *
- copy()
- {
- asm {
- movea.l TEScrpHandle,a0
- _HLock
- move.l (a0),d0
- }
- if (c.inverse) asm {
- movea.l d0,a1
- move.w TEScrpLength,d1
- bra.s @2
- @1 tst.b (a1)+
- bpl.s @2
- bclr #7,-1(a1)
- @2 dbra d1,@1
- }
- }
-
-
- /*
- * endcopy - done using text obtained by "copy"
- *
- */
-
- static void
- endcopy()
- {
- asm {
- movea.l TEScrpHandle,a0
- _HUnlock
- }
- }
-
-
- /*
- * newline - print a newline character
- *
- */
-
- static void
- newline()
- {
- register TEPtr pTE = deactivate();
- register int *line, delta, len;
- Rect bounds;
- RgnHandle rgn;
- Handle hText;
- EventRecord event;
-
- if (c.reading && !c.edit && !c.cbreak)
- return;
-
- /* wait while mouse is down */
-
- asm {
- lea event,a0
- moveq #mDownMask,d0
- _GetOSEvent
- bne.s @2
- @1 moveq #mUpMask,d0
- _GetOSEvent
- bne.s @1
- @2 }
-
- /* copy current line to echo-file */
-
- if (c.echo2fp) {
- line = &pTE->lineStarts[c.cursor.v];
- pTE->selStart = line[0];
- pTE->selEnd = line[1];
- TECopy(c.hTE);
- fwrite(copy(), 1, TEScrpLength, c.echo2fp);
- endcopy();
- }
-
- /* advance cursor, scrolling if necessary */
-
- if (++c.cursor.v == c.nrows) {
- pTE = *c.hTE;
- hText = pTE->hText;
- len = pTE->teLength -= delta = pTE->lineStarts[1];
- ++pTE->teLength;
- bounds = pTE->destRect;
- ScrollRect(&bounds, 0, -c.height, rgn = NewRgn());
- DisposeRgn(rgn);
- Munger(hText, 0, 0, delta, "", 0);
- Munger(hText, len, 0, 0, "\r", 1);
- TECalText(c.hTE);
- --c.cursor.v;
- }
- c.cursor.h = 0;
- }
-
-
- /* ---------- console driver ---------- */
-
-
- /*
- * open_console_driver - install and initialize the console driver
- *
- */
-
- static int
- open_console_driver()
- {
- int i;
- DCtlHandle dceH;
- register DCtlPtr dce;
-
- /* create driver on heap */
-
- if (!drvrH) {
- drvr.vCtl.vCode = doControl;
- drvr.vClose.vCode = doClose;
- asm {
- lea drvr,a0
- move.l #sizeof(drvr),d0
- _PtrToHand
- move.l a0,drvrH
- }
- }
-
- /* find available slot in unit table */
-
- for (i = 27; dceH = UTableBase[i]; i++) {
- if (!((**dceH).dCtlFlags & dOpened))
- break;
- }
- i = ~i;
-
- /* create DCE */
-
- asm {
- move.w i,d0
- dc.w 0xA13D ; _DrvrInstall
- movea.l (a0),dce
- }
- dce->dCtlDriver = (Ptr) drvrH;
- dce->dCtlFlags = drvr.drvrFlags;
- dce->dCtlEMask = drvr.drvrEMask;
- return(i);
- }
-
-
- /*
- * doClose - handle _PBClose call
- *
- * Normally, we shouldn't get a close call, because a console window has
- * no go-away box. If we do reach here, we can keep from crashing (except
- * on 64K ROMs) by refusing to close.
- *
- */
-
- static int
- doClose()
- {
- return(closeErr);
- }
-
-
- /*
- * doControl - handle _PBControl call
- *
- */
-
- static int
- doControl()
- {
- register cntrlParam *pb;
- DCtlPtr dce;
- struct save save, save2;
- register EventRecord *event;
- int key;
-
- SetUpA5();
- asm {
- move.l a0,pb
- move.l a1,dce
- }
- setup((WindowPeek) FrontWindow(), &save);
- switch (pb->csCode) {
- case accCursor:
- doCursor();
- break;
- case accCut:
- doCut();
- break;
- case accCopy:
- doCopy();
- break;
- case accPaste:
- doPaste();
- break;
- case accClear:
- doKey('\33');
- break;
- case accEvent:
- event = * (EventRecord **) pb->csParam;
- switch (event->what) {
- case updateEvt:
- setup((WindowPeek) event->message, &save2);
- break;
- case mouseDown:
- doClick(event);
- break;
- case keyDown:
- case autoKey:
- key = (unsigned char) event->message;
- if (event->modifiers & cmdKey) {
- if (event->what == autoKey)
- break;
- key = doCmdKey(key);
- }
- if (key)
- doKey(key);
- break;
- }
- break;
- }
- asm {
- movea.l drvrH,a0
- _HUnlock ; unlock driver
- movea.l dce,a0
- _RecoverHandle SYS
- _HUnlock ; unlock DCE
- }
- restore(&save);
- RestoreA5();
- return(0);
- }
-
-
- /*
- * doCursor - cursor maintenance
- *
- */
-
- static void
- doCursor()
- {
- Point where;
-
- TEIdle(c.hTE);
- GetMouse(&where);
- if (PtInRect(where, &c.wp->port.portRect))
- SetCursor(*GetCursor(iBeamCursor));
- else asm {
- movea.l (a5),a0
- pea -108(a0) ; arrow
- _SetCursor
- }
- }
-
-
- /*
- * doClick - handle mouse-down event
- *
- * Since the click was passed to the console driver, the front window
- * must be a console window, and the click can only be in its zoom box
- * or content region (including the grow region).
- *
- */
-
- static void
- doClick(event)
- register EventRecord *event;
- {
- int part;
-
- c.wp->windowKind = userKind;
- part = FindWindow(event->where, &c.wp);
- c.wp->windowKind = console_refnum;
- switch (part) {
- case inZoomIn:
- case inZoomOut:
- doZoom(event->where, part);
- break;
- case inGrow:
- if (!(event->modifiers & (cmdKey|optionKey))) {
- doGrow(event->where);
- break;
- }
- /* ... */
- case inContent:
- doSelect(event);
- break;
- }
- }
-
-
- /*
- * doZoom - handle click in zoom box
- *
- * The "zoomed" size is that needed to display the entire console.
- *
- */
-
- static void
- doZoom(where, part)
- Point where;
- int part;
- {
- register WindowPeek wp = c.wp;
-
- InitCursor();
- if (TrackBox(wp, where, part)) {
- EraseRect(&wp->port.portRect);
- ZoomWindow(wp, part, 0);
- resize();
- }
- }
-
-
- /*
- * doGrow - handle click in grow region
- *
- * No grow box is actually visible; nonetheless, clicking in the lower
- * right corner has the same effect. Hold down the command or option
- * key to defeat this behavior (e.g. to select corner text).
- *
- * The maximum window size is that needed to display the entire console.
- *
- */
-
- static void
- doGrow(where)
- Point where;
- {
- register WindowPeek wp = c.wp;
- long size;
- static Rect limit = { 100, 120, 9999, 9999 };
-
- InitCursor();
- botRight(limit) = c.limit;
- if (size = GrowWindow(wp, where, &limit)) {
- EraseRect(&wp->port.portRect);
- SizeWindow(wp, loword(size), hiword(size), 0);
- resize();
- }
- }
-
-
- /*
- * doSelect - handle click in content region, initiating selection
- *
- */
-
- static void
- doSelect(event)
- register EventRecord *event;
- {
- int extend = 0;
- register TEPtr pTE;
-
- if (!(**c.hTE).active)
- setcursor(0);
- else if (event->modifiers & shiftKey)
- extend = 1;
- strip();
-
- /* let TE do the work */
-
- GlobalToLocal(&event->where);
- TEClick(event->where, extend, c.hTE);
- pTE = *c.hTE;
-
- /* fix selection */
-
- if (pTE->selStart == pTE->selEnd) {
- pTE->clikStuff = 255; /* per TN127 */
- if (!c.reading || c.raw)
- TEDeactivate(c.hTE);
- else if (pTE->selStart < in.min)
- TESetSelect(in.min, in.min, c.hTE);
- else if (pTE->selEnd > in.max)
- TESetSelect(in.max, in.max, c.hTE);
- }
- }
-
-
- /*
- * doCmdKey - handle command key
- *
- */
-
- static int
- doCmdKey(key)
- int key;
- {
- if (c.raw)
- return(key & 0x1F); /* controlify */
- switch (key) {
- case 'x': case 'X':
- doCut();
- break;
- case 'c': case 'C':
- doCopy();
- break;
- case 'v': case 'V':
- doPaste();
- break;
- case '.':
- if (console_environment)
- interrupted = 1;
- /* ... */
- case 'd': case 'D':
- return('\4'); /* ctrl-D */
- case 'u': case 'U':
- case 'z': case 'Z':
- return('\25'); /* ctrl-U */
- case 'q': case 'Q':
- if (console_environment) {
- console_options.pause_atexit = 0;
- exit(0);
- }
- break;
- }
- return(0);
- }
-
-
- /*
- * doKey - handle keypress
- *
- */
-
- static void
- doKey(key)
- register int key;
- {
- register TEPtr pTE = *c.hTE;
- register int selStart = pTE->selStart;
- register int selEnd = pTE->selEnd;
- register int len;
- register char *p;
-
- if (!c.reading || c.inverse && key > 0x7F)
- goto beep;
- if (c.raw) {
- *in.ptr++ = key;
- in.cnt = 0;
- return;
- }
-
- /* process control characters */
-
- if (key < ' ') {
- switch (key) {
- case '\25': /* ^U */
- case '\33': /* escape, clear */
- in.cnt += in.ptr - in.buf;
- in.ptr = in.buf;
- selStart = in.min;
- selEnd = in.max;
- goto delete;
- case '\b': /* backspace */
- if (c.edit)
- goto delete;
- if (c.cbreak)
- goto buffer;
- if (in.ptr == in.buf)
- goto beep;
- --in.ptr;
- ++in.cnt;
- goto cursor;
- case '\34': /* left arrow */
- if (selStart == selEnd)
- --selStart;
- goto cursor;
- case '\35': /* right arrow */
- if (selStart == selEnd)
- ++selEnd;
- selStart = selEnd;
- goto cursor;
- case '\36': /* up arrow */
- selStart = in.min;
- goto cursor;
- case '\37': /* down arrow */
- case '\t': /* tab */
- selStart = in.max;
- goto cursor;
- case '\4': /* ^D */
- case '\r': /* return */
- case '\3': /* enter */
- if (len = in.max - in.min) {
- p = *pTE->hText + in.min;
- asm {
- movea.l in.ptr,a0
- bra.s @2
- @1 move.b (p)+,(a0)+
- @2 dbra len,@1
- move.l a0,in.ptr
- }
- }
- if (key != '\4')
- *in.ptr++ = '\n';
- newline();
- in.cnt = 0;
- break;
- }
- return;
- }
-
- /* delete any existing selection */
-
- delete:
- if (c.edit) {
- if (selStart == selEnd) {
- if (key != '\b')
- goto insert;
- --selStart;
- }
- if (selStart < in.min || selEnd > in.max)
- goto beep;
- delete(selStart, selEnd);
- }
-
- /* insert the key */
-
- insert:
- if (key >= ' ') {
- if (in.max - in.min == in.cnt - 1)
- SysBeep(2);
- else if (c.edit)
- insert(key, selStart++);
- else {
- buffer: *in.ptr++ = key;
- if (c.cbreak) {
- output(in.ptr - 1, 1);
- in.cnt = 0;
- return;
- }
- --in.cnt;
- }
- }
-
- /* update the cursor */
-
- cursor:
- if (selStart > in.max)
- selStart = in.max;
- else if (selStart < in.min)
- selStart = in.min;
- setcursor(selStart - in.min);
- return;
-
- /* beep only */
-
- beep:
- SysBeep(2);
- }
-
-
- /*
- * doCut - handle "cut" command
- *
- * Selected text (if any) is placed in the desk scrap, then deleted.
- *
- */
-
- static void
- doCut()
- {
- register TEPtr pTE = *c.hTE;
-
- if (pTE->active && pTE->selStart < pTE->selEnd) {
- if (!c.reading || pTE->selStart < in.min || pTE->selEnd > in.max)
- SysBeep(2);
- else {
- doCopy();
- doKey('\b');
- }
- }
- }
-
-
- /*
- * doCopy - handle "copy" command
- *
- * Selected text (if any) is placed in the desk scrap.
- *
- */
-
- static void
- doCopy()
- {
- register TEPtr pTE = *c.hTE;
-
- if (pTE->active && pTE->selStart < pTE->selEnd) {
- TECopy(c.hTE);
- ZeroScrap();
- PutScrap(TEScrpLength, 'TEXT', copy());
- endcopy();
- }
- }
-
-
- /*
- * doPaste - handle "paste" command
- *
- * Pasted text is obtained from the desk scrap and stored in the paste
- * buffer, "c.pasteH". ProcessEvent will take characters from the buffer
- * in preference to the keyboard.
- *
- */
-
- static void
- doPaste()
- {
- if (!c.reading || (**c.hTE).selStart < in.min || (**c.hTE).selEnd > in.max) {
- SysBeep(2);
- return;
- }
- if ((c.pasteLen = GetScrap(TEScrpHandle, 'TEXT', &c.pasteOfs)) > 0) {
- c.pasteH = TEScrpHandle;
- TEScrpHandle = NewHandle(0);
- c.pasteOfs = 0;
- }
- TEScrpLength = 0;
- }
-
-
- /* ---------- printing ---------- */
-
-
- /*
- * print_console - print the echo file
- *
- */
-
- static void
- print_console()
- {
- /* check for availability of printing */
-
- #ifdef _PrintTraps_
- asm {
- move.w #0xA89F,d0
- _GetTrapAddress
- move.l a0,a1
- move.w #0xA8FD,d0
- _GetTrapAddress
- cmpa.l a0,a1
- bne.s @ok
- }
- c.echo2fp->delete = 0;
- return;
- #endif
-
- /* print away */
-
- ok: if (!noPrint) {
- PrOpen();
- if (!PrError()) {
- print();
- PrClose();
- }
- }
- }
-
-
- /*
- * print - spool file to printer
- *
- */
-
- static void
- print()
- {
- static THPrint hPrint;
- THPrint h;
- GrafPtr savePort;
- TPPrPort port;
- register TEPtr pTE;
- int ascent, nlines, i;
- Rect pageRect;
- Point where;
- char buf[BUFSIZ];
- TPrStatus status;
-
- /* set up job record */
-
- h = (THPrint) NewHandle(sizeof(TPrint));
- PrintDefault(h);
- if (hPrint) {
- PrJobMerge(hPrint, h);
- DisposHandle(hPrint);
- }
- else {
- InitCursor();
- if (!PrJobDialog(h)) {
- noPrint = 1;
- return;
- }
- }
- hPrint = h;
-
- /* set up printing port */
-
- GetPort(&savePort);
- port = PrOpenDoc(h, NULL, NULL);
- pTE = *c.hTE;
- TextFont(pTE->txFont);
- TextSize(pTE->txSize);
- TextFace(pTE->txFace);
- ascent = pTE->fontAscent;
- pageRect = (**h).prInfo.rPage;
- nlines = (pageRect.bottom - pageRect.top) / c.height;
- where.h = pageRect.left + 36; /* leave 1/2 inch margin */
-
- /* print each page */
-
- rewind(c.echo2fp);
- c.echo2fp->binary = 0;
- do {
- PrOpenPage(port, NULL);
- where.v = pageRect.top + ascent;
- for (i = 0; i < nlines && fgets(buf, sizeof buf, c.echo2fp); i++) {
- MoveTo(where.h, where.v);
- DrawText(buf, 0, strlen(buf) - 1);
- where.v += c.height;
- }
- PrClosePage(port);
- } while (!PrError() && !feof(c.echo2fp));
-
- /* done printing */
-
- PrCloseDoc(port);
- SetPort(savePort);
- if ((**h).prJob.bJDocLoop == bSpoolLoop && !PrError())
- PrPicFile(h, NULL, NULL, NULL, &status);
- }
-
-
- /* ---------- memory manager glue ---------- */
-
-
- static pascal Handle
- NewHandle(size)
- long size;
- {
- asm {
- move.l size,d0
- _NewHandle
- move.l a0,d0
- }
- }
-
-
- static pascal void
- DisposHandle(h)
- void *h;
- {
- asm {
- movea.l h,a0
- _DisposHandle
- }
- }
-