home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Carousel
/
CAROUSEL.cdr
/
mactosh
/
lang
/
lsc30p4u.sit
/
printf-2-w.c
< prev
next >
Wrap
Text File
|
1989-01-15
|
30KB
|
1,404 lines
/*
printf routines for LightspeedC
(C) Copyright 1986. THINK Technologies, Inc. All rights reserved.
NOTE: Proportional fonts can be used, but lines will wrap as if they
are monospaced. In this version, since each line is drawn with
DrawChar or DrawText without repositioning, it will look better
than the old monospaced repositioning version of putch.
*/
/* If you have a non-Mac screen like a Radius or E-Machines, etc. stdio
may not operate correctly since it normally directly moves the graphics
pen to achieve reasonable speeds in drawing characters. By defining
_NonMacScreen_ you can convert all of the specialized code into the
standard Macintosh Toolbox traps so it will work correctly */
/* #define _NonMacScreen_ */
#include "config.h"
#ifndef _stdioh_
#include "stdio.h"
#endif
#ifndef _QuickDraw_
#include "QuickDraw.h"
#endif
#ifndef _FontMgr_
#include "FontMgr.h"
#endif
#ifndef _MenuMgr_
#include "MenuMgr.h"
#endif
#ifndef _ToolboxUtil_
#include "ToolboxUtil.h"
#endif
#ifndef _fopenwh_
#include "fopenw.h"
#endif
char *CtoPstr();
char *PtoCstr();
char *std_ver();
void drawcursor();
void Std_updatewindow();
/* screen display globals */
static WindowPtr Currentswrp = 0;
static FILE *CurrentWindow = 0;
static WindowPtr _exit_wp = 0; /* for special exit window handling */
static WindowPtr _console_wp = 0;
/* default font info */
static GrafPort dummyPort;
static FontInfo _sf; /* holds the info about the font */
static int _font = monaco,
_size = 9,
_face = 0,
_mode = srcOr; /* stuff for Stdio_Config */
static RgnHandle emptyrgn; /* used for scrolling */
static Rect bounds;
Boolean _inited = false; /* whether Mac is inited yet */
static Boolean _screen = false; /* whether screen is inited */
static Boolean _click_on = true; /* wait at exit from program */
static Boolean _our_menus = false; /* flag to indicate if our menus */
static int deskacc_count = 0; /* # desk accessories open */
Boolean _echo = true; /* global Echo status for keyboard input */
extern void (*_echo_to_printer_)(); /* global Echo call variable for printer */
#define movecursor(swrp, x, y)\
MoveTo( _LEFTEDGE + (x) * swrp->charwidth,\
_TOPEDGE + swrp->sf.ascent + ((y)+swrp->visrow-swrp->opt.maxrow) * swrp->charheight)
/* Determine if this is one of the stdio created windows or not */
static
Boolean OurWindow(window)
register StdWindowRec *window;
{
if (window)
if ((window == (StdWindowRec *)_exit_wp) || (window->signature == _OURSIGNATURE))
return (true);
return (false);
}
/* Dispatch via refcon field of window record for window events */
static
Boolean WindowEvent(xevent)
XEventRecord *xevent;
{
register WindowPeek wp;
register eventinfo **refcon;
register int (*proc)();
if (! OurWindow(wp = (WindowPeek) xevent->window)) return (false);
if (wp->windowKind >= 8 && (refcon = (eventinfo**) wp->refCon)
&& (proc = (**refcon).eventProc))
return ((*proc)(xevent));
return (false);
}
/* If we set up the screen, we set up a simple menu as well
for DAs and such */
static
void setup_menus()
{
register MenuHandle menu; /* handle for our menus */
InitMenus();
menu = NewMenu(1, "\p\024"); /* apple menu */
AddResMenu(menu, 'DRVR');
InsertMenu(menu, 0);
menu = NewMenu(2, "\pFile");
AppendMenu(menu, "\p(New;Open;Close;(Save;(-;Quit");
InsertMenu(menu, 0);
menu = NewMenu(3, "\pEdit");
#ifdef _STD_PASTE_
AppendMenu(menu, "\p(Undo;(-;(Cut;(Copy;Paste;(Clear;(-");
#else
AppendMenu(menu, "\p(Undo;(-;(Cut;(Copy;(Paste;(Clear;(-");
#endif _STD_PASTE_
AppendMenu(menu, CtoPstr(std_ver()));
PtoCstr(std_ver());
InsertMenu(menu, 0);
DrawMenuBar();
_our_menus = true;
}
static
void do_exit()
{Cursor watch;
watch = **GetCursor(watchCursor);
SetCursor(&watch);
_click_on = false;
exit(0);
}
static
doMenu(event)
register XEventRecord *event;
{
short item;
if (event->record.what != menuEvent)
return;
item = event->record.message;
switch (* (short *) &event->record.message)
{
case 1:
event->record.what = appleEvent;
HiliteMenu(0);
break;
case 2:
switch (item)
{
case 2: /* Open entry on file menu */
event->record.what = openEvent;
break;
case 3: /* Close entry on file menu */
event->record.what = closeEvent;
break;
case 6: /* Quit entry on file menu */
do_exit();
break;
}
break;
case 3:
#ifdef _STD_PASTE_
if (item == 5)
/* Paste entry on edit menu */
_std_setup_paste();
#endif _STD_PASTE_
HiliteMenu(0);
event->record.what = editEvent;
break;
}
}
/* enable edit menu picks for undo, cut, copy, paste, etc. */
static
void edit_enable()
{register MenuHandle editmenu;
if (_our_menus)
{
if (editmenu = GetMHandle(3))
{register int i;
for (i=CountMItems(editmenu); i; i--)
EnableItem(editmenu, i);
DisableItem(editmenu, 2); /* gray line */
DisableItem(editmenu, 7); /* gray line */
DisableItem(editmenu, 8); /* Library version */
}
}
}
static
void edit_disable()
{register MenuHandle editmenu;
if (_our_menus)
{
if (editmenu = GetMHandle(3))
{register int i;
for (i=CountMItems(editmenu); i; i--)
DisableItem(editmenu, i);
#ifdef _STD_PASTE_
EnableItem(editmenu, 5); /* Paste */
#endif _STD_PASTE_
EnableItem(editmenu, 8); /* Library version */
}
}
}
/*
* StdEvent - event handler
*
*/
#line 0 StdEvent
Boolean StdEvent(event)
register EventRecord *event;
{
XEventRecord ev;
register XEventRecord *xevent = &ev;
register short item, refnum;
Rect r;
long size;
int (*proc)();
static char accessory[256];
Init_stdio();
/* copy event to local data structure */
ev = *(XEventRecord*) event;
/* reset event to point to this extended event record */
event = (EventRecord*) &ev;
xevent->window = FrontWindow();
switch (event->what)
{
default:
return (WindowEvent(event));
case nullEvent:
if (! WindowEvent(event)) return (false);
switch (FindWindow(event->where, &xevent->window))
{
case inContent:
if (xevent->window == FrontWindow())
{
SetPort(xevent->window);
GlobalToLocal(&event->where);
event->what = cursorEvent;
return (WindowEvent(event));
}
default:
SetCursor(&arrow);
break;
}
break;
case updateEvt:
if (! OurWindow(xevent->window = (WindowPtr) event->message))
return (false);
BeginUpdate(xevent->window);
SetPort(xevent->window);
WindowEvent(event);
EndUpdate(xevent->window);
break;
case activateEvt:
if (! OurWindow(xevent->window = (WindowPtr) event->message))
return (false);
SetPort(xevent->window);
if (!(event->modifiers & activeFlag))
event->what = deactivateEvt;
WindowEvent(event);
break;
case mouseDown:
switch (FindWindow(event->where, &xevent->window))
{
default:
return (false);
case inMenuBar:
if (! _our_menus)
return (false);
xevent->window = FrontWindow();
SetCursor(&arrow);
doMenu(event);
event->message = MenuSelect(event->where);
if (hiword(event->message) == 0) break;
event->what = menuEvent;
doMenu(event);
switch (event->what)
{
case editEvent:
if (SystemEdit((short) event->message - 1))
break;
WindowEvent(event);
break;
case closeEvent:
if (xevent->window)
{
refnum = ((WindowPeek) xevent->window)->windowKind;
if (refnum < 0)
{
CloseDeskAcc(refnum);
}
else
WindowEvent(event);
}
break;
case openEvent:
if (_console->filebuf)
{
if (!((WindowPeek)_console->filebuf)->visible)
{
ShowWindow(_console->filebuf);
Std_updatewindow(_console->filebuf);
}
}
break;
case appleEvent:
GetItem(GetMHandle(hiword(event->message)),
loword(event->message),
accessory);
OpenDeskAcc(accessory);
edit_enable();
break;
}
break;
case inSysWindow:
SystemClick(event, xevent->window);
break;
case inContent:
if (! OurWindow(xevent->window)) return (false);
if (xevent->window != FrontWindow())
{
event->what = selectEvent;
WindowEvent(event);
if (event->what != mouseDown)
{
SelectWindow(xevent->window);
break;
}
}
SetPort(xevent->window);
GlobalToLocal(&event->where);
if (event->message = FindControl(event->where,
xevent->window,
&xevent->control))
{
proc = (int (*)()) (event->message > 128 ? 0L : -1L);
if (TrackControl(xevent->control, event->where, proc) == 0)
break;
event->what = controlEvent;
}
WindowEvent(event);
if (event->what != dragEvent) break;
LocalToGlobal(&event->where);
/* ... */
case inDrag:
/* don't select window if command key is down */
if (!(event->modifiers & cmdKey))
if (xevent->window != FrontWindow())
{
SelectWindow(xevent->window);
break;
}
SetRect(&r, 4, _MBARHEIGHT + 4, screenWidth - 4, screenHeight - 4);
SetCursor(&arrow);
DragWindow(xevent->window, event->where, &r);
break;
case inGrow:
if (! OurWindow(xevent->window)) return (false);
{register StdWindowRec *swrp = (StdWindowRec*)xevent->window;
SetRect(&r,
swrp->charwidth + _LEFTEDGE + _CONTROLWIDTH + 3,
swrp->charheight + _TOPEDGE + _CONTROLWIDTH + 8,
swrp->charwidth * swrp->opt.maxcol + _LEFTEDGE + _CONTROLWIDTH + 3,
swrp->charheight * swrp->opt.maxrow + _TOPEDGE + _CONTROLWIDTH + 8);
}
SetCursor(&arrow);
if (size = GrowWindow(xevent->window, event->where, &r))
{
SizeWindow(xevent->window, loword(size), hiword(size), 0);
SetPort(xevent->window);
InvalRect(&xevent->window->portRect);
event->what = growEvent;
WindowEvent(event);
{StdWindowRec *swrp = ((StdWindowRec*)xevent->window);
swrp->viscol = (loword(size)-_CONTROLWIDTH-1-swrp->charwidth+1)/swrp->charwidth;
swrp->visrow = (hiword(size)-_CONTROLWIDTH-1-swrp->charheight+1)/swrp->charheight;
/* make sure neither variable exceeds legal bounds */
if (swrp->viscol > swrp->opt.maxcol) swrp->viscol = swrp->opt.maxcol;
if (swrp->visrow > swrp->opt.maxrow) swrp->visrow = swrp->opt.maxrow;
}
}
break;
case inGoAway:
if (! OurWindow(xevent->window)) return (false);
SetCursor(&arrow);
if (TrackGoAway(xevent->window, event->where))
{
event->what = closeEvent;
WindowEvent(event);
}
break;
}
break;
}
return (true);
}
static
void stdio_fontset(portp)
GrafPtr portp;
{
/* set up a font */
SetPort(portp);
TextFont(_font);
TextSize(_size);
TextFace(_face);
TextMode(_mode);
}
static
void drawcursor(swrp, flag)
register StdWindowRec *swrp;
Boolean flag;
{register int x, y, savey;
#ifdef _NonMacScreen_
Point savepoint;
#endif
if (swrp->opt.cursor_visible)
{register int mode = notPatCopy;
if (flag == ON) mode = patCopy;
/* adjust and save pen position */
#ifdef _NonMacScreen_
GetPen(&savepoint);
x = savepoint.h - 1;
savey = savepoint.v;
y = savey + swrp->sf.descent;
MoveTo(x,y);
#else
x = ((WindowPtr)swrp)->pnLoc.h -= 1;
savey = ((WindowPtr)swrp)->pnLoc.v;
y = (((WindowPtr)swrp)->pnLoc.v += swrp->sf.descent);
#endif
/* cursor is simply a vertical line */
#ifdef _NonMacScreen_
PenMode(mode);
#else
((WindowPtr)swrp)->pnMode = mode; /*improved speed on Mac screen */
#endif
LineTo(x, y - swrp->charheight);
#ifdef _NonMacScreen_
MoveTo(x+1, savey);
#else
((WindowPtr)swrp)->pnLoc.h = x + 1;
((WindowPtr)swrp)->pnLoc.v = savey;
#endif
/* redraw character where cursor is if we turned it off */
if (flag == OFF)
{
DrawChar(swrp->screen[((swrp->toprow+swrp->row)%swrp->opt.maxrow)*swrp->opt.maxcol+swrp->col]);
/* replaced with below to improve speed */
#ifdef _NonMacScreen_
MoveTo(x+1, savey);
#else
((WindowPtr)swrp)->pnLoc.h = x + 1;
((WindowPtr)swrp)->pnLoc.v = savey;
#endif
}
}
}
#line 0 Std_updatewindow
void Std_updatewindow(swrp)
register StdWindowRec *swrp;
{
register int i, thisrow;
SetPort(swrp);
EraseRect(&((WindowPtr)swrp)->portRect);
/* redraw last n rows in the visible region */
for (i=0,
thisrow = (swrp->toprow + (swrp->opt.maxrow-swrp->visrow)) % swrp->opt.maxrow;
i<swrp->visrow;
i++, thisrow = ++thisrow % swrp->opt.maxrow)
{
movecursor(swrp, 0, i+swrp->opt.maxrow-swrp->visrow);
DrawText(&swrp->screen[thisrow*swrp->opt.maxcol], 0, swrp->viscol);
}
if (!swrp->opt.no_grow)
{Rect r;
/* invalidate the scroll bar regions of the window, so
the scroll bars and grow box get drawn properly */
r = ((WindowPtr)swrp)->portRect;
r.left = r.right-_CONTROLWIDTH-2;
r.top = r.bottom-_CONTROLWIDTH-2;
InvalRect(&r);
DrawControls(swrp);
DrawGrowIcon(swrp);
}
/* make sure there is no further update event on this window */
ValidRect(&((WindowPtr)swrp)->portRect);
movecursor(swrp, swrp->col, swrp->row);
drawcursor(swrp, ON);
}
static
Stdwindow_doEvent(xevent)
XEventRecord *xevent;
{
register WindowPtr wp = xevent->window;
register int i;
switch (((EventRecord*)xevent)->what)
{
case activateEvt:
edit_disable();
break;
case deactivateEvt:
{StdWindowRec *srp;
edit_disable();
if ((srp = (StdWindowRec*)FrontWindow()))
if (! OurWindow(srp))
edit_enable();
break;
}
case updateEvt:
Std_updatewindow(wp);
break;
case closeEvent:
/* hide the window */
HideWindow(wp);
/* THIS PATCHED OUT CODE ALLOWS CLOSING ALL WINDOWS WHICH SHARE
THIS WINDOW POINTER AND RELEASING THEIR WINDOW RECORDS:
for (i= _NFILE-1; i>=0 ; i--)
if (_file[i].filebuf == (char*)wp)
fclosew(&_file[i]);
*/
break;
default:
/* event was not handled by us */
return (false);
}
/* event was handled somewhere above */
return (true);
}
#line 0 fclosew
int fclosew(who)
register FILE *who;
{
if (!who->window) return (EOF);
if (who != _console)
{
who->window = false;
who->InUse = false;
/* Now release the memory for the window record unless
it's the console which we never should release */
if (OurWindow(who->filebuf) && ((WindowPtr)who->filebuf != _console_wp))
{
((StdWindowRec*)who->filebuf)->signature = 0;
DisposHandle(((WindowPeek)who->filebuf)->refCon);
DisposeWindow(who->filebuf);
}
who->filebuf = NULL;
if (who == CurrentWindow)
{
CurrentWindow = _console;
Currentswrp = _console_wp;
}
}
return (0);
}
static
void clearscreenmem(swrp)
register StdWindowRec *swrp;
{
register char sp = ' ';
register char *begp, *p;
/* clear screen buffer to spaces working backwards through buffer */
p = (begp = swrp->screen) + swrp->opt.maxcol * swrp->opt.maxrow;
while (--p >= begp) *p = sp;
}
/* RMS 4/20/88 */
/* procedure to determine if MultiFinder is running by checking for the
existence of the WaitNextEvent() trap */
static int MFIsRunning()
{ /* $8F is for _MFDispatch, $9F is the unimplemented trap */
return (GetTrapAddress(0x8FL) != GetTrapAddress(0x9FL));
}
static
FILE *fopenwx(titlebar, upper_left, optionsptr, whichfilevar, ourwp)
char *titlebar;
Point upper_left;
register StdWindowOptions *optionsptr;
FILE *whichfilevar;
WindowPtr ourwp;
{
register int maxrow = 0, maxcol = 0;
register FILE *who;
register StdWindowRec *swrp;
register Boolean grow = true, goaway = true;
eventinfo et;
Init_stdio();
if (whichfilevar)
{
/* a specific file variable was specified */
who = whichfilevar;
if ((!who->StdStream) || who->InUse)
{
/* don't allow this for other than standard streams */
errno = -47; /* file busy error */
return (NULL);
}
}
else
{register int free_slot = _NFILE;
/* look thru FILE array for an open slot */
while ((--free_slot>=0) && _file[free_slot].InUse)
;
if (free_slot < 0)
{
errno = -42; /* tmfoErr - too many files open */
return (NULL);
}
who = &_file[free_slot];
if (!ourwp && optionsptr)
{
/* override defaults */
maxcol = optionsptr->maxcol;
maxrow = optionsptr->maxrow;
grow = !optionsptr->no_grow;
goaway = !optionsptr->no_goaway;
}
}
/* if ourwp is nonzero, then the window is already set up and all
we need to do is set up the file record */
if (ourwp) swrp = (StdWindowRec*) ourwp;
else
{{register int charheight;
stdio_fontset(&dummyPort);
GetFontInfo(&_sf);
charheight = (_sf.ascent + _sf.descent + _sf.leading);
/* set up default number of rows and columns depending on screen */
if (!maxrow)
maxrow = (screenHeight - upper_left.v - _TOPEDGE - _CONTROLWIDTH - 1 - charheight + 1) /
charheight;
/***************** RMS 4/20/88 ***************
*
*
* If MultiFinder is running, we'll make the console window half-height,
* so that we can see the contents while running the debugger.
*
* As soon as a possible, "MFIsRunning()" will be replaced by a
* mechanism to see if the debugger is being used.
*
**********************************************/
#ifdef _HALFWINDOW_
if (MFIsRunning()) maxrow = 11; /* half a standard screen */
#endif
if (!maxcol)
maxcol = (screenWidth - upper_left.h - _LEFTEDGE - _CONTROLWIDTH - 1 - _sf.widMax + 1) /
_sf.widMax;
/* create a pointer block big enough to accomodate the window record
and all of our stuff */
if (!(swrp = (StdWindowRec*) (NewPtr(sizeof(StdWindowRec)+maxrow*maxcol))))
{
errno = -108; /* MemFullErr - ran out of memory */
return (NULL);
}
swrp->sf = _sf;
swrp->charheight = charheight;
swrp->charwidth = _sf.widMax;
} /* just provides scoping for charheight */
swrp->toprow = swrp->col = 0;
swrp->row = maxrow - 1; /* start cursor at bottom of screen */
swrp->signature = _OURSIGNATURE;
bounds.top = upper_left.v;
bounds.left = upper_left.h;
bounds.right = bounds.left + _LEFTEDGE + maxcol * swrp->charwidth + _CONTROLWIDTH + 1;
bounds.bottom = bounds.top + _TOPEDGE + maxrow * swrp->charheight + _CONTROLWIDTH + 1 + 4;
NewWindow(swrp, &bounds, CtoPstr(titlebar), true,
(grow ? documentProc : noGrowDocProc), -1L, goaway, 0L);
PtoCstr(titlebar);
/* set up event processing hooks */
et.eventProc = Stdwindow_doEvent;
et.vscroll = 0;
PtrToHand(&et, &((WindowPeek)swrp)->refCon, sizeof et);
stdio_fontset(swrp);
if (grow)
{
InvalRect(&((WindowPtr)swrp)->portRect);
DrawControls(swrp);
DrawGrowIcon(swrp);
}
ValidRect(&((WindowPtr)swrp)->portRect);
if (optionsptr)
swrp->opt = *optionsptr;
else
{
swrp->opt.maxrow = maxrow;
swrp->viscol = swrp->opt.maxcol = maxcol;
swrp->opt.cursor_visible = true;
swrp->opt.echo_state = true;
swrp->opt._tab_width = 4;
swrp->opt.no_pull_front = false;
swrp->opt.no_grow = !grow;
swrp->opt.no_drag = false;
swrp->opt.no_goaway = !goaway;
swrp->opt.no_scroll = false;
swrp->opt.no_wrap = false;
}
swrp->visrow = maxrow;
swrp->viscol = maxcol;
/* clear screen memory to spaces */
clearscreenmem(swrp);
movecursor(swrp, swrp->col, swrp->row);
drawcursor(swrp, ON);
}
/* set all relevant items in FILE record */
who->filebuf = (char *) swrp;
who->StdStream = true;
who->InUse = true;
who->window = true;
who->rd = true; /* 11/13/87 rms - changed from FALSE */
who->wr = true;
return (who);
}
#line 0 fopenw
FILE *fopenw(titlebar, upper_left, optionsptr)
char *titlebar;
Point upper_left;
StdWindowOptions *optionsptr;
{
fopenwx(titlebar, upper_left, optionsptr, NULL, NULL);
}
#line 0 setwindow
int setwindow(windowfile)
register FILE *windowfile;
{
register StdWindowRec *swrp;
if (windowfile &&
windowfile->InUse &&
windowfile->window &&
(swrp = ((StdWindowRec*)windowfile->filebuf))->signature == _OURSIGNATURE)
{
CurrentWindow = windowfile;
Currentswrp = (WindowPtr) swrp;
_echo = swrp->opt.echo_state;
}
else
return (EOF);
return (0);
}
stdwsave(windowfile, env)
FILE *windowfile;
StdwsaveRecord *env;
{
Init_stdio();
env->fp = CurrentWindow;
env->wp = Currentswrp;
return (setwindow(windowfile));
}
stdwrestore(windowfile, env)
FILE *windowfile;
StdwsaveRecord *env;
{
if (windowfile != CurrentWindow) return (EOF);
CurrentWindow = env->fp;
Currentswrp = env->wp;
_echo = ((StdWindowRec*)Currentswrp)->opt.echo_state;
return (0);
}
#line 0 Click_On()
void Click_On(flag)
{
_click_on = flag;
}
static
draw_exit_text(xevent)
XEventRecord *xevent;
{
WindowPtr wp = xevent->window;
switch (((EventRecord*)xevent)->what)
{
case updateEvt:
SetPort(wp);
MoveTo(4, 24+_sf.descent);
DrawString("\p Click close box of this window or press Return to continue");
break;
case closeEvent:
do_exit();
default:
/* event not handled by us */
return (false);
}
/* event was handled above */
return (true);
}
static
void click_to_continue()
{
eventinfo et;
/* make sure all exit routines have been called before we
do anything */
_exiting(1);
/* if (emptyrgn) DisposeRgn(emptyrgn); - need not bother since the
entire application heap should be vaporized shortly */
if (_click_on)
{
/* cancel any pending events */
FlushEvents(everyEvent, 0);
bounds.left = bounds.top = 50;
bounds.right = 456;
bounds.bottom = 100;
/* Put up a window and handle window events
until goaway is clicked for this window */
_exit_wp = NewWindow(0L, &bounds, "\pExit Window",
true, noGrowDocProc,
-1L, true, 0L);
et.eventProc = draw_exit_text;
PtrToHand(&et, &((WindowPeek) _exit_wp)->refCon, sizeof et);
_font = systemFont;
_size = 12;
stdio_fontset(_exit_wp);
/* small event loop to process window events such as bringing
to front, resizing, dragging, etc. */
for (;;)
{EventRecord event;
while (! GetNextEvent(everyEvent, &event))
{
HiliteMenu(0);
SystemTask();
}
SetCursor(&arrow);
if (event.what == keyDown && (char) event.message == '\r')
break;
StdEvent(&event);
}
do_exit();
}
}
#line 0 Stdio_Config()
void Stdio_Config(font,size,face,mode)
int font,size,face,mode;
{
/* modify defaults */
_font = font;
_size = size;
_face = face;
_mode = mode;
}
#line 0 Stdio_config() /* lower case c since it was wrong in the manual! */
void Stdio_config(font,size,face,mode)
int font,size,face,mode;
{
Stdio_Config(font, size, face, mode);
}
void Init_stdio()
{
register StdWindowRec *swrp;
Point topleftcorner;
if (_inited && _screen) return;
if (!_inited)
{
_inited = true;
InitGraf(&thePort);
InitFonts();
InitWindows();
InitDialogs(0L);
setup_menus();
TEInit();
FlushEvents(everyEvent, 0);
HiliteMenu(0);
SystemTask();
}
if (!_screen)
{
_screen = true;
OpenPort(&dummyPort);
/* this font information must be set up for fopenw to know how
big to make the window */
topleftcorner.h = 4;
topleftcorner.v = _MBARHEIGHT + _TITLEBARHEIGHT + 4;
setwindow(fopenwx("console", topleftcorner, NULL, _console, NULL));
_console_wp = Currentswrp;
/* unlike other windows, console is multi-purpose and
so it is handled specially */
_console->rd = true;
/* set up stdout and stderr to match */
if (stdout->StdStream)
fopenwx("", topleftcorner, NULL, stdout, _console_wp);
if (stderr->StdStream)
fopenwx("", topleftcorner, NULL, stderr, _console_wp);
/* set up exit procedure */
onexit(click_to_continue);
SetCursor(&arrow);
}
if (!emptyrgn) emptyrgn=NewRgn();
}
#line 0 Set_Echo()
void Set_Echo(state)
Boolean state;
{
_echo = state;
if (CurrentWindow)
((StdWindowRec*)(Currentswrp))->opt.echo_state = state;
}
/* pdg - 6/10/86 - Stdio_MacInit() allows coexistence of Mac windows and
stdio if called with flag set to true so stdio won't
reinitialize all of the Mac stuff. */
#line 0 Stdio_MacInit()
void Stdio_MacInit(flag)
Boolean flag;
{
_inited = flag;
}
#line 0 Set_Tab
void Set_Tab(len)
int len;
{
Init_stdio();
((StdWindowRec*) Currentswrp)->opt._tab_width = len > 1 ? len : 1;
}
#line 0 gotoxy
void gotoxy(x,y)
register int x,y;
{
register StdWindowRec *swrp;
Init_stdio();
swrp = (StdWindowRec*) Currentswrp;
if ((x < swrp->opt.maxcol) && (y < swrp->opt.maxrow))
{
drawcursor(swrp, OFF);
swrp->col = x;
swrp->row = y;
movecursor(swrp, x,y);
drawcursor(swrp, ON);
}
}
#line 0 getxpos
int getxpos()
{
Init_stdio();
return (((StdWindowRec*) Currentswrp)->col);
}
#line 0 getypos
int getypos()
{
Init_stdio();
return (((StdWindowRec*) Currentswrp)->row);
}
#line 0 Get_ScreenPtr
char *Get_ScreenPtr(who)
register FILE *who;
{
Init_stdio();
if (who->InUse && who->window)
return (((StdWindowRec*) who->filebuf)->screen);
return (NULL);
}
#line 0 Get_WindowPtr
void *Get_WindowPtr(who) /* actually returns a WindowPtr! */
register FILE *who;
{
Init_stdio();
if (who->InUse && who->window)
return ((void*) who->filebuf);
return (NULL);
}
#line 0 putch
void putch(c)
register char c;
{
register StdWindowRec *swrp;
register char *screenp;
static inited=false;
if (!inited)
{
inited = true;
Init_stdio();
}
if (! Currentswrp || ! CurrentWindow->InUse) return;
if (_echo_to_printer_ && (Currentswrp == _console_wp))
(*_echo_to_printer_)(c);
SetPort(swrp = (StdWindowRec*) Currentswrp);
if (swrp != (StdWindowRec *)FrontWindow())
if (! swrp->opt.no_pull_front)
{
SelectWindow(swrp);
Std_updatewindow(swrp);
}
/* wait here if mouse is down */
while (Button());
if (c<' ')
{
switch(c)
{
case '\t':
{register int over;
Boolean newline = false;
over = swrp->opt._tab_width - (swrp->col % swrp->opt._tab_width);
if ((swrp->col + over) > swrp->opt.maxcol)
{
newline = true;
c = '\n';
over = swrp->opt.maxcol - swrp->col;
}
/* want to write spaces into those columns where tab is */
if (over > 0)
{Rect r;
screenp = swrp->screen +
(((swrp->toprow+swrp->row)%swrp->opt.maxrow) * swrp->opt.maxcol) + swrp->col - 1;
drawcursor(swrp, OFF);
/* erase character positions on screen */
r.right = (r.left = ((WindowPtr)swrp)->pnLoc.h) + over * swrp->charwidth;
r.top = (r.bottom = ((WindowPtr)swrp)->pnLoc.v + swrp->sf.descent) - swrp->charheight;
EraseRect(&r);
swrp->col += over;
while (--over>=0) *++screenp = ' ';
movecursor(swrp, swrp->col, swrp->row);
drawcursor(swrp, ON);
}
if (newline) break;
return;
}
case '\r': /* simply return cursor to start of line */
drawcursor(swrp, OFF);
swrp->col = 0;
movecursor(swrp, 0, swrp->row);
drawcursor(swrp, ON);
return;
case '\b': /* simply reposition cursor back one column */
{
/* This won't work for proportional fonts
since we don't have the true width handy
true, it could be looked up in the font...*/
drawcursor(swrp, OFF);
if (swrp->col == 0)
{
if (((swrp->row == 0) && (!swrp->opt.no_scroll))
|| swrp->opt.no_wrap)
{
drawcursor(swrp, ON);
return;
}
/* return to previous row */
if (swrp->row == 0)
swrp->row = swrp->opt.maxrow;
swrp->row--;
swrp->col = swrp->opt.maxcol;
}
swrp->col--;
movecursor(swrp, swrp->col, swrp->row);
drawcursor(swrp, ON);
return;
}
case '\f':
{Rect r;
drawcursor(swrp, OFF);
r = ((WindowPtr)swrp)->portRect;
r.right -= _CONTROLWIDTH+2;
r.bottom -= _CONTROLWIDTH+2;
EraseRect(&r);
swrp->toprow = swrp->row = swrp->col = 0;
clearscreenmem(swrp);
movecursor(swrp, 0, 0);
drawcursor(swrp, ON);
return;
}
case 7: SysBeep(2); /* Bell */
return;
}
}
drawcursor(swrp, OFF);
if ((c != '\n') && (swrp->col < swrp->opt.maxcol))
{
screenp = swrp->screen + ((swrp->toprow+swrp->row)%swrp->opt.maxrow)*swrp->opt.maxcol+swrp->col;
/* dump character into the screen buffer and
possibly draw the character */
if (swrp->col < swrp->viscol)
{
if (*screenp != ' ')
{Rect r;
/* erase this character position on screen */
r.right = (r.left = ((WindowPtr)swrp)->pnLoc.h) + swrp->charwidth;
r.top = (r.bottom = ((WindowPtr)swrp)->pnLoc.v + swrp->sf.descent) - swrp->charheight;
EraseRect(&r);
}
DrawChar(*screenp = c);
}
else
*screenp = c;
}
/* need to do a newline? */
if ((c=='\n') || ((++swrp->col >= swrp->opt.maxcol) && !swrp->opt.no_wrap))
{
if (swrp->opt.no_scroll)
/* if we don't scroll, toprow doesn't move and the characters
wrap back to the first screen line */
swrp->row = (swrp->row + 1) % swrp->opt.maxrow;
else
{
if (swrp->row >= swrp->opt.maxrow-1)
{Rect scrollrect;
register int i;
register char *p;
scrollrect = ((WindowPtr)swrp)->portRect;
scrollrect.top += _TOPEDGE;
scrollrect.left += _LEFTEDGE;
scrollrect.right -= _CONTROLWIDTH+1;
scrollrect.bottom -= _CONTROLWIDTH+1;
ScrollRect(&scrollrect,0,-swrp->charheight,emptyrgn);
/* toprow points to the new first line */
swrp->toprow = (swrp->toprow + 1) % swrp->opt.maxrow;
p = swrp->screen + ((swrp->toprow + swrp->opt.maxrow - 1) % swrp->opt.maxrow) * swrp->opt.maxcol - 1;
/* clear the reallocated line in the buffer */
for (i=swrp->opt.maxcol; i; i--)
*++p = ' ';
}
else
++swrp->row;
}
swrp->col = 0;
movecursor(swrp, 0, swrp->row);
}
drawcursor(swrp, ON);
}